Skip to content

Channel Analyzer: draw a swept spectrum instead of stacked bars - #2756

Open
vnxdtzip wants to merge 3 commits into
BruceDevices:devfrom
vnxdtzip:ui/channel-analyzer-spectrum
Open

Channel Analyzer: draw a swept spectrum instead of stacked bars#2756
vnxdtzip wants to merge 3 commits into
BruceDevices:devfrom
vnxdtzip:ui/channel-analyzer-spectrum

Conversation

@vnxdtzip

@vnxdtzip vnxdtzip commented Aug 4, 2026

Copy link
Copy Markdown

The analyzer drew eleven horizontal bars and repainted one of them per dwell.
The display jumped from channel to channel, showed nothing about how adjacent
channels overlap, and sat still between measurements.

It now renders through WifiSpectrumView: the eleven channels become
overlapping spectral lobes on a real frequency axis, with a peak-hold trace, a
scrolling waterfall, a channel ruler and a status line. The view is also
animated inside the dwell window, so levels glide toward the last measurement
instead of snapping when a channel commits.

The measurement path is untouched. The promiscuous RX callback, the WiFi
bring-up, the channel hop and the airtime estimate are byte-identical; the
whole presentation layer simply left this file. Up/Down still adjust the dwell
between 150 and 1000ms and ESC still exits.

New Feature / UI rework. No breaking change. Airtime measurement behaviour is
unchanged.

Flash and open WiFi -> Channel Analyzer. Expect:

  • a continuous skyline across channels 1-11 rather than eleven bars, with
    visibly overlapping lobes around 1/6/11
  • the lobe of the channel being measured filled brighter, sweeping across
  • a red-tinted peak-hold line above the live trace
  • a waterfall under the trace, scrolling one row per measurement
  • the channel ruler highlighting the current channel
  • Up/Down changing the dwell shown in the status line

Sitting next to a busy AP on a known channel should raise that lobe; the
airtime percentages in the status line should match what the previous build
reported for the same environment.

No unit test harness exists for this layer. Compiled for m5stack-cardputer on
this branch. Not yet verified on hardware by me - the numbers should be
sanity-checked against the previous build in the same RF environment, since
this PR is only supposed to change how they are drawn.

None. Depends on #2755 (ui/spectrum-view).

Channel Analyzer now shows a swept spectrum with overlapping channel lobes, peak hold and a waterfall instead of one bar per channel. Controls are unchanged.

Net -43 lines: the drawing code moved into the shared component, which
ui/jam-detect-spectrum then reuses unchanged.


Stacked PR. This branch is built on #2754 and #2755. GitHub can only base a cross-fork PR on an upstream branch, so until they are merged the diff above also contains their commits. Review only the commit titled Channel Analyzer: draw a swept spectrum instead of stacked bars; the diff shrinks on its own once the base lands.

Vinicius and others added 3 commits August 4, 2026 19:54
#### Proposed Changes ####

A module that needs a dimmed or highlighted shade of the active theme has no
way to ask for one. The only helper available, getColorVariation, steps
brightness up or down and cannot mix toward another colour, so modules fall
back to a fixed constant such as TFT_DARKGREY or TFT_WHITE. That is the root
cause of most of the screens in Bruce that stop following the user's theme as
soon as they need more than the primary colour.

This adds two helpers next to it in core/display:

  blendColors(a, b, t)      linear RGB565 mix; t = 0 keeps a, t = 255 keeps b
  buildHeatPalette(lut, n)  fills a lookup table with a theme ramp running
                            from the background up to a brightened primary,
                            for waterfalls and other intensity plots

Both are pure additions. No existing function is modified, and nothing calls
them in this PR - the modules that consume them follow separately.

#### Types of Changes ####

New Feature (internal helper API). No behaviour change and no breaking change.

#### Verification ####

Nothing on screen changes from this PR alone, so verification is limited to
confirming the build is clean and that only insertions were made:

    pio run -e m5stack-cardputer
    git show --stat   # 2 files changed, 31 insertions(+), 0 deletions(-)

#### Testing ####

Bruce has no unit test harness covering the display layer, so this was
verified by compiling for m5stack-cardputer on this branch. The helpers get
exercised on hardware through the follow-up PRs that use them.

#### Linked Issues ####

None. This is the base commit of a series that standardises the
spectrum-style screens; the module PRs listed below depend on it.

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

#### Further Comments ####

Prerequisite for ui/spectrum-view, ui/rf-waterfall-theme and
ui/rf-spectrum-theme.
#### Proposed Changes ####

Every "signal strength across a band" screen in Bruce draws its own bars,
picks its own colours and hardcodes its own geometry. No two look alike, and
none of them scale past the panel the original author happened to own.

This adds SpectrumPlot (core/spectrum_plot), which owns the whole
presentation for that shape of data:

  - layout derived from tftWidth/tftHeight, degrading on short screens by
    dropping the ruler first, then the status line, then the waterfall
  - filled trace with a peak-hold line, an animated noise floor and a dashed
    reference grid visible only through the empty sky
  - scrolling waterfall backed by a ring of rendered rows
  - labelled ruler and a status line
  - every colour derived from the active theme through blendColors

Callers keep their own radio and fill an envelope of width() values in 0-100;
the component owns every pixel. Each pixel of the band is written exactly once
per frame, so the animation is flicker free without needing a full-screen
sprite.

WifiSpectrumView (modules/wifi/wifi_spectrum) sits on top and maps the 2.4GHz
channels onto a real frequency axis as overlapping spectral lobes, so the
22MHz overlap between neighbours becomes visible and a sweep reads as one
continuous trace. It also eases the drawn levels toward the measured ones, so
the trace glides rather than snapping channel by channel.

Nothing uses either component in this PR; the modules move over separately.

#### Types of Changes ####

New Feature (internal UI component). No behaviour change and no breaking
change on its own.

#### Verification ####

Nothing on screen changes from this PR alone. The component becomes visible
through ui/channel-analyzer-spectrum, ui/jam-detect-spectrum and
ui/nrf-spectrum, which is where the rendering should be judged.

    pio run -e m5stack-cardputer
    git show --stat   # 4 new files, 445 insertions(+), 0 deletions(-)

#### Testing ####

No unit test harness exists for this layer. Both files were compiled for
m5stack-cardputer as part of ui/channel-analyzer-spectrum, which stacks
directly on this branch and builds clean; this branch was not built in
isolation. Rendering has not yet been checked on hardware by me - a reviewer
with a device should confirm the layout on a non-240x135 panel in particular,
since the degradation path for short screens is the least exercised part.

#### Linked Issues ####

None. Depends on ui/color-helpers for blendColors and buildHeatPalette.

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

#### Further Comments ####

Memory cost is one calloc of wfRows * plotW bytes for the waterfall history
(about 5KB on a 240px panel) plus two envelope buffers of plotW bytes each,
all freed on exit. If the waterfall allocation fails the component degrades to
a plot without history rather than refusing to start.
The analyzer drew eleven horizontal bars and repainted one of them per dwell.
The display jumped from channel to channel, showed nothing about how adjacent
channels overlap, and sat still between measurements.

It now renders through WifiSpectrumView: the eleven channels become
overlapping spectral lobes on a real frequency axis, with a peak-hold trace, a
scrolling waterfall, a channel ruler and a status line. The view is also
animated inside the dwell window, so levels glide toward the last measurement
instead of snapping when a channel commits.

The measurement path is untouched. The promiscuous RX callback, the WiFi
bring-up, the channel hop and the airtime estimate are byte-identical; the
whole presentation layer simply left this file. Up/Down still adjust the dwell
between 150 and 1000ms and ESC still exits.

New Feature / UI rework. No breaking change. Airtime measurement behaviour is
unchanged.

Flash and open WiFi -> Channel Analyzer. Expect:

  - a continuous skyline across channels 1-11 rather than eleven bars, with
    visibly overlapping lobes around 1/6/11
  - the lobe of the channel being measured filled brighter, sweeping across
  - a red-tinted peak-hold line above the live trace
  - a waterfall under the trace, scrolling one row per measurement
  - the channel ruler highlighting the current channel
  - Up/Down changing the dwell shown in the status line

Sitting next to a busy AP on a known channel should raise that lobe; the
airtime percentages in the status line should match what the previous build
reported for the same environment.

No unit test harness exists for this layer. Compiled for m5stack-cardputer on
this branch. Not yet verified on hardware by me - the numbers should be
sanity-checked against the previous build in the same RF environment, since
this PR is only supposed to change how they are drawn.

None. Depends on ui/spectrum-view.

```release-note
Channel Analyzer now shows a swept spectrum with overlapping channel lobes, peak hold and a waterfall instead of one bar per channel. Controls are unchanged.
```

Net -43 lines: the drawing code moved into the shared component, which
ui/jam-detect-spectrum then reuses unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vnxdtzip

vnxdtzip commented Aug 5, 2026

Copy link
Copy Markdown
Author
IMG_8388

@bmorcelli bmorcelli added the enhancement New feature or request label Aug 5, 2026
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