dhhagan / py-opc

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

USB connection not working #63

Closed krkol closed 6 years ago

krkol commented 6 years ago

I am trying to connect an OPCN2 to a Raspberry pi 3 using the USB-SPI connection. I've checked that the connection is in ACM0, the OPC has firmware version 18, and I've downloaded the pyusbiss version 0.2.0. I think that the problem might be related to the libraries running on python 2.7, but I have python 3.4.2 installed and all of the text files for the program that I open have (3.4.2) after the file extension .py. Here are the errors I am getting:

Traceback (most recent call last): File "OPCUSBtest.py", line 13, in alpha = opc.OPCN2(spi) File "/usr/local/lib/python2.7/dist-packages/opc/init.py", line 238, in init super(OPCN2, self).init(spi_connection, model='N2', **kwargs) File "/usr/local/lib/python2.7/dist-packages/opc/init.py", line 64, in init raise FirmwareVersionError(msg) opc.exceptions.FirmwareVersionError: Your firmware version could not be automatically detected. This is usually caused by bad wiring or a 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

or /usr/local/lib/python2.7/dist-packages/opc/init.py:522: UserWarning: Data transfer was incomplete. warnings.warn("Data transfer was incomplete.")

I am using the exact same code as Davis has posted on the main page.

Thank you for any advice!

dhhagan commented 6 years ago

Hi @krkol Could you tell me which version of this library you are using? If you issue the command pip list at your terminal/command line, it should spit out versions for all libraries. In addition, could you attach the code in OPCUSBtest.py? It sounds like it is using python27 to run the code instead of python34; try running with $ python3 OPCUSBtest.py and see what happens? I don't think the python version is the issue, but it's worth a shot.

DancingQuanta commented 6 years ago

Did you install pyusbiss via pip? Pyusbiss currently works for python 3 not 2.7 at the moment. Do you have python 3?

On Thu, 12 Apr 2018, 02:22 David H Hagan, notifications@github.com wrote:

Hi @krkol https://github.com/krkol Could you tell me which version of this library you are using? If you issue the command pip list at your terminal/command line, it should spit out versions for all libraries. In addition, could you attach the code in OPCUSBtest.py? It sounds like it is using python27 to run the code instead of python34; try running with $ python3 OPCUSBtest.py and see what happens? I don't think the python version is the issue, but it's worth a shot.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/dhhagan/py-opc/issues/63#issuecomment-380644697, or mute the thread https://github.com/notifications/unsubscribe-auth/AIB3Vad35lEx8pYBO2q-lDbFQ5tyxmpNks5tnqxJgaJpZM4TQ97y .

krkol commented 6 years ago

Hi @dhhagan, Thank you for the help! We are using version 1.5.0 of py-opc. And then we are using version 0.2.0 of pyusbiss. I got everything to run through python 3 and it's giving the same errors. I can hear the alphasense fan running, so I know it has power. I installed everything with pip3. The raspberry pi has both python 2.7 and python 3.4 installed. I am using the code pasted below:

from usbiss.spi import SPI import opc

Build the connector

spi = SPI("/dev/ttyACM0")

Set the SPI mode and clock speed

spi.mode = 1 spi.max_speed_hz = 500000

alpha = opc.OPCN2(spi)

Turn on the device

alpha.on()

Read the histogram

alpha.histogram()

Turn the device off

alpha.off()

DancingQuanta commented 6 years ago

Please post the traceback when you run the code through python 3.

krkol commented 6 years ago

The error message that I get is either: /usr/local/lib/python3.4/dist-packages/opc/init.py:522: UserWarning: Data transfer was incomplete. warnings.warn("Data transfer was incomplete.")

or Traceback (most recent call last): File "/usr/local/lib/python3.4/dist-packages/opc/init.py", line 55, in init self.firmware['version'] = int(re.findall("\d{3}", self.read_info_string())[-1]) IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/lib/python3.4/dist-packages/opc/init.py", line 59, in init self.firmware['version'] = int(re.findall("\d{1}", self.read_info_string())[-1]) IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "OPCUSBtest.py", line 15, in alpha = opc.OPCN2(spi) File "/usr/local/lib/python3.4/dist-packages/opc/init.py", line 238, in init super(OPCN2, self).init(spi_connection, model='N2', **kwargs) File "/usr/local/lib/python3.4/dist-packages/opc/init.py", line 64, in init raise FirmwareVersionError(msg) opc.exceptions.FirmwareVersionError: Your firmware version could not be automatically detected. This is usually caused by bad wiring or a 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

DancingQuanta commented 6 years ago

@dhhagan In parsing the version of firmware I think it would be more useful to execute read_info_string() function and store output in a variable before parsing it rather than all in one liner. This way we can check if output of read_info_string() is valid.

dhhagan commented 6 years ago

@DancingQuanta That's a great idea, in addition, maybe add a debug arg/kwarg that prints debugging info to the console. Do you want to take a stab at it and send a PR? If not, I can do it next week probably.

DancingQuanta commented 6 years ago

I do not have Alphasense's version of USB-ISS where they packaged the USB-ISS in a compact case with a wire with a small connector (micro-usb?). @dhhagan do you have such packaged USB-ISS? If you do, can you figure out how to do a SPI loopback test on it? By shorting two of the connector's contacts. I wanted to make sure @krkol have a functioning USB-ISS module with proper connections.

A debug state would be a great idea, preferably managed with the import logger module. Perhaps if @krkol have time, they could work on the debug state.

krkol commented 6 years ago

I tried using another wrapper that I found written by @dhhagen that is available here: https://www.snip2code.com/Snippet/553675/Run-Alphasense-OPC-N2. There were a few things to edit in the code to match the newest version of all of the libraries. This worked much better. The problem seemed to be that the connection would sometimes happen, but sometimes not. When an error gets thrown, there needs to be a way to try again. Maybe the USB line gets "busy", I know this happens with serial connections. It seemed to work best if I restarted the pi and tried the program fresh.

dhhagan commented 6 years ago

You can fairly easily unscrew the cover of the Alphasense USB-ISS converter and test it that way - but it sounds like @krkol got it to work eventually (confirm?). I like all of these suggestions and will implement them ASAP (maybe later this week). @krkol I typically write my firmware in that way (trying several times to ensure the connection is good), but I could add a max_retries argument that would keep trying until the connection is successful. Does that sound like a working solution?

DancingQuanta commented 6 years ago

Does this connection problem occurs more with USB than with direct SPI? I do remember that @dhhagan added a sleep() to deal with this issue earlier. If the issue is unique to USB then we need to understand what is happening there. I thought maybe timing mismatch or something else.

teokino commented 6 years ago

Hello! I have the same issue as @krkol. Happens almost every time that launching the command "alpha = opc.OPCN2(spi)" I got the error message: "Startup Error: Your firmware version could not be automatically detected. This is usually caused by bad wiring or a poor power supply [..]".

My configuration is about a RPi 3 Model B and a OPCN2 connected using the USB-SPI device and Python 3.5.3. Below I have attached the output of pip3 list:

automationhat (0.1.0) blinker (1.3) blinkt (0.1.1) buttonshim (0.0.2) Cap1xxx (0.1.3) chardet (2.3.0) click (6.6) colorama (0.3.7) cryptography (1.7.1) drumhat (0.1.0) envirophat (1.0.0) ExplorerHAT (0.4.2) Flask (0.12.1) fourletterphat (0.1.0) gpiozero (1.4.1) idna (2.2) itsdangerous (0.24) jedi (0.10.2) Jinja2 (2.8) keyring (10.1) keyrings.alt (1.3) MarkupSafe (0.23) mcpi (0.1.1) microdotphat (0.2.1) mote (0.0.3) motephat (0.0.2) numpy (1.12.1) oauthlib (2.0.1) pantilthat (0.0.5) pgzero (1.2) phatbeat (0.1.0) pianohat (0.1.0) picamera (1.13) picraft (1.0) piglow (1.2.4) pigpio (1.38) Pillow (4.0.0) pip (9.0.1) py-opc (1.5.0) pyasn1 (0.1.9) pycrypto (2.6.1) pygame (1.9.3) pygobject (3.22.0) pyinotify (0.9.6) PyJWT (1.4.2) pyOpenSSL (16.2.0) pyserial (3.4) python-apt (1.1.0b5) pyusbiss (0.2.0) pyxdg (0.25) rainbowhat (0.0.2) requests (2.12.4) requests-oauthlib (0.7.0) RPi.GPIO (0.6.3) RTIMULib (7.2.1) scrollphat (0.0.7) scrollphathd (1.2.1) SecretStorage (2.3.1) sense-emu (1.0) sense-hat (2.2.0) setuptools (33.1.1) simplejson (3.10.0) six (1.10.0) skywriter (0.0.7) sn3218 (1.2.7) spidev (3.3) thonny (2.1.16) touchphat (0.0.1) twython (3.4.0) unicornhathd (0.0.3) urllib3 (1.19.1) Werkzeug (0.11.15) wheel (0.29.0)

The strange is that after few attemps, I managed to access OPCN2 and show you these outputs. The only thing I do not understand well is because the "LaserDACVal" value (# 115) is different from (# 230) than the one on the py-opc documentation.

>>>alpha = opc.OPCN2(spi)

>>>alpha Alphasense OPC-N2v18.2

>>>alpha.read_firmware() {'minor': 2, 'major': 18, 'version': 18.2}

>>>alpha.read_pot_status() {'LaserON': 1, 'FanON': 1, 'LaserDACVal': 115, 'FanDACVal': 255}

Another strange thing but I do not think it is linked with the py-opc problem is that the usbiss library is accessible from python 3.5.3 only with not sudoer. In that case python does not recognize the installed package as well as pyserial.

At first I thought the problem was related to the fact that OPCN2 is connected to a powered hub and connected with a 3 meter USB 2.0 A-B cable. I have verified using the Alpasense software in Windows and this is not the cause of the problem.

As you can see the histogram values are null, instead using "alpha.pm()" I got some concrete values.

>>>alpha.histogram() {'Sampling Period': 48.6558952331543, 'Bin 13': 0.0, 'Bin3 MToF': 0.0, 'Bin 7': 0.0, 'Bin 14': 0.0, 'Pressure': None, 'Bin 4': 0.0, 'Bin1 MToF': 0.0, 'Bin 2': 0.0, 'Bin 0': 0.0, 'Bin 1': 0.0, 'Temperature': None, 'Bin 12': 0.0, 'Bin 9': 0.0, 'Bin 8': 0.0, 'Bin5 MToF': 0.0, 'PM2.5': 0.0, 'SFR': 4.5, 'Checksum': 0, 'PM1': 0.0, 'Bin 6': 0.0, 'Bin7 MToF': 0.0, 'Bin 10': 0.0, 'Bin 5': 0.0, 'PM10': 0.0, 'Bin 15': 0.0, 'Bin 11': 0.0, 'Bin 3': 0.0} >>> alpha.pm() {'PM10': 4.638123989105225, 'PM2.5': 2.157435178756714, 'PM1': 1.5189740657806396}

Thank you

DancingQuanta commented 6 years ago

USB connection: Yes you have to try a number of times before you could connect. I suggest putting alpha = opc.OPCN2(spi) in a while loop so that this command can repeat until successful connection. Here is an example:

alpha = None
while alpha is None:
    sleep(10)
    try:
        # connect
        alpha = opc.OPCN2(spi)
    except:
         pass

Perhaps a form of this can be incorporated in @dhhagan's library with max_retries limiting number of attemps in a for loop.

Sudoer: Can you explain more on this please? Why do you need to use sudo? As a author of usbiss library I do not have any awareness that I could influence this sudo. I think you have two different set of packages on your device; root and user. You probably had installed pyusbiss into user where root cannot see.

teokino commented 6 years ago

I am grateful for the kind reply. The need to be root is not necessarily linked to OPC-N2 but to the fact that the collected data are uploaded to a web server and to do this I must be superuser. In any case, I will solve it in some way.

Although I have read the bees I can not understand the difference between alpha.histogram () and alpha.histogram (False). It would seem that alpha.pm () gives PM point values with the corrections obtained from the histogram bin values.

As you can see:

alpha.histogram()
{'Temperature': None, 'PM2.5': 0.1172892227768898, 'Bin 8': 0.0022492796358061116, 'Bin5 MToF': 9.333333333333334, 'Bin 7': 0.0, 'Bin 6': 0.004498559271612223, 'Bin 15': 0.0, 'Bin 3': 0.011246398179030559, 'Bin7 MToF': 0.0, 'Bin 1': 0.022492796358061118, 'Pressure': None, 'Bin1 MToF': 7.0, 'Bin 4': 0.0, 'Bin 13': 0.0, 'Bin 12': 0.0, 'Bin3 MToF': 7.0, 'PM1': 0.08618641644716263, 'Bin 9': 0.0, 'Bin 14': 0.0, 'Bin 2': 0.008997118543224446, 'PM10': 0.17635871469974518, 'SFR': 4.624794960021973, 'Checksum': 101, 'Bin 10': 0.0, 'Bin 5': 0.006747838907418335, 'Sampling Period': 96.13113403320312, 'Bin 11': 0.0, 'Bin 0': 0.1709452523212645}
[alpha.histogram(False)
{'Temperature': None, 'PM2.5': 1.327651023864746, 'Bin 8': 0, 'Bin5 MToF': 0.0, 'Bin 7': 1, 'Bin 6': 0, 'Bin 15': 0, 'Bin 3': 1, 'Bin7 MToF': 9.666666666666666, 'Bin 1': 8, 'Pressure': None, 'Bin1 MToF': 6.666666666666667, 'Bin 4': 0, 'Bin 13': 0, 'Bin 12': 0, 'Bin3 MToF': 8.333333333333334, 'PM1': 1.12907075881958, 'Bin 9': 0, 'Bin 14': 0, 'Bin 2': 1, 'PM10': 1.655051827430725, 'SFR': 4.609755039215088, 'Checksum': 58, 'Bin 10': 0, 'Bin 5': 0, 'Sampling Period': 4.422698497772217, 'Bin 11': 0, 'Bin 0': 47}]
alpha.pm()
{'PM2.5': 1.7809854745864868, 'PM10': 1.8168011903762817, 'PM1': 1.4750860929489136}
DancingQuanta commented 6 years ago

I suggest opening a new issue on the PMs values, this issue is about USB connectivity and so it will get confusing fast if people ask a lot of different things here. If the vendor supplied software on Windows can fetch the PM values for you then report that in the new issue so the @dhhagan can give his opinion on what ailing you.

Unsolicited advice on sudo, avoid sudo if possible in routine operations such as uploading data. This will make things a bit smoother as sudo can be a bit unpredictable if not understood properly and can be security risk if used liberally.

dhhagan commented 6 years ago

I agree with opening a new issue @DancingQuanta. In other news, changes including logging and retrying connections are now available on the dev branch. I will test here in a few minutes.

dhhagan commented 6 years ago

Also, @teokino The difference between the two histograms you were outputting is that you are reading them in different units.

Number Concentration

Output the binned values in units of # of particles per cubic centimeter.

$ alpha.histogram(number_concentration=True)

Bin Values

Output the binned values as the number of particles in a given bin since the last time you emptied the bin (i.e. called the histogram function)

$ alpha.histogram(number_concentration=False)

I thought I had explained this in the docs (http://py-opc.readthedocs.io/en/latest/#opc.OPCN2.histogram), but if I can make it more clear, please feel free to comment here or to send recommended updates to the documentation.

dhhagan commented 6 years ago

Okay, for everyone on this issue, version 1.6 is now released via GitHub (not yet on PyPi). Once a few of you can test/verify the issues are solved, I will issue a new release. Let me know if you have any questions/comments/concerns.

biogis commented 6 years ago

Hello, Using the last py-opc version (1.6) on python 2.7 and a direct connection on a rPi3 GPIO, I still got the same error:

I got 6 times the following error message: ERROR:opc:Could not parse the fimrware version from Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/opc/init.py", line 77, in init self.firmware['version'] = int(re.findall("\d{3}", infostring)[-1]) IndexError: list index out of range

and then the final:


FirmwareVersionError Traceback (most recent call last)

in () ----> 1 alpha = opc.OPCN2(spi) /usr/local/lib/python2.7/dist-packages/opc/__init__.pyc in __init__(self, spi_connection, **kwargs) 258 """ 259 def __init__(self, spi_connection, **kwargs): --> 260 super(OPCN2, self).__init__(spi_connection, model='N2', **kwargs) 261 262 firmware_min = 14. # Minimum firmware version supported /usr/local/lib/python2.7/dist-packages/opc/__init__.pyc in __init__(self, spi_connection, firmware, max_cnxn_retries, retry_interval_ms, **kwargs) 69 """ 70 ---> 71 raise FirmwareVersionError(msg) 72 73 # store the info_string FirmwareVersionError: Your firmware version could not be automatically detected. This is usually caused by bad wiring or a 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. Another option would be to increase the max_cnxn_retries variable if you feel the serial communication is being held up for some reason. Any idea how to solve this? Thanks an dbest regards
dhhagan commented 6 years ago

Hi @biogis Could you post the code you used to try this? Specifically interested in the clock speed..

biogis commented 6 years ago

Hi,

I used the same code on the readme doc:

import spidev import opc from time import sleep

spi = spidev.SpiDev() spi.open(0, 0) spi.mode = 1 spi.max_speed_hz = 500000

alpha = opc.OPCN2(spi)

biogis commented 6 years ago

Hello,

It finally worked, the MOSI and MISO were wrong in the GPIO... Sorry...

dhhagan commented 6 years ago

@biogis No worries. Thanks for letting us know!