feat: production-ready firmware with BLE memory management, device_id fixes, and docs
- Reduce debug level to 1 (errors only) for production builds - Replace BLE pause/resume with full deinit/reinit during HTTP uploads (~25KB freed) - Add 60s boot report delay for fast post-deploy connectivity verification - Add device_id to BLE batch and heartbeat request bodies - Correct API host to http:// (plain HTTP, not HTTPS) - Add HTTP response logging and CV entry/exit serial logging - Create root README.md with operator setup and architecture overview - Update design spec: HMAC format, BLE memory approach, request body shapes, reporting intervals Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
107
README.md
Normal file
107
README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# DoorCounter
|
||||
|
||||
Retail door traffic counter using M5Stack TimerCamera-F (ESP32 + OV3660). Counts entries/exits via overhead camera CV, passively scans BLE foot traffic, and reports hourly to `logs.research.bike`.
|
||||
|
||||
## Hardware
|
||||
|
||||
- **Device**: M5Stack TimerCamera-F (ESP32-S, OV3660, PSRAM, WiFi/BLE)
|
||||
- **Mount**: Overhead, camera pointing straight down, centered above doorway
|
||||
- **Power**: USB (any phone charger)
|
||||
|
||||
## Firmware
|
||||
|
||||
Built with PlatformIO. Target: `timercam`.
|
||||
|
||||
```bash
|
||||
cd firmware
|
||||
pio run -t upload --upload-port /dev/ttyUSB0
|
||||
```
|
||||
|
||||
### What it does
|
||||
|
||||
| Module | Behavior |
|
||||
|--------|----------|
|
||||
| CV pipeline | 5 fps, 96×96 grayscale, blob tracking, line-crossing count |
|
||||
| BLE scanner | Continuous passive scan; deinits during hourly upload to free heap |
|
||||
| Reporter | Hourly HMAC-signed POST; 60s boot report for fast connectivity check |
|
||||
| Provisioning | Captive portal AP on first boot for WiFi setup |
|
||||
| OTA | Arduino OTA; operator push via `ota_push.py` |
|
||||
|
||||
### Reporting intervals
|
||||
|
||||
- **First report**: 60 seconds after NTP sync (connectivity check)
|
||||
- **Subsequent reports**: every 3600 seconds
|
||||
|
||||
## Operator Setup
|
||||
|
||||
### 1. Flash firmware
|
||||
|
||||
```bash
|
||||
cd firmware
|
||||
pio run -t upload --upload-port /dev/ttyUSB0
|
||||
```
|
||||
|
||||
### 2. Provision device identity
|
||||
|
||||
```bash
|
||||
python tools/flash_device.py \
|
||||
--port /dev/ttyUSB0 \
|
||||
--device-id dc-0042 \
|
||||
--location-id retailer-123 \
|
||||
--hmac-secret <32-byte-hex> \
|
||||
--wifi-ssid "StoreWiFi" \
|
||||
--wifi-password "secret"
|
||||
```
|
||||
|
||||
WiFi credentials are optional — if omitted, device starts captive portal on boot.
|
||||
|
||||
### 3. OTA updates
|
||||
|
||||
```bash
|
||||
python tools/ota_push.py \
|
||||
--host dc-0042.local \
|
||||
--firmware firmware/.pio/build/timercam/firmware.bin
|
||||
```
|
||||
|
||||
## End User Setup
|
||||
|
||||
1. Mount device overhead, camera pointing straight down
|
||||
2. Plug into USB power
|
||||
3. Connect phone to `DoorCounter-Setup` WiFi
|
||||
4. Browser opens automatically → enter store WiFi password → done
|
||||
|
||||
**LED indicators**: Red = no WiFi · Blue = counting · Yellow = uploading
|
||||
|
||||
## API
|
||||
|
||||
Endpoint: `http://logs.research.bike`
|
||||
|
||||
| Endpoint | Data |
|
||||
|----------|------|
|
||||
| `POST /api/v1/camera/events/batch` | Hourly entry/exit counts |
|
||||
| `POST /api/v1/events/batch` | Hourly BLE proximity records |
|
||||
| `POST /api/v1/heartbeat` | Device health (uptime, RSSI, pending records) |
|
||||
|
||||
All requests are HMAC-SHA256 signed. See [design spec](docs/superpowers/specs/2026-04-13-door-counter-design.md) for full API shapes and auth scheme.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
DoorCounter/
|
||||
├── firmware/
|
||||
│ ├── platformio.ini
|
||||
│ ├── lib/hmac/ — HMAC-SHA256 signing library
|
||||
│ └── src/
|
||||
│ ├── main.cpp — FreeRTOS tasks, boot sequence
|
||||
│ ├── config.* — NVS read/write
|
||||
│ ├── provisioning.* — captive portal
|
||||
│ ├── camera.* — frame capture + CV pipeline
|
||||
│ ├── ble_scanner.* — BLE passive scan
|
||||
│ └── reporter.* — hourly batch POST + local buffer
|
||||
├── tools/
|
||||
│ ├── flash_device.py — NVS provisioning script
|
||||
│ └── ota_push.py — OTA push script
|
||||
├── docs/superpowers/specs/
|
||||
│ └── 2026-04-13-door-counter-design.md
|
||||
└── server/ — API server (separate deployment)
|
||||
```
|
||||
Reference in New Issue
Block a user