Hardware
There is a real arm. Nothing in the classroom depends on it.
A five-servo ESP8266 arm exists and its firmware is open. It is where the joint model came from and where it goes back to — but the simulator has no serial, Bluetooth, or network dependency on it, and a school does not need one to teach the whole course.
Design
Rust owns the policy; C++ is a hardware library
The dependency direction is one-way. Only one crate declares imported hardware functions, and the boundary between them carries bytes — never Arduino strings, C++ objects, routes, JSON, or application state.
Rust owns
- Startup policy and the cooperative executor
- Hotaru routing and the protocol
- HTTP parsing and responses
- Servo validation and state
C++ owns
Only operations that require Arduino or ESP8266 symbols:
- Clocks, interrupt masking, watchdog, restart, heap, random, serial
- Wi-Fi access-point and station modes, raw TCP and UDP handles
- Captive DNS and SPIFFS handles
- GPIO, PWM, servo pulse writes, raw OTA writes
Native WiFiClient, File, and Servo objects stay behind integer handles on the C++ side. Embedded Arduino firmware has no ordinary Rust fn main(), so the gateway exports one non-returning C entry that setup() calls once.
Workspace
The crates
- hcr-gateway
- The application. Startup policy, routing, and the single C entry point Arduino calls once.
- hcr-http
- no_std HTTP parsing and responses, plus the Hotaru protocol.
- hcr-io-esp8266
- Hotaru transport over the platform’s TCP.
- hcr-rt-esp8266
- Runtime, time, and critical sections.
- hcr-platform
- Platform traits and values shared across the workspace.
- ffi/hcr-ffi
- The only crate that declares imported hardware functions, plus safe adapters over them.
Protocol
One envelope, three transports
The app, the service, and the firmware speak hcr.v1. Every payload is an envelope — nothing is ever published bare.
| Client | Transport | Encoding |
|---|---|---|
| Browser | MQTT over WebSocket | JSON |
| Rust firmware (target) | MQTT over TCP/TLS | CBOR |
| ESP8266 (today) | Gateway translation — not MQTT | Text command language |
| Any HTTP client | HTTPS request–response | JSON |
Correlation in the envelope
Not in MQTT 5 properties. Devices may negotiate 3.1.1 and the HTTP binding has no properties at all — one mechanism that works everywhere beats two that each work sometimes.
Timestamps are not ordering
Device clocks are unreliable; the ESP8266 only reaches NTP when the router is up. Ordering comes from per-topic FIFO, never from the sender’s clock.
Additive minor versions
New optional fields, new kinds, new topics. A receiver that meets something it does not know logs and drops it rather than failing.