Skip to content

projects/ janelia/ Mouse Joystick/

The pyControl device class

MouseJoystick in pycontrol/devices/mouse_joystick.py, as pyControl's task sees it. Generated by tools/pycontrol_api_doc.py from the class's own docstrings; do not edit, change the class and run the script. The full account of the host side, the controller it needs and how it is delivered is pycontrol/README.md; the wire format is the UART protocol.

pyControl device class for one mouse-joystick board.

Every command method sends one line and returns its sequence number; the board's ack or nak for that number, and every event, come back through poll() when the port's event fires. A task matches the ack to the number it is waiting for, as the rig's trial task does.

Method Sends What it does
poll() Drain the link and return decoded messages, oldest first.
identify() ID Send ID. The reply is delivered through poll(), then apply_identity().
apply_identity(data) Record an ID reply, refusing a board this class cannot drive.
has(capability)
ping() PING The safety heartbeat. Must be sent more often than the host timeout.
status() STATUS
limits() LIMITS
hv(on) HV Motor rail on or off. hv;s;ON also arms the board's host-loss watchdog (protocol V1.12, 2026-10-06), so the task's heartbeat must be running from here on: a host that dies before its first heartbeat no longer leaves the rail up.
hv_state() HV
home(timeout_ms=None) HOME
arm() ARM
disarm() DISARM
move_to(degrees) MOVETO Absolute. Rejected by the board outside its travel limits.
move(degrees) MOVE Relative. Rejected if the resulting position is outside travel.
stop() STOP Controlled stop. Always permitted.
brake(torque_ncm) BRAKE Engage the brake at torque_ncm and release the drive, as one board operation; ev;RELEASED follows the ack. On a board whose caps lack brake the torque is ignored and only the release happens.
watch(pull_deg, push_deg, timeout_ms, hold_ms=None, touch_ncm=None, maxdur_ms=None) WATCH Arm the one-shot classifier (RELEASED only). Exactly one of ev;PULL, ev;PUSH, ev;NOMOVE, ev;ABORT follows; thresholds are relative to the angle at release, pull-positive.
cfg(**values) CFG cfg;s;key=value;...: wdt_ms, deadband_deg, stream_hz, and the capture window around the WATCH outcome, pre_ms and post_ms (each 0-2047, together at most 2047; defaults 500 and 500). All or nothing: one value out of range and the board applies none of them.
cfg_get() CFG
fetch(k0=0, n=32) FETCH One chunk of the frozen capture window of the last WATCH: the ack carries n, k0, t0, dt_us, pre and lost (window samples that are grid fills after a missed 1 kHz tick on the board; 0 means every sample was taken on time); cap lines follow through poll(), then cap;end. The window is the last pre_ms samples before the outcome sample, that sample (k == pre) and post_ms after it; after a TRIAL with outcome=NONE there is no outcome sample and the window holds pre lines. Page with k0 += n until a chunk has fewer than n lines; nak;busy while the window is still filling. Fetch before the next BRAKE, which restarts the ring.
stream(on, rate_hz=None) STREAM
angle_output(on) ANGOUT
angle_scale(deg_lo, deg_hi) ANGSCALE
torque_zero() TQ Tare the torque reading at rest (tq;s;zero). v1.0 boards only.
torque_get() TQ tq;s;get -> ack with torque (tared), raw (untared) in N.cm and cal (the shunt-calibration switch, 0 or 1).
torque_cal(on) TQ The torque bridge's shunt-calibration switch. On pcb v1.0 as built the switch is inert (bring-up log, 2026-10-06), so this is a verb and not a calibration there; the board accepts it either way.
faults() FAULTS
clear_fault() CLRFAULT
instrumentation(on) INSTR
calibration() CAL
set_calibration(key, value) CAL

Methods whose names begin with an underscore are internal.