Python library
TercioBridge.py is a single file with one dependency, pyserial. It speaks protocol v2 through the Tercio FD, tracks telemetry from every node in the background, and converts units for you.
motor.position is always fresh.TercioError with the driver’s status.Install
Section titled “Install”-
Python 3.8 or newer, and pyserial:
Terminal window pip install pyserial -
Download TercioBridge.py and put it next to your script.
First script
Section titled “First script”from TercioBridge import Bus, Stepper, Unit
with Bus("COM5") as bus: # or "/dev/ttyACM0", "/dev/cu.usbmodem…" for info in bus.discover(): # every node on the bus print(info)
motor = Stepper(bus, 1, unit=Unit.DEGREES) motor.enable() motor.move_to(180, wait=True) print(f"at {motor.position:.2f}°")Bus() without a port opens the first serial port it finds, which is only safe when the adapter is the only one. Only one program can hold the port: close Tercio Control first.
The bus
Section titled “The bus”Bus(port=None, baud=115200, timeout=0.2) |
Opens on open() or with. A background thread reads everything the adapter sends. timeout is how long a command waits for its reply. |
bus.discover(wait=0.15) |
Broadcasts GetInfo and returns a NodeInfo per answer: node ID, firmware, protocol, hardware revision, encoder and 12-byte uid. Two drivers sharing an ID both show up. |
bus.nodes() |
Node IDs that sent telemetry in the last second. |
bus.assign_node_id(uid, new_id) |
Gives the driver with this serial a new ID. Then Stepper(bus, new_id).save(). |
bus.stop_all(), bus.emergency_stop_all() |
Broadcast Stop or Emergency stop. |
bus.sync() |
Starts every move queued with deferred=True. |
bus.telemetry(node) |
Latest Telemetry of a node, or None. |
bus.on_fault |
callback(node, faults, warnings, state), called on every fault event. |
bus.send(can_id, opcode, payload) |
Raw frame, for anything the helpers don’t cover. |
A motor
Section titled “A motor”Stepper(bus, node_id, unit=Unit.DEGREES). Positions and speeds are in unit: Unit.DEGREES (default), Unit.RADIANS or Unit.TURNS.
| Method | Does |
|---|---|
enable(), disable() |
Bridge on (hold) or off. |
move_to(pos, velocity=None, acceleration=None, deferred=False, wait=False, timeout=30, ack=True) |
Absolute move. velocity and acceleration can only lower the limits. wait=True blocks until settled. ack=False streams without waiting for a reply. |
move_by(delta, …) |
Relative move, same options. |
set_velocity(v, acceleration=None) |
Continuous rotation; 0 stops and holds. |
stop(), emergency_stop() |
Decelerate and hold, or bridge off at once. |
set_zero(pos=0.0) |
The current position becomes pos. |
calibrate(wait=True), home(wait=True) |
Run the procedure; by default block until it ends and raise if it failed. |
auto_tune(minimum, maximum) |
Find the speed limits between two positions; returns (velocity, acceleration). |
get_param(Param.X), set_param(Param.X, value) |
Any parameter, in its wire units (turns). set_param returns the value as applied. |
set_limits(velocity, acceleration), set_current(run_ma, hold_percent), set_microsteps(n), set_pid(kp, ki, kd) |
Shortcuts; limits in unit. |
set_node_id(new_id, persist=True) |
Change the ID (and save). |
save(), factory_reset(), reboot(), clear_faults(), info() |
System commands. |
telemetry, position, velocity |
Latest values from the background thread. |
wait_settled(timeout=30) |
Block until holding and settled; raises on a fault or stall. |
Telemetry
Section titled “Telemetry”motor.telemetry is the latest frame, or None until the first one arrives (at 100 Hz by default, so give it a moment after opening the bus):
t = motor.telemetryt.state # AxisState.HOLDING, MOVING, …t.flags # Flag.ENABLED | Flag.CALIBRATED | …t.calibrated, t.settled, t.enabledt.faults, t.warnings # Fault / Warning_ flagst.position, t.target # turnst.velocity, t.following_error # turns/s, turnst.temperature_c, t.supply_vt.control_load_pct, t.sequenceTelemetry values are in turns; motor.position and motor.velocity convert to the motor’s unit.
Errors
Section titled “Errors”A refused command raises TercioError with .status set to the status the driver answered:
from TercioBridge import TercioError, Status
try: motor.move_to(90)except TercioError as e: if e.status == Status.NOT_CALIBRATED: motor.calibrate() else: raiseNo reply within timeout raises TercioError("timeout").
Several axes
Section titled “Several axes”x = Stepper(bus, 1)y = Stepper(bus, 2)for m in (x, y): m.enable()
x.move_to(90, deferred=True)y.move_to(-90, deferred=True)bus.sync() # both start on the same instantx.wait_settled(); y.wait_settled()
bus.on_fault = lambda node, faults, warnings, state: print(f"node {node}: {faults!r}")on_fault runs on the reader thread: keep it short, and don’t send commands that wait for replies from inside it.
The adapter
Section titled “The adapter”print(bus.adapter_info()) # firmware, hardware revision, uid, boot optionss = bus.adapter_status # refreshed every 250 msprint(s.bus_state.name, s.tx_error_count, s.dropped_to_can)bus.reset_adapter_counters()bus.enter_adapter_bootloader() # USB update mode; closes the busThe IMU
Section titled “The IMU”from TercioBridge import Bus, Imu, ZeroMode, FusionMode
imu = Imu(bus) # node 100 by defaultimu.zero() # or imu.zero_heading()t = imu.telemetry # None until the first frameprint(t.roll, t.pitch, t.yaw, t.quaternion)print(t.acceleration, t.rate, t.temperature_c, t.calibration)
imu.wait_calibrated() # blocks until gyro and accel (and mag in NDOF) are calibratedimu.save_calibration() # restored at every power-upimu.set_fusion_mode(FusionMode.NDOF)imu.save() # settings and zero to flashImu(bus, node_id=100) |
One Tercio IMU. bus.imus() lists the IMUs reporting; bus.discover() marks each node with device. |
zero(mode=ZeroMode.ALL), zero_heading(), clear_zero() |
Set or clear the zero reference. |
save_calibration(), wait_calibrated(timeout) |
Store the calibration in flash; wait for full calibration. |
get_param(ImuParam.X), set_param(ImuParam.X, value), set_fusion_mode(mode) |
Node ID, telemetry rate, fusion mode, axis mapping. |
save(), factory_reset(), reboot(), clear_faults(), info() |
System commands. |
telemetry |
ImuTelemetry: state, flags, faults, warnings, calibration, quaternion, roll, pitch, yaw, acceleration, rate, temperature_c. |
See Tercio IMU.