Files

4.7 KiB
Raw Permalink Blame History

Controls and hardware map

Model: Johnny 5 (Short Circuit) MOC. Seven motors across two Technic hubs.

Control scheme is tank drive: every input drives exactly one motor. Nothing is mixed, so a single stick can never command two motors at once.

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 AD can be ignored.

Controls

Input Function
Left stick Y Left track
Right stick Y Right track
D-pad up / down Head tilt
D-pad left / right Head turn
R2 Body lift up (proportional)
L2 Body lift down (proportional)
Square / Circle Left arm up / down
Triangle / Cross Right arm up / down
L1 (held) Precision mode, 40% track speed
R1 (held) Full speed, 100% track speed
L1 + R1 together All stop

Default track scale is 75%. The stick X axes are unused.

Bluepad32 names buttons Xbox-style, so in the code x() is Square, b() is Circle, y() is Triangle and a() is Cross. throttle() is R2 and brake() is L2, both analog 01023.

Trade-offs in this layout:

  • Tracks are independent. Turning means pushing one stick further than the other, like a skid-steer. Takes a minute to get used to, but you always know which motor you are commanding.
  • The head is digital now, not proportional — d-pad has no analog travel, so it runs at a fixed HEAD_MAX. Drop that constant if it moves too fast to aim.
  • Body lift kept the triggers because they are the only remaining analog inputs, and it is the axis that benefits most from proportional control.
  • D-pad diagonals will tilt and turn the head simultaneously. That is two motors from one thumb, but only when you deliberately press a diagonal.

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

static const int TRACK_MAX = 100;
static const int HEAD_MAX  = 45;
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.

Clearing stale pairings

Bluepad32 stores Bluetooth pairing keys in NVS, and reflashing the sketch does not clear them. If you end up with a pad paired into more than one slot, or an old device from a previous build still remembered, uncomment this in setup():

BP32.forgetBluetoothKeys();

Flash once, re-pair, then comment it out again — leaving it in means re-pairing on every boot. For a full wipe, Tools → Erase All Flash Before Sketch Upload → Enabled, upload once, then set it back to Disabled.


Created by: Jess Rogerson (yelling commands at Claude.AI)