diff --git a/docs/CONTROLS.md b/docs/CONTROLS.md new file mode 100644 index 0000000..e945851 --- /dev/null +++ b/docs/CONTROLS.md @@ -0,0 +1,100 @@ +# Controls and hardware map + +Model: Johnny 5 (Short Circuit) MOC. Seven motors across two Technic hubs. + +## Port map + +| Hub | Address | Port | Function | Desired field | +| --- | --- | --- | --- | --- | +| 0 | `90:84:2b:61:e6:8c` | A | Right track | `rightTrack` | +| 0 | | B | Left track | `leftTrack` | +| 0 | | D | Body lift | `bodyLift` | +| 1 | `90:84:2b:61:f2:d7` | A | Head tilt | `headTilt` | +| 1 | | B | Head turn | `headTurn` | +| 1 | | C | Left arm | `leftArm` | +| 1 | | D | Right arm | `rightArm` | + +The sketch does not rely on this table — it is here for humans. At connect the +hubs report their own inventory over notifications, so the serial log tells you +what is actually plugged in: + +``` +hub0 port A : Technic Control+ LARGE motor (0x002E) +hub0 port B : Technic Control+ LARGE motor (0x002E) +hub0 port D : Technic Control+ XL motor (0x002F) +hub0 port 0x32 : hub RGB LED (0x0017) +... +``` + +Internal devices (LED on `0x32`, battery voltage, current, IMU) report as +attached too. Anything not on A–D can be ignored. + +## Controls + +| Input | Function | +| --- | --- | +| Left stick Y | Drive forward / back | +| Left stick X | Turn | +| Right stick X | Head turn | +| Right stick Y | Head tilt | +| R2 | Body lift up (proportional) | +| L2 | Body lift down (proportional) | +| D-pad up / down | Left arm up / down | +| Triangle / Cross | Right arm up / down | +| L1 (held) | Precision mode, 40% drive | +| R1 (held) | Full speed, 100% drive | +| Circle | All stop | + +Default drive scale is 75%. + +Bluepad32 names buttons Xbox-style, so in the code `y()` is Triangle, `a()` is +Cross and `b()` is Circle. `throttle()` is R2 and `brake()` is L2, both analog +0–1023. + +Why this layout: arcade drive on one stick keeps the other free for the head, +which is the expressive part of this model. The analog triggers go to body lift +because it is the heavy slow axis that benefits most from proportional feel. +Arms are digital because they are pose-and-hold, not modulate. + +To remap, set `DEBUG_BUTTONS` to 1 at the top of the sketch and press each +button — it prints the mask so you can match your pad's firmware exactly. + +## Power caps + +```cpp +static const int TRACK_MAX = 100; +static const int HEAD_MAX = 50; +static const int LIFT_MAX = 60; +static const int ARM_MAX = 45; +``` + +**Everything except the tracks runs into a mechanical end stop.** There is no +position feedback in this code, so holding a direction against a stop stalls the +motor — that means stripped gears or a browned-out hub, and the hub will not +complain until it drops the BLE connection entirely. That is why the non-track +caps are well below 100. Lower them further if an axis feels forceful, and do +not hold a direction once the axis has stopped moving. + +The real fix, worth doing once the travel of each axis is known: Control+ motors +have absolute encoders. Subscribe to position with Port Input Format Setup +(`0x41`), learn each axis's limits, and refuse to drive past them. That turns a +mechanical hazard into a software one. + +## Rate limiting + +Two limits, both in `driveMotor`: + +* `MOTOR_MIN_GAP_MS` (100ms) per port +* `HUB_MIN_GAP_MS` (25ms) per hub, roughly 40 commands/sec + +The second one exists because hub 1 has four motors on it. The per-port limit +alone would let through up to 66 commands/sec to a single hub, which is more +than these will absorb — you get stutter, then a dropped link. Stops are exempt +from both and always go out immediately. + +If motors feel laggy, lower `MOTOR_MIN_GAP_MS` before touching the hub limit. +If a hub drops out under heavy stick movement, raise `HUB_MIN_GAP_MS`. + +--- + +Created by: Jess Rogerson (yelling commands at Claude.AI)