Module isotope.isotope
Main module that provides the Isotope class for communicating with the Isotope Breakout board and its I/O ports.
This module collects all submodules that implement different parts of the isotope communication protocol into one place,
including the isotope.isotope_comms_lib module, the submodules in isotope.port.
All I/O ports can be accessed by invoking the appropriate class variables.
Examples
import isotope
isot = isotope.Isotope("COM3")
isot.connect()
# enable power output port 0
isot.powers[0].enable()
# set PWM value of PWM output port 0
isot.pwms[0].set_pwm(512)
# read value from ADC input port 0
value = isot.adcs[0].get_value()
# read value from temperature sensor port 0
value = isot.temps[0].get_value()
# configure motor port 0
isot.motors[0].configure(resolution=7, current=100, rpm=100)
# move motor port 0
isot.motors[0].rotate_by_steps(100)
isot.disconnect()
See Also
Functions
def clamp_i(i: int, min_i: int, max_i: int) ‑> int-
Clamp the value of i between min_i and max_i.
Args
i:int- Value to be clamped.
min_i:int- Nin value.
max_i:int- Max value.
Returns
int- Clamped value.
def version_from_string(firmware_string: str) ‑> tuple[int, ...]-
Converts version in string to int tuple.
Args
firmware_string:str- version in string.
Returns
tuple[int, …]- version in tuple.
def version_to_string(firmware_tuple: tuple[int, ...]) ‑> str-
Converts version in int tuple to string.
Args
firmware_tuple:tuple[int, …]- version to be converted.
Returns
str- version in string.
Classes
class Isotope (usb_address: str, debug=False, response_timeout=5)-
The Isotope class is the higher-level class for communicating with the Isotope Breakout, with a single method call connect() to connect to the board and initialise all the I/O ports. A heartbeat thread is incorporated to keep the connection alive.
The I/O ports can be accessed using the the class variables including:
Variable Class type Port powersPowerOutputPower output ports, i.e. Output X. motorsMotorStepper motor ports, i.e. MOT X. adcsADCInputAnalogue-digital-converter ports, i.e. ADC X. pwmsPWMOutputPWM output ports, i.e. PWM X. tempsTempInputTemperature sensor ports, i.e. TEMP X. Attributes
heart_beat_interval:int- Interval in seconds for sending heartbeats, default is 1.
Args
usb_address:str- USB port address of the Isotope board.
debug:bool- Set to True to enable debug information. Default is False.
response_timeout:int- Time in seconds for waiting for responses from the Isotope board before timeout. Default is 5 seconds.
serial_baudrate:int- Baud rate for the serial connection. Default is 115200.
Expand source code
class Isotope: """The Isotope class is the higher-level class for communicating with the Isotope Breakout, with a single method call connect() to connect to the board and initialise all the I/O ports. A heartbeat thread is incorporated to keep the connection alive. The I/O ports can be accessed using the the class variables including: | Variable | Class type | Port | |------------|----------------------------|-------------------------------------------------| | `powers` | `isotope.port.power_output.PowerOutput` | Power output ports, i.e. Output X. | | `motors` | `isotope.port.motor.Motor` | Stepper motor ports, i.e. MOT X. | | `adcs` | `isotope.port.adc_input.ADCInput` | Analogue-digital-converter ports, i.e. ADC X. | | `pwms` | `isotope.port.pwm_output.PWMOutput` | PWM output ports, i.e. PWM X. | | `temps` | `isotope.port.temp_input.TempInput` | Temperature sensor ports, i.e. TEMP X. | Attributes: heart_beat_interval (int): Interval in seconds for sending heartbeats, default is 1. """ def __init__(self, usb_address: str, debug=False, response_timeout=5) -> None: """ Args: usb_address (str): USB port address of the Isotope board. debug (bool): Set to True to enable debug information. Default is False. response_timeout (int): Time in seconds for waiting for responses from the Isotope board before timeout. Default is 5 seconds. serial_baudrate (int): Baud rate for the serial connection. Default is 115200. """ screen_level = logging.DEBUG if debug else logging.INFO self._logger = setup_logger(__package__, screen_level=screen_level) self._logger.info("==============================================") self._logger.info(f"Initiating Isotope Breakout connected to port {usb_address}") self._logger.info(f"SDK version: {version_to_string(__version_info__)}") self._logger.info(f"Minimum firmware: {version_to_string(__minimum_firmware__)}") self._logger.info(f"Response timeout: {response_timeout}") self.comms = icl.Isotope_comms_protocol(usb_address, response_timeout) try: self.powers = port.PowerOutput(self.comms) self.motors = port.Motor(self.comms) self.adcs = port.ADCInput(self.comms) self.pwms = port.PWMOutput(self.comms) self.temps = port.TempInput(self.comms) except ValueError as e: self._logger.error(e, exc_info=True) raise e self.heart_beat_interval = 1 self._heartbeat_thread = threading.Thread(target=self._heartbeat) def connect(self) -> bool: """Connect to the Isotope board. Returns: bool: True if the connection is successful, False otherwise. """ try: self.comms.connect() self._verify_firmware() except IsotopeException as e: self._logger.error(e, exc_info=True) raise e self._logger.info(f"Board firmware: {version_to_string(self.board_firmware)}") if self.comms.is_connected(): self._heartbeat_thread.start() self._logger.debug("Heartbeat thread started.") return True def disconnect(self) -> None: """Disconnect from the Isotope board.""" self.comms.disconnect() def set_RGB_colour(self, red_i: int, green_i: int, blue_i: int) -> bool: """Set RGB colour. Args: red_i (int): Value for the red channel, ranging from 0 to 255. green_i (int): Value for the green channel, ranging from 0 to 255. blue_i (int): Value for the blue channel, ranging from 0 to 255. Returns: bool: True if successful. Otherwise, false. """ msg = self.comms.send_cmd(icl.CMD_TYPE_SET, icl.SEC_RGB_RED, 0, clamp_i(red_i, 0, 255)) ok = self.comms.is_resp_ok(msg) msg = self.comms.send_cmd(icl.CMD_TYPE_SET, icl.SEC_RGB_GREEN, 0, clamp_i(green_i, 0, 255)) ok = ok and self.comms.is_resp_ok(msg) msg = self.comms.send_cmd(icl.CMD_TYPE_SET, icl.SEC_RGB_BLUE, 0, clamp_i(blue_i, 0, 255)) return ok and self.comms.is_resp_ok(msg) def _heartbeat(self) -> None: """Heartbeat thread to keep the connection alive. """ while self.comms.is_connected(): if time.perf_counter() - self.comms.last_comm_tick < self.heart_beat_interval: time.sleep(0.1) continue try: self.comms.send_cmd(icl.CMD_TYPE_SET, icl.SEC_HEARTBEAT, 0, 0) except SerialException as e: self._logger.error(e, exc_info=True) pass def _verify_firmware(self): """Verify the firmware version of the Isotope board. """ payload, msg = self.comms.send_cmd(icl.CMD_TYPE_GET, icl.SEC_WHO_I_AM, 0, 0) if not self.comms.is_resp_ok(msg): raise IsotopeException("Error! No Isotope found.") if payload == "ISOTOPE_BOARD": self.board_firmware = (0, 0, 0) if __minimum_firmware__ != (0, 0, 0): raise IsotopeException(f"Requires minimum firmware v{version_to_string(__minimum_firmware__)}, board firmware is v0.") return re = payload.split(",") if not len(re) == 2: raise IsotopeException("Error! Wrong firmware format") my_board_name = re[0].split("=")[1] if my_board_name != icl.BOARD_NAME: raise IsotopeException("Error! No Isotpe found") self._logger.debug("Found Isotope board!") my_firmware = re[1].split("=")[1] self.board_firmware = version_from_string(my_firmware) if self.board_firmware >= __minimum_firmware__: return raise IsotopeException(f"Requires minimum firmware v{version_to_string(__minimum_firmware__)}, board firmware is v{my_firmware}.")Methods
def connect(self) ‑> bool-
Connect to the Isotope board.
Returns
bool- True if the connection is successful, False otherwise.
def disconnect(self) ‑> None-
Disconnect from the Isotope board.
def set_RGB_colour(self, red_i: int, green_i: int, blue_i: int) ‑> bool-
Set RGB colour.
Args
red_i:int- Value for the red channel, ranging from 0 to 255.
green_i:int- Value for the green channel, ranging from 0 to 255.
blue_i:int- Value for the blue channel, ranging from 0 to 255.
Returns
bool- True if successful. Otherwise, false.
class IsotopeException (*args, **kwargs)-
General exception for Isotope class.
Expand source code
class IsotopeException(Exception): """General exception for Isotope class. """ passAncestors
- builtins.Exception
- builtins.BaseException