NRF Spectrum: continuous trace, theme colours and a frequency ruler - #2758
Open
vnxdtzip wants to merge 3 commits into
Open
NRF Spectrum: continuous trace, theme colours and a frequency ruler#2758vnxdtzip wants to merge 3 commits into
vnxdtzip wants to merge 3 commits into
Conversation
#### 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.
#### Proposed Changes #### The sweeper drew one bar per channel with the colour alternating on index parity, which is texture rather than information. It cleared the screen with a literal TFT_BLACK, drew its grid in a magic RGB565(25, 25, 25), and had no border, no title and no status bar. Its only axis labels sat in the middle of the plot. It now renders through SpectrumPlot: the 80 carriers are interpolated into a continuous trace, peak hold decays one level per sweep, and the module gets the standard frame plus a 2.40-2.48GHz ruler and a status line naming the strongest carrier and its level. Scanning is also split from drawing. scanChannels() now only measures and returns its result string, which is what the WebUI already advertised in the header will need; the loop drives the plot separately. Redraws are capped at 40ms so repainting does not starve the radio sweep. The RPD sampling itself is unchanged: same channel order, same 128us listen window, same smoothing accumulator. #### Types of Changes #### New Feature / UI rework, plus a small refactor separating scan from render. No breaking change - scanChannels keeps its signature and its return format. #### Verification #### Flash and open NRF -> Spectrum with an NRF24 attached over SPI. Expect: - a continuous trace across the band instead of 80 alternating bars - a peak-hold line that decays slowly rather than sticking - a title, border and status bar consistent with the rest of Bruce - a 2.40 / 2.42 / 2.44 / 2.46 / 2.48 ruler along the bottom - the status line naming the busiest carrier Holding a 2.4GHz transmitter near the radio should raise the trace at the matching frequency, and the status line should name that channel. With no NRF24 present the module should still show its frame and then the "NRF24 not found" error, rather than a blank screen. #### Testing #### No unit test harness exists for this layer. nrf_spectrum.cpp compiles clean for m5stack-cardputer, verified in the combined tree; this branch was not built in isolation. Not yet verified on hardware by me, and I have no NRF24 to test against - a reviewer with the radio should confirm the trace tracks a known transmitter. #### Linked Issues #### None. Depends on ui/spectrum-view. #### User-Facing Change #### ```release-note NRF Spectrum now draws a continuous trace with peak hold, a frequency ruler and a waterfall, follows the active theme, and shows the standard title and status bar. ``` #### Further Comments #### Splitting scanChannels from the rendering is the part worth a second look: the function previously drew as a side effect, so anything calling it for the WebUI string would also have painted the screen. It now does what its name and return type suggest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed Changes
The sweeper drew one bar per channel with the colour alternating on index
parity, which is texture rather than information. It cleared the screen with a
literal TFT_BLACK, drew its grid in a magic RGB565(25, 25, 25), and had no
border, no title and no status bar. Its only axis labels sat in the middle of
the plot.
It now renders through SpectrumPlot: the 80 carriers are interpolated into a
continuous trace, peak hold decays one level per sweep, and the module gets
the standard frame plus a 2.40-2.48GHz ruler and a status line naming the
strongest carrier and its level.
Scanning is also split from drawing. scanChannels() now only measures and
returns its result string, which is what the WebUI already advertised in the
header will need; the loop drives the plot separately. Redraws are capped at
40ms so repainting does not starve the radio sweep.
The RPD sampling itself is unchanged: same channel order, same 128us listen
window, same smoothing accumulator.
Types of Changes
New Feature / UI rework, plus a small refactor separating scan from render.
No breaking change - scanChannels keeps its signature and its return format.
Verification
Flash and open NRF -> Spectrum with an NRF24 attached over SPI. Expect:
Holding a 2.4GHz transmitter near the radio should raise the trace at the
matching frequency, and the status line should name that channel.
With no NRF24 present the module should still show its frame and then the
"NRF24 not found" error, rather than a blank screen.
Testing
No unit test harness exists for this layer. nrf_spectrum.cpp compiles clean
for m5stack-cardputer, verified in the combined tree; this branch was not
built in isolation. Not yet verified on hardware by me, and I have no NRF24 to
test against - a reviewer with the radio should confirm the trace tracks a
known transmitter.
Linked Issues
None. Depends on #2755 (ui/spectrum-view).
User-Facing Change
Further Comments
Splitting scanChannels from the rendering is the part worth a second look: the
function previously drew as a side effect, so anything calling it for the
WebUI string would also have painted the screen. It now does what its name and
return type suggest.