NKIDO on embedded hardware

Cedar runs on a $10 ESP32. That puts nkido in range of guitar pedals, Eurorack modules, stompboxes, and custom instruments. Anywhere you want live-coded audio without a laptop in the loop.

Phase 3 Reference build runs on AI-Thinker ESP32-A1S Audio Kit: boot, live-push, six-key control

Proof of concept, not a product

The ESP32 port is about showing that the cedar VM (hot-swap, live-coded patches, all the pieces that make nkido feel the way it does) fits on a chip that's cheap and widely available. Once that's true, the interesting question shifts from "does it work?" to "what do you build with it?"

Guitar pedal

Pair the chip with a pedal-grade audio frontend, wire footswitches to GPIO and an expression pedal to the ADC, and you have a programmable effect box. The same live-push workflow applies: edit a patch, stomp, the sound changes.

Eurorack module

Map CV inputs to patch parameters, gate inputs to envelope triggers, and fit the result into a few HP of front panel. Cedar's live-push means the module's voice can be redefined without a firmware flash.

Standalone instrument

Battery, a small screen, a handful of physical controls. No host required. The last-pushed patch persists across reboots, so the device boots straight into whatever sound it was making.

None of those are built yet. The port gets us to the starting line: running cedar on a cheap chip, with the nkido workflow intact.

What's running today

The reference build targets the AI-Thinker ESP32-A1S Audio Kit 2.2, a classic ESP32 paired with an ES8388 stereo codec, a headphone amp, and six onboard tactile switches. It boots, plays a 440 Hz sine out the jack, accepts patch pushes over USB serial, and binds the six buttons to the running patch's parameters. Other ESP32 + ES8388 boards will probably work with little or no modification; different codecs or chips need a new driver and sensible config changes.

The full story of the port (what fought me, the decisions behind each phase, and what turned out easier than expected) is in the dev journal.

Try it

If you have an A1S Audio Kit and a USB cable, the fastest path is the Docker build. No toolchain install required.

git clone --recursive https://github.com/mlaass/cedar-esp32.git
cd cedar-esp32
./scripts/docker-build.sh
./scripts/docker-flash.sh /dev/ttyUSB0

Once it's running, push a new patch over serial:

python3 -m cedar_push --port /dev/ttyUSB0 my-patch.cbc

For native ESP-IDF builds, pin maps, board-specific config, and the full reference, see the repo README and build-docker.md.

How it works

Live patch push

The host compiles an Akkado patch to bytecode with parameter metadata, wraps it in a small .cbc container, and sends it over USB serial. Cedar's built-in crossfade handles the transition at the next audio block, so patches swap without dropping samples. End-to-end latency is under 50 ms. Wire format and frame types are in docs/uart-protocol.md.

Controls bind to the patch, not the board

Patches declare parameters. The device binds the first six declarations to the six onboard buttons in order, and each new patch re-maps them. This is the key insight for embedded deployment: a pedal or module's front panel can be wired to patch parameters the same way, and the patch stays portable between hardware targets.

VM in slow memory, hot path in fast memory

The cedar VM's working state (around 1.15 MB of buffer pools, state pools, and reverb buffers) lives in the ESP32's PSRAM, the chip's slower external memory. Internal SRAM is reserved for the audio-rate code path. That split is what makes the footprint budget work on a chip with only ~128 KB of fast memory.

Persistence

The most recent pushed patch is stored in on-chip flash and loaded at boot. Send cedar-push --reset-program to revert to the built-in demo.

Footprint

The Phase 3 firmware weighs in at about 306 KB, roughly 10% of the app partition. To make that budget work, several cedar features are compiled out of the embedded build: audio decoders, SoundFont support, FFT, generic file I/O, MinBLEP oscillators, and the debug probe ring. Most come back in Phase 4 once on-device sample playback is wired up.

Full size breakdown, per-opcode profiler output, and the regression rule are in docs/size-baseline.md.