Satellite chain
The chain is the reason a Rodeo panel can grow without the motherboard changing. Each satellite carries a cent-scale microcontroller, reads its own controls, and passes frames along a ring. A satellite’s position in the chain is its address, so there is nothing to configure and no jumpers to set.
This page is the short version. The contract in full — discovery, commands,
fault codes, programming — is
hardware/rodeo-motherboard/docs/RODEO_SATELLITE_CHAIN_CONTRACT.md.
Connector
Section titled “Connector”Every satellite has an IN and an OUT, both JST SH 5-pin. The motherboard has one chain connector wired like a satellite’s OUT.
| Pin | Signal | On a satellite |
|---|---|---|
| 1 | GND | — |
| 2 | 3V3 | Supply in, passed straight through to OUT |
| 3 | DATA_FWD | MCU RX on IN, MCU TX on OUT |
| 4 | DATA_RET | Straight through, with the MCU’s return tap on it |
| 5 | PRESENT | Tied to GND on IN; an input with a pull-up on OUT |
DATA_FWD is point to point — one transmitter and one receiver per cable.
DATA_RET is a single wire from the end of the chain back to the Seed, passing
through every satellite.
| Format | UART, 8N1, LSB first, idle high |
| Rate | 1 Mbaud |
| Levels | 3.3 V CMOS; satellites run directly from the chain supply |
| Seed side | USART3 — TX on pin 3, RX on pin 2 |
The ring closes itself
Section titled “The ring closes itself”At boot and every millisecond after, each satellite reads the PRESENT pin on
its OUT connector.
- Low — something is plugged in downstream, so transmit on
DATA_FWD. - High — this is the last satellite, so move the UART’s transmit onto the
DATA_RETtap. Frames then travel back along the return wire to the Seed.
No terminator plug, and nothing to configure when a panel grows. A satellite drives the return tap only while it is actually transmitting; the rest of the time the tap is high-impedance and the motherboard’s pull-up holds the line idle, so two satellites can never fight over the return wire.
Frames
Section titled “Frames”A 4-byte header followed by N slots of 4 bytes, at most 260 bytes — 2.6 ms at 1 Mbaud.
Header
| Byte | Field |
|---|---|
| 0 | SOF, 0xA5 for protocol v1 |
| 1 | TYPE — 0x01 scan, 0x02 discover, 0x03 command |
| 2 | N, slots that follow, 0–64 |
| 3 | HOP, satellites passed through so far |
Slot — KIND, D0, D1, then a CRC-8 over the first three bytes
(polynomial 0x07, init 0x00, CRC-8/SMBUS).
Slot kinds
Section titled “Slot kinds”Satellites report state, not events. If a frame is lost nothing is missed: counters wrap, and the Seed works out what changed from the difference with the last good value.
KIND | Name | Carries |
|---|---|---|
0x01 | POT | 16-bit position, scaled 0–65535 whatever the ADC’s resolution |
0x02 | BUTTON | Pressed-now bit, plus a press counter that wraps at 256 |
0x03 | ENCODER | Detent counter wrapping at 256, plus switch state and its counter |
0x04 | SWITCH | Position index |
0x7F | FAULT | Fault code and detail |
0x10 | LED | Seed to satellite: brightness, and steady or blinking |
Board kinds
Section titled “Board kinds”A resistor to ground on an ADC pin tells the one satellite firmware image which board it is running on. Position in the chain is still the address; the kind only says what the board has on it.
| Kind | Board | Slots |
|---|---|---|
1 | potentiometer (rodeo-pot-1) | 1 × POT |
2 | button (rodeo-button-1, specified) | 1 × BUTTON |
3 | encoder with push switch (rodeo-encoder-1) | 1 × ENCODER |
4 | rotary switch, up to 8 positions (rodeo-rotary-switch-1: 4 positions, specified) | 1 × SWITCH |
5 | pot bank ×4 (rodeo-pot-bank-4) | 4 × POT |
6 | encoder bank ×4 (rodeo-encoder-bank-4) | 4 × ENCODER |
7 | button bank ×4 (rodeo-button-bank-4) | 4 × BUTTON |
14 | custom board on its own firmware (the satellite dev board) | 1–4, as it declares |
15 | no resistor fitted — reports EMPTY | 1 |
Kinds 8–13 are kept for future Rodeo satellites. A new board type needs a resistor value and a firmware update, not a firmware of its own. Kind 14 is the exception: a board Rodeo doesn’t make runs its own firmware and declares its slots when the Seed discovers it, so the Seed needs nothing new to read it.
Timing
Section titled “Timing”One frame is in the ring at a time. The Seed sends the next after the previous returns, or after a timeout.
- Ring time ≈ (4 + 4N) × 10 µs + 40 µs per satellite. For thirty one-slot satellites that is about 2.5 ms.
- Default scan period 4 ms, so 250 scans a second. A control change reaches the Seed within roughly one period plus one ring time — about 6.5 ms worst case across thirty satellites.
- Scans are paced from a timer, never from the audio callback.
What has actually run
Section titled “What has actually run”A ring of a motherboard, a pot bank and an encoder bank, on 2 November 2026: about 24,600 scans in two minutes, none bad, every reply the full 36 bytes. All four pots swept their range, all four encoders turned both ways and pressed, and the Seed drove each board’s LED. Pulling a satellite mid-scan cost seven bad scans, all at the moment of the unplug, and the chain recovered.
It did not work first time. Both boards were discovered, but most scans came back short until the satellite firmware moved to passing frames through in its UART interrupt rather than in its main loop.
Untried: breaks within the ring, three or more satellites, and every board that has not been made — the button bank and the single-control boards.
What limits the chain is voltage drop, not current. It is fed from one end at 3.3 V, every satellite has to work down to 2.7 V, and each link — 150 mm of 28 AWG plus two connector matings, there and back — is about 0.14 Ω carrying the current of everything past it.
The baseline is ≈6 mA per satellite including its indicator LED, for thirty on one feed through a 0.75 A resettable fuse. That puts the last of thirty roughly 0.4 V down, leaving about 0.2 V of headroom.
You can spend that headroom. A satellite drawing ΔI more than the baseline at position p lowers the far end by ≈0.14 Ω × p × ΔI, and the rule is to keep Σ (p × ΔI) under about 1.4 A across the whole chain. Four single-colour lit buttons cost 85 mV even at position thirty, and under 30 mV ten boards in.
LEDs that want more than 3.3 V or tens of milliamps — addressable RGB, meters — take their LED power from a separate 5 V feed and keep their microcontroller on the chain, so logic levels do not move. Rev B does not bring 5 V to a connector yet; that is on the motherboard’s list for its next revision.