Skip to content

evaderkrub/sensorview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SensorView

A polished, multi-sensor instrument app for the FreeWili 2 (Raspberry Pi RP2350B), built in C with the Pico SDK and LVGL 9. SensorView turns the FreeWili 2's 480×320 touchscreen, 9-axis motion stack, environmental sensors, and 4-microphone array into a set of live instruments: environment dashboards, an artificial horizon, a tilt-compensated compass, a spectrum analyzer, and an acoustic direction finder.

Audio screen with the DOA radar gauge

License: MIT  Target: RP2350B · Pico SDK 2.2.0 · LVGL 9.2.3


Highlights

  • 🌡️ Environment — temperature, humidity, and ambient light with gauges, history charts, and a hero readout; the backlight auto-dims to the room.
  • 📐 Motion — a 2-axis bubble level (mirrored on the LED strip), live accel/gyro bars, and a sensor-fused artificial horizon + 3D wireframe attitude view.
  • 🧭 Field — a tilt-compensated compass with hard-iron auto-calibration, a magnetic-field meter, and an auto-zeroing metal detector.
  • 🔊 Audio — a real-time FFT spectrum + waterfall with an LED VU meter, plus an acoustic direction-of-arrival (DOA) radar that points an arrow at the dominant sound source.
  • 💡 16 addressable LEDs used as instruments: a tilt arm, a north hint, a VU bar, and a "point at the sound" direction arm.
  • 🧪 Host-tested DSP/math — the pure signal-processing and geometry (CIC, FFT, DOA, fusion render, value→pixel mappings) compile and run on the host with assertions, independent of hardware.

Screenshots

Home Environment Motion (level + LED tilt arm)
Home Environment Motion
Field (detector) Audio — spectrum + DOA radar
Field Audio DOA

Photos are taken of the live panel — it's a real 480×320 display, not a simulator.


Hardware

Part Role Bus
RP2350B Dual Cortex-M33 MCU
ST7796 (480×320) LCD, RGB565 over SPI1 + DMA SPI1
FT6336U Capacitive touch (polled) I²C1 @ 0x38
PCAL6524 IO expander (gates display reset, mic power) I²C1 @ 0x23
SHT40 Temperature + humidity I²C1 @ 0x44
OPT4001 Ambient light (lux) I²C1 @ 0x45
BMI323 3-axis accel + gyro (IMU) I²C1 @ 0x68
BMM350 3-axis magnetometer I²C1 @ 0x14
4× PDM MEMS mics 19 mm linear array (DOA) PIO @ 1.024 MHz
16× WS2812 Addressable RGB LEDs PIO (GPIO21)

The board runs at a stable 153.6 MHz (vreg 1.15 V) with clk_peri re-sourced from clk_sys — the proven-clean recipe for the display SPI/PIO bring-up on this hardware.


Features in depth

Environment

SHT40 + OPT4001 polled at 2 Hz. Three views — analog-style Gauges, a scrolling Chart of recent history, and a large Hero readout. A PWM backlight follows ambient light (with a comfortable floor) so the panel is readable in any room.

Motion

BMI323 IMU at 20 Hz. Level shows an on-screen bubble and drives a 2-axis tilt indicator on the LED strip (a horizontal arm + a vertical arm). Accel and Gyro are live bar meters. Attitude runs the IMU + magnetometer through the vendored x-io Fusion AHRS to draw an artificial horizon and a mini 3D wireframe cube, projected on an lv_canvas.

Field

BMM350 magnetometer with full OTP / temperature / cross-axis compensation. Compass is tilt-compensated (heading from the fused yaw) and auto-calibrates hard-iron offsets on the fly to fight the board's own speaker/haptic magnets. Field is a µT bar meter; Detector is an auto-zeroing deviation meter with an LED bar — wave it near metal.

Audio

The 4-mic PDM array is decimated on-chip (CIC + DC-block) to 16 kHz PCM.

  • Spectrum — a 256-point FFT drawn as log-spaced bars over a scrolling heat waterfall, with an LED VU meter.
  • Direction (DOA) — all four mics are transformed (fft_forward) and fed to a dominant-bin phase-difference estimator that recovers the azimuth (±90°) and a confidence. A radar-gauge panel — arc rim, graduated fan, tick labels, and a confidence-colored arrow with a real arrowhead — points at the source, and the LED strip lights the arm LED nearest the bearing. Mics are remapped to physical line order {D, B, A, C} before estimation (the array's phase is monotonic only in that order).

Build, flash, and test

Tooling is Windows PowerShell + the Raspberry Pi Pico VS Code extension toolchain (~/.pico-sdk, SDK 2.2.0). Diagnostics are over SEGGER RTT (the board is USB host-mode, no serial stdio).

# Build (always pass -Clean before a hardware verify; see note below)
powershell -File tools/build.ps1 -Clean

# Flash + reset over the CMSIS-DAP debug probe (OpenOCD, no BOOTSEL dance)
Get-Process openocd -ErrorAction SilentlyContinue | Stop-Process -Force
powershell -File tools/flash.ps1

# Live RTT console (scaled-integer logs; RTT printf has no float support)
powershell -File tools/rtt.ps1 -Seconds 10

# Host unit tests (pure DSP/math, system gcc — no SDK required)
powershell -File tests/host/run_host_tests.ps1

The host suite covers the signal-processing and geometry that can be reasoned about off-hardware: CIC decimation, the FFT, the DOA estimator (synthetic plane-wave recovery within tolerance), the AHRS render math, sensor conversions, and the value→pixel/colour mappings.


Architecture

src/
├── main.c                 # boot: clocks, drivers, LVGL, app shell
├── platform/              # board bring-up, IO expander, backlight, RTT diag
├── display/ st7796.c      # 480x320 RGB565 SPI+DMA panel driver
├── touch/   ft6336.c      # capacitive touch (rotated transform)
├── leds/    ws2812_driver # 16 addressable LEDs (PIO, hardware-inverted)
├── sensors/               # SHT40, OPT4001, BMI323, BMM350 + sensor_hub poller
├── fusion/                # x-io Fusion AHRS wrapper, mag cal, 3D render
├── pdm/     pdm_capture   # 4-mic PDM capture (PIO + on-chip CIC)
├── dsp/                   # cic, dcblock, radix-2 fft
├── doa/                   # delay/phase DOA estimator + per-mic calibration
├── audio/   audio_engine  # mics -> FFT -> spectrum + DOA
└── ui/                    # app shell + one screen per tile, views, LVGL canvas
docs/superpowers/          # design specs + implementation plans per phase
tests/host/                # self-checking host unit tests
third_party/               # LVGL, x-io Fusion, SEGGER RTT (own licenses)

Each sensor tile is an LVGL screen built from small, independently-testable view modules. A shared sensor_hub polls the I²C sensors and advances the fusion filter; the heavy attitude/audio canvases share a single RGB565 buffer to fit the ~520 KB of SRAM. The pure math lives behind hardware-free interfaces so it can be unit-tested on the host.

Note on rebuilds: the project lives in a Dropbox folder, and Dropbox can rewrite file timestamps such that Ninja skips a recompile. Always pass -Clean (or delete the specific .obj) before flashing for a hardware check.


Project history

SensorView was built in phases, each with its own design spec and implementation plan (under docs/superpowers/): foundation/app-shell → environment/motion/field dashboards → sensor fusion instruments → audio spectrum → acoustic direction finder. Every phase was verified end-to-end on real hardware.

License

MIT © 2026 Dave Robins.

Vendored components under third_party/ retain their own licenses: LVGL (MIT), x-io Technologies Fusion (MIT), and SEGGER RTT (SEGGER's BSD-style license).

Acknowledgements

Built for the FreeWili 2. Display, audio, and magnetometer bring-up drew on the FreeWili reference firmware and community projects for this board.

About

A polished multi-sensor instrument app for the FreeWili 2 (RP2350B): environment dashboards, fused attitude/compass, FFT spectrum, and an acoustic direction finder. C + Pico SDK + LVGL 9.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors