Additional guidance for AI agents working with the Aquavate codebase.
This is an active hardware + firmware + iOS app project. The firmware standalone features are complete (phases 1-2.6), with sensor integration, power management, daily intake tracking, and deep sleep working. The iOS app is in skeleton stage. Next phase is BLE integration.
- Check PROGRESS.md - Always read this first to understand active work and avoid conflicts
- Review recent commits - Use
git log -10 --onelineto see what's been done recently - Check current branch - This project uses feature branches, check which one you're on
Key Files:
- firmware/src/main.cpp - Main entry point, sensor initialization, wake/sleep logic, UI rendering
- firmware/src/calibration.cpp - Two-point calibration state machine
- firmware/src/gestures.cpp - Gesture detection (inverted hold, upright stable)
- firmware/src/weight.cpp - Load cell reading and stability detection
- firmware/src/drinks.cpp - Daily intake tracking and drink detection
- firmware/src/storage.cpp - NVS storage for calibration and settings
- firmware/src/storage_drinks.cpp - NVS circular buffer for drink records
- firmware/src/serial_commands.cpp - USB serial commands for configuration
- firmware/src/display.cpp - Smart display state tracking and rendering
- firmware/include/config.h - Pin definitions, calibration constants, debug flags, power settings
- firmware/platformio.ini - Build configurations for both hardware options
Hardware Configurations:
- Default: Adafruit ESP32 Feather V2 + 2.13" E-Paper FeatherWing
- Alternative: SparkFun ESP32-C6 Qwiic Pocket + Waveshare 1.54" E-Paper
Build & Test:
cd firmware
pio run # Build for Adafruit (default)
pio run -t upload # Upload to board
pio device monitor # Serial monitorImportant Implementation Details:
- ADXL343 INT1 pin must be wired to ESP32 GPIO 27 (not just I2C)
- ADXL343 needs always-on 3V power (not STEMMA QT which powers down)
- Wake-on-tilt threshold: 0.5g (0x08) — ACTIVITY_WAKE_THRESHOLD in config.h
- Deep sleep: Dual modes (normal 30s with motion wake, extended 60s with timer wake)
- RTC memory: Used for display state and drink baseline persistence across sleep
- NVS: Circular buffer with 600 records (30 days history)
Key Files:
- ios/Aquavate/Aquavate/AquavateApp.swift - App entry point
- ios/Aquavate/Aquavate/ContentView.swift - Main view (currently "Hello World")
Status: Skeleton only - CoreBluetooth, CoreData, and UI implementation pending.
- If your changes touch
calibration.cpp,weight.cpp, ordrinks.cpp, run the unit tests:All tests must pass. No hardware required — runs on Mac in seconds.cd firmware && ~/.platformio/penv/bin/platformio test -e native
- Build for Adafruit Feather and verify no compile errors.
- Flash and manual-test the changed behaviour on device.
- If your changes touch
HydrationReminderService.swift, run the unit tests:All tests must pass.cd ios/Aquavate && xcodebuild test -scheme Aquavate -destination 'platform=iOS Simulator,name=iPhone 17'
- Build and verify no compile errors.
- Manual-test the changed behaviour on simulator or device.
When completing work:
- PROGRESS.md - Keep lean and current. Delete completed sections, only track active work.
- CLAUDE.md - Update if key decisions or patterns change
- README.md - Update if features move from planned to implemented
- Keep docs concise - move detailed research notes to Plans/ directory
Firmware (C++):
- Arduino-style setup() and loop() pattern
- Use Adafruit sensor libraries where available
- Add comments for hardware-specific behavior (interrupt config, power management)
- Serial debug output for development, with debug level control (0-4, 9)
- Smart state tracking: only update when values change
iOS (Swift):
- SwiftUI for all views
- MVVM architecture with ObservableObject for state management
- CoreBluetooth for BLE (native, not third-party libraries)
- Add hardware wiring notes to PRD.md
- Update config.h with pin definitions or I2C addresses
- Initialize in setup()
- Read in loop() or create dedicated function
- Update PROGRESS.md with what works and what's next
- Reference PRD.md for GATT service design
- Use NimBLE-Arduino library (already in platformio.ini)
- Create separate ble/ directory under firmware/src/
- Add to PROGRESS.md active work section
- Current implementation uses Adafruit_ThinkInk library
- Display updates are slow (~2s), plan accordingly
- Only update on wake events to save power
- Smart state tracking: display.cpp tracks all displayed values and only updates when changed
- Main screen shows: time (centered top), battery (top right), bottle graphic (left), water level (right), daily intake visualization (center)
- Optional "Zzzz" indicator for extended sleep mode
The firmware supports comprehensive serial commands for configuration and testing:
Debug Control:
0-4,9- Set debug level (0=OFF, 1=Events, 2=+Gestures, 3=+Weight, 4=+Accel, 9=All)T- Test interrupt state (shows ADXL343 INT_SOURCE register)
Time/Timezone:
SET DATETIME YYYY-MM-DD HH:MM:SS [tz]- Set date, time, and timezoneSET DATE YYYY-MM-DD- Set date onlySET TIME HH[:MM[:SS]]- Set time (flexible format)SET TZ offset- Set timezone offsetGET TIME- Show current time
Drink Tracking:
GET DAILY STATE- Show current daily intakeGET LAST DRINK- Show most recent drink recordDUMP DRINKS- Display all drink recordsSET DAILY INTAKE ml- Set current daily intakeRESET DAILY INTAKE- Reset daily counterCLEAR DRINKS- Clear all drink records
Display:
SET DISPLAY MODE mode- Switch visualization (0=human, 1=tumblers)
Power Management:
SET SLEEP TIMEOUT sec- Normal sleep timeout (0=disable, default=30)SET EXTENDED SLEEP TIMER sec- Extended sleep wake timer (default=60)SET EXTENDED SLEEP THRESHOLD sec- Awake threshold for extended mode (default=120)
System:
GET STATUS- Show all system status and settings
- Code will compile but sensor init will fail gracefully
- Use serial monitor to see "NAU7802 not found" etc messages
- Good for testing build system and code structure
- Check sensor I2C addresses: NAU7802 (0x2A), ADXL343 (0x53)
- Verify load cell wiring: Red (E+), Black (E-), White (A-), Green (A+)
- Test wake-on-tilt by tilting board
- Monitor deep sleep current with multimeter (target <200µA)
- Use serial commands to configure and test features
- docs/PRD.md - Complete product specification and firmware architecture
- Plans/004-sensor-puck-design.md - Mechanical design and assembly
- Plans/005-standalone-calibration-mode.md - Two-point calibration implementation
- Plans/006-usb-time-setting.md - USB time setting via serial commands
- Plans/007-daily-intake-tracking.md - Daily intake tracking implementation
- Plans/010-deep-sleep-reinstatement.md - Deep sleep power management
- Plans/011-extended-deep-sleep-backpack-mode.md - Extended deep sleep for backpack mode
- Plans/002-bom-adafruit-feather.md - UK parts list
When uncertain:
- Check PRD.md for design decisions
- Check PROGRESS.md for current status
- Look at recent git commits for context
- Ask the user if requirements are ambiguous