PyLabRobot / pylabrobot

interactive & hardware agnostic SDK for lab automation
https://docs.pylabrobot.org
MIT License
177 stars 62 forks source link

pylibftdi cannot find the CLARIOstar #38

Closed DavidBellamy closed 8 months ago

DavidBellamy commented 1 year ago

I would love to try out the CLARIOstar class to control our instrument, but I am getting an error during pylabrobot's set up of the plate reader. A minimal reproducible example follows.

Environment setup

I began by installing libftdi on MacOS with brew install libftdi.

I then installed pylabrobot from source using:

git clone https://github.com/pylabrobot/pylabrobot.git
cd pylabrobot
pip install -e '.[dev]'

The [dev] extras include pylabrobot's [plate_reading] extras, which itself includes an installation of pylibftdi – a Python library that wraps libftdi for communication with FTDI USB devices.

The Erroring Code

I attempt to run the following code:

import asyncio

from pylabrobot.plate_reading.clario_star import CLARIOStar
from pylabrobot.plate_reading.plate_reader import PlateReader

async def main():
    pr = PlateReader(name="plate reader", backend=CLARIOStar())
    await pr.setup()  # error occurs here
    return 0

data = asyncio.run(main())

But I encounter an error at await pr.setup().

Debugging Efforts

I can trace this error into the CLARIOStar class' setup() method, where I can see that USE_FTDI is set to True. The error occurs precisely on the line: self.dev = Device() within CLARIOStar.setup(). Seeing as this is primarily an issue with pylibftdi/FTDI and not pylabrobot, I tried troubleshooting it for several hours before posting here. I tried moving to a Windows machine and installing libftdi and libusb there. I tried using WSL on the Windows machine as well, but later realized that WSL has issues accessing USB.

Regardless of what OS I used, the output of python3 -m pylibftdi.examples.list_devices was always blank. However, using system_profiler SPUSBDataType on MacOS, I could see the CLARIOstar listed there. Similarly, I could see it listed in Device Manager on Windows. I tried adding the product ID (PID) to pylibftdi's USB_PID_LIST variable, per the documentation's recommendation here: https://pylibftdi.readthedocs.io/en/latest/how_to.html#can-i-use-pylibftdi-with-device-xyz

But the device list remained empty and thus the error remained.

Questions

Has anyone here encountered this issue with pylabftdi? How were you able to "find" the CLARIOstar using pylibftdi? More specifically, what OS were you successful with and what are the environment set up steps I should follow?

Thank you very much in advance!

rickwierenga commented 1 year ago

Thank you for flagging this and for the detailed report.

I also had this issue with the plate reader at first, and fixed it by editing driver.py in the library (as you mentioned) to what is listed below.

FTDI_VENDOR_ID = 0x0403
USB_VID_LIST = [FTDI_VENDOR_ID, 0xc251]
USB_PID_LIST = [0x6001, 0x6010, 0x6011, 0x6014, 0x6015, 0xbb68, 0x1705]

I added 0xc251 to USB_VID_LIST and 0xbb68 to USB_PID_LIST. 0x1705 is for another device.

I'll be sure to update the documentation soon. Could you just confirm this fix works for you?

Additionally--you have probably have seen this but just to make it explicit--let me warn you that the plate reader backend has limited functionality compared to the official GUI right now. I'll be very happy to help with future troubleshooting / adding new features, just want to make sure your expectations are realistic.

DavidBellamy commented 1 year ago

My pleasure! Love the work you've been doing. I'll try this out in an hour or so and get back to you after some more attempts.

Do you recall what operating system you were using when you succeeded to connect? Second, did you need to change any of the driver software installed for the CLARIOstar? And finally, do you recall how you installed and set up libftdi/libusb so that pylibftdi could properly find and use the relevant binaries?

And yes, I am aware that the backend has limited functionality compared to the GUI. No worries, I am keen on the proof of concept even if it is fairly basic functionality for now. I also might like to contribute some additional functionality if possible!

rickwierenga commented 1 year ago

Great to hear!

I have been using my Mac. I did not change drivers, except for installing libftdi (using Homebrew iirc).

DavidBellamy commented 1 year ago

I tried your suggestion but to no avail unfortunately. Here is some more potentially diagnostic information:

> brew info libftdi
==> libftdi: stable 1.5 (bottled)
Library to talk to FTDI chips
https://www.intra2net.com/en/developer/libftdi
/opt/homebrew/Cellar/libftdi/1.5_2 (58 files, 1.1MB) *
  Poured from bottle using the formulae.brew.sh API on 2023-09-12 at 12:10:37
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/lib/libftdi.rb
License: LGPL-2.1-only
==> Dependencies
Build: cmake ✘, pkg-config ✘, swig ✘
Required: boost ✔, confuse ✔, libusb ✔
==> Analytics
install: 877 (30 days), 2,156 (90 days), 4,447 (365 days)
install-on-request: 145 (30 days), 361 (90 days), 629 (365 days)
build-error: 1 (30 days)

I don't have the build dependencies installed on Mac (cmake, pkg-config, swig), but I don't think those are necessary since I'm not building libftdi from source (I'm installing a bottled version of it). The dependencies for running libftdi (boost, confuse, libusb) seem to be installed.

When I check pylibftdi info in the venv that I'm working out of I see

> python3 -m pylibftdi.examples.info
pylibftdi version     : 0.21.0
libftdi version       : libftdi_version(major=1, minor=5, micro=0, version_str='1.5', snapshot_str='unknown')
libftdi library name  : /opt/homebrew/lib/libftdi1.dylib
libusb version        : libusb_version(major=1, minor=0, micro=26, nano=11724, rc='', describe='http://libusb.info')
libusb library name   : /opt/homebrew/lib/libusb-1.0.dylib
Python version        : 3.9.17
OS platform           : macOS-13.4-arm64-arm-64bit

Interesting to note that when I run this same command within a conda environment (instead of a virtualenv), libftdi and libusb are not detected:

> python3 -m pylibftdi.examples.info
pylibftdi version     : 0.21.0
libftdi library       : Missing
libusb library        : Missing
Python version        : 3.10.10
OS platform           : macOS-13.4-arm64-arm-64bit

That being said, in my Macbook's System Information app, I can see the CLARIOstar under USB devices. My Macbook only has USB C ports, so I'm using a belkin USB 2->C adapter. I'm not sure if that could cause any issue but regardless I have this problem on the Windows computer and it has USB 2 ports.

Screenshot 2023-09-13 at 9 28 10 AM

The VID and PID of our CLARIOstar differs from the numbers you provided above, which is interesting.

rickwierenga commented 1 year ago

Strange... My first guess would be to change the values in pylibftdi to reflect those of your machine. I also use a USB adapter for all PLR work, and it has never caused issues for me, so I would be surprised if it does for you. To double check, you could confirm that the vendor/product ID are the same on your Windows computer that does not use an adapter.

DavidBellamy commented 1 year ago

Yeah that was the first thing I tried a couple days ago but still no device detected. Good to know that the USB adapter shouldn't be causing any issue. The VID and PID are indeed the same across the computers I've tried. So I'm still stuck on this.

rickwierenga commented 1 year ago

Could you make and share a Wireshark capture on the Windows machine when running a very simple measurement using the official software?

rickwierenga commented 8 months ago

Closing due to inactivity. Please re-open if this is still an issue.