OctoMY™ has one hardware controller today — Fixo — that compiles your robot's actuator/sensor configuration into purpose-built firmware via embedded LLVM/Clang. Earlier releases also shipped a runtime-configurable path called Fluxo (originally ArduMY) and a Servotor32 binding. Both were retired in 2026 in favour of the single Fixo path. This page explains the reasoning so the choice doesn't look arbitrary.
Did You Know?
The name Fixo comes from Latin fixus — fixed, fastened. The retired runtime-config sibling was named Fluxo (Latin fluxus, flowing), reflecting the static/dynamic split. After Fluxo's removal the duality is gone, but the Fixo name stuck because it accurately describes how the firmware is generated.
Fixo's job is to take a FixoPreset (board + actuators + sensors + lobes) and produce a purpose-built firmware binary for that exact configuration. The C++ optimizer inlines every actuator type, pin number, and sensor descriptor as a compile-time constant; dead code paths are eliminated; the resulting binary contains zero runtime configuration overhead.
Agent
│
├─ FirmwareGenerator : preset → C++ source
├─ FirmwareCompiler : LLVM/Clang → AVR ELF + native .so
├─ FirmwareFlasher : ELF → MCU flash
│
└──serial──▶ Arduino (purpose-built firmware)
│
├─ All actuator types are compile-time constants
├─ All pin assignments are compile-time constants
├─ Lobe logic is compiled in
└─ Reports sensor values via numex
Configuration changes require a rebuild + reflash — but with the embedded LLVM toolchain that takes seconds, not the minutes a traditional cross-compiler workflow would. The flash cycle itself is around five seconds for a typical binary.
Fluxo (the previous dynamic-config path) worked but carried inherent costs on the constrained MCUs OctoMY targets:
Fixo flips all of those: every value is a compile-time constant, the optimizer collapses unused branches, and the generated source can host whatever C++ a lobe author wants to write.
Note
The runtime-configurable path made sense in a world where compiling C++ on a developer machine was a multi-step toolchain dance. Once we vendored LLVM/Clang into the Agent itself, that ergonomic cost disappeared: the user clicks Build and the firmware lands on the board seconds later. With the cost gone, the runtime-config drawbacks weren't worth carrying.
A lot of what was once described as "shared between Fixo and Fluxo" survived the removal:
| Component | Where it lives now |
|---|---|
| Numex wire protocol | libnumex/ — the value/command protocol talks to whatever firmware is running |
| Board definitions | libboard/ — pin capabilities, flash sizes |
| Flash protocols | libfirmware/ — STK500v1/v2/AVR109 flashing |
| Actuator and sensor types | libfixo/ — now part of the Fixo type registries |
A robot still uses exactly one controller. There's just no longer a "controller type" decision to make: it's Fixo.
| Feature | Status |
|---|---|
| Actuator control (servo, motor, stepper, relay) | Stable |
| Sensor reading (digital, analog, encoder, limit-switch, tachometer) | Stable |
| Identity lobe (passthrough) | Stable |
| Wheeled / tracked drive lobes | Stable |
| Hexapod gait, limb placement, hovering | Stable (templates ship in the studio) |
| AVR backend (ATmega328P, ATmega2560) | Stable |
| Native backend (host-side testing via dlopen) | Stable infrastructure; native compilation pipeline lands per spec |
| Stanza switching with conflict-disabling | Stable (Phase 7) |
| Live sensor readback on Remote | Stable (Phase 7) |