Skip to content

BuzzBand

ESP32-C3 wristband firmware (PlatformIO/Arduino), Flutter app, Firebase RTDB. Repo: ~/Documents/GitHub/BuzzBand

Decisions

  • Flash layout is the two-slot OTA table Firmware/BuzzBand_001/partitions_custom.csv: nvs 0x9000, otadata 0xe000, nvs_prod 0x10000, app0 0x20000, app1 0x1E0000 (4 MB flash). otadata must stay at 0xe000 because PlatformIO always writes boot_app0.bin (8 KB) there.
  • PlatformIO ignores the partition table for the app offset; board_upload.offset_address = 0x20000 in platformio.ini sets it.
  • Browser flasher: app-only writes go at 0x20000, not 0x10000. Ship a merged image at offset 0 (bootloader 0x0, partitions 0x8000, boot_app0 0xe000, firmware 0x20000).

Halloween heartbeat (Firmware/BuzzBand_Heartbeat)

  • Standalone wearable: IMU-driven heartbeat (motor + LEDs, optional piezo). Reuses BuzzBand_001 drivers in place; see its README. dev vs wearable envs.
  • Light sleep gates the LEDC PWM clock: never nap while audio_is_playing() (fixed 2026-09-30 after weird piezo sounds in the wearable build; dev build never sleeps so it hid the bug). Blocking blinks must silence audio first.
  • Motor vibration corrupts IMU samples for ~200 ms after each pulse (caused a 165 BPM runaway); fixed by blanking + HP filter reset.
  • Power numbers are estimates only, never measured (no current meter): light sleep engaged (USB drops after 15 s) but battery life unverified.

  • Heartbeat button UI: tap = next mode (reactive/calm/racing/dying), hold 0.7 s = sound toggle, hold 2 s = sleep. Piezo must run near 4 kHz; TC1240A SHDN is active-HIGH shutdown (LOW = doubler on), config.h comment fixed.

  • Heartbeat settings (mode, sound, vibration) saved to NVS namespace "heart" on change; survive power loss. A merged.bin flash erases NVS, so settings reset to defaults.

  • Heartbeat colour themes (blood/pumpkin/zombie/witch/ghost) on double-tap, saved in NVS. Single tap now waits 350 ms for a possible second tap.

  • Piezo tuning tool: pio run -e soundtest (A/B by ear, saves pitch + warble span to NVS "sound"; heartbeat reads it). By-ear comparison on the board: steady 4 kHz tick is louder than any sweep (+/-75 Hz and wider were worse); default is steady 4 kHz both ticks. Tuner not needed unless the piezo is swapped.

Serial menu test firmware (Firmware/BuzzBand_SerialMenu)

  • Fake config shell/menu over USB serial for testing a serial terminal tool. Flashed 2026-09-30; core commands verified, rest untested (see its README). Opening the port can reset the C3 into download mode.

Gotchas

  • Serial port shows busy when the browser flasher tab still holds it (Web Serial); disconnect or close the tab.
  • USB-CDC boot banner is only seen if the monitor is open at reset; opening pyserial with DTR/RTS pulses can drop the chip into download mode.

Log

  • 2026-09-30: Moved from huge_app (no OTA) to partitions_custom.csv, fixed its otadata/nvs_prod overlap, production_flash.py NVS_PROD_OFFSET 0xf000 -> 0x10000. Built (90.6% of 1.75 MB slot) and flashed; boots, BLE advertising. OTA and rollback not yet exercised.
  • 2026-09-30: Added Firmware/BuzzBand_001/scripts/make_merged.sh -> .pio/build/esp32-c3-devkitm-1/merged.bin (flash at offset 0). Verified byte-identical to the board. Caveat: merged image erases gaps, so it wipes NVS (Wi-Fi creds) and nvs_prod; use app-only at 0x20000 for updates.

Open

  • Finish verifying the serial menu (stream, flood, backspace, Ctrl-C, reboot persistence) once the board is back on USB; settle DTR/RTS handling for the browser serial tool.
  • Commit uncommitted work: SerialMenu folder, Heartbeat release/ binaries, make_merged.sh args.
  • Verify double-tap colour themes and settings persistence on hardware (built 2026-09-30, not yet flashed/tested).
  • Verify heartbeat button modes on hardware (built and flashed 2026-09-30, serial log could not be read afterwards, so untested).
  • Measure wearable current draw (meter on the battery lead) and tune LED_PEAK / pulse lengths; battery capacity unknown.
  • Verify piezo thump audibility (button tap toggles sound) and pick SOUND_*_HZ.
  • Confirm heart rate responds to a real wrist shake (only rest behaviour verified so far).
  • Browser flasher (https://flashers-rc.embeddedera-site.pages.dev/tools/esp32-flasher/): switch to merged image at offset 0, or set app offset to 0x20000. Needs an SOP.
  • Verify OTA end to end and whether the Arduino bootloader has app rollback enabled (esp_ota_mark_app_valid_cancel_rollback may be a no-op).
  • Firmware prints "Accelerometer motion triggered activity reset." continuously with the board sitting still; check LIS2DH12 threshold/INT pin in src/sensors/motion.cpp.
  • Commit the partition/offset changes (uncommitted on main).