Support for Zeroborg events
This commit is contained in:
parent
b36a8095ab
commit
7a7acbe6b9
3 changed files with 175 additions and 140 deletions
19
platypush/message/event/zeroborg.py
Normal file
19
platypush/message/event/zeroborg.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
|
from platypush.message.event import Event
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroborgEvent(Event):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroborgDriveEvent(ZeroborgEvent):
|
||||||
|
def __init__(self, motors: Union[list, tuple], direction: Optional[str] = None, *args, **kwargs):
|
||||||
|
super().__init__(*args, motors=motors, direction=direction, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroborgStopEvent(ZeroborgEvent):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# vim:sw=4:ts=4:et:
|
|
@ -2,6 +2,10 @@ import enum
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from platypush.context import get_bus
|
||||||
|
from platypush.message.event.zeroborg import ZeroborgDriveEvent, ZeroborgStopEvent
|
||||||
from platypush.plugins import Plugin, action
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
|
|
||||||
|
@ -21,12 +25,13 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
ZeroBorg plugin. It allows you to control a ZeroBorg
|
ZeroBorg plugin. It allows you to control a ZeroBorg
|
||||||
(https://www.piborg.org/motor-control-1135/zeroborg) motor controller and
|
(https://www.piborg.org/motor-control-1135/zeroborg) motor controller and
|
||||||
infrared sensor circuitry for Raspberry Pi
|
infrared sensor circuitry for Raspberry Pi
|
||||||
"""
|
|
||||||
|
|
||||||
_drive_thread = None
|
Triggers:
|
||||||
_can_run = False
|
|
||||||
_direction = None
|
* :class:`platypush.message.event.zeroborg.ZeroborgDriveEvent` when motors direction changes
|
||||||
_init_in_progress = threading.Lock()
|
* :class:`platypush.message.event.zeroborg.ZeroborgStopEvent` upon motors stop
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, directions=None, **kwargs):
|
def __init__(self, directions=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -96,6 +101,8 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
self.directions = directions
|
self.directions = directions
|
||||||
self.auto_mode = False
|
self.auto_mode = False
|
||||||
self._direction = None
|
self._direction = None
|
||||||
|
self._drive_thread: Optional[threading.Thread] = None
|
||||||
|
self._can_run: bool = False
|
||||||
|
|
||||||
self.zb = ZeroBorg.ZeroBorg()
|
self.zb = ZeroBorg.ZeroBorg()
|
||||||
self.zb.Init()
|
self.zb.Init()
|
||||||
|
@ -155,10 +162,6 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._can_run = True
|
|
||||||
self._direction = direction.lower()
|
|
||||||
self.logger.info('Received ZeroBorg drive command: {}'.format(direction))
|
|
||||||
|
|
||||||
def _run():
|
def _run():
|
||||||
try:
|
try:
|
||||||
while self._can_run and self._direction:
|
while self._can_run and self._direction:
|
||||||
|
@ -173,7 +176,7 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
if self._direction == Direction.DIR_AUTO.value:
|
if self._direction == Direction.DIR_AUTO.value:
|
||||||
self.auto_mode = True
|
self.auto_mode = True
|
||||||
|
|
||||||
motor_1_power = motor_2_power = motor_3_power = motor_4_power = 0.0
|
motors = [0, 0, 0, 0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.auto_mode:
|
if self.auto_mode:
|
||||||
|
@ -181,25 +184,27 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
if self._direction in self.directions and self._direction != Direction.DIR_AUTO.value:
|
if self._direction in self.directions and self._direction != Direction.DIR_AUTO.value:
|
||||||
motor_1_power = self.directions[self._direction]['motor_1_power']
|
motors = self.directions[self._direction]
|
||||||
motor_2_power = self.directions[self._direction]['motor_2_power']
|
|
||||||
motor_3_power = self.directions[self._direction]['motor_3_power']
|
|
||||||
motor_4_power = self.directions[self._direction]['motor_4_power']
|
|
||||||
else:
|
else:
|
||||||
self.logger.warning('Invalid direction {}: stopping motors'.format(self._direction))
|
self.logger.warning('Invalid direction {}: stopping motors'.format(self._direction))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error('Error on _get_direction_from_sensors: {}'.format(str(e)))
|
self.logger.error('Error on _get_direction_from_sensors: {}'.format(str(e)))
|
||||||
break
|
break
|
||||||
|
|
||||||
self.zb.SetMotor1(motor_1_power)
|
for i, power in enumerate(motors):
|
||||||
self.zb.SetMotor2(motor_2_power)
|
method = getattr(self.zb, 'SetMotor{}'.format(i+1))
|
||||||
self.zb.SetMotor3(motor_3_power)
|
method(power)
|
||||||
self.zb.SetMotor4(motor_4_power)
|
|
||||||
finally:
|
finally:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
self._drive_thread = None
|
||||||
|
|
||||||
self._drive_thread = threading.Thread(target=_run)
|
self._can_run = True
|
||||||
self._drive_thread.start()
|
self._direction = direction.lower()
|
||||||
|
get_bus().post(ZeroborgDriveEvent(direction=self._direction, motors=self.directions[self._direction]))
|
||||||
|
|
||||||
|
if not self._drive_thread:
|
||||||
|
self._drive_thread = threading.Thread(target=_run)
|
||||||
|
self._drive_thread.start()
|
||||||
|
|
||||||
return {'status': 'running', 'direction': direction}
|
return {'status': 'running', 'direction': direction}
|
||||||
|
|
||||||
|
@ -217,7 +222,7 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
|
|
||||||
self.zb.MotorsOff()
|
self.zb.MotorsOff()
|
||||||
self.zb.ResetEpo()
|
self.zb.ResetEpo()
|
||||||
|
get_bus().post(ZeroborgStopEvent())
|
||||||
return {'status': 'stopped'}
|
return {'status': 'stopped'}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,64 +33,67 @@ import types
|
||||||
import time
|
import time
|
||||||
|
|
||||||
# Constant values
|
# Constant values
|
||||||
I2C_SLAVE = 0x0703
|
I2C_SLAVE = 0x0703
|
||||||
PWM_MAX = 255
|
PWM_MAX = 255
|
||||||
I2C_NORM_LEN = 4
|
I2C_NORM_LEN = 4
|
||||||
I2C_LONG_LEN = 24
|
I2C_LONG_LEN = 24
|
||||||
|
|
||||||
I2C_ID_ZEROBORG = 0x40
|
I2C_ID_ZEROBORG = 0x40
|
||||||
|
|
||||||
COMMAND_SET_LED = 1 # Set the LED status
|
COMMAND_SET_LED = 1 # Set the LED status
|
||||||
COMMAND_GET_LED = 2 # Get the LED status
|
COMMAND_GET_LED = 2 # Get the LED status
|
||||||
COMMAND_SET_A_FWD = 3 # Set motor 1 PWM rate in a forwards direction
|
COMMAND_SET_A_FWD = 3 # Set motor 1 PWM rate in a forwards direction
|
||||||
COMMAND_SET_A_REV = 4 # Set motor 1 PWM rate in a reverse direction
|
COMMAND_SET_A_REV = 4 # Set motor 1 PWM rate in a reverse direction
|
||||||
COMMAND_GET_A = 5 # Get motor 1 direction and PWM rate
|
COMMAND_GET_A = 5 # Get motor 1 direction and PWM rate
|
||||||
COMMAND_SET_B_FWD = 6 # Set motor 2 PWM rate in a forwards direction
|
COMMAND_SET_B_FWD = 6 # Set motor 2 PWM rate in a forwards direction
|
||||||
COMMAND_SET_B_REV = 7 # Set motor 2 PWM rate in a reverse direction
|
COMMAND_SET_B_REV = 7 # Set motor 2 PWM rate in a reverse direction
|
||||||
COMMAND_GET_B = 8 # Get motor 2 direction and PWM rate
|
COMMAND_GET_B = 8 # Get motor 2 direction and PWM rate
|
||||||
COMMAND_SET_C_FWD = 9 # Set motor 3 PWM rate in a forwards direction
|
COMMAND_SET_C_FWD = 9 # Set motor 3 PWM rate in a forwards direction
|
||||||
COMMAND_SET_C_REV = 10 # Set motor 3 PWM rate in a reverse direction
|
COMMAND_SET_C_REV = 10 # Set motor 3 PWM rate in a reverse direction
|
||||||
COMMAND_GET_C = 11 # Get motor 3 direction and PWM rate
|
COMMAND_GET_C = 11 # Get motor 3 direction and PWM rate
|
||||||
COMMAND_SET_D_FWD = 12 # Set motor 4 PWM rate in a forwards direction
|
COMMAND_SET_D_FWD = 12 # Set motor 4 PWM rate in a forwards direction
|
||||||
COMMAND_SET_D_REV = 13 # Set motor 4 PWM rate in a reverse direction
|
COMMAND_SET_D_REV = 13 # Set motor 4 PWM rate in a reverse direction
|
||||||
COMMAND_GET_D = 14 # Get motor 4 direction and PWM rate
|
COMMAND_GET_D = 14 # Get motor 4 direction and PWM rate
|
||||||
COMMAND_ALL_OFF = 15 # Switch everything off
|
COMMAND_ALL_OFF = 15 # Switch everything off
|
||||||
COMMAND_SET_ALL_FWD = 16 # Set all motors PWM rate in a forwards direction
|
COMMAND_SET_ALL_FWD = 16 # Set all motors PWM rate in a forwards direction
|
||||||
COMMAND_SET_ALL_REV = 17 # Set all motors PWM rate in a reverse direction
|
COMMAND_SET_ALL_REV = 17 # Set all motors PWM rate in a reverse direction
|
||||||
COMMAND_SET_FAILSAFE = 18 # Set the failsafe flag, turns the motors off if communication is interrupted
|
COMMAND_SET_FAILSAFE = 18 # Set the failsafe flag, turns the motors off if communication is interrupted
|
||||||
COMMAND_GET_FAILSAFE = 19 # Get the failsafe flag
|
COMMAND_GET_FAILSAFE = 19 # Get the failsafe flag
|
||||||
COMMAND_RESET_EPO = 20 # Resets the EPO flag, use after EPO has been tripped and switch is now clear
|
COMMAND_RESET_EPO = 20 # Resets the EPO flag, use after EPO has been tripped and switch is now clear
|
||||||
COMMAND_GET_EPO = 21 # Get the EPO latched flag
|
COMMAND_GET_EPO = 21 # Get the EPO latched flag
|
||||||
COMMAND_SET_EPO_IGNORE = 22 # Set the EPO ignored flag, allows the system to run without an EPO
|
COMMAND_SET_EPO_IGNORE = 22 # Set the EPO ignored flag, allows the system to run without an EPO
|
||||||
COMMAND_GET_EPO_IGNORE = 23 # Get the EPO ignored flag
|
COMMAND_GET_EPO_IGNORE = 23 # Get the EPO ignored flag
|
||||||
COMMAND_GET_NEW_IR = 24 # Get the new IR message received flag
|
COMMAND_GET_NEW_IR = 24 # Get the new IR message received flag
|
||||||
COMMAND_GET_LAST_IR = 25 # Get the last IR message received (long message, resets new IR flag)
|
COMMAND_GET_LAST_IR = 25 # Get the last IR message received (long message, resets new IR flag)
|
||||||
COMMAND_SET_LED_IR = 26 # Set the LED for indicating IR messages
|
COMMAND_SET_LED_IR = 26 # Set the LED for indicating IR messages
|
||||||
COMMAND_GET_LED_IR = 27 # Get if the LED is being used to indicate IR messages
|
COMMAND_GET_LED_IR = 27 # Get if the LED is being used to indicate IR messages
|
||||||
COMMAND_GET_ANALOG_1 = 28 # Get the analog reading from port #1, pin 2
|
COMMAND_GET_ANALOG_1 = 28 # Get the analog reading from port #1, pin 2
|
||||||
COMMAND_GET_ANALOG_2 = 29 # Get the analog reading from port #2, pin 4
|
COMMAND_GET_ANALOG_2 = 29 # Get the analog reading from port #2, pin 4
|
||||||
COMMAND_GET_ID = 0x99 # Get the board identifier
|
COMMAND_GET_ID = 0x99 # Get the board identifier
|
||||||
COMMAND_SET_I2C_ADD = 0xAA # Set a new I2C address
|
COMMAND_SET_I2C_ADD = 0xAA # Set a new I2C address
|
||||||
|
|
||||||
COMMAND_VALUE_FWD = 1 # I2C value representing forward
|
COMMAND_VALUE_FWD = 1 # I2C value representing forward
|
||||||
COMMAND_VALUE_REV = 2 # I2C value representing reverse
|
COMMAND_VALUE_REV = 2 # I2C value representing reverse
|
||||||
|
|
||||||
COMMAND_VALUE_ON = 1 # I2C value representing on
|
COMMAND_VALUE_ON = 1 # I2C value representing on
|
||||||
COMMAND_VALUE_OFF = 0 # I2C value representing off
|
COMMAND_VALUE_OFF = 0 # I2C value representing off
|
||||||
|
|
||||||
COMMAND_ANALOG_MAX = 0x3FF # Maximum value for analog readings
|
COMMAND_ANALOG_MAX = 0x3FF # Maximum value for analog readings
|
||||||
|
|
||||||
IR_MAX_BYTES = I2C_LONG_LEN - 2
|
IR_MAX_BYTES = I2C_LONG_LEN - 2
|
||||||
|
|
||||||
def ScanForZeroBorg(busNumber = 1):
|
|
||||||
|
# noinspection PyPep8Naming
|
||||||
|
def ScanForZeroBorg(busNumber=1):
|
||||||
"""
|
"""
|
||||||
ScanForZeroBorg([busNumber])
|
ScanForZeroBorg([busNumber])
|
||||||
|
|
||||||
Scans the I?C bus for a ZeroBorg boards and returns a list of all usable addresses
|
Scans the I?C bus for a ZeroBorg boards and returns a list of all usable addresses
|
||||||
The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1
|
The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied
|
||||||
|
the default is 1
|
||||||
"""
|
"""
|
||||||
found = []
|
found = []
|
||||||
print('Scanning I?C bus #%d' % (busNumber))
|
print('Scanning I?C bus #%d' % busNumber)
|
||||||
bus = ZeroBorg()
|
bus = ZeroBorg()
|
||||||
for address in range(0x03, 0x78, 1):
|
for address in range(0x03, 0x78, 1):
|
||||||
try:
|
try:
|
||||||
|
@ -98,7 +101,7 @@ The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Re
|
||||||
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
||||||
if len(i2cRecv) == I2C_NORM_LEN:
|
if len(i2cRecv) == I2C_NORM_LEN:
|
||||||
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
||||||
print('Found ZeroBorg at %02X' % (address))
|
print('Found ZeroBorg at %02X' % address)
|
||||||
found.append(address)
|
found.append(address)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
@ -106,10 +109,11 @@ The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Re
|
||||||
pass
|
pass
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
print('Error on ZeroBorg scan: {}: {}'.format(type(e), str(e)))
|
||||||
|
|
||||||
if len(found) == 0:
|
if len(found) == 0:
|
||||||
print('No ZeroBorg boards found, is bus #%d correct (should be 0 for Rev 1, 1 for Rev 2)' % (busNumber))
|
print('No ZeroBorg boards found, is bus #%d correct (should be 0 for Rev 1, 1 for Rev 2)' % busNumber)
|
||||||
elif len(found) == 1:
|
elif len(found) == 1:
|
||||||
print('1 ZeroBorg board found')
|
print('1 ZeroBorg board found')
|
||||||
else:
|
else:
|
||||||
|
@ -117,13 +121,15 @@ The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Re
|
||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
def SetNewAddress(newAddress, oldAddress = -1, busNumber = 1):
|
# noinspection PyPep8Naming
|
||||||
|
def SetNewAddress(newAddress, oldAddress=-1, busNumber=1):
|
||||||
"""
|
"""
|
||||||
SetNewAddress(newAddress, [oldAddress], [busNumber])
|
SetNewAddress(newAddress, [oldAddress], [busNumber])
|
||||||
|
|
||||||
Scans the I?C bus for the first ZeroBorg and sets it to a new I2C address
|
Scans the I?C bus for the first ZeroBorg and sets it to a new I2C address
|
||||||
If oldAddress is supplied it will change the address of the board at that address rather than scanning the bus
|
If oldAddress is supplied it will change the address of the board at that address rather than scanning the bus
|
||||||
The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied the default is 1
|
The busNumber if supplied is which I?C bus to scan, 0 for Rev 1 boards, 1 for Rev 2 boards, if not supplied
|
||||||
|
the default is 1.
|
||||||
Warning, this new I?C address will still be used after resetting the power on the device
|
Warning, this new I?C address will still be used after resetting the power on the device
|
||||||
"""
|
"""
|
||||||
if newAddress < 0x03:
|
if newAddress < 0x03:
|
||||||
|
@ -142,52 +148,57 @@ Warning, this new I?C address will still be used after resetting the power on th
|
||||||
print('Changing I2C address from %02X to %02X (bus #%d)' % (oldAddress, newAddress, busNumber))
|
print('Changing I2C address from %02X to %02X (bus #%d)' % (oldAddress, newAddress, busNumber))
|
||||||
bus = ZeroBorg()
|
bus = ZeroBorg()
|
||||||
bus.InitBusOnly(busNumber, oldAddress)
|
bus.InitBusOnly(busNumber, oldAddress)
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
||||||
if len(i2cRecv) == I2C_NORM_LEN:
|
if len(i2cRecv) == I2C_NORM_LEN:
|
||||||
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
||||||
foundChip = True
|
foundChip = True
|
||||||
print('Found ZeroBorg at %02X' % (oldAddress))
|
print('Found ZeroBorg at %02X' % oldAddress)
|
||||||
else:
|
else:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (oldAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (
|
||||||
|
oldAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
||||||
else:
|
else:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Missing ZeroBorg at %02X' % (oldAddress))
|
print('Missing ZeroBorg at %02X' % oldAddress)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Missing ZeroBorg at %02X' % (oldAddress))
|
print('Missing ZeroBorg at %02X' % oldAddress)
|
||||||
if foundChip:
|
if foundChip:
|
||||||
bus.RawWrite(COMMAND_SET_I2C_ADD, [newAddress])
|
bus.RawWrite(COMMAND_SET_I2C_ADD, [newAddress])
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
print('Address changed to %02X, attempting to talk with the new address' % (newAddress))
|
print('Address changed to %02X, attempting to talk with the new address' % newAddress)
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
bus.InitBusOnly(busNumber, newAddress)
|
bus.InitBusOnly(busNumber, newAddress)
|
||||||
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
i2cRecv = bus.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
||||||
if len(i2cRecv) == I2C_NORM_LEN:
|
if len(i2cRecv) == I2C_NORM_LEN:
|
||||||
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
||||||
foundChip = True
|
foundChip = True
|
||||||
print('Found ZeroBorg at %02X' % (newAddress))
|
print('Found ZeroBorg at %02X' % newAddress)
|
||||||
else:
|
else:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (newAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (
|
||||||
|
newAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
||||||
else:
|
else:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Missing ZeroBorg at %02X' % (newAddress))
|
print('Missing ZeroBorg at %02X' % newAddress)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
foundChip = False
|
foundChip = False
|
||||||
print('Missing ZeroBorg at %02X' % (newAddress))
|
print('Missing ZeroBorg at %02X' % newAddress)
|
||||||
if foundChip:
|
if foundChip:
|
||||||
print('New I?C address of %02X set successfully' % (newAddress))
|
print('New I?C address of %02X set successfully' % newAddress)
|
||||||
else:
|
else:
|
||||||
print('Failed to set new I?C address...')
|
print('Failed to set new I?C address...')
|
||||||
|
|
||||||
|
|
||||||
# Class used to control ZeroBorg
|
# Class used to control ZeroBorg
|
||||||
|
# noinspection PyPep8Naming
|
||||||
class ZeroBorg:
|
class ZeroBorg:
|
||||||
"""
|
"""
|
||||||
This module is designed to communicate with the ZeroBorg
|
This module is designed to communicate with the ZeroBorg
|
||||||
|
@ -200,13 +211,12 @@ printFunction Function reference to call when printing text, if None "
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Shared values used by this class
|
# Shared values used by this class
|
||||||
busNumber = 1 # Check here for Rev 1 vs Rev 2 and select the correct bus
|
busNumber = 1 # Check here for Rev 1 vs Rev 2 and select the correct bus
|
||||||
i2cAddress = I2C_ID_ZEROBORG # I?C address, override for a different address
|
i2cAddress = I2C_ID_ZEROBORG # I?C address, override for a different address
|
||||||
foundChip = False
|
foundChip = False
|
||||||
printFunction = None
|
printFunction = None
|
||||||
i2cWrite = None
|
i2cWrite = None
|
||||||
i2cRead = None
|
i2cRead = None
|
||||||
|
|
||||||
|
|
||||||
def RawWrite(self, command, data):
|
def RawWrite(self, command, data):
|
||||||
"""
|
"""
|
||||||
|
@ -218,11 +228,11 @@ Command codes can be found at the top of ZeroBorg.py, data is a list of 0 or mor
|
||||||
Under most circumstances you should use the appropriate function instead of RawWrite
|
Under most circumstances you should use the appropriate function instead of RawWrite
|
||||||
"""
|
"""
|
||||||
rawOutput = bytes([command])
|
rawOutput = bytes([command])
|
||||||
if data: rawOutput += bytes(data)
|
if data:
|
||||||
|
rawOutput += bytes(data)
|
||||||
self.i2cWrite.write(rawOutput)
|
self.i2cWrite.write(rawOutput)
|
||||||
|
|
||||||
|
def RawRead(self, command, length, retryCount=3):
|
||||||
def RawRead(self, command, length, retryCount = 3):
|
|
||||||
"""
|
"""
|
||||||
RawRead(command, length, [retryCount])
|
RawRead(command, length, [retryCount])
|
||||||
|
|
||||||
|
@ -234,6 +244,8 @@ If it does not it will retry the request until retryCount is exhausted (default
|
||||||
|
|
||||||
Under most circumstances you should use the appropriate function instead of RawRead
|
Under most circumstances you should use the appropriate function instead of RawRead
|
||||||
"""
|
"""
|
||||||
|
reply = []
|
||||||
|
|
||||||
while retryCount > 0:
|
while retryCount > 0:
|
||||||
self.RawWrite(command, [])
|
self.RawWrite(command, [])
|
||||||
rawReply = self.i2cRead.read(length)
|
rawReply = self.i2cRead.read(length)
|
||||||
|
@ -247,8 +259,7 @@ Under most circumstances you should use the appropriate function instead of RawR
|
||||||
if retryCount > 0:
|
if retryCount > 0:
|
||||||
return reply
|
return reply
|
||||||
else:
|
else:
|
||||||
raise IOError('I2C read for command %d failed' % (command))
|
raise IOError('I2C read for command %d failed' % command)
|
||||||
|
|
||||||
|
|
||||||
def InitBusOnly(self, busNumber, address):
|
def InitBusOnly(self, busNumber, address):
|
||||||
"""
|
"""
|
||||||
|
@ -259,24 +270,22 @@ This call does not check the board is present or working, under most circumstanc
|
||||||
"""
|
"""
|
||||||
self.busNumber = busNumber
|
self.busNumber = busNumber
|
||||||
self.i2cAddress = address
|
self.i2cAddress = address
|
||||||
self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0)
|
self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering=0)
|
||||||
fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress)
|
fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress)
|
||||||
self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0)
|
self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering=0)
|
||||||
fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress)
|
fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress)
|
||||||
|
|
||||||
|
|
||||||
def Print(self, message):
|
def Print(self, message):
|
||||||
"""
|
"""
|
||||||
Print(message)
|
Print(message)
|
||||||
|
|
||||||
Wrapper used by the ZeroBorg instance to print messages, will call printFunction if set, print otherwise
|
Wrapper used by the ZeroBorg instance to print messages, will call printFunction if set, print otherwise
|
||||||
"""
|
"""
|
||||||
if self.printFunction == None:
|
if self.printFunction is None:
|
||||||
print(message)
|
print(message)
|
||||||
else:
|
else:
|
||||||
self.printFunction(message)
|
self.printFunction(message)
|
||||||
|
|
||||||
|
|
||||||
def NoPrint(self, message):
|
def NoPrint(self, message):
|
||||||
"""
|
"""
|
||||||
NoPrint(message)
|
NoPrint(message)
|
||||||
|
@ -287,42 +296,45 @@ ZB.printFunction = ZB.NoPrint
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def Init(self, tryOtherBus=False):
|
||||||
def Init(self, tryOtherBus = False):
|
|
||||||
"""
|
"""
|
||||||
Init([tryOtherBus])
|
Init([tryOtherBus])
|
||||||
|
|
||||||
Prepare the I2C driver for talking to the ZeroBorg
|
Prepare the I2C driver for talking to the ZeroBorg
|
||||||
|
|
||||||
If tryOtherBus is True, this function will attempt to use the other bus if the ThunderBorg devices can not be found on the current busNumber
|
If tryOtherBus is True, this function will attempt to use the other bus if the ThunderBorg devices can not be found on
|
||||||
|
the current busNumber.
|
||||||
|
|
||||||
This is only really useful for early Raspberry Pi models!
|
This is only really useful for early Raspberry Pi models!
|
||||||
"""
|
"""
|
||||||
self.Print('Loading ZeroBorg on bus %d, address %02X' % (self.busNumber, self.i2cAddress))
|
self.Print('Loading ZeroBorg on bus %d, address %02X' % (self.busNumber, self.i2cAddress))
|
||||||
|
|
||||||
# Open the bus
|
# Open the bus
|
||||||
self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering = 0)
|
self.i2cRead = io.open("/dev/i2c-" + str(self.busNumber), "rb", buffering=0)
|
||||||
fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress)
|
fcntl.ioctl(self.i2cRead, I2C_SLAVE, self.i2cAddress)
|
||||||
self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering = 0)
|
self.i2cWrite = io.open("/dev/i2c-" + str(self.busNumber), "wb", buffering=0)
|
||||||
fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress)
|
fcntl.ioctl(self.i2cWrite, I2C_SLAVE, self.i2cAddress)
|
||||||
|
|
||||||
# Check for ZeroBorg
|
# Check for ZeroBorg
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_ID, I2C_NORM_LEN)
|
||||||
if len(i2cRecv) == I2C_NORM_LEN:
|
if len(i2cRecv) == I2C_NORM_LEN:
|
||||||
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
if i2cRecv[1] == I2C_ID_ZEROBORG:
|
||||||
self.foundChip = True
|
self.foundChip = True
|
||||||
self.Print('Found ZeroBorg at %02X' % (self.i2cAddress))
|
self.Print('Found ZeroBorg at %02X' % self.i2cAddress)
|
||||||
else:
|
else:
|
||||||
self.foundChip = False
|
self.foundChip = False
|
||||||
self.Print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (self.i2cAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
self.Print('Found a device at %02X, but it is not a ZeroBorg (ID %02X instead of %02X)' % (
|
||||||
|
self.i2cAddress, i2cRecv[1], I2C_ID_ZEROBORG))
|
||||||
else:
|
else:
|
||||||
self.foundChip = False
|
self.foundChip = False
|
||||||
self.Print('Missing ZeroBorg at %02X' % (self.i2cAddress))
|
self.Print('Missing ZeroBorg at %02X' % self.i2cAddress)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
self.foundChip = False
|
self.foundChip = False
|
||||||
self.Print('Missing ZeroBorg at %02X' % (self.i2cAddress))
|
self.Print('Missing ZeroBorg at %02X' % self.i2cAddress)
|
||||||
|
|
||||||
# See if we are missing chips
|
# See if we are missing chips
|
||||||
if not self.foundChip:
|
if not self.foundChip:
|
||||||
|
@ -332,15 +344,16 @@ If tryOtherBus is True, this function will attempt to use the other bus if the T
|
||||||
self.busNumber = 0
|
self.busNumber = 0
|
||||||
else:
|
else:
|
||||||
self.busNumber = 1
|
self.busNumber = 1
|
||||||
self.Print('Trying bus %d instead' % (self.busNumber))
|
self.Print('Trying bus %d instead' % self.busNumber)
|
||||||
self.Init(False)
|
self.Init(False)
|
||||||
else:
|
else:
|
||||||
self.Print('Are you sure your ZeroBorg is properly attached, the correct address is used, and the I2C drivers are running?')
|
self.Print(
|
||||||
|
'Are you sure your ZeroBorg is properly attached, the correct address is used, and the I2C ' +
|
||||||
|
'drivers are running?')
|
||||||
self.bus = None
|
self.bus = None
|
||||||
else:
|
else:
|
||||||
self.Print('ZeroBorg loaded on bus %d' % (self.busNumber))
|
self.Print('ZeroBorg loaded on bus %d' % (self.busNumber))
|
||||||
|
|
||||||
|
|
||||||
def SetMotor1(self, power):
|
def SetMotor1(self, power):
|
||||||
"""
|
"""
|
||||||
SetMotor1(power)
|
SetMotor1(power)
|
||||||
|
@ -365,6 +378,7 @@ SetMotor1(1) -> motor 1 moving forward at 100% power
|
||||||
if pwm > PWM_MAX:
|
if pwm > PWM_MAX:
|
||||||
pwm = PWM_MAX
|
pwm = PWM_MAX
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(command, [pwm])
|
self.RawWrite(command, [pwm])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -372,7 +386,6 @@ SetMotor1(1) -> motor 1 moving forward at 100% power
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending motor 1 drive level!')
|
self.Print('Failed sending motor 1 drive level!')
|
||||||
|
|
||||||
|
|
||||||
def GetMotor1(self):
|
def GetMotor1(self):
|
||||||
"""
|
"""
|
||||||
power = GetMotor1()
|
power = GetMotor1()
|
||||||
|
@ -384,6 +397,7 @@ e.g.
|
||||||
-0.5 -> motor 1 moving reverse at 50% power
|
-0.5 -> motor 1 moving reverse at 50% power
|
||||||
1 -> motor 1 moving forward at 100% power
|
1 -> motor 1 moving forward at 100% power
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_A, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_A, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -401,7 +415,6 @@ e.g.
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def SetMotor2(self, power):
|
def SetMotor2(self, power):
|
||||||
"""
|
"""
|
||||||
SetMotor1(power)
|
SetMotor1(power)
|
||||||
|
@ -426,6 +439,7 @@ SetMotor2(1) -> motor 2 moving forward at 100% power
|
||||||
if pwm > PWM_MAX:
|
if pwm > PWM_MAX:
|
||||||
pwm = PWM_MAX
|
pwm = PWM_MAX
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(command, [pwm])
|
self.RawWrite(command, [pwm])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -433,7 +447,6 @@ SetMotor2(1) -> motor 2 moving forward at 100% power
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending motor 2 drive level!')
|
self.Print('Failed sending motor 2 drive level!')
|
||||||
|
|
||||||
|
|
||||||
def GetMotor2(self):
|
def GetMotor2(self):
|
||||||
"""
|
"""
|
||||||
power = GetMotor2()
|
power = GetMotor2()
|
||||||
|
@ -445,6 +458,7 @@ e.g.
|
||||||
-0.5 -> motor 2 moving reverse at 50% power
|
-0.5 -> motor 2 moving reverse at 50% power
|
||||||
1 -> motor 2 moving forward at 100% power
|
1 -> motor 2 moving forward at 100% power
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_B, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_B, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -462,7 +476,6 @@ e.g.
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def SetMotor3(self, power):
|
def SetMotor3(self, power):
|
||||||
"""
|
"""
|
||||||
SetMotor3(power)
|
SetMotor3(power)
|
||||||
|
@ -487,6 +500,7 @@ SetMotor3(1) -> motor 3 moving forward at 100% power
|
||||||
if pwm > PWM_MAX:
|
if pwm > PWM_MAX:
|
||||||
pwm = PWM_MAX
|
pwm = PWM_MAX
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(command, [pwm])
|
self.RawWrite(command, [pwm])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -494,7 +508,6 @@ SetMotor3(1) -> motor 3 moving forward at 100% power
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending motor 3 drive level!')
|
self.Print('Failed sending motor 3 drive level!')
|
||||||
|
|
||||||
|
|
||||||
def GetMotor3(self):
|
def GetMotor3(self):
|
||||||
"""
|
"""
|
||||||
power = GetMotor3()
|
power = GetMotor3()
|
||||||
|
@ -506,6 +519,7 @@ e.g.
|
||||||
-0.5 -> motor 3 moving reverse at 50% power
|
-0.5 -> motor 3 moving reverse at 50% power
|
||||||
1 -> motor 3 moving forward at 100% power
|
1 -> motor 3 moving forward at 100% power
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_C, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_C, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -523,7 +537,6 @@ e.g.
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def SetMotor4(self, power):
|
def SetMotor4(self, power):
|
||||||
"""
|
"""
|
||||||
SetMotor4(power)
|
SetMotor4(power)
|
||||||
|
@ -548,6 +561,7 @@ SetMotor4(1) -> motor 4 moving forward at 100% power
|
||||||
if pwm > PWM_MAX:
|
if pwm > PWM_MAX:
|
||||||
pwm = PWM_MAX
|
pwm = PWM_MAX
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(command, [pwm])
|
self.RawWrite(command, [pwm])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -555,7 +569,6 @@ SetMotor4(1) -> motor 4 moving forward at 100% power
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending motor 4 drive level!')
|
self.Print('Failed sending motor 4 drive level!')
|
||||||
|
|
||||||
|
|
||||||
def GetMotor4(self):
|
def GetMotor4(self):
|
||||||
"""
|
"""
|
||||||
power = GetMotor4()
|
power = GetMotor4()
|
||||||
|
@ -567,6 +580,7 @@ e.g.
|
||||||
-0.5 -> motor 4 moving reverse at 50% power
|
-0.5 -> motor 4 moving reverse at 50% power
|
||||||
1 -> motor 4 moving forward at 100% power
|
1 -> motor 4 moving forward at 100% power
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_D, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_D, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -584,7 +598,6 @@ e.g.
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def SetMotors(self, power):
|
def SetMotors(self, power):
|
||||||
"""
|
"""
|
||||||
SetMotors(power)
|
SetMotors(power)
|
||||||
|
@ -609,6 +622,7 @@ SetMotors(1) -> all motors are moving forward at 100% power
|
||||||
if pwm > PWM_MAX:
|
if pwm > PWM_MAX:
|
||||||
pwm = PWM_MAX
|
pwm = PWM_MAX
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(command, [pwm])
|
self.RawWrite(command, [pwm])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -616,13 +630,13 @@ SetMotors(1) -> all motors are moving forward at 100% power
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending all motors drive level!')
|
self.Print('Failed sending all motors drive level!')
|
||||||
|
|
||||||
|
|
||||||
def MotorsOff(self):
|
def MotorsOff(self):
|
||||||
"""
|
"""
|
||||||
MotorsOff()
|
MotorsOff()
|
||||||
|
|
||||||
Sets all motors to stopped, useful when ending a program
|
Sets all motors to stopped, useful when ending a program
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(COMMAND_ALL_OFF, [0])
|
self.RawWrite(COMMAND_ALL_OFF, [0])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -630,7 +644,6 @@ Sets all motors to stopped, useful when ending a program
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending motors off command!')
|
self.Print('Failed sending motors off command!')
|
||||||
|
|
||||||
|
|
||||||
def SetLed(self, state):
|
def SetLed(self, state):
|
||||||
"""
|
"""
|
||||||
SetLed(state)
|
SetLed(state)
|
||||||
|
@ -650,13 +663,13 @@ Sets the current state of the LED, False for off, True for on
|
||||||
self.Print('Failed sending LED state!')
|
self.Print('Failed sending LED state!')
|
||||||
self.Print(e)
|
self.Print(e)
|
||||||
|
|
||||||
|
|
||||||
def GetLed(self):
|
def GetLed(self):
|
||||||
"""
|
"""
|
||||||
state = GetLed()
|
state = GetLed()
|
||||||
|
|
||||||
Reads the current state of the LED, False for off, True for on
|
Reads the current state of the LED, False for off, True for on
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_LED, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_LED, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -670,13 +683,13 @@ Reads the current state of the LED, False for off, True for on
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def ResetEpo(self):
|
def ResetEpo(self):
|
||||||
"""
|
"""
|
||||||
ResetEpo()
|
ResetEpo()
|
||||||
|
|
||||||
Resets the EPO latch state, use to allow movement again after the EPO has been tripped
|
Resets the EPO latch state, use to allow movement again after the EPO has been tripped
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(COMMAND_RESET_EPO, [0])
|
self.RawWrite(COMMAND_RESET_EPO, [0])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -684,7 +697,6 @@ Resets the EPO latch state, use to allow movement again after the EPO has been t
|
||||||
except:
|
except:
|
||||||
self.Print('Failed resetting EPO!')
|
self.Print('Failed resetting EPO!')
|
||||||
|
|
||||||
|
|
||||||
def GetEpo(self):
|
def GetEpo(self):
|
||||||
"""
|
"""
|
||||||
state = GetEpo()
|
state = GetEpo()
|
||||||
|
@ -694,6 +706,7 @@ If False the EPO has not been tripped, and movement is allowed.
|
||||||
If True the EPO has been tripped, movement is disabled if the EPO is not ignored (see SetEpoIgnore)
|
If True the EPO has been tripped, movement is disabled if the EPO is not ignored (see SetEpoIgnore)
|
||||||
Movement can be re-enabled by calling ResetEpo.
|
Movement can be re-enabled by calling ResetEpo.
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_EPO, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_EPO, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -707,7 +720,6 @@ If True the EPO has been tripped, movement is disabled if the EPO is not ignored
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def SetEpoIgnore(self, state):
|
def SetEpoIgnore(self, state):
|
||||||
"""
|
"""
|
||||||
SetEpoIgnore(state)
|
SetEpoIgnore(state)
|
||||||
|
@ -719,6 +731,7 @@ Sets the system to ignore or use the EPO latch, set to False if you have an EPO
|
||||||
else:
|
else:
|
||||||
level = COMMAND_VALUE_OFF
|
level = COMMAND_VALUE_OFF
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(COMMAND_SET_EPO_IGNORE, [level])
|
self.RawWrite(COMMAND_SET_EPO_IGNORE, [level])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -726,13 +739,13 @@ Sets the system to ignore or use the EPO latch, set to False if you have an EPO
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending EPO ignore state!')
|
self.Print('Failed sending EPO ignore state!')
|
||||||
|
|
||||||
|
|
||||||
def GetEpoIgnore(self):
|
def GetEpoIgnore(self):
|
||||||
"""
|
"""
|
||||||
state = GetEpoIgnore()
|
state = GetEpoIgnore()
|
||||||
|
|
||||||
Reads the system EPO ignore state, False for using the EPO latch, True for ignoring the EPO latch
|
Reads the system EPO ignore state, False for using the EPO latch, True for ignoring the EPO latch
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_EPO_IGNORE, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_EPO_IGNORE, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -746,7 +759,6 @@ Reads the system EPO ignore state, False for using the EPO latch, True for ignor
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def HasNewIrMessage(self):
|
def HasNewIrMessage(self):
|
||||||
"""
|
"""
|
||||||
state = HasNewIrMessage()
|
state = HasNewIrMessage()
|
||||||
|
@ -768,7 +780,6 @@ If True there has been a new IR message which can be read using GetIrMessage().
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def GetIrMessage(self):
|
def GetIrMessage(self):
|
||||||
"""
|
"""
|
||||||
message = GetIrMessage()
|
message = GetIrMessage()
|
||||||
|
@ -777,6 +788,7 @@ Reads the last IR message which has been received and clears the new IR message
|
||||||
Returns the bytes from the remote control as a hexadecimal string, e.g. 'F75AD5AA8000'
|
Returns the bytes from the remote control as a hexadecimal string, e.g. 'F75AD5AA8000'
|
||||||
Use HasNewIrMessage() to see if there has been a new IR message since the last call.
|
Use HasNewIrMessage() to see if there has been a new IR message since the last call.
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_LAST_IR, I2C_LONG_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_LAST_IR, I2C_LONG_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -787,10 +799,9 @@ Use HasNewIrMessage() to see if there has been a new IR message since the last c
|
||||||
|
|
||||||
message = ''
|
message = ''
|
||||||
for i in range(IR_MAX_BYTES):
|
for i in range(IR_MAX_BYTES):
|
||||||
message += '%02X' % (i2cRecv[1+i])
|
message += '%02X' % (i2cRecv[1 + i])
|
||||||
return message.rstrip('0')
|
return message.rstrip('0')
|
||||||
|
|
||||||
|
|
||||||
def SetLedIr(self, state):
|
def SetLedIr(self, state):
|
||||||
"""
|
"""
|
||||||
SetLedIr(state)
|
SetLedIr(state)
|
||||||
|
@ -802,6 +813,7 @@ Sets if IR messages control the state of the LED, False for no effect, True for
|
||||||
else:
|
else:
|
||||||
level = COMMAND_VALUE_OFF
|
level = COMMAND_VALUE_OFF
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(COMMAND_SET_LED_IR, [level])
|
self.RawWrite(COMMAND_SET_LED_IR, [level])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -809,13 +821,13 @@ Sets if IR messages control the state of the LED, False for no effect, True for
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending LED state!')
|
self.Print('Failed sending LED state!')
|
||||||
|
|
||||||
|
|
||||||
def GetLedIr(self):
|
def GetLedIr(self):
|
||||||
"""
|
"""
|
||||||
state = GetLedIr()
|
state = GetLedIr()
|
||||||
|
|
||||||
Reads if IR messages control the state of the LED, False for no effect, True for incoming messages blink the LED
|
Reads if IR messages control the state of the LED, False for no effect, True for incoming messages blink the LED
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_LED_IR, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_LED_IR, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -829,7 +841,6 @@ Reads if IR messages control the state of the LED, False for no effect, True for
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def GetAnalog1(self):
|
def GetAnalog1(self):
|
||||||
"""
|
"""
|
||||||
voltage = GetAnalog1()
|
voltage = GetAnalog1()
|
||||||
|
@ -837,6 +848,7 @@ voltage = GetAnalog1()
|
||||||
Reads the current analog level from port #1 (pin 2).
|
Reads the current analog level from port #1 (pin 2).
|
||||||
Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_ANALOG_1, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_ANALOG_1, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -849,7 +861,6 @@ Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
||||||
level = float(raw) / float(COMMAND_ANALOG_MAX)
|
level = float(raw) / float(COMMAND_ANALOG_MAX)
|
||||||
return level * 3.3
|
return level * 3.3
|
||||||
|
|
||||||
|
|
||||||
def GetAnalog2(self):
|
def GetAnalog2(self):
|
||||||
"""
|
"""
|
||||||
voltage = GetAnalog2()
|
voltage = GetAnalog2()
|
||||||
|
@ -857,6 +868,7 @@ voltage = GetAnalog2()
|
||||||
Reads the current analog level from port #2 (pin 4).
|
Reads the current analog level from port #2 (pin 4).
|
||||||
Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_ANALOG_2, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_ANALOG_2, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -869,7 +881,6 @@ Returns the value as a voltage based on the 3.3 V reference pin (pin 1).
|
||||||
level = float(raw) / float(COMMAND_ANALOG_MAX)
|
level = float(raw) / float(COMMAND_ANALOG_MAX)
|
||||||
return level * 3.3
|
return level * 3.3
|
||||||
|
|
||||||
|
|
||||||
def SetCommsFailsafe(self, state):
|
def SetCommsFailsafe(self, state):
|
||||||
"""
|
"""
|
||||||
SetCommsFailsafe(state)
|
SetCommsFailsafe(state)
|
||||||
|
@ -884,6 +895,7 @@ The failsafe is disabled at power on
|
||||||
else:
|
else:
|
||||||
level = COMMAND_VALUE_OFF
|
level = COMMAND_VALUE_OFF
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
self.RawWrite(COMMAND_SET_FAILSAFE, [level])
|
self.RawWrite(COMMAND_SET_FAILSAFE, [level])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -891,7 +903,6 @@ The failsafe is disabled at power on
|
||||||
except:
|
except:
|
||||||
self.Print('Failed sending communications failsafe state!')
|
self.Print('Failed sending communications failsafe state!')
|
||||||
|
|
||||||
|
|
||||||
def GetCommsFailsafe(self):
|
def GetCommsFailsafe(self):
|
||||||
"""
|
"""
|
||||||
state = GetCommsFailsafe()
|
state = GetCommsFailsafe()
|
||||||
|
@ -899,6 +910,7 @@ state = GetCommsFailsafe()
|
||||||
Read the current system state of the communications failsafe, True for enabled, False for disabled
|
Read the current system state of the communications failsafe, True for enabled, False for disabled
|
||||||
The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second
|
The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
i2cRecv = self.RawRead(COMMAND_GET_FAILSAFE, I2C_NORM_LEN)
|
i2cRecv = self.RawRead(COMMAND_GET_FAILSAFE, I2C_NORM_LEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -912,18 +924,17 @@ The failsafe will turn the motors off unless it is commanded at least once every
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def Help(self):
|
def Help(self):
|
||||||
"""
|
"""
|
||||||
Help()
|
Help()
|
||||||
|
|
||||||
Displays the names and descriptions of the various functions and settings provided
|
Displays the names and descriptions of the various functions and settings provided
|
||||||
"""
|
"""
|
||||||
funcList = [ZeroBorg.__dict__.get(a) for a in dir(ZeroBorg) if isinstance(ZeroBorg.__dict__.get(a), types.FunctionType)]
|
funcList = [ZeroBorg.__dict__.get(a) for a in dir(ZeroBorg) if
|
||||||
funcListSorted = sorted(funcList, key = lambda x: x.func_code.co_firstlineno)
|
isinstance(ZeroBorg.__dict__.get(a), types.FunctionType)]
|
||||||
|
funcListSorted = sorted(funcList, key=lambda x: x.func_code.co_firstlineno)
|
||||||
|
|
||||||
print(self.__doc__)
|
print(self.__doc__)
|
||||||
print
|
print()
|
||||||
for func in funcListSorted:
|
for func in funcListSorted:
|
||||||
print('=== %s === %s' % (func.func_name, func.func_doc))
|
print('=== %s === %s' % (func.func_name, func.func_doc))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue