firmware: add I2S MEMS microphone driver; fix missing essence migration

Mic: confirmed via its pinout (L/R, WS, SCK, SD, VCC, GND) that the third
target module is a standard I2S digital MEMS mic (INMP441-family). Added
mems_mic.c/h using ESP-IDF's current driver/i2s_std.h API — reports RMS
audio level in dBFS as sensor_type "evp" rather than attempting on-device
voice-band FFT (the browser EVP mode's approach); the backend's existing
statistical anomaly detector handles spike detection from the raw level,
same as it already does for temperature/pressure/presence.

Also fixes a real gap Workstream B's report flagged: User.essence (a live
model column used throughout merged code — /auth/me, inventory purchases,
summon trickle) had no migration line in main.py's lifespan, which would
have broken on the actual production Postgres database.
This commit is contained in:
Indiana
2026-07-24 21:52:03 +00:00
parent 7ebedf363b
commit f09e077199
6 changed files with 288 additions and 6 deletions

View File

@@ -16,6 +16,12 @@ with 28 programmable GPIOs). All pin assignments and the Wi-Fi bring-up
approach below are specific to this board — see the Wi-Fi section for the
reserved SDIO pins and [Wiring / pinout](#wiring--pinout) for sensor pins.
**Target sensors:** a **GY-BMP280** breakout (temperature/pressure, I2C),
an **Ai-Thinker RD-03E** 24GHz mmWave radar (presence/distance/gesture,
UART), and an **I2S digital MEMS microphone** (INMP441-family pinout —
`L/R`/`WS`/`SCK`/`SD` — EVP-style audio level). See
[Wiring / pinout](#wiring--pinout) for exact connections.
## Honesty policy — READ THIS FIRST
> This app's whole ethos is "real signal processing on real data, and it
@@ -54,7 +60,8 @@ firmware/esp32p4-sensor-node/
├── sensor_driver.h the sensor_driver_t registry interface
├── sensor_registry.{h,c} the concrete list of compiled-in drivers
├── bmp280.{h,c} temperature/pressure over I2C
└── rd03e.{h,c} presence/distance/gesture over UART
├── rd03e.{h,c} presence/distance/gesture over UART
└── mems_mic.{h,c} EVP-style audio RMS level over I2S
```
## Build instructions
@@ -136,6 +143,12 @@ consistent; no known syntax errors or obviously-wrong API usage):
driver reports it as a raw code in `metadata` rather than guessing at a
translated label. Cross-confirmed from multiple sources: 256000 baud,
8N1 UART framing.
- I2S MEMS microphone driver (`mems_mic.c`): uses ESP-IDF's current
`driver/i2s_std.h` API (standard/Philips mode, mono, 32-bit slot). The
24-bit-in-32-bit-slot right-shift and dBFS reference level are the
commonly-documented values for the INMP441 family this module's pinout
(`L/R`/`WS`/`SCK`/`SD`) matches. Deliberately does RMS-level reporting
only, not on-device voice-band FFT — see its header comment for why.
- Sensor driver registry (`sensor_driver.h`, `sensor_registry.c`): a
`sensor_driver_t { name, init, read }` struct, a compile-time array of
them, and generic init/collect functions that `app_main.c` and
@@ -159,6 +172,11 @@ consistent; no known syntax errors or obviously-wrong API usage):
third-party source rather than an official datasheet. Verify against a
logic analyzer capture before trusting field values, and treat the
gesture code's meaning as genuinely unknown until cross-checked.
- I2S mic timing/levels: the BCLK/WS timing relationship, whether the
24-bit-in-32-bit-slot shift is exactly right for this specific module
revision, and whether the dBFS numbers land in a sane, usable range —
none of this has been bench-tested. Confirm by talking near the mic and
checking the reported level actually rises before trusting it unattended.
- Wi-Fi reconnect behavior under real-world conditions (router reboot,
weak signal, captive portals) — the backoff logic is reasoned about, not
soak-tested.
@@ -277,6 +295,36 @@ only the module's free-running "simple report" frames — no configuration
handshake is sent or required. GPIO numbers and baud rate are `#define`s
at the top of `rd03e.h`.
### I2S MEMS microphone — EVP-style audio level
Confirmed against the actual part in use via its pinout (`L/R`, `WS`,
`SCK`, `SD`, `VCC`, `GND` — the standard INMP441-family I2S digital MEMS
mic breakout naming). Unlike the browser-based EVP mode's client-side
voice-band FFT, this driver does not attempt on-device spectral analysis —
it samples a short audio block per cycle, computes RMS level in dBFS, and
reports that as a plain numeric reading. The backend's existing
statistical anomaly detector (the same one already used for
temperature/pressure) does the spike detection from there — simpler and
more honest than pretending to replicate real voice-band filtering without
ever having tested it.
| Mic pin | Connects to |
|---------|-------------------------------------------|
| VCC | 3V3 |
| GND | GND |
| L/R | GND (selects left-channel output — tie to 3V3 instead for right, either works, just match the driver's `I2S_STD_SLOT_LEFT` default or change it) |
| WS | GPIO11 (`MEMS_MIC_I2S_WS_GPIO`) — word select / LRCLK |
| SCK | GPIO10 (`MEMS_MIC_I2S_BCLK_GPIO`) — bit clock |
| SD | GPIO12 (`MEMS_MIC_I2S_DIN_GPIO`) — serial data, mic OUT to ESP32 IN |
(GPIO10/11/12 avoid this board's reserved SDIO range, the BMP280's I2C
pins, and the RD-03E's UART pins — a reasonable, currently-unused pick,
same verification caveat as the other sensors' pins above.)
16kHz sample rate, 256ms sample block per reporting cycle (4096 samples) —
`#define`s at the top of `mems_mic.h`. Reports `sensor_type: "evp"`,
`unit: "dbfs"`.
## Sensor driver registry — the extensibility pattern
`sensor_driver.h` defines: