Architecture

Architecture

Five layers, one orchestrated device. From sensor input to wireless broadcast, every signal passes through a deterministic pipeline tuned for low latency and high reliability.

Five layers, one orchestrated device. From sensor input to wireless broadcast, every signal passes through a deterministic pipeline tuned for low latency and high reliability. Nothing in the WB-1 is event-loop spaghetti — each stage has a fixed contract, a measured latency budget, and a defined failure mode. That is what lets us promise sub-8-millisecond sensor-to-broadcast and actually hit it on every cycle, not just the median one.

The pipeline at a glance

Signals flow left to right. Each layer hands the next a strictly typed frame and a timestamp drawn from the same hardware clock, so latency is additive and auditable rather than emergent.

  INPUTS        NORMALIZE       ENGINE          TRANSMIT        OUTPUTS
 ┌───────┐     ┌─────────┐    ┌──────────┐    ┌──────────┐    ┌────────┐
 │ 12 ch │ ──▶ │ unify + │──▶ │ fuse +   │──▶ │ BLE/WiFi │──▶ │ actu-  │
 │ radios│     │ stamp   │    │ decide   │    │ /LoRa fan│    │ ators  │
 └───────┘     └─────────┘    └──────────┘    └──────────┘    └────────┘
  ~0.5 ms        ~1.2 ms        ~2.5 ms          ~3 ms          —

The per-layer budgets above are worst-case at full channel load; typical operation runs roughly 40% under. The Cortex-M7 owns the deterministic real-time path (normalize → engine → transmit-schedule), while the ESP32 owns the radios, the web stack, and the cloud sync. Splitting the two means a slow REST request can never stall a safety interlock.

Layer 1: Inputs

What it does: terminates every physical and wireless source the device can see — 12 channels spanning analog (0–10V, 4–20mA), digital GPIO, I²C/SPI/UART sensor buses, plus BLE and Wi-Fi scan results.

In / out: raw electrical or packet data in; a tagged sample (channel_id, value, hw_timestamp) out.

Latency budget: ~0.5 ms. ADC sampling and bus reads are DMA-driven, so the CPU is never blocked polling.

What can go wrong: a flapping sensor, a disconnected bus, an out-of-range analog reading. How to debug: every channel exposes a live rssi/quality field in the dashboard; a dead channel shows as stale with its last-good timestamp.

Layer 2: Normalization

What it does: converts the zoo of input formats into one unified wire frame. Every sample is timestamped against the shared monotonic clock, priority-tagged, and deduplicated against the last frame on that channel.

In / out: heterogeneous tagged samples in; a uniform Frame struct out.

Latency budget: ~1.2 ms including the dedup window.

What can go wrong: clock skew between input sources, or a chatty sensor flooding its channel. How to debug: the normalize layer emits a dropped_duplicates counter per channel — a spike there usually means a sensor needs debounce tuning, not a device fault.

Layer 3: Bobulation Engine

What it does: the decisioning core. Multi-input fusion with weighted confidence, the YAML rule engine, deterministic conflict resolution, and context-aware routing. This is the layer worth the price of the box, and it gets its own deep-dive.

In / out: normalized frames in; routing decisions (output_target, payload, priority) out.

Latency budget: ~2.5 ms worst-case for a 12-channel fusion with a deep rule set.

What can go wrong: a rule conflict with no defined precedence. How to debug: the engine never silently picks a winner — unresolved conflicts hit the audit log with both contending rules and the freshness scores that broke the tie.

Layer 4: Transmission

What it does: schedules and fans out decisions across BLE 5.3, Wi-Fi 6, and LoRa — one radio or all three simultaneously.

In / out: routing decisions in; framed radio packets out.

Latency budget: ~3 ms, dominated by the BLE connection interval. LoRa is fire-and-forget for range; BLE/Wi-Fi carry the low-latency traffic.

What can go wrong: RF congestion, a saturated 2.4 GHz band. How to debug: the transmit layer reports airtime utilization per radio; if BLE airtime is pegged, move bulk traffic to Wi-Fi via a one-line routing rule.

Layer 5: Outputs

What it does: the far end — actuators, downstream devices, cloud APIs, dashboards, and alerts. The Bobulator doesn’t care whether the receiver is a relay board or a Kubernetes ingress; it’s all addressable output.

In / out: radio packets in; physical actuation or API calls out.

Layer-to-layer contracts

From → ToFrame typeGuarantee
Inputs → NormalizeTaggedSamplehardware timestamp, never reordered
Normalize → EngineFramededuplicated, priority-tagged
Engine → TransmitDecisiondeterministic, audit-logged
Transmit → OutputsRadioPacketper-radio delivery receipts (BLE/Wi-Fi)

Every boundary is a typed struct, not a loose dictionary. That is the whole trick: because each contract is fixed, you can reason about — and test — each layer in isolation.

Failure modes & recovery

A deterministic pipeline is only as good as its behaviour when something breaks. Every layer has a defined failure mode and a defined recovery — none of them is “the device hangs and someone reboots it.” Here is what actually happens.

M7 hangs ESP32 WATCHDOG → RESET < 50 ms

The Cortex-M7 hangs. The ESP32 holds an independent hardware watchdog that the M7 must pet every tick. Miss the deadline and the ESP32 resets the M7 within 50 ms, then replays the last-good rule set from NVRAM. Because the two chips are independent, a wedged control loop cannot also wedge the watchdog that’s supposed to catch it.

Radio SPI bus errors BACK OFF → RETRY → ESCALATE TO MESH

A radio’s SPI bus errors out. The driver backs off with a bounded exponential retry rather than hammering a dead bus. If the fault persists past the retry budget, the transmit layer marks that radio degraded and escalates the affected traffic to mesh neighbours, so a single failed radio downgrades range and redundancy instead of dropping the link.

Power below threshold GRACEFUL SHUTDOWN → NVRAM STATE WRITE

Power drops below threshold. At the 3.1 V brown-out point the M7 takes a hardware interrupt with reserve energy in the bulk capacitance — enough to write the last rule state and audit cursor to NVRAM before shutdown. On the next power-up the engine resumes from that checkpoint rather than cold-booting blind.

Cloud connection lost RUN ON LAST-KNOWN RULES + LOCAL HISTORY

Cloud connection is lost. Nothing stops. The engine runs entirely on the last-known rule set and recent sensor history held on-device; the audit log buffers locally and hash-chains forward, then syncs when the link returns. The WB-1 was designed offline-first — the cloud is where you manage the fleet, never where you run it.

Ready to go deeper? Read about the Bobulation Engine, pick a wireless topology for your site, scan the full technical specifications, or read how it’s built.

copied!