Module gonioimsoft.arduino_serial
1) Reading rotation encoder signals from an Arduino Board. 2) and controlling stepper motors.
Classes
class ArduinoReader (port=None, baudrate=9600, timeout=0.01)
-
Read rotation encoders from Arduino over USB serial.
ArduinoReader reads so called "angle pairs" from two rotation encoders connected to an Arduino board running compatible firmware.
Arguments
port
:string
- On Windows, "COM4" or similar. May change if other serial devices are addded or removed?
baudrate
:int
- Default 9600.
timeout
:float
- Default 0.01.
Expand source code
class ArduinoReader: '''Read rotation encoders from Arduino over USB serial. ArduinoReader reads so called "angle pairs" from two rotation encoders connected to an Arduino board running compatible firmware. ''' def __init__(self, port=None, baudrate=9600, timeout=0.01): ''' Arguments --------- port : string On Windows, "COM4" or similar. May change if other serial devices are addded or removed? baudrate : int Default 9600. timeout : float Default 0.01. ''' # Serial lib not available if not serial: self.serial = None # Use the provided serial port and case closed if port is not None: self.serial = serial.Serial( port=port, baudrate=baudrate, timeout=timeout) else: # Autodetect the Arduino board: # Use the first one with text "Arduino" in it ports = [str(p) for p in comports()] if not ports: self.serial = None else: print(f'Selecting an Arduino from {ports}') for port in ports: if not 'arduino' in port.lower(): continue print(f' Trying {port}') try: self.serial = serial.Serial( port=port.split(' ')[0], baudrate=baudrate, timeout=timeout) self.serial.readline() print(f'Accepted port {port}') break except Exception as e: print(e) self.latest_angle = (0,0) self.offset = (0,0) def _offset_correct(self, angles): ''' Rreturn the offset (zero-point) corrected angles pair. ''' return (angles[0] - self.offset[0], angles[1] - self.offset[1]) def read_angles(self): ''' Read the oldest unread angles pair that Arduino has sent to the serial. Returns angle pair, (horizontal_angle, vertical_angle). ''' if self.serial is None: return (0,0) read_string = self.serial.readline().decode("utf-8") if read_string: angles = read_string.split(',') self.latest_angle = tuple(map(int, angles)) return self._offset_correct(self.latest_angle) def get_latest(self): ''' Returns the latest angle that has been read from Arduino. (Arduino sends an angle only when it has changed) ''' return self._offset_correct(self.latest_angle) def close_connection(self): ''' If it is required to manually close the serial connection. ''' if self.serial: self.serial.close() def current_as_zero(self): ''' Sets the current angle pair value to (0,0) ''' self.offset = self.latest_angle def move_motor(self, i_motor, direction, time=1): ''' Move motor i_motor to given direction for the given time (default 1 s) Communication to the Arduino board controlling the motor states happens by sending characters to the serial; each sent character makes the motor to move for 100 ms ideally; letters as a for the motor 0 to + direction A for the motor 0 to - direction b for the motor 1 to + direction .... Input arguments i_motor Index number of the motor direction Positive for + direction, negative number for - direction 0 makes nothing time In seconds ''' if self.serial is None: print('Pretending to drive motor {}'.format(i_motor)) return None motor_letters = ['a', 'b', 'c', 'd', 'e'] letter = motor_letters[i_motor] if not direction == 0: if direction > 0: letter = letter.lower() else: letter = letter.upper() N = round(time * 10) string = ''.join([letter for i in range(N)]) self.serial.write(bytearray(string.encode())) def get_sensor(self, i_sensor): ''' Yet another way to read anglepairs, separated. ''' angles = self.get_latest() return angles[i_sensor]
Methods
def close_connection(self)
-
If it is required to manually close the serial connection.
def current_as_zero(self)
-
Sets the current angle pair value to (0,0)
def get_latest(self)
-
Returns the latest angle that has been read from Arduino. (Arduino sends an angle only when it has changed)
def get_sensor(self, i_sensor)
-
Yet another way to read anglepairs, separated.
def move_motor(self, i_motor, direction, time=1)
-
Move motor i_motor to given direction for the given time (default 1 s)
Communication to the Arduino board controlling the motor states happens by sending characters to the serial; each sent character makes the motor to move for 100 ms ideally; letters as a for the motor 0 to + direction A for the motor 0 to - direction b for the motor 1 to + direction ....
Input arguments i_motor Index number of the motor direction Positive for + direction, negative number for - direction 0 makes nothing time In seconds
def read_angles(self)
-
Read the oldest unread angles pair that Arduino has sent to the serial.
Returns angle pair, (horizontal_angle, vertical_angle).