Skip to content

About

PlatformIO Raceband RSSI scanner for RX5808/RC832 FPV receivers — LED indicators, a WiFi web UI with pilot reservations and a calibration wizard, and composite TV output, across Arduino/ESP32/ESP8266 boards

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

30 Commits

Folders and files

Repository files navigation

Raceband RSSI Scanner

License: Apache 2.0

Scans all 8 channels of the analog FPV Raceband (5658-5917 MHz) with a single RX5808/RTC6715-based receiver module and reports RSSI per channel over serial. Since one receiver can only listen to one frequency at a time, "monitoring 8 channels" means continuously re-tuning the module across all 8 Raceband channels and sampling RSSI after each retune (a frequency sweep), rather than listening to all 8 simultaneously.

Hardware

Any RX5808 module works, including a modified RC832 with its RTC6715 tuner chip's SPI control lines exposed (the standard "RX5808 SPI mod": bridging or removing the onboard resistor/pad that ties the bus-select pin low, freeing up DATA/CLK/LE for direct microcontroller control instead of the module's onboard button-scan logic).

You'll also need one LED per Raceband channel (each with a current-limiting resistor, e.g. 220Ω) to show that channel's busy/free state.

Wiring

Wire everything to an Arduino Uno/Nano (ATmega328P) as follows:

Signal Arduino pin
RX5808/RC832 DATA D10
RX5808/RC832 CLK D11
RX5808/RC832 LE / SEL (CS) D12
RX5808/RC832 RSSI A0
RX5808/RC832 GND GND
RX5808/RC832 3.3V / 5V per your module's onboard regulator
R1 busy/free LED D2
R2 busy/free LED D3
R3 busy/free LED D4
R4 busy/free LED D5
R5 busy/free LED D6
R6 busy/free LED D7
R7 busy/free LED D8
R8 busy/free LED D9

LEDs wire from their pin, through the resistor, to GND. Each LED lights up whenever that specific channel is considered busy (see below).

RX5808 pin assignments are #defines at the top of include/rx5808.h (overridable via build_flags, see the promicro16 env below); LED pin assignments are CHANNEL_STATE_LED_PINS in src/main.cpp - change either if you need different pins.

Arduino Pro Micro

The Pro Micro (ATmega32U4) doesn't break out D11/D12 on its header, so the promicro16 build environment remaps the RX5808 bus to D14-D16 instead:

Signal Arduino pin
RX5808/RC832 DATA D14
RX5808/RC832 CLK D15
RX5808/RC832 LE / SEL (CS) D16
RX5808/RC832 RSSI A0

LED wiring (D2-D9) is unchanged.

ESP32

The ESP32's WiFi is used to serve a live channel-status web page (see below), so the esp32 build environment moves every pin off the AVR defaults: GPIO6-11 are wired internally to the module's flash chip and can't be used as GPIOs, and GPIO0/2/5/12/15 are boot-mode strapping pins best left alone. RSSI is the only signal read with analogRead(), and WiFi takes over ADC2 for as long as it's active, so RSSI specifically needs an ADC1 pin - hence GPIO34. The LED pins are plain digitalWrite() outputs, so a few of them (GPIO25/26/27) doubling as ADC2 channels doesn't matter - that conflict only affects analog reads on a pin, not digital I/O.

Signal ESP32 pin
RX5808/RC832 DATA GPIO16
RX5808/RC832 CLK GPIO17
RX5808/RC832 LE / SEL (CS) GPIO18
RX5808/RC832 RSSI GPIO34
R1 busy/free LED GPIO19
R2 busy/free LED GPIO21
R3 busy/free LED GPIO22
R4 busy/free LED GPIO23
R5 busy/free LED GPIO25
R6 busy/free LED GPIO26
R7 busy/free LED GPIO27
R8 busy/free LED GPIO32

The ESP32 is 3.3V native, so unlike the 5V Nano/Uno/Pro Micro there's no need to worry about the RX5808's logic-level tolerance.

ESP8266

The esp8266 build environment also serves the live channel-status web page, but has no per-channel busy/free LEDs - the ESP8266 doesn't have eight spare GPIOs once WiFi and the RX5808 bus are accounted for (and several of the ones it does have are boot-mode strapping pins best left alone), so this board relies on the Web UI as its only busy/free indicator. Only the RX5808 bus needs pins, remapped clear of the GPIO0/2/15 strapping pins:

Signal ESP8266 pin (NodeMCU)
RX5808/RC832 DATA GPIO4 (D2)
RX5808/RC832 CLK GPIO5 (D1)
RX5808/RC832 LE / SEL (CS) GPIO14 (D5)
RX5808/RC832 RSSI A0

Like the ESP32, the ESP8266 is 3.3V native, so there's no RX5808 logic-level tolerance to worry about. A NodeMCU/Wemos D1 mini's onboard resistor divider on A0 is also what makes it safe to feed the RX5808's 0-3.3V RSSI output directly into a pin whose bare ADC otherwise tops out around 1V.

Building

pio run                       # build (defaults to nanoatmega328new)
pio run -t upload             # build + flash
pio device monitor -b 115200  # view RSSI output

Other board environments are defined in platformio.ini:

  • nanoatmega328new - Nano with the newer bootloader (default)
  • nanoatmega328 - Nano with the old bootloader (uses 57600 baud upload)
  • uno - Arduino Uno
  • promicro16 - Arduino/SparkFun Pro Micro, 5V/16MHz (see Wiring above for its remapped pins)
  • esp32 - Espressif ESP32 dev board, adds the web UI below (see Wiring above for its remapped pins)
  • esp8266 - Espressif ESP8266 dev board, adds the web UI below but has no busy/free LEDs (see Wiring above)
  • nanoatmega328new_tvout - Nano with composite/analog video output added (see TV Output below)
  • esp32_tvout - Same as esp32, with composite/analog video output added (see TV Output below)

Select one explicitly with pio run -e uno.

Output

Each line is one full 8-channel sweep, printed as raw ADC RSSI (0-1023), a calibrated percentage, and each channel's resulting busy/free state:

1234 ms	R1=142 (29%, FREE)	R2=138 (25%, FREE)	R3=205 (60%, BUSY)	R4=95 (2%, FREE)	R5=101 (5%, FREE)	R6=110 (10%, FREE)	R7=99 (4%, FREE)	R8=120 (15%, FREE)

Per-channel busy/free LEDs

After every sweep, each channel's calibrated RSSI percentage is compared against the busy threshold (50% by default - see Calibration below). Channels at or above the threshold are considered busy - a video transmitter appears to be active on that frequency - and their LED is driven HIGH. Channels below it are free and their LED is driven LOW. This gives a quick visual per-channel "is this Raceband frequency clear" indicator without needing the serial monitor.

Skipped entirely on the esp8266 build (CHANNEL_STATE_LEDS_ENABLED in src/main.cpp defaults to off there) - see the ESP8266 wiring notes above for why. The busy/free state is still computed and reported over serial and the Web UI either way, just without driving any LED pins.

Web UI

On the esp32 and esp8266 builds, the scanner also hosts its own WiFi access point and serves a live status page: one box per channel, green when free and red when busy (matching the LEDs, on boards that have them). Each box also carries a checkmark/warning-triangle icon (not just color) so the state is readable regardless of color vision. On boot it prints the network name and page URL to serial, e.g.:

Web UI: join WiFi "BandoBuddy" (password "raceband1") and browse to http://192.168.4.1

Join that network from a phone or laptop and open the printed address. The page polls the current busy/free state twice a second; there's no need to keep the serial monitor open. This is compiled out entirely on boards without WiFi (Nano/Uno/Pro Micro).

Web UI showing free, busy, and reserved channels

Pilot reservations

Pilots can tap a free or busy card, type their name, and reserve that channel - the card turns white with a padlock icon and their name so everyone at the field can see who's on which frequency. Tapping a reserved card again releases it. If the channel actually keys up while reserved, the card still turns red (the live RSSI reading always takes priority over the reservation display). Reservations are held in RAM on the ESP32/ESP8266 only and don't survive a reboot, and there's no login - anyone on the AP can reserve or release any channel, matching the rest of this trust-based, pit-side device.

Admin page and calibration wizard

The gear icon (⚙) next to the title links to /admin, a small settings page for the RSSI calibration and busy threshold covered in Calibration below - no reflash needed to retune them. It has three controls (RSSI min, RSSI max, and the busy threshold as a slider) and a Save button, plus a Calibrate... button that walks through measuring RSSI min/max instead of guessing at raw ADC numbers:

  1. Step 1 (noise floor): with no video transmitter powered on nearby, the modal shows the live raw RSSI reading updating twice a second. Click Next once it's settled to capture it as the RSSI min candidate.
  2. Step 2 (signal strength): power on a video transmitter on Raceband channel R5 (5806MHz) and place it about 2m (6ft) from the receiver antenna. The modal tracks the live reading and the peak seen so far (so a moment of misalignment while positioning the VTX doesn't ruin the reading) - click Done once the peak has stopped climbing. A Reset button next to the peak clears it back to zero, for starting the measurement over without leaving the step (e.g. after a stray spike, or repositioning the VTX).
  3. Review: shows the RSSI min/max values it's about to set. Save writes them (keeping whatever busy threshold the slider is currently at); Cancel discards them and leaves the existing calibration untouched.

The wizard always measures channel R5 specifically (regardless of which channel you eventually fly on) so it has one consistent, repeatable reference point - the same min/max then applies to all 8 channels' RSSI readings, since the RX5808's absolute RSSI scale doesn't vary meaningfully channel-to-channel.

Like reservations, calibration values live in RAM only and reset to their compile-time defaults (see Calibration below) on reboot.

TV Output

Two build environments add a composite (PAL/NTSC) video signal that mirrors the Web UI's per-channel grid directly onto a small CRT, composite monitor, or FPV goggles - no WiFi, browser, or phone needed. Both are opt-in (disabled in the default nanoatmega328new/esp32 builds) since each needs its own pin remap - see the wiring for each below. Reservations aren't shown on either - those live only in the ESP32 Web UI's RAM, and pilots have no way to type a name into a TV screen - so both mirror the same busy/free bitmask that drives the LEDs.

AVR (Nano/Uno/Pro Micro)

The nanoatmega328new_tvout build environment uses the TVout library:

pio run -e nanoatmega328new_tvout -t upload

Each of the 8 boxes shows the channel name and its "FREE"/"BUSY" state, same as the Web UI, laid out in the same 4-column grid. Composite video here only carries luma (brightness), no chroma, so unlike the Web UI's green/red coding, a busy channel is marked with a solid block in the corner of its box in addition to the text - a shape difference, not a color one, so the state still reads without relying on color, matching the accessibility approach already used for the LEDs and Web UI icons.

Wiring

TVout hard-codes its sync and video pins per chip; on the ATmega328 (Uno/Nano) these are D9 (sync) and D7 (video), so this build environment moves R6's and R8's busy/free LEDs off those two pins onto A1/A2 (used as plain digital outputs) to free them up:

Signal Arduino pin
Composite sync D9
Composite video D7
R6 busy/free LED A1
R8 busy/free LED A2

(R1-R5 and R7 stay on their default pins - see Wiring above.)

Mix the sync and video signals into a single composite line with two resistors, then feed that into an RCA jack (center pin = signal, shield = GND):

D9 (sync)  ---[470ohm]---+
                          +--- RCA center pin --- to display
D7 (video) ---[1k ohm]----+

PAL is available via -D TV_OUT_PAL (added to that environment's build_flags); NTSC is the default.

Caveats

  • The 128x64 monochrome frame buffer is allocated at runtime (~1KB) on the ATmega328's 2KB of RAM, on top of the rest of the sketch's globals and stack. This build has been compiled and its RAM/flash usage checked, but not run on real hardware - if it locks up or corrupts the display, freeing more RAM (e.g. dropping RSSI_SAMPLES) or reducing TV_HRES/TV_VRES in src/tv_ui.cpp (must stay a multiple of 8) are the first things to try.
  • Generating a video signal digitally right next to a 5.8GHz RF front-end is a plausible source of noise on the RSSI reading. This hasn't been validated on hardware either - keep the composite video wiring/cable routed away from the RX5808 module and antenna, and re-check calibration (see below) once everything is wired up.

ESP32

The esp32_tvout build environment uses the ESP_8_BIT library, which drives composite video off the ESP32's onboard DAC on GPIO25 (shield to GND). See the known issue below before wiring this up for FPV goggles - it's confirmed working electrically, but the picture isn't watchable on at least one goggle model (Fatshark) as of this library version:

pio run -e esp32_tvout -t upload

This is on top of the regular esp32 build - the WiFi Web UI still runs, so you get both a browser page and a goggles/monitor feed from the same board. Unlike the AVR build, ESP_8_BIT's composite signal does carry color, so the grid uses the same green (free) / red (busy) coding as the Web UI, plus the "FREE"/"BUSY" text for the same colorblind-friendly redundancy as everywhere else in this project.

ESP_8_BIT's DAC output is fixed to GPIO25, which is R5's busy/free LED in the default esp32 pin mapping, so this build environment moves that LED to GPIO33 instead:

Signal ESP32 pin
Composite video GPIO25
R5 busy/free LED GPIO33

(Everything else - RX5808, R1-R4/R6-R8 LEDs - stays on the pins in the Wiring section above.)

PAL is available via -D TV_OUT_PAL (same flag as the AVR build, added to esp32_tvout's build_flags); NTSC is the default.

Known issue: rolling picture on FPV goggles

Tested on real hardware (ESP32-D0WD-V3, well past the chip revisions this library's README warns don't work at all) into a pair of Fatshark goggles: the firmware runs fine - WiFi, RX5808 scanning, everything else is unaffected - but the picture on the goggles never holds still, rolling continuously regardless of:

  • NTSC vs. PAL (TV_OUT_PAL) - both roll the same way.
  • Signal level - tried GPIO25 direct, and in series with 1kOhm, 270Ohm, and 135Ohm resistors (targeting the ~1Vpp/75Ohm composite spec that real FPV video receiver modules output into the same input). Level changed brightness/visibility, not the roll.
  • This isn't specific to this project's drawing code either - the library's own unmodified example sketch (GFX_HelloWorld) rolls the same way over the same wiring.

The likely cause: this library generates its signal via a low-level ESP32 hardware hack the author's own README describes as tested against old-school tube TVs. CRTs have a free-running analog deflection oscillator that's very forgiving of imprecise sync timing. FPV goggles instead decode composite video with a digital chip driving an LCD/OLED panel, which generally needs tighter, more consistent sync timing than a CRT to frame the picture at all - so a signal loose enough for a CRT to display cleanly can still roll on goggles. (PSRAM is a documented cause of near-identical "jiggling" symptoms for this library, but doesn't apply here - the esp32dev board build has no PSRAM support compiled in to begin with.)

Bottom line: this backend runs correctly (WiFi/RX5808/etc. all unaffected) and its author reports it working on CRT-class displays, but we don't have one to confirm that ourselves, and it isn't currently known to work cleanly with FPV goggles - that part is confirmed, on real hardware, not a compiled-only guess. If you get it stable on a Fatshark (or other) goggle - through different wiring, a different resistor value, or a library fix - an issue or PR updating this section would be welcome.

Other caveats

  • ESP_8_BIT generates its signal off an interrupt tied to the I2S/DAC peripheral, independent of the main loop and the WiFi stack; the Web UI and RX5808 scan were confirmed unaffected during testing.
  • As with the AVR build, generating a video signal next to a 5.8GHz RF front-end is a plausible source of RSSI noise; keep the composite wiring away from the RX5808 module and antenna and re-check calibration once wired up. (Not yet specifically confirmed either way.)

Calibration

The printed/reported percentage is derived from an RSSI min (noise floor) and RSSI max (strong signal) raw ADC value, and compared against a busy threshold percentage - all three defined in include/calibration.h as RSSI_RAW_MIN_DEFAULT (90), RSSI_RAW_MAX_DEFAULT (280), and CHANNEL_BUSY_THRESHOLD_PCT_DEFAULT (50). These are just the starting values a freshly flashed board boots with - overridable via build_flags for a board-specific starting point (e.g. -D RSSI_RAW_MIN_DEFAULT=100), same as the LED pin lists elsewhere in this README.

On esp32/esp8266: all three are also adjustable at runtime, no reflash needed, from the Web UI's admin page (see "Admin page and calibration wizard" above) - either by typing values directly or via the guided "Calibrate..." wizard, which measures your specific RX5808 module's noise floor and a real VTX's signal strength for you rather than needing a serial-monitor readout. These runtime values live in RAM only and reset to the compile-time defaults above on reboot; there's currently no persistence across power cycles.

On Nano/Uno/Pro Micro (no Web UI to change them from), calibrate by editing the compile-time defaults directly:

  1. Flash and open the serial monitor with no video transmitter powered on nearby - note the raw values (noise floor) → use as RSSI_RAW_MIN_DEFAULT.
  2. Power a video transmitter at close range on each Raceband channel in turn and note the raw peak values → use the highest as RSSI_RAW_MAX_DEFAULT.
  3. Update the two defaults (in include/calibration.h, or via build_flags) and reflash.

On ESP32/ESP8266, their ADCs are less linear than the AVR boards' - calibrate on the esp32/esp8266 build itself (the runtime admin page makes this easy - see above) rather than reusing values measured on a Nano/Uno/Pro Micro.

Tuning speed vs. stability

RSSI_SETTLE_MS in src/main.cpp controls how long the code waits after switching channels before trusting the RSSI reading (PLL relock + RSSI output settling time). The default of 20ms gives a full 8-channel sweep in roughly 170-200ms (~5 sweeps/second). Lowering it speeds up the scan but increases reading noise/inaccuracy right after a channel switch.

About

PlatformIO Raceband RSSI scanner for RX5808/RC832 FPV receivers — LED indicators, a WiFi web UI with pilot reservations and a calibration wizard, and composite TV output, across Arduino/ESP32/ESP8266 boards

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages