Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding Thorlabs DC4100 led driver #37

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

arielleleon
Copy link

I have added the ThorlabsDC4100 driver to the acq4 drivers directory. This is an LED device used for the IVSCC upgrade that can communicate via a USB serial connection. The device can connect to an LED hub which can hold up to 4 LEDs.

Documentation for hardware can be found here:
DC4100 Device: https://www.thorlabs.com/thorproduct.cfm?partnumber=DC4100
DC4100 Hub: https://www.thorlabs.com/thorproduct.cfm?partnumber=DC4100-HUB

Copy link

@campagnola campagnola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks really good! I have some comments below, and one major suggestion: consider making this code thread-safe by adding a mutex that locks the serial communication for each send/receive cycle. Acq4 does a lot of multithreading under the hood, so you could end up in a situation where two threads are trying to make simultaneous calls to the device.


__author__ = """arielle leon"""
__email__ = '[email protected]'
__version__ = '0.1.0'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init needs to import the Thorlabs DC4100 class.
Also: I recommend omitting the author/email/version.

self.escape = '\n\n'
self.read_buffer = []

def led_on(self, channel: int):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause a syntax error in python 2. I hope python 3 support is coming soon, but currently micromanager is also py2 only and we don't know when that will be fixed..

"error_status": "E?"
}
class ThorlabsDC4100:
def __init__(self,port,baudrate,timeout):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style comments:

  • PEP8 likes spaces after commas (and I think it makes the code easier to read).
  • Acq4 uses camelCase instead of snake_case; consistency is preferred here. (this decision was originally inherited from Qt, although I regret it somewhat at this point..)

self._write_to_LED(COMMANDS["led_on"].format(channel))

def led_off(self,channel: int):
self._write_to_LED(COMMANDS["led_off"].format(channel))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another minor suggestion: by rewriting _write_to_LED a little, you could turn this into

self._write_to_LED('led_off', channel)

..which reduces the amount of repeated code and makes everything more readable.

self.dev.write(f"{command} {self.escape}".encode())

def _read_from_LED(self):
while self.dev.is_open:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If self.dev.is_open becomes False before this method has returned, then it will just return None, whereas I assume raising an exception would be more appropriate. You'd also potentially have junk left in self.read_buffer. For context: serial errors are relatively common in our setup, so making this bit robust is key. I recommend reading over (and maybe using) the code in https://github.com/acq4/acq4/blob/develop/acq4/drivers/SerialDevice.py, since it incorporates many of the lessons we learned through years of dealing with serial failures.

if len(self.read_buffer) == 0 and output == '\r':
self.dev.flush()
continue
if output == "\n":

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I am not mistaken, it's possible for output to contain multiple bytes ending with \n, in which case we are stuck in an infinite loop here (and in general, there seem to be a few other ways we could end up stuck here forever, depending on how (un)reliable the serial communication is). Something like readUntil (https://github.com/acq4/acq4/blob/develop/acq4/drivers/SerialDevice.py#L156) might work here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants