8.1 KiB
8.1 KiB
| title | tags | project | author | date | status | authority | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Firmware v3.1 — Modo B / $PHLG en banda — Design Brief & Execution Prompt |
|
Project Drogheda | Helgen CTO + Claude (decisión registrada 2026-08-08) | 2026-08-08 | Active — EL prompt para la sesión de implementación de la telemetría en banda (v3.1 núcleo EPCT) | ejecuta la decisión A de `Informe-Tecnico-V3-V4` §4.7–4.8 (v1.2); hardware canónico = watchdog-electrical-design-state.md; hallazgos F1–F9 = firmware-review-v2.3-EinarBoard.md |
Firmware v3.1 (núcleo EPCT) — encender la telemetría en banda
Cómo usar este doc. Es la instrucción autocontenida para convertir la decisión «A =
$PHLGtal cual, en banda por Modo B, es la palabra canónica de telemetría» (Leo, 2026-08-08) en software corriendo sobre V3 (EinarBoard 1.0, vía adaptador inversor) y V4 (HBOX v4). Una sesión (humana o Claude) debe poder arrancar solo con este archivo. Reglas vigentes: hostsim en verde antes de tocar hardware; banco antes de campo; el NC de K1 es la garantía de hardware — ningún cambio puede debilitarla.
0. La decisión y su estado de partida
| Hecho | Estado hoy (v2.3 flota / v3.0 escrito) |
|---|---|
| Flujo NMEA al servidor | Sin alterar — posición pura; K1 desenergizado (PB5 sin manejar), ENABLE_PHLG_RELAY=0 |
$PHLG |
Se construye y emite cada 30 s solo al log USB (21 campos v2.3 / 25 v3.0, checksum XOR correcto) |
| Camino Modo B en cobre | Listo y verificado en ambas tarjetas (PA10 tap · PA9→NO · PB5→Q6→bobina · NC fail-safe) |
| Transparencia del módem | Probada 2026-06-22: $PUBX inyectada llegó byte-idéntica al servidor |
| Palabra canónica | DECIDIDA 2026-08-08: opción A — la misma $PHLG del log USB, sin recortar ni re-empacar (una sola palabra en USB y aire; append-only se mantiene) |
Consecuencia inmediata útil: el decodificador del backend puede desarrollarse y probarse HOY contra capturas USB de banco — son los mismos bytes que llegarán por aire.
1. Fases (cada una con compuerta propia; 1 y 2 pueden correr en paralelo)
| Fase | Qué | Compuerta de salida |
|---|---|---|
| 1 — Servidor primero (cero riesgo, sin tocar firmware) | htracker: extender PHLG_FIELDS a los 24 campos de datos v3.0; parser tolerante por longitud (20 = v2.3, 24 = v3.0+, extras = ignorar); validar checksum XOR; sentinelas −127/−1 → null; almacenar por unidad (llave cell_id) + panel/alertas (limp=1, rec subiendo, cflt=1, nmea_age>60000, tmax≥75 o celda ≥55) |
Decodifica al 100 % un log USB real de banco (v2.3 y v3.0) |
| 2 — Prerrequisitos F4 (firmware, sin encender nada) | SHT40 no bloqueante en dos fases + rings UART de 256 B (§3.1–3.2) | hostsim verde; TLM intacta; sin delay() en el lazo |
| 3 — Relevo Modo B en banco V3 | ENABLE_PHLG_RELAY=1 + driver PB5 (§3.3–3.5) en una 1.0 de banco (adaptador inversor) |
Los 5 gates de banco de §4 en verde |
| 4 — Piloto en vivo | Una unidad transmitiendo; Fase 1 ya desplegada | $PHLG visible en el panel; RTK fix≥4 sostenido con relevo insertado; consumo medido |
| 5 — V4 | Mismo código bajo TARGET_HBOXV4 (PA9/PA10/PB5 = nets idénticas); después v3.2 = espejo de la MISMA palabra por W5500/TCP |
bring-up V4 + gates §4 repetidos |
2. Diseño de la inserción (política de K1)
- Insertar solo en la transición BOOTING→RUNNING (después de «Boot complete»), una vez
por sesión de energía: orden estricto
RELAY.begin(115200)→digitalWrite(PB5, HIGH). El transfer del G5V-1 (~ms) puede morder una sentencia en el switchover — aceptable una vez por sesión; jamás conmutar por-sentencia. - Retirar en TODA salida de RUNNING — dentro de
setPower(false)(cubrebeginPowerCycley SLEEP):digitalWrite(PB5, LOW)(NC restituye al instante) →RELAY.end()→pinMode(PA9, INPUT)(flotar TX, espejo del patrón PA2 — no retroalimentar el riel). - Fallas: cuelgue del MCU → IWDG resetea → GPIO a default → PB5 cae → el NC restituye el camino por hardware (R41 10 k garantiza Q6 apagado durante el reset). Nada que programar: documentar como la historia de seguridad y probarla (gate G4).
- Presupuesto: bobina ~30 mA de
SYS5Vmientras está insertado. En respaldo queremos la telemetría viva (¡ahí viajavbat!) — se queda insertado; 30 mA contra 12 Ah es ruido. Datos: ~95 B/30 s ≈ ~0.3 MB/mes/unidad — despreciable.
3. Cambios de código (archivo único blackpillrtkcode_v3.ino → v3.1)
- SHT40 en dos fases (F4): sustituir
readSHT40()bloqueante por máquina de dos estados dentro dethermalService(): pasada N dispara (Wirewrite0xFD, marcasht40TrigMs), pasada N+1 (≥10 ms después; THERMAL_PERIOD=2 s sobra) cosecha los 6 bytes. Cerodelay()en el lazo. TMP102 queda igual (free-running, lectura corta). - Rings UART de 256 B:
build_opt.hen la carpeta del sketch con-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=256(vía STM32duino; equivalente--build-propertyen arduino-cli). Aplica a GNSS y RELAY. - Driver de inserción:
#define PIN_BYP_CTRL PB5; ensetup()OUTPUT+LOWantes de cualquier otra cosa; helpersetModoB(bool)con el orden de §2; llamada ON en la transición a RUNNING, OFF dentro desetPower(false). - Flags:
ENABLE_PHLG_RELAY 1en el build EinarBoard; el pump (pumpRelay()) y la colapendingPhlgya existen y son correctos (reenvío byte a byte + inyección solo tras ≥8 ms de línea ociosa, solo en RUNNING) — no reescribir, solo encender. - Target V4: introducir
TARGET_HBOXV4(tercer target excluyente): hereda TODO el EPCT deTARGET_EINARBOARD; difiere en medidor/RGB→PCF8574 y en no tocar PB12–15 (SPI2 del W5500). El Modo B es idéntico — cero cambios. - hostsim: nuevo escenario
relay: alimentar 10 min de GGA sintéticas a 1 Hz por el stub, verificar (a) salida byte-exacta salvo líneas$PHLGcompletas en fronteras de línea, (b) ninguna inyección con <8 ms de hueco, (c)setModoB(false)al salir de RUNNING. Correr toda la red existente (ladder/sps/rtkloss/gga/phlg/charge/gauge) sin regresión. - Docs: CHANGELOG v3.1; LOGGING-SPEC §5b marcar «relay ON por default en EinarBoard»; PINOUT.md (la reescritura F7 pendiente absorbe esto).
4. Compuertas de banco (todas en una 1.0 con adaptador, antes de piloto)
- G1 — Integridad byte-exacta: capturar simultáneo F9P TX2 y módem DIN (o segunda
USB-UART en el nodo DIN) 10 min @1 Hz → diff = solo líneas
$PHLGíntegras, ninguna GGA partida ni byte alterado. - G2 — Sin regresión RTK/VRS: con relevo insertado y caster real, la unidad alcanza y sostiene fix ≥4 (la GGA de cortesía al caster sigue siendo válida).
- G3 — Llegada al servidor: repetir la prueba
$PUBXpero con$PHLGreal → Fase 1 la decodifica en el panel. - G4 — Fail-safe: forzar cuelgue (bucle infinito de prueba) → IWDG resetea → verificar con osciloscopio/continuidad que PB5 cae y el NC restituye ANTES del re-arranque; el flujo de posición nunca se detiene.
- G5 — Presupuesto de lazo: con relevo activo,
TLMsigue a 2 s, IWDG jamás dispara, sinrxbadcreciente (los rings de 256 aguantan la ráfaga de época GNSS).
5. Riesgos / notas
- F4 es prerrequisito duro — encender el relevo sin él corrompe el uplink GGA del caster VRS (10 ms bloqueados ≈ 115 bytes vs ring de 64). El orden de fases no es opcional.
- El switchover de K1 muerde ~1 sentencia una vez por sesión — el backend ya tolera pérdida de época (heartbeat 1 Hz); documentado, no mitigado.
- v2.3 en flota no cambia: unidades sin re-flashear siguen transmitiendo posición pura
por el NC — el backend debe seguir aceptando flujo sin
$PHLGindefinidamente. - La opción C (Modbus, Bloque M de V4) queda como espejo por consulta para el cliente — no sustituye la palabra canónica; su mapa de registros sigue gateado por firma del cliente.
- No tocar: la doctrina de recuperación, el formato
$PHLG(append-only), ni el NC de K1.