A firmware for recording 6-axis IMU data (accel + gyro) plus distance-to-ground/obstacle to SD card, with button-based session control, an LED that blinks while recording (and idle-heartbeats/solid-faults/gesture-signals otherwise), and a WiFi dashboard to download and clear recordings.
0x29): time-of-flight distance sensorFive-layer design:
Button.h/.cpp): Non-blocking gesture detection
update() callStatusLed.h/.cpp): Non-blocking LED blinker
signal(Signal) queues a one-shot pattern that preempts the idle/active visual: StopBlink (3 blinks) after a recording stops, EventBlink (2 quick blinks) after a mid-recording event mark — a fault still takes priorityImuRecorder.h/.cpp): IMU + distance sampling + file management
-1 is written if no reading is availableannotateEvent() flags the next sampled row’s event column instead of interrupting the recording/rec_index.txt); on stop, every segment is renamed with the annotation suffix (_ann-1.csv, _ann0.csv, _ann1.csv)Dashboard.h/.cpp): WiFi + NTP + web UI for offloading recordings
/.env on the SD card; missing file or failed connection is non-fatal — the device keeps recording standaloneconfigTzTime, Europe/Rome) so SD file timestamps are meaningfulWebServer, no auth) listing every recorded file, with per-file download, a streamed “Download all” .zip, and a two-step “Delete all”main.cpp): Event loop
cane is the default PlatformIO environment (see platformio.ini), so -e cane can be omitted below.
Build:
cd Firmware
pio run -e cane
Upload:
pio run -e cane -t upload
Monitor serial output (115200 baud):
pio device monitor -e cane -b 115200
Clean build:
pio run -e cane --target clean
pio run -e cane
See POWER_ANALYSIS.md for the component-by-component current budget, estimated battery life per scenario, and power-saving opportunities not yet implemented.
WiFi credentials are read from a plain-text file at the SD card root, /.env — not hardcoded, so they can be changed without reflashing. Create it on the card before inserting:
WIFI_SSID=YourNetworkName
WIFI_PASSWORD=YourPassword
(Blank lines and lines starting with # are ignored.) This file is excluded from the dashboard’s file listing and from “Download all”/”Delete all” — it’s never treated as a recording, and /clear never removes it.
If /.env is missing or has no WIFI_SSID, boot skips WiFi entirely (logged, non-fatal) and the device just records standalone.
On boot, the serial log shows the WiFi connect attempt and either the dashboard URL (http://<ip>/) on success, or a warning that it’s continuing without the dashboard (recording still works normally either way).
Once connected, open that URL in a browser on the same network:
/ — lists every recorded session (name, size, timestamp) with a Download link each.zip (built on the fly, not buffered in RAM or written to the SD card)The dashboard is unavailable (503) while a recording is in progress — stop the recording via the button first.
Firmware logs all events with prefixes:
[Main] — initialization, status[Button] — gesture detection[Recorder] — IMU/SD operations[Dashboard] — WiFi/NTP statusSee Dataset/README.md for the recording filename convention, the CSV column
layout, and the annY annotation.
distance_testA separate, standalone project under Firmware/src/distance_test/ — just the
Modulino Distance sensor, printing one reading per line for the Serial
Plotter, independent of the rest of this firmware. Useful for checking
sensor wiring/mounting without recording a full session:
pio run -e distance_test -t upload