P-01Application noterev 2026.08

Prototype to CES floor in two quarters: five boards, one platform, one firmware engineer

A smart bed that reads 10,756 pressure points and moves 46 actuators to correct posture. When I joined Water™ Robotics it collected pressure data and did nothing with it. This note is the ledger: what existed on day one, what shipped, and the four problems that stood between them.

Company
Water™ Robotics — Sleep Research and Development
Silicon
STM32H757 dual-core ×5 · Raspberry Pi host
Stack
FreeRTOS per core · bare-metal bootloader · C on Linux · ZeroMQ
Role
Sole firmware engineer · team of four
Span
Two quarters, prototype → CES 2026
1Scope ledgerTable 1.1

Line by line, what the product could do when I arrived and what it could do on the show floor. Everything in the right-hand column is firmware, host software or tooling I wrote.

Subsystem
Day one
At CES 2026
Sensing
Pressure readings off a mat, serially, one region at a time
10,756 points per frame across four boards, 250 ms per full frame
Actuation
None. No motor control of any kind
46 actuators, closed-loop position control with time-of-flight feedback, stall detection and per-class safety cutoffs
System shape
A board on a bench
Four identical sensing boards plus an aggregator on CAN-FD, feeding a Linux host
Host layer
None
Multi-threaded C daemon on Raspberry Pi: reads the aggregator, re-syncs the stream, publishes frames on ZeroMQ for the classification system
Boot & update
Flash over a debug probe, by hand, per board
One shared bootloader on all five boards; signed and encrypted OTA with A/B slots, staged rollout and automatic rollback
Connectivity
None
Secure WebSocket gateway bridging the internal bus to the mobile app and cloud, multiple clients at once
Diagnostics
Print statements
Shared-memory logging across both cores, reset-cause forensics on every boot, resource telemetry, silent-transmit-failure detection
Release
Whatever was on the engineer’s machine
Scripted build of every image, version stamped from git, and a gate that refuses to release a dirty tree, an untagged commit or a debug build
Table 1.1 — scope at join versus scope at launch. Ownership boundary: posture classification itself was built by teammates; I built the pipeline that feeds it.
2The platformFig. 2.1
SENSING · 4 IDENTICAL BOARDSboard 01 · M7 + M4board 02 · M7 + M4board 03 · M7 + M4board 04 · M7 + M4pressure matrix + actuators per boardCAN-FDaggregatordouble-bufferedUART / SPILinux host5 threads, Cframe re-syncZeroMQclassifier — teammatesmotor commandssecure gateway · app
Fig. 2.1 — solid blocks are mine; the dashed block consumes my feed. Each sensing board runs the same binary and learns which board it is at boot.
3Four problems
3.1 · Problem

A full sensor frame took 3.4 seconds. Real-time posture correction needs several per second.

The original scan walked every sensing point in turn: select the point, drive it, wait for the converter to settle, read it, move on. The settling wait dominated everything, and multiplying it by 10,756 made the product impossible on hardware that was already fixed.

3.1 · What I did

Rebuilt the acquisition path as a pipeline: both sensor buses on a core driven concurrently by DMA so multiple rows are in flight at once, settling delays timed off a hardware cycle counter instead of generic scheduler sleeps, and rows beyond the tallest active zone on that board skipped entirely rather than scanned and thrown away.

Before
3.4 s
After
250 ms
13.6× faster · 4 fps classification, on the same hardware
3.2 · Problem

Two cores on one chip, exchanging data, corrupting it intermittently.

Each core runs its own kernel at its own clock on its own power domain, sharing only a small window of memory. One core could read that window while the other was still mid-write. Worse, the faster core caches aggressively — a write could sit in cache and never reach the memory the other core was reading. Intermittent, load-dependent, and invisible in a debugger.

3.2 · What I did

Made every cross-core exchange take a hardware semaphore first — a silicon peripheral, not a software mutex, because a mutex only means something inside one core’s scheduler. Paired it with explicit cache maintenance so a write actually lands in physical memory, and memory barriers so the processor cannot reorder the release ahead of the data.

The corruption class disappeared. The pattern then became the standard for every cross-core access on the platform — the same discipline is in the aggregator, the bootloader and, later, the chair.

3.3 · Problem

Five boards to update, inside a bed, in a customer’s bedroom.

A single failed write is a service call at best. Updating a dual-core chip adds a second problem: the other core must stop touching flash before the write starts, or it corrupts the bank it is running from.

3.3 · What I did

Built the update path end to end: A/B flash slots with a guarded boot record, chunked transfer with missing-piece tracking, verification of the image in memory and again after it is written, a handshake that quiesces the second core before any erase, and automatic fallback to the previous image if the new one does not confirm a healthy boot.

Images are encrypted and signed. Rollout is staged in groups so no board is ever asked to overwrite the slot it is currently running. Underneath it all, one bare-metal bootloader, deployed identically to all five boards.

3.4 · Problem

Four sensing boards in different positions, doing slightly different jobs.

The obvious route is four hardware variants with four firmware builds. That is four things to fab, four to flash correctly on the line, four to keep in step for the rest of the product’s life — and a mis-flashed board that looks fine until it moves the wrong zone.

3.4 · What I did

One PCB and one firmware image. At boot each board reads its identity from jumper pins and configures itself from a static topology table — which zones it owns, which sensors and actuators map to them, which identifier it uses on the bus.

One image to build, sign, test and ship. The factory cannot flash the wrong one, because there is only one.

4Outcome
2 QUARTERS

Launched publicly at CES 2026 as a shipping consumer device — full sensing, actuation, secure updates and app connectivity. The company raised its next round shortly after the show. The architecture carried straight into the second product line: the smart chair reuses the same wire protocol, the same motor-driver integration and the same cross-core discipline.

10,756
Sensors per frame
46
Closed-loop actuators
5
MCUs, one image each role
1
Firmware engineer
Book a call →All projects