dhhagan / py-opc

Python wrapper for the Alphasense OPC-N2 built around py-spidev
MIT License
30 stars 26 forks source link

Connection to v18 from raspberry pi #40

Closed lionfish0 closed 7 years ago

lionfish0 commented 7 years ago

Hello, Thanks for the library. I'm having some trouble connecting to the Alphasense OPC N2.

First I'd like to note that I've not connected a separate power supply to the device (I'm using the 5V pin on the raspberry, using a 1.5Amp 5V supply, however, I've measured the voltage while the device is running and it's at a steady 5.01V).

I ran spidev_test as recommended and got something that looks promising:

pi@raspberrypi:~ $ ./spidev_test -D /dev/spidev0.0
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

79 BF FA 63 7C EF 
FE F9 80 00 62 00 
5F 3B FF 7C EF FE 
F9 BF FB 31 7C EF 
FE 79 BF FA 63 7C 
FB E7 5F BF DA 63 
5F DF 

I tried sending commands, but maybe I've not set something up correctly, I do think it must be sort-of working as I get 'regular' patterns in the response data, and I some how manage to turn on and off the fan sometimes!

I think this has firmware v18 (as it says that at the top of the excel spreadsheet that's on the onboard sd card).

When I run the following code,

import spidev
import opc

# Open a SPI connection on CE0
spi = spidev.SpiDev()
spi.open(0, 0)
spi.mode = 0b01
spi.max_speed_hz = 500000

try:
    alpha = opc.OPCN2(spi)
except Exception as e:
    print ("Startup Error: {}".format(e))
else:
    alpha.on()
    print alpha.histogram()
    alpha.off()

I get:


pi@raspberrypi:~ $ sudo python test.py 
Startup Error: 
                        Your firmware version could not be automatically detected. This is usually caused
                        by a bad wiring or poor power supply. If niether of these are likely candidates, please
                        open an issue on the GitHub repository at https://github.com/dhhagan/py-opc/issues/new

pi@raspberrypi:~ $ sudo python test.py 
Startup Error: 
                        Your firmware version could not be automatically detected. This is usually caused
                        by a bad wiring or poor power supply. If niether of these are likely candidates, please
                        open an issue on the GitHub repository at https://github.com/dhhagan/py-opc/issues/new

pi@raspberrypi:~ $ sudo python test.py 
/usr/local/lib/python2.7/dist-packages/opc/__init__.py:524: UserWarning: Data transfer was incomplete.
  warnings.warn("Data transfer was incomplete.")

I'll mess around with spidev_test (I'll try sending different payloads and set up the SPI mode correctly, etc). But if you've any suggestions too that would be fantastic.

Thanks.

dhhagan commented 7 years ago

Hey @lionfish0 . Have you hooked up the OPC-N2 via the GPIO pins? Or directly via the SPI-USB converter?

lionfish0 commented 7 years ago

Sorry, I should have said - via the GPIO pins. I'll add more info this evening when I get home (e.g. I can't remember the pinouts etc). Thanks for your reply!

Edit: I should say that, if I unplug the connector the spidev_test command returns 00 00 00 00 00...etc, so hopefully that's a good sign too! Thanks again for your help.

lionfish0 commented 7 years ago

I think I've got something working.

First the pin outs:

OPC GPIO    Notes
---------------------
 1    2    5V Power
 2   23    SPIO SCLK
 3   21    SPIO MISO
 4   19    SPIO MOSI
 5   20    GND
 6    6    GND

I've altered the spidev_test program. It now just sends the 0x3F command, and outputs ASCII characters instead of the 8bit hex pairs:

pi@raspberrypi:~ $ ./spidev_t -s 10000 -H 0 -d 10000 -D /dev/spidev0.0
spi mode: 1
bits per word: 8
max speed: 10000 Hz (10 KHz)

�OPC-N2 FirmwareVer=OPC-018.2..............................

So I'm able to read back the firmware version. I find it doesn't work at high clock speeds (over 60kHz). The delay (-d) seems unnecessary.

The first character (the black question mark symbol) is 0xF3.

So I'm guessing the hardware connection etc is ok, but I need to work out why the python code doesn't work.

edit, I tried using the spidev python library, with that command;

import spidev
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 5000
spi.mode = 0b01
to_send = [0x3F]
spi.xfer(to_send)
resp = spi.readbytes(30)
print ''.join([chr(r) for r in resp])

This python program does print out the OPC version string back from the device:

pi@raspberrypi:~ $ python test_simple.py 
OPC-N2 FirmwareVer=OPC-018.2..

Interestingly the first character is the letter O, not the 0xF3 character, so that seems an improvement.

dhhagan commented 7 years ago

@lionfish0 Ahh. Try plugging Pin 5 into GPIO pin 24 (CE0). You probably need a slave select pin! Have you already tried that?

lionfish0 commented 7 years ago

Sorry, not sure if you saw my last comment. I've made more progress, think I've got it all working!

I basically ended up adding a couple of sleeps which seem to solve things. I'm not finding it necessarily 100% reliable, occasionally it says there's a transfer error, I'll investigate that in a sec, in the meantime, here's my code:

import spidev
import opc
from time import sleep
# Open a SPI connection on CE0
spi = spidev.SpiDev()
spi.open(0, 0)

# Set the SPI mode and clock speed
spi.mode = 0b01
spi.max_speed_hz = 10000

#get it used to sending things!  
to_send = [0x3F]
spi.xfer(to_send);

#wait a bit.       
sleep(1.0)
try:
    alpha = opc.OPCN2(spi)
except Exception as e:
    print ("Startup Error: {}".format(e))
print alpha

print alpha.on()
sleep(1.0) #give it time to turn on...

    # Read the histogram and print to console
print alpha.histogram()

And the output:


pi@raspberrypi:~ $ python test.py
Alphasense OPC-N2v18.2
True
{'Temperature': None, 'Bin 10': 0.0, 'SFR': 3.700000047683716, 'Bin 12': 0.0, 'Bin 13': 0.0, 'Bin 14': 0.0, 'Bin 15': 0.0, 'PM2.5': 0.0, 'Bin1 MToF': 0.0, 'Pressure': None, 'Bin 11': 0.0, 'Bin5 MToF': 0.0, 'PM1': 0.0, 'Bin7 MToF': 0.0, 'Checksum': 0, 'Bin3 MToF': 0.0, 'PM10': 0.0, 'Bin 8': 0.0, 'Bin 9': 0.0, 'Bin 6': 0.0, 'Bin 7': 0.0, 'Bin 4': 0.0, 'Bin 5': 0.0, 'Bin 2': 0.0, 'Bin 3': 0.0, 'Bin 0': 0.0, 'Bin 1': 0.0, 'Sampling Period': 8.829802513122559}
pi@raspberrypi:~ $ python test.py
Alphasense OPC-N2v18.2
True
{'Temperature': None, 'Bin 10': 0.0, 'SFR': 3.700000047683716, 'Bin 12': 0.0, 'Bin 13': 0.0, 'Bin 14': 0.0, 'Bin 15': 0.0, 'PM2.5': 7.043149948120117, 'Bin1 MToF': 6.666666666666667, 'Pressure': None, 'Bin 11': 0.0, 'Bin5 MToF': 9.333333333333334, 'PM1': 4.846642971038818, 'Bin7 MToF': 12.333333333333334, 'Checksum': 550, 'Bin3 MToF': 9.333333333333334, 'PM10': 7.3570027351379395, 'Bin 8': 0.0, 'Bin 9': 0.0, 'Bin 6': 0.055977902259907675, 'Bin 7': 0.01865930075330256, 'Bin 4': 0.2612302105462358, 'Bin 5': 0.11195580451981535, 'Bin 2': 1.7912928723170456, 'Bin 3': 1.2128545489646663, 'Bin 0': 4.123705466479866, 'Bin 1': 2.6869393084755684, 'Sampling Period': 14.484479904174805}

Thanks again for your help! I'll play about with it now and see how if I can get rid of the sleeps etc.

dhhagan commented 7 years ago

Great to here! The sleeps are more or less how I usually operate it. There is rarely an instance where you don't need them. Once up and running, each time you call histogram() or pm() it will reset the histogram which shouldn't be done at more than 1Hz. The default setting with the Alphasense software is something like 1 sample every 1.4 seconds.

lionfish0 commented 7 years ago

Ah, ok - I'll look into the sampling rate etc.

Got it hooked up to thingspeak now: https://thingspeak.com/channels/212257/charts/1?bgcolor=%23ffffff&color=%23d62020&dynamic=true&results=6000&type=line

We're going to buy a couple more and use them as part of a network of air quality monitors in Kampala (some of the monitors will be on motorbike taxis!). Thanks!

dhhagan commented 7 years ago

@lionfish0 Did you end up connecting the CS pin? Or did it work without? And that's awesome! Good luck!

lionfish0 commented 7 years ago

I did connect up the CS pin. I think I had it connected a week ago, but had tried with the GND pin instead to see if CS wasn't working, if that makes sense? I switched back to using the CS pin on the pi again, but I don't know if that made a difference; I think it was the sleeps that did it.

dhhagan commented 7 years ago

@lionfish0 Okay! I would be surprised and (very) confused if it worked without the CS pin. You could always check with a logic analyzer if you have one. I'm going to go ahead and close this though, since you were able to get it working..

beleme commented 7 years ago

@lionfish0 hello I have equal this problem how can you solved this problem?

please help