For Agents
Living index of themes for this project. Each H2 is a topic; bullets are wikilinks to related notes. Updated by
obsidian-documenterwhen documenting work. Read byhistorianat bootstrap. Topics kept alphabetical.
ADC
- esp32 — ADC2 is unusable whenever WiFi is active (garbage or blocking reads); ADC1 = GPIO1–10 on S3, GPIO32–39 on classic (34–39 input-only). Stay on ADC1 even with no WiFi so it can be added later. A rock-solid
raw=0means held at ground, not floating — floating reads noisy - 2026-08-12-lightaim-bench-bringup — the joystick fault that produced the stuck-at-zero rule
Antennas & RF
- esp32 — ESP32-S3-WROOM-1 has a PCB trace antenna and NO U.FL; only the “U” variants (WROOM-1U, WROOM-32U/32UE) have a connector. The antenna buys ~1 dB, the connector buys 10–20 dB by escaping enclosure loss, keep-out violations and orientation mismatch. SMA and RP-SMA thread together but never make contact
- tatabanya-mesh — the same SMA/RP-SMA trap on LoRa, plus feedline loss (~0.5–1 dB/m at 868 MHz) and height-over-terrain dominance
- 2026-07-31-telep-mainframe-ax210-ble-scan-broken — a radio that is “up but deaf” is an antenna fault; check physical RF first
Battery & Low Power
- esp32-battery-deep-sleep — ⭐ the whole low-power layer. DevKit carrier = 20–45 mA “asleep” vs 7–10 µA bare WROOM-1 (~3000×, ~4 days vs ~30 years on an 18650) — the CH343/AMS1117/LED are upstream of anything firmware can switch off. WS2812 draws ~0.7–1 mA showing black (~100× the sleep budget) — plain LEDs or gate VDD with a FET. Power-bank/boost modules (MH-CD42, IP5306 class) shut their own output off below ~40–50 mA 🔶 — test with a 470 Ω load for a minute; salvage as a charger by tapping B+/B−; use TP4056+DW01A (~5 µA, ~$0.30) instead. LDO Iq can exceed the MCU: AP2112K 55 µA, MCP1700 can’t do the 350–500 mA WiFi peak, XC6220 (9 µA, 1 A) does both. Never run an ESP32 off a raw 4.2 V cell (rated 3.6 V). Self-discharge ~2 %/mo ≈ 1.9 mAh/day is the floor — 8× a sleeping S3’s 0.24 mAh/day, so nRF52840 buys nothing on an 18650; its real edge is coin cells, which an ESP32 physically cannot use (CR2032 10–15 Ω ESR collapses above ~20 mA vs 350 mA WiFi peaks). ⚠️ MEASURE: octal-PSRAM
N16R8may add tens of µA via VDD_SPI — unverified, and all 10 bare modules on hand are R8 - esp32 — the parent reference; carries the DevKit warning on Boards on Hand and a one-line rule table under Power & Interfacing
- 2026-07-29-hardcut-design — where the AP2112K-3.3 comes from; correct downstream of an alternator, wrong on a cell
Boards & Variant Choice
- inventory — ⭐ what is physically owned, vault-wide. The boards are
100.474.96(S3-WROOM-1 ×10) and100.495.37(32UE DevKit ×5) with100.364.22pigtails ×5, from HESTORE H26/7333913 — boards alone were 47 600 Ft of the 84 100 Ft order. Carries the ⭐ cikkszám = product URL number with dots inserted rule (prod_10022512.html→100.225.12, split 3-3-2, dots optional in cart imports), the zero-ceramic-capacitor gap (no 100 nF decoupling anywhere), and an unresolved 2026-01-24 list that may contain a sixteenth ESP32 (100.481.79) - esp32 — boards on hand (10× S3-WROOM-1-N16R8-M, 5× DEVKIT-32UE-4M — the scarce U.FL-capable stock). S3 vs classic vs C3: C3 is single-core with no MCPWM; S3 has native USB-JTAG (no probe needed), classic does not; classic does 20-bit LEDC vs the S3’s 14
- esp32-battery-deep-sleep — the battery reclassification of that same stock: the 10 bare WROOM-1 modules are usable (⚠️ pending the R8 PSRAM measurement), the 5 DevKits are not — a DevKit is fine to develop on, but never conclude anything about power from one. ESP8266 is disqualified outright for any button-woken device
- 2026-07-29-hardcut-design — the S3-over-C3 decision in context
Breadboards & Prototyping
- Breadboards — the 5-column geometry rule — ⭐ a standard breadboard is 1.1 in (27.9 mm) outermost row to outermost row: five rows spanning 0.4 in, a 0.3 in channel, five more spanning 0.4 in. Free rows per side by pin pitch: 0.3 in → 4+4, 0.6 in → 2+3, 0.9 in → 1+1, 🔴 1.0 in (ESP32 DevKitC / 32UE) → 1+0, 1.1 in → 0+0. At 1.0 in half the GPIOs are physically unreachable. ⛔ No larger breadboard fixes it — width is fixed across every standard breadboard. Fixes: more boards (one per ESP32), two boards butted with facing power rails removed, F-M jumpers to lift the board off entirely, or a 0.6 in pitch board
- Breadboards — the 5-column geometry rule — ✅ correction: the BB-102 is a FULL SIZE board — 56 × 165 mm, 630 + 200 tie points — not a 170-point mini. Earlier sessions assumed otherwise and nearly ordered the wrong fix (830-point boards) for a problem extra length cannot touch
- buttonbox — the XIAO ESP32C3 (0.6 in pitch, 21 × 17.5 mm) was ordered for an enclosure constraint and solves the breadboard problem structurally as a side effect
- Mechanical and Interconnect — the BB-102 in the owned-stock table; 3 more are on the 2026-09-02 cart (ON ORDER — the 2026-09-02 Cart as Submitted, on order, not owned)
Buttons & Human Input
- buttonbox — ⭐ the two-button device worked end to end. NO/NC convention (green NO, red NC) chosen because NC fails loud — a broken wire on an NO button is silent and indistinguishable from idle, while NC reads as permanently pressed. Mains-powered final wiring is trivial: both buttons GPIO → contact → GND on internal pull-ups, zero external components, red inverted in one line — because 73 µA is design-breaking on a cell and irrelevant on mains. The device sends
{"button", "held_ms", "seq"}on release and nothing else; all gesture semantics live server-side, so a new gesture is a config edit rather than a reflash.held_msdoubles as stuck-switch detection — a 45 000 ms “press” is a fault - A normally-closed switch bleeds current continuously — the battery-era version of the same wiring: NC to 3V3 + 1 MΩ pull-DOWN
- Controls and calibration — single-button UX precedent: short press homes, hold ≥600 ms recalibrates
Deep Sleep & Wake Sources
- esp32-battery-deep-sleep — ⭐
ext1ANY_LOWis level-triggered, not edge-triggered: entering deep sleep while a masked pin is already low = infinite wake loop, flat cell in hours, and a stuck or broken-wire NC button causes exactly that. Firmware must read every masked pin before sleeping, mask out stuck pins and sleep on the rest plus a timer re-check.esp_sleep_enable_ext1_wakeup()takes ONE trigger level for the whole mask — you cannot mix wake-on-low and wake-on-high without the IDF-5.x per-IO API (esp_sleep_enable_ext1_wakeup_io()). A normally-closed switch on the internal 45 kΩ pull-up burns 73 µA continuously — wire NC to 3V3 with a 1 MΩ pull-DOWN, internal pulls off (3.3 µA), which also inverts the sense to LOW-on-press so it matches an NO button. NC’s upside: it fails loud (broken wire = permanently pressed) where NO fails silent. ESP8266EX has no GPIO deep-sleep wake at all — RTC timer via GPIO16→RST only; a reset carries no record of which pin, and ~250 ms to user code loses a quick tap, so it needs a 74HC74 latch per button - hardcut-bench-inventory — 2× 74HC74 dual D flip-flops and 2× SS-5GL SPDT (NO+NC) microswitches already in hand
- esp32 — Flash operations are the real threat, which is why wake-path state belongs in RTC slow memory, not NVS
Flashing
- esp32 — always flash over UART (CH343
1a86:55d3); the native USB/OTG port (303a:*) cannot flash a board already running firmware (No serial data received, on bothdefault_resetandusb_reset). Manual download mode: hold BOOT, tap RESET, release BOOT. Offsets: bootloader0x0on S3 /0x1000on classic, partitions0x8000, boot_app00xe000, firmware0x10000. Docker--device /dev/ttyACM0sidestepsdialout. Reset via pyserial DTR/RTS to capture boot output esptool would eat - 2026-08-11-ruview-esp32-csi-real-hardware — where the USB-port trap was first paid for (node 2 flash FAILED, left unprovisioned)
- 2026-08-12-lightaim-bench-bringup — hit independently a second time; source of the flash-offset table
LEDC & PWM
- esp32 — ⭐ the S3 caps LEDC duty resolution at 14 bits (classic does 20). At 16:
ledcSetup(): ... bit width too big (maximum 14)thenledc: ledc_get_duty(745): LEDC is not initialized— no PWM output at all while the rest of the firmware looks perfectly healthy. 14 bits still gives 1.22 µs on a 20 ms period. Core 2.xledcSetup/ledcAttachPin/ledcWrite(ch,…)vs core 3.xledcAttach/ledcWrite(pin,…), with the verbatimESP_ARDUINO_VERSION_MAJORguard - lightaim —
SERVO_RES_BITStuning constant and the fix in situ
Power & Interfacing
- esp32 — never power a servo from the board’s 5 V pin (MG996R stalls at ~2.5 A; ESP32 peaks ~500 mA on WiFi TX, brownout trips at 2.43 V); common ground is mandatory on any split supply and is the most commonly forgotten wire; resistive-divider modules take 3V3 on the
+5Vpad or they put 5 V into a 3.3 V ADC pin; automotive 12 V is 13.8–14.4 V running, 6–9 V cranking, 35–40 V+ on load dump → fuse + reverse-polarity protection + SMBJ33A TVS - lightaim — the split-supply bench setup that made a bulk cap unnecessary; the vehicle protection block
- Full Speed Is a Code Constant, Not a Power Limit — ⭐ a power problem that did not exist. “Full speed” was
MAX_RATE_DEG_S = 60.0fin the source, not the supply — the rig runs at ~1/7 of the MG996R’s ~430 °/s, and a UBEC + 2200 µF purchase was cancelled on the finding. Before buying hardware to raise a ceiling, check whether the ceiling is a literal in the source - Not Stocked at HESTORE — Verified Negative Knowledge — ⚠️ XC6220 is not stocked at HESTORE, and nothing in stock meets both low-Iq and 500 mA+. Closest is HT7833-A
100.478.84: ~4 µA Iq but only 450 mA, marginal against 350–500 mA WiFi peaks — workable with 100 µF+ bulk because the bursts are milliseconds - 2026-07-29-hardcut-design — LM74700-Q1 → SMBJ33A → LM5164-Q1 → AP2112K-3.3 automotive chain
- esp32-battery-deep-sleep — the same section for a cell instead of an alternator: quiescent current becomes the selection criterion, the WS2812 becomes a load, and WiFi wake-to-delivered drops 2.6 s → ~500 ms by caching BSSID+channel in RTC slow memory + static lease + literal IP + no TLS on-LAN, with a full-scan fallback for router/channel churn
Real-Time & RTOS
- esp32 — core pinning does NOT isolate an ISR from WiFi (bus/DPORT arbitration isn’t partitioned by core): ~4 µs baseline GPIO ISR latency, WiFi adds 50–100 µs — Espressif forum figures, not a rigorous study. Flash write/erase is the real threat — cache off, task code stalls for milliseconds, so no NVS/LittleFS/OTA while anything timing-critical runs. ISR hygiene:
ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, writeGPIO.out_w1ts/out_w1tcdirectly (gpio_set_level()is not IRAM-safe), no printf/float/flash-resident constants - 2026-07-29-hardcut-design — the timing budget this comes from, and the radio-off-whenever-armed conclusion
- 2026-08-08-hardcut-plan — refusing config writes while armed
Toolchain & PlatformIO
- esp32 —
uvx --from platformio pioFAILS withNo module named pip→MissingPackageManifestError(uvx env has no pip, PlatformIO shells out topip install). Fix:--with pipplusrm -rf ~/.platformio/packages/tool-esptoolpy; alternativepipx install platformio. Theespressif32platform ships Arduino core 2.0.17 (framework-arduinoespressif32 @ 3.20017), not 3.x - 2026-08-12-lightaim-bench-bringup — where both were discovered