python-seabreeze icon indicating copy to clipboard operation
python-seabreeze copied to clipboard

QE Pro cannot be reconnected without replugging

Open positron96 opened this issue 11 months ago • 6 comments

Hi. We are using QE Pro spectrometer and pyseabreeze backend. When we close our python program, next attempt to start it fails with this error (relevant stacktrace):

  File "...\.venv\Lib\site-packages\seabreeze\spectrometers.py", line 135, in from_serial_number
    return cls.from_first_available()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...\.venv\Lib\site-packages\seabreeze\spectrometers.py", line 111, in from_first_available
    return cls(dev)
           ^^^^^^^^
  File "...\.venv\Lib\site-packages\seabreeze\spectrometers.py", line 80, in __init__
    self.open()  # always open the device here to allow caching values
    ^^^^^^^^^^^
  File "...\.venv\Lib\site-packages\seabreeze\spectrometers.py", line 372, in open
    self._dev.open()
  File "...\.venv\Lib\site-packages\seabreeze\pyseabreeze\devices.py", line 380, in open
    self._serial_number = self.get_serial_number()
                          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "...\.venv\Lib\site-packages\seabreeze\pyseabreeze\devices.py", line 423, in get_serial_number      
    serial_len = ord(protocol.query(0x00000101))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: ord() expected a character, but string of length 8 found

Seems like the spectrometer continues to send data from the previous session. The only way to connect is to unplug the spectrometer from USB and replug it back. Then the code connects fine.

Is there a shutdown sequence I am missing when I close the program?

positron96 avatar Mar 27 '25 09:03 positron96

Hi @positron96

Can you provide a minimal code example that causes the issue?

Thanks, Andreas

ap-- avatar Mar 27 '25 10:03 ap--

Hello @ap-- ,

I am having a very similar problem. I have a test script setup that connects to the spectrometer, disconnects from it (using close()) and then reconnects to it. The script runs as expected (successfully) but, re-running the script hangs the spectrometer. I found that the only way to re-run the script is to restart the spectrometer by unplugging and re-plugging the USB.

Script:

import seabreeze.spectrometers as sb

spectrometer = None

def get_spectrometers():
   try:			
       devices = sb.list_devices()
       print(devices)
       if devices:
           return devices
       else:
           return None
   except Exception as e:
       print(f"Error listing spectrometers: {e}")
       return None
			
def connect_to_spectrometer(device):
   global spectrometer
   if (device):
       print(f"Attempting connection to: {device}")
       try:
           spectrometer = sb.Spectrometer(device)
           
           print(f"Connected to spectrometer {device}")
           return f"OK"
       except Exception as e:
           return e
   else:
       return "Invalid spectrometer given!\nFailed to connect!" 

def close():
   global spectrometer
   if spectrometer:
       try:
           spectrometer.close()
           return "OK"
       except Exception as e:
           return e
       finally:
           spectrometer = None
   else:
       return "No spectrometer connected!"

print("Getting Spectrometers:")
device = get_spectrometers()[0]     ## Hangs here on re-run
print(device)

if (device != None):
   print("Connecting to spectrometer:")
   ack = connect_to_spectrometer(device)

   if (ack != "OK"):
       print(ack)
   else:
       print("Closing")
       close_ack = close()
       print(close_ack)

       # Attempt reconnection (works)
       print("Connecting to spectrometer:")
       ack = connect_to_spectrometer(device)

       print("Closing")
       close_ack = close()
       print(close_ack)

Script tested on - OCEAN-FX-UV-VIS

Many thanks, Akash.

akashsingh2608 avatar Apr 01 '25 10:04 akashsingh2608

@ap--

Can you provide a minimal code example that causes the issue?

Well, it is complicated. We need to synchronize the spectrometer capture with some actions on the PC, and haven't find a way to do that with this library (seems like the library runs the spectrometer in freewheeling mode with no way to tell it to capture spectra at the specific moment). So we've modified the code to support commands

OBP_ABORT_ACQUISITION = 0x00100000
OBP_START_BUFFERING = 0x00100902
OBP_CLEAR_BUFFER_ALL = 0x00100830

(from file QE-Pro-Data-Sheet.pdf) This works for us, but apparently something gets broken when the connection is closed. It seems the spectrometer continues to send some data over USB, and it is not expected by python code in list_devices. Which is weird as I take caution to properly empty the buffers when quitting...

By the way, if I mislooked the "manual" mode for the spectrometer already present in the library, I would gladly switch to it.

@akashsingh2608 This looks like a different problem... In my case it crashes instead of hanging.

positron96 avatar Apr 01 '25 14:04 positron96

Usually I'd recommend to run the spectrometer in its own thread or process and do the communcation via a message queue. opening and closing and reopening the spectrometer can often cause hickups with uncleared buffers etc...

ap-- avatar May 21 '25 12:05 ap--

opening and closing and reopening the spectrometer can often cause hickups with uncleared buffers

that's definitely what we are experiencing, though we restart the python process, so anything python-related is cleared. Which means that the stale buffer is somewhere else (libusb? OS? spectrometer itself?..)

positron96 avatar May 21 '25 12:05 positron96

From my experience it's likely some internal spectrometer state requiring a powercycle of the spectrometer to be cleared. The ocean-optics software seems to do a better job there, but i've managed to reproduce a similar lockup twice on a USB2000+ using the oceanview.

I have so far not been able to work out a way of resetting the spectrometer via other means in these cases.

ap-- avatar May 21 '25 13:05 ap--