Skip to content

Repository files navigation

broken-transmitter is a Raspberry Pi to Raspberry Pi file transfer project built around nRF24L01 radios, a fixed 32-byte packet format, and deliberately fragile transmission algorithms.

  • Pi A runs the transmitter web app.
  • Pi B runs the receiver web app.
  • The transmitter selects an algorithm per transfer.
  • The receiver auto-detects the matching decoder from the START packet flags.

This project explores how different transport styles behave when the radio link is intentionally lossy. Best way to observe this behaviour is to transmit BMP image files.

Architecture

Transfers follow one control-plane flow and then diverge into algorithm-specific data packets:

  1. TX sends START.
  2. TX may send up to three START_HEADER packets for file header recovery.
  3. TX streams algorithm-specific body packets.
  4. TX sends STOP.
  5. RX sends START_ACK and STOP_ACK when it can.

Internal layout

  • src/broken_transmitter/core/: runtime models, transmitter pipeline, receiver state machine, and receiver service thread
  • src/broken_transmitter/wire/: packet constants, flag helpers, and packet serialization/parsing
  • src/broken_transmitter/transport/: RF24 transports and in-memory transports used by tests
  • src/broken_transmitter/algorithms/: transfer algorithms plus the explicit algorithm manifest
  • src/broken_transmitter/web/: TX/RX FastAPI app composition, app state, and serializers
  • src/broken_transmitter/templates/: Jinja templates for the TX/RX web pages
  • src/broken_transmitter/static/: CSS and browser-side JavaScript

Requirements

  • Raspberry Pi OS with SPI enabled
  • 2 x nRF24L01 modules powered correctly at 3.3V
  • Python 3.11+
  • pyrf24 installed on the target Pis

Deploy

Use the deployment script from this repo root:

scripts/deploy.sh \
  --tx-host transmitter.local \
  --rx-host receiver.local \
  --user pi

By default, this syncs the repo, optionally bootstraps the Python environment, updates .env.tx / .env.rx, and refreshes the remote run-tx.sh / run-rx.sh launchers. It does not create or restart systemd services unless you opt in.

Example with explicit overrides:

scripts/deploy.sh \
  --tx-host 192.168.1.50 \
  --rx-host 192.168.1.51 \
  --user pi \
  --tx-web-port 8080 \
  --rx-web-port 8080 \
  --ce-pin 22 \
  --channel 108 \
  --tx-address BTX01 \
  --rx-address BRX01

After a default deployment:

  • TX: ssh pi@<tx-host> 'cd /home/pi/broken-transmitter && ./run-tx.sh'
  • RX: ssh pi@<rx-host> 'cd /home/pi/broken-transmitter && ./run-rx.sh'

Local Testing

The current test suite uses unittest and does not require RF hardware.

Install dev tooling:

uv sync --all-extras --dev

Install and run pre-commit:

uv run pre-commit install
uv run pre-commit run --all-files

Run tests:

uv run python -m unittest discover -s tests -v

About

Intentionally unreliable data transmission

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages