feat: pogoda, poprawki w wyświetlaniu. Clean Architecture
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# ESP32-C6 Desk Buddy — Project Memory
|
||||
|
||||
## Hardware
|
||||
- Board: Seeed XIAO ESP32-C6
|
||||
- Display: SSD1306 128x64 OLED
|
||||
- Gesture sensor: CJMCU-7620 (PAJ7620U2, I2C addr 0x73)
|
||||
|
||||
## I2C — CRITICAL
|
||||
- ESP32-C6 has two I2C buses:
|
||||
- I2C0 (HP, `Wire`): configurable to any GPIO — USE THIS
|
||||
- I2C1 (LP, `Wire1`): hardware-locked to SDA=GPIO6, SCL=GPIO7 — NOT usable on XIAO (pins not exposed)
|
||||
- **Both SSD1306 and PAJ7620 share one bus**: `Wire.begin(22, 23)` — SDA=GPIO22(D4), SCL=GPIO23(D5)
|
||||
- SSD1306=0x3C, PAJ7620=0x73 — different addresses, coexist fine
|
||||
- SW I2C (U8g2 bit-bang) blocks CPU ~40ms/frame — kills WiFi on single-core ESP32-C6. Always use HW I2C.
|
||||
- U8g2 HW I2C constructor: `U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, 23, 22)`
|
||||
|
||||
## PAJ7620 API
|
||||
- Library: `acrandal/RevEng PAJ7620`
|
||||
- Gesture type: `Gesture` (NOT `Gesture_t`)
|
||||
- begin() takes pointer: `sensor.begin(&Wire)` (NOT reference)
|
||||
- `Wire1` pre-defined in framework — do not redeclare `TwoWire Wire1(1)`
|
||||
- Gesture index: `(int)g - 1` maps GES_UP(1)..GES_WAVE(9) to 0..8
|
||||
|
||||
## HTTP Server — CRITICAL
|
||||
- `WebServer.h` does NOT work reliably on ESP32-C6 with IDF 5.x (pioarduino platform)
|
||||
- Use `AsyncWebServer` from `mathieucarbou/ESPAsyncWebServer@^3.3.12`
|
||||
- No `handleClient()` needed — callback-based, works on interrupts
|
||||
- JSON POST body handler: use the 3-arg `on()` with body callback (4th param)
|
||||
|
||||
## NVS / Preferences
|
||||
- Always open with `prefs.begin("namespace", false)` — `true` (read-only) fails with NOT_FOUND if namespace doesn't exist yet
|
||||
- NVS key max 15 chars — use short prefixes: u/d/l/r/f/b/cw/ccw/w for gestures
|
||||
|
||||
## platformio.ini
|
||||
```ini
|
||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
|
||||
board = seeed_xiao_esp32c6
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
olikraus/U8g2
|
||||
acrandal/RevEng PAJ7620
|
||||
bblanchon/ArduinoJson@^7.2.1
|
||||
mathieucarbou/ESPAsyncWebServer@^3.3.12
|
||||
build_flags =
|
||||
-std=gnu++17
|
||||
board_build.partitions = default # no Zigbee partitions needed
|
||||
```
|
||||
|
||||
## Desk Buddy — Architecture
|
||||
- Moods (0-11): NORMAL, HAPPY, SLEEPY, SURPRISED, ANGRY, SAD, EXCITED, WINK_L, WINK_R, HUNGRY, PLAYFUL, DIRTY
|
||||
- Actions (0-6): NONE, DATETIME, WIFI, FEED, PLAY, CLEAN, STATUS
|
||||
- Eyes: `drawFilledEllipse` + mood-specific shapes; wink = `drawCircle` UPPER arc
|
||||
- Wink: WINK_L closes screen-RIGHT eye (!isLeft = buddy's left), WINK_R closes screen-LEFT
|
||||
- Blink: state machine OPEN→CLOSING→CLOSED→OPENING, 4px/tick
|
||||
- Pupil: smooth drift toward random target every 1.5-4s (NORMAL only)
|
||||
- Sleepy: triggered after 5 min idle (`lastEvent` tracking), ZZZ bubbles
|
||||
- Auto-revert: `revertAt` timestamp, 0 = permanent mood
|
||||
- Display refresh: 50ms (~20fps) — OK with HW I2C
|
||||
|
||||
## Webhook System
|
||||
- Per-gesture config: URL (128 chars) + mood (0=none, 1-6) + enabled
|
||||
- Fired async via FreeRTOS `xTaskCreate` — non-blocking
|
||||
- POST `{"gesture":"wave"}` to configured URL, 3s timeout
|
||||
- Config persisted in NVS, served/edited via HTTP at GET/POST /
|
||||
- JSON API: GET /api/config, POST /api/config
|
||||
|
||||
## Key Files
|
||||
- `src/main.cpp` — hardware + drawing + HTTP server + WiFi + FreeRTOS (~400 lines)
|
||||
- `lib/BuddyDomain/` — BuddyTypes.h, BuddyLogic.h/.cpp (mood, blink, pupil — no Arduino)
|
||||
- `lib/TamaLogic/` — TamaLogic.h/.cpp (hunger/happiness/hygiene ticks — no Arduino)
|
||||
- `lib/GestureConfig/` — GestureConfig.h/.cpp (struct, enums, string tables)
|
||||
- `platformio.ini` — [env:esp32-c6] + [env:native]
|
||||
- `test/native/test_buddy/` + `test/native/test_tama/` — Unity tests (40 total)
|
||||
- Reference project: `../handsensor/` — webhook/config patterns
|
||||
|
||||
## Testing
|
||||
- `pio test -e native` or `task test` — runs 40 unit tests on Mac (no device needed)
|
||||
- `pio run -e esp32-c6` — firmware build
|
||||
- Domain libs have zero Arduino deps: `<algorithm>` only; RngFn injection for determinism
|
||||
|
||||
## Domain API
|
||||
- `initBuddy(BuddyState &b, uint32_t now)` — pass millis()
|
||||
- `setBuddyMood(BuddyState &b, Mood m, uint32_t now, uint32_t durationMs=0)`
|
||||
- `updateBuddyAnim(BuddyState &b, uint32_t now, RngFn rng)` — RngFn = int32_t(*)(lo,hi)
|
||||
- `initTama(TamaState &t, uint32_t now)`
|
||||
- `updateTama(TamaState &t, const BuddyState &b, uint32_t now)` → returns Mood override
|
||||
- `tamaFeed/Play/Clean(TamaState &t)` — direct state mutations
|
||||
Reference in New Issue
Block a user