NODE_ID & CAN Addressing
Every STM32 board on the CAN bus has a NODE_ID — a small integer that defines which CAN frames it owns. It's how PanelBridge tells one PanelGroup node from another, and it's baked in at compile time. Get it right once and it never changes.
The scheme
- Set at compile time via
build_flags = -DNODE_ID=Ninplatformio.ini— not a#defineinmain.cpp. - Range 0–63.
- 0 — PanelBridge (the CAN master). Reserved; its heartbeat
HB_0is never transmitted. - 1–63 — PanelGroup nodes, assigned incrementally, permanent once assigned.
- SimGateway has no NODE_ID — it's not on the CAN bus.
A node's frame IDs are computed from its NODE_ID with the helper functions — heartbeat
canIdHb(n), events canIdEvt(n), echo canIdEcho(n), ready canIdReady(n). Never hard-code
these. The full frame map is in CAN Bus Protocol.
Why build_flags and not #define
A #define NODE_ID in main.cpp is visible only in that translation unit. The CAN
protocol library and other units need NODE_ID to compute frame IDs. build_flags
injects it as a compiler flag visible to every translation unit in the project.
The registry
The authoritative record lives in Firmware/NODE_IDS.md at the repo root. Current state:
| NODE_ID | Panel Group | Console | Status |
|---|---|---|---|
| 0 | PanelBridge | — | Reserved — CAN master, never transmitted on bus |
| 1 | Center_Armament | Center | Active |
| 2 | Right_Navigation | Right | Active |
How to claim a new NODE_ID
IDs are permanent — never reuse one, even if a panel is retired (mark it Retired instead). When you start a new panel group:
- Open
Firmware/NODE_IDS.mdand take the next available number (currently 2). - Add a row with your panel group, console, and status.
- Set
build_flags = -DNODE_ID=Nin your board'splatformio.ini. - Commit the registry change in the same PR that creates the panel sketch.
One NODE_ID per physical STM32 board. See Adding a New Panel Group for the full workflow — claiming the ID is step one.
CI enforces this
A CI check (tools/check_node_ids.py) validates every production panel under
Firmware/Panels/ against this registry on each firmware PR: it fails the build if a board's
NODE_ID is unregistered, duplicated, or out of range. The table above is transcluded directly
from Firmware/NODE_IDS.md, so the docs can't drift from the registry.