Skip to content

feat(sim): run the receiver firmware and inject RF frame loss - #173

Merged
FredM67 merged 2 commits into
devfrom
sim/receiver-firmware
Sep 30, 2026
Merged

FredM67 merged 2 commits into
devfrom
sim/receiver-firmware

Conversation

@FredM67

@FredM67 FredM67 commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Stage 2 of the RF mock, following #171. The remote units now run the real RemoteLoadReceiver firmware, and RF frames can be lost on purpose.

Changes

  • Radio model, receive side (rfm69.c): a frame that has been sent reaches every other radio.
    • A radio listening (RX mode) on the same network gets the frame in its FIFO, with PayloadReady set and DIO0 raised on D2 (INT0). The library's interrupt and receiveDone() path therefore runs unmodified.
    • A radio that isn't listening misses the frame, and this is counted.
  • Real receivers: grid_sim -r <node>=<receiver.elf> runs the receiver firmware in its own simulated AVR, in step with the router on the same clock.
    • Its load pins (receiver_pins 4 3) drive the remote loads.
    • Its serial output is shown, prefixed R<node>|, and its "RF link LOST" messages are counted.
    • Nodes without firmware keep the ideal receiver.
  • Frame loss:
    • rf_drop <t0> <t1> [node] loses every frame in a window.
    • rf_loss <percent> loses frames at random, from a fixed seed, so every run loses the same frames.
    • expect rf_links_lost <node> <min> <max> checks how often a receiver lost the link.
  • build_receivers.sh: builds the receiver once per node ID, since REMOTE_NODE_ID is a constant in its config_rf.h, and restores the file afterwards.
  • Makefile and CI: make check-rf uses the receiver firmware for RX_NODES (15 by default); RX_NODES= switches back to ideal receivers. The CI step is unchanged apart from its name.

Results with the receiver firmware

Scenario Result
remote_override 139/139 frames received; 5/5
remote_step 744/744 frames received, grid regulated through the remote load; 10/10
link_loss (new): no frames to node 15 from 10 to 11 s load off at 10.41 s (500 ms after the last frame), back on at 11.00 s, link lost once; 6/6
lossy_link (new): 20 % of frames lost 54 of 239 frames lost, link never lost; 4/4

The ideal receivers give the same results in all four scenarios. No frame was missed because a receiver wasn't listening.

Each receiver roughly halves the simulation speed: check-rf takes ~50 s with one receiver.

Next, on #160

  • Set RX_NODES to 15 16.
  • Add node 16 to the loss scenarios, for example losing unit 1's frames while unit 2 keeps its load.

🤖 Generated with Claude Code

FredM67 and others added 2 commits September 30, 2026 23:00
The RFM69 model gets its receiving side: a frame that has been sent reaches
every other radio; one listening on the same network gets it in its FIFO,
with PayloadReady and DIO0 (D2, INT0) raised, so the library's receive path
runs unchanged. A radio not listening misses it.

grid_sim -r <node>=<receiver.elf> runs the RemoteLoadReceiver firmware in its
own simulated AVR, in step with the router. Its load pins (receiver_pins)
drive the remote loads, its serial output is shown and its link losses
counted. Nodes without firmware keep the ideal receiver.

Frames can be lost: rf_drop <t0> <t1> [node] and rf_loss <percent> (fixed
seed). New expectation: expect rf_links_lost <node> <min> <max>, and two
scenarios, link_loss (1 s blackout) and lossy_link (20 % loss).

build_receivers.sh builds the receiver once per node ID; make check-rf uses
it for RX_NODES (15 by default, empty for ideal receivers).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its executable bit was not recorded (committed from Windows): make failed with
Permission denied in CI. The bit is set now too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@FredM67
FredM67 merged commit b70cd37 into dev Sep 30, 2026
9 checks passed
@FredM67
FredM67 deleted the sim/receiver-firmware branch September 30, 2026 21:08
FredM67 added a commit that referenced this pull request Sep 30, 2026
…nits

Brings in the receiver firmware in grid_sim (#173). Both remote units now
run the RemoteLoadReceiver firmware in check-rf (RX_NODES 15 16):
- link_loss: unit 16 keeps its frames and its load while unit 15's are lost
- lossy_link: 10 % frame loss instead of 20 %. With a 100 ms refresh, 4 frames
  lost in a row already reach the 500 ms timeout; at 20 %, unit 16 lost its
  link once in 30 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant