Skip to content

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.

Transport binding and encoding per client
ClientTransportEncoding
BrowserMQTT over WebSocketJSON
Rust firmware (target)MQTT over TCP/TLSCBOR
ESP8266 (today)Gateway translation — not MQTTText command language
Any HTTP clientHTTPS request–responseJSON

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.