Skip to content

UI/rf waterfall sdr style - #2880

Merged
bmorcelli merged 2 commits into
BruceDevices:devfrom
vnxdtzip:ui/rf-waterfall-sdr
Sep 15, 2026
Merged

bmorcelli merged 2 commits into
BruceDevices:devfrom
vnxdtzip:ui/rf-waterfall-sdr

Conversation

@vnxdtzip

Copy link
Copy Markdown

Proposed Changes

This reworks RF Waterfall onto the shared SpectrumPlot component and adds an
opt-in SDR colourmap to that component, so the screen reads like desktop SDR
software while its chrome stays consistent with the rest of Bruce.

Two parts:

  1. SpectrumPlot gains an optional SDR waterfall colourmap:

    bool begin(const String &title, bool sdrWaterfall = false);
    

    When true, the waterfall ramp is the classic SDR gradient (noise floor
    blended into the panel, then blue, cyan, green, yellow, red, up to a
    white-hot peak) instead of the theme heat ramp. The trace on top stays
    theme-coloured. The parameter defaults to false, so NRF Spectrum, Jam Detect
    and Channel Analyzer are unchanged and keep the theme ramp.

  2. RF Waterfall is rebuilt on that component. It previously swept the CC1101 one
    pixel-column at a time, mapped RSSI through a hand-rolled rainbow with an
    inverted ramp (strong signals came out dark, the noise floor bright red),
    scrolled a manual framebuffer and drew its labels in literal TFT_* colours
    with no border, title or status bar. Now:

    • the top is SpectrumPlot's filled trace with a peak-hold line and animated
      noise floor; the drawn envelope eases toward each measurement (as Jam
      Detect does) so the trace glides instead of snapping
    • the waterfall below is fed by the same envelope, so the falls track the
      waveform above them, drawn with the new SDR colourmap
    • a five-tick frequency ruler and a status line naming the peak dBm and
      frequency, all theme-consistent
    • UP/DOWN (or PREV/NEXT) pan the whole window; the ruler and peak-hold reset
      to follow

    The sweep itself is fixed too. In the scan path setMHZ only rewrites the
    frequency, and the CC1101 needs a few milliseconds for the PLL/RSSI to settle
    before getRssi() is valid (the working RF RSSI view waits 5ms). The old
    per-pixel 100us wait was far too short, so a real signal never rose above the
    noise floor - the rainbow only ever showed noise. It now samples WF_BINS
    points with a real settle and interpolates the envelope across the plot, so a
    transmitter actually paints the trace and the waterfall.

Types of Changes

Bugfix (RSSI never settled, so nothing was detected; the colour ramp was
inverted) plus a UI rework onto the shared component and an opt-in rendering
option on that component. No behaviour change for existing SpectrumPlot callers,
no breaking change.

Verification

pio run -e m5stack-cardputer

Flash and open RF -> Waterfall on a device with a CC1101. Expect:

  • a filled trace with peak-hold across the top, gliding as it updates
  • a waterfall below in the SDR gradient (dark for the noise floor, climbing
    through blue/green/yellow to red/white on a strong signal) that follows the
    trace
  • a frequency ruler and a status line naming the peak dBm and frequency
  • UP/DOWN pans the band

Transmitting on a frequency inside the band should raise the trace at the
matching column and leave a bright streak falling down the waterfall.

NRF Spectrum, Jam Detect and Channel Analyzer should be visually unchanged
(they keep the theme ramp).

Testing

No unit test harness exists for this layer. Compiled clean for m5stack-cardputer.
Not yet verified on hardware by me - a reviewer with a CC1101 should confirm a
known transmitter paints the trace and that the pan controls track.

Linked Issues

None.

User-Facing Change

RF Waterfall now renders on the shared spectrum plot with a gliding peak-hold trace and an SDR-style colour waterfall, follows the theme for its chrome, and actually detects signals (the sweep now lets the CC1101 settle before reading RSSI).

Further Comments

WF_BINS (64) and WF_SETTLE_MS (3) trade sweep resolution against refresh rate;
they are #defines at the top of the run function so they are easy to tune on
hardware. The SDR gradient stops follow the common SDR waterfall colourmaps
(GQRX, SDR#, SDRPlay); index 0 is the panel background so a dead band blends
with the frame rather than showing a hard black bar.

waterfall

Vinicius and others added 2 commits September 11, 2026 18:57
#### Proposed Changes ####

SpectrumPlot's waterfall has always used buildHeatPalette, a single-hue ramp
derived from the active theme. That keeps the spectrum screens consistent, but
it does not read like the waterfall people know from desktop SDR software,
where signal strength climbs through a full blue -> cyan -> green -> yellow ->
red spectrum.

This adds an opt-in SDR colourmap to the shared component:

    bool begin(const String &title, bool sdrWaterfall = false);

When sdrWaterfall is true the waterfall ramp is built from the classic SDR
gradient (noise floor blended into the panel, then blue, cyan, green, yellow,
red, up to a white-hot peak) instead of the theme ramp. The trace on top stays
theme-coloured either way, so the header, border and spectrum line still match
the rest of Bruce.

The parameter defaults to false, so every current caller - NRF Spectrum, Jam
Detect and Channel Analyzer - is unchanged and keeps the theme ramp.

#### Types of Changes ####

New Feature (opt-in rendering option on an internal component). No behaviour
change for existing callers and no breaking change.

#### Verification ####

    pio run -e m5stack-cardputer

Nothing changes on screen for existing callers; the colourmap becomes visible
through the RF Waterfall module that turns it on (separate commit).

#### Testing ####

No unit test harness exists for this layer. Compiled for m5stack-cardputer. The
palette is exercised on hardware through the RF Waterfall commit.

#### Linked Issues ####

None. Prerequisite for the RF Waterfall SDR rework.

#### User-Facing Change ####
```release-note
NONE
```

#### Further Comments ####

The gradient stops follow the common SDR waterfall colourmaps (GQRX, SDR#,
SDRPlay). Index 0 is the panel background so a dead band blends with the frame
rather than showing a hard black bar.

Co-authored-by: Vinicius <discoestudio5@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#### Proposed Changes ####

RF Waterfall drew its own screen: it swept the CC1101 one pixel-column at a
time, mapped RSSI through a hand-rolled rainbow with an inverted ramp (strong
signals came out dark, the noise floor bright red), pushed each row into a
manually scrolled framebuffer, and drew its labels and max readout in literal
TFT_* colours with no border, title or status bar. It shared no code with the
spectrum screens that were standardised on SpectrumPlot.

It now renders through the shared component, so the top matches Jam Detect and
the bottom reads like a desktop SDR:

  - the top is SpectrumPlot's filled trace with a peak-hold line and animated
    noise floor; the drawn envelope eases toward each measurement (as Jam
    Detect does) so the trace glides instead of snapping
  - the waterfall below is fed by the same envelope, so the falls track the
    waveform above them, drawn with the new SDR colourmap (begin(title, true))
  - a five-tick frequency ruler and a status line showing the peak dBm and
    frequency, all theme-consistent
  - UP/DOWN (or PREV/NEXT) pan the whole window; the ruler and peak-hold reset
    to follow

The sweep itself is fixed as well. setMHZ only rewrites the frequency in the
scan path, and the CC1101 needs a few milliseconds for the PLL/RSSI to settle
before getRssi() is valid (the working RF RSSI view waits 5ms). The old
per-pixel 100us wait was far too short, so a real signal never rose above the
noise floor - the rainbow only ever showed noise. It now samples WF_BINS points
with a real settle and interpolates the envelope across the plot, so a
transmitter actually paints the trace and the waterfall.

The band-selection menu (Start/End frequency, Start Waterfall, Main Menu) is
unchanged.

#### Types of Changes ####

Bugfix (RSSI never settled, so nothing was detected; the colour ramp was
inverted) plus UI rework onto the shared component.

#### Verification ####

Flash and open RF -> Waterfall on a device with a CC1101. Expect:

  - a filled trace with peak-hold across the top, gliding as it updates
  - a waterfall below in the SDR gradient (dark for the noise floor, climbing
    through blue/green/yellow to red/white on a strong signal) that follows the
    trace
  - a frequency ruler and a status line naming the peak dBm and frequency
  - UP/DOWN pans the band

Transmitting on a frequency inside the band should raise the trace at the
matching column and leave a bright streak falling down the waterfall.

#### Testing ####

No unit test harness exists for this layer. rf_waterfall.cpp compiles clean for
m5stack-cardputer. Not yet verified on hardware by me - a reviewer with a
CC1101 should confirm a known transmitter paints the trace and that the pan
controls track.

#### Linked Issues ####

None. Depends on the SpectrumPlot SDR colourmap commit.

#### User-Facing Change ####
```release-note
RF Waterfall now renders on the shared spectrum plot with a gliding peak-hold trace and an SDR-style colour waterfall, follows the theme for its chrome, and actually detects signals (the sweep now lets the CC1101 settle before reading RSSI).
```

#### Further Comments ####

WF_BINS (64) and WF_SETTLE_MS (3) trade sweep resolution against refresh rate;
they are #defines at the top of the run function so they are easy to tune on
hardware.

Co-authored-by: Vinicius <discoestudio5@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bmorcelli bmorcelli added the enhancement New feature or request label Sep 15, 2026
@bmorcelli
bmorcelli merged commit 976c1a6 into BruceDevices:dev Sep 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants