Source code for devctrl.devices.led_controller.impl.thorlabs_ledd1b

import serial
import serial.tools.list_ports

from ..base import LedController

import logging
log = logging.getLogger(__name__)

ARDUINO_SOFTWARE_VERSION_STRING = "Arduino Nano CPD 1"
"""Software version string that the Arduino's firmware must return upon query"""


[docs] class LEDD1B(LedController): """Control Thorlabs LEDD1B LED driver using an Arduino Nano The Arduino must have the correct software loaded on it. See the arduino-thorlabs-ledd1b project directory for details. :param port: Serial port name (default: "COM4") """ _CLASS_TYPE = "implementation"
[docs] def __init__(self, port="COM4"): super().__init__() self.port = port self.arduino = serial.Serial(port=port, baudrate=9600, timeout=0.1) # flush input while self.arduino.read(1): pass self.level = None
[docs] def __del__(self): self.off() self.arduino.close()
[docs] def check_has_correct_software(self, no_error=False): """Verify the Arduino has the correct software loaded Runs the identify command and raises an exception if the Arduino does not reply with the expected output string. :param no_error: If True, don't raise exception on error :raises ConnectionError: If Arduino doesn't have expected software """ self._write('i') lines = self.read() if len(lines) < 1 or not lines[-1].startswith(bytes(ARDUINO_SOFTWARE_VERSION_STRING, "utf-8")): log.error(f"Arduino did not return the expected output - does it have the correct software loaded?\nExpected: '{ARDUINO_SOFTWARE_VERSION_STRING}'\nReceived:{lines}") if not no_error: raise ConnectionError("Arduino did not return the expected output - does it have the correct software loaded?")
[docs] def is_connected(self) -> bool: """Check if the Arduino is connected and responding Sends an identify command to verify communication. :return: True if Arduino responds, False otherwise """ try: self._write('i') lines = self.read() return True except Exception as e: log.error(f"Failed to query 'i': {e}") return False
[docs] def _write(self, val): """Send a command to the Arduino :param val: Command string to send """ self.arduino.write(bytes(val, 'utf-8')) self.arduino.flush()
[docs] def read(self): """Read response lines from the Arduino :return: List of response lines """ data = self.arduino.readlines() return data
[docs] def on(self): self._write("1")
[docs] def off(self): self._write("0")
[docs] def set_brightness_percent(self, level:int): """Set the LED brightness percentage This controller only supports 0% or 100% brightness. :param level: Brightness level (0 or 100) :raises ValueError: If level is not 0 or 100 """ if level == 0: self.off() elif level == 100: self.on() else: raise ValueError(f"LEDD1B Led controller can only set 0% or 100%") self.level = level
[docs] def get_brightness_percent(self): """Get the current brightness percentage :return: Current brightness level (0 or 100) :raises RuntimeError: If brightness was never set """ if self.level is None: raise RuntimeError(f"{self}: Can not return brightness because it was not set for this instance.") return self.level
[docs] def __repr__(self) -> str: """ :return: Formatted string with device model and port """ return f"Thorlabs LEDD1B ({self.port})"
[docs] def get_capabilities(self) -> int: """Get controller capabilities Returns a bitmask indicating supported features. :return: Capabilities bitmask (BRIGHTNESS_ON_OFF) """ return LedController.BRIGHTNESS_ON_OFF
[docs] @classmethod def _enumerate_devices(cls) -> list[str]: """Enumerate available LEDD1B devices Scans serial ports for Arduino devices matching the expected criteria. :return: List of available serial port names """ devs = [] coms = serial.tools.list_ports.comports() # Require a device with no product field and empty serial number # Change these conditions to support different devices for com in coms: if com.product is not None: continue if com.serial_number: continue if com.manufacturer not in ["wch.cn"]: continue devs.append(com.device) return devs
[docs] @classmethod def connect_device(cls, device_name: str) -> "LEDD1B": """Connect to a LEDD1B LED controller Creates a new LEDD1B instance connected to the specified serial port. :param device_name: Serial port name :return: Configured LEDD1B instance """ return LEDD1B(port=device_name)
if __name__ == '__main__': led = LEDD1B()