diff --git a/components/actor/pololu1376.py b/components/actor/pololu1376.py index a4264fc..8d0669a 100644 --- a/components/actor/pololu1376.py +++ b/components/actor/pololu1376.py @@ -48,6 +48,24 @@ class Varid(enum.Enum): MOTOR_CURRENT_LIMIT_OCCURRENCE_COUNT = 45 +# Bit flags of the STATUS variable (Varid.STATUS). A non-zero +# SAFE_START_VIOLATION is the "fail-safe" state: the controller accepted +# the GO command but still refuses to spin the motor. The other bits are +# the SMC's other error conditions, which also stop the motor and can +# make GO fail to bring it back. +class StatusError(enum.IntFlag): + SAFE_START_VIOLATION = 0x0001 + REQUIRED_CHANNEL_INVALID = 0x0002 + SERIAL_ERROR = 0x0004 + COMMAND_TIMEOUT = 0x0008 + LIMIT_KILL_SWITCH = 0x0010 + LOW_VIN = 0x0020 + HIGH_VIN = 0x0040 + OVER_TEMPERATURE = 0x0080 + MOTOR_DRIVER_ERROR = 0x0100 + ERR_LINE_HIGH = 0x0200 + + class Pololu1376: def __init__(self, serial_port): # Deferred-open pyserial idiom: serial_port is constructed with no @@ -117,8 +135,15 @@ class Pololu1376: return rsp[1:] + def get_status_errors(self): + return StatusError(self.get_variable(Varid.STATUS)) + def go(self): - return self.cmd("GO") + rsp = self.cmd("GO") + errors = self.get_status_errors() + if errors: + print(f"Pololu1376: ERROR - still in fail-safe after GO, active errors: {errors!r}") + return rsp def stop(self): return self.cmd("X") diff --git a/components/actor/stirrerpololu1376.py b/components/actor/stirrerpololu1376.py index f49cb08..39e5d9b 100644 --- a/components/actor/stirrerpololu1376.py +++ b/components/actor/stirrerpololu1376.py @@ -75,11 +75,11 @@ class StirrerPololu1376(AStirrer): if not self.connected: return try: - status = self.drv.get_variable(Varid.STATUS) - limit_status = self.drv.get_variable(Varid.STATUS_LIMIT_STATUS) - if status & 0x01 == 0x01: - if limit_status & 0x01 == 0x01: - print("Recover after motor error!") + errors = self.drv.get_status_errors() + if errors: + print(f"StirrerPololu1376: motor controller reports errors: {errors!r}") + if StatusError.SAFE_START_VIOLATION in errors: + print("Recover after safe start violation!") self.drv.go() except Exception as e: print(f"StirrerPololu1376: comm error in _on_process: {e}")