esp32.diy

Embedded-AI-Harness: AI Closed-Loop Firmware Dev for ESP32

Oct 11, 2026 · 6 min read

Advanced 190 stars 59 forks Python MIT Updated 2026-10-09
TL;DR Embedded-AI-Harness connects Claude to a Raspberry Pi testbench so the AI can write, compile, flash, and test ESP32 firmware autonomously. The loop runs — correcting itself on every failure — until every test is green on real silicon.
What you need
  • Raspberry Pi 3, 4, or 5
  • Raspberry Pi Zero 2 W (with USB hub and USB Ethernet adapter)
  • ESP32
  • USB hub
  • USB Ethernet adapter
  • RTL-SDR dongle (optional)
  • Si5351 + PE4302 (optional)
  • Jumper wires to EN/BOOT pins (optional)
BoardESP32 (testbench on Raspberry Pi 3/4/5 or Zero 2 W)
LanguagePython 3.11+
AI DriverClaude Code with custom slash-command skills
MCP Tools70 tools over HTTP
LicenseMIT
DifficultyAdvanced

What You Will Build

The Embedded-AI-Harness turns an AI assistant into a firmware engineer that works on real hardware rather than in a chat window. You describe what your ESP32 project should do, and the harness takes it from there: Claude writes the firmware, pushes it to GitHub Actions for a CI build, downloads the compiled binary, flashes it to a board sitting in a slot on a Raspberry Pi testbench, runs tests against real WiFi, MQTT, BLE, and RF signals, reads the results, corrects the code, and repeats — until every test passes.

The README calls this AI Closed-Loop Programming (AICLP). Ordinary AI coding is open-loop: you prompt, the AI guesses, you copy-paste and hope. AICLP closes the gap with a feedback path. The spec (a Functional Specification Document, or FSD) is the setpoint. The tests are the sensor. Failing tests are the error signal. Claude is the controller that corrects until the error reaches zero. The loop exits only when all tests are green on real silicon — not on a simulator, not in a local build directory.

If you have ever spent an afternoon babysitting a flashing script or rewriting the same WiFi connection test for a third project, this harness is worth the setup time.

What You Need

Hardware

Software and accounts

No local ESP-IDF or PlatformIO installation is required on your development machine. The CI pipeline handles all compilation in a pinned container.

Typical use cases

Autonomous Firmware Development

Hand Claude a product spec and let it write, compile, flash, and test ESP32 firmware end-to-end without manual intervention between iterations.

Hardware-in-the-Loop Testing

Run automated tests against real WiFi, MQTT, BLE, and RF hardware on every CI push, with the same binary that will ship to users.

Remote Multi-Board Lab

Centralise several ESP32 boards on one Raspberry Pi and flash or debug any slot over the network from a laptop or a GitHub Actions runner.

True Test-Driven Embedded Development

Derive tests from requirements before writing code, run them on real silicon, and prevent any feature from shipping unless it passes — enforced by the loop itself.

How It Works

The testbench is the physical half of the harness. The Raspberry Pi sits on your LAN and exposes everything over HTTP. Its onboard WiFi becomes a test access point, its Bluetooth stack scans and connects, and its USB hub maps each physical port to a numbered slot (SLOT1, SLOT2, ...). Plug a board into a port and it appears in that slot — always, regardless of how many times you swap boards or reboot the Pi. The README calls this slot-based identity: a slot is a physical hole in the hub, so scripts and platformio.ini entries never go stale.

Serial communication travels over RFC2217, a Telnet extension that carries baud rate and control signals over TCP. That means esptool, PlatformIO, and ESP-IDF can flash and monitor a board physically attached to the Pi as though it were plugged into your own machine — or the GitHub Actions runner.

The firmware binary that reaches the chip is always the one CI produced, never a local build. That is intentional: the artifact on the chip matches the artifact in the GitHub Actions run log, which makes the test evidence auditable and allows a tagged release to self-verify on the testbench before it publishes.

Claude drives all of this through 70 MCP tools or through four slash-command skills that correspond to the four phases of a project: /define (produce an FSD with falsifiable requirements), /harness (one-time project setup), /commission (prove the board and peers are working), and /build (the closed loop itself — requirements turning green one by one).

Building the Testbench

Flash Raspberry Pi OS Lite 64-bit to your Pi and boot it with wired Ethernet connected. If you are using a Pi Zero 2 W, apply the memory hardening described in User Manual §2.2 before anything else — 512 MB is tight and hard crashes under load can corrupt the SD card.

Clone the repo onto the Pi and run the installer:

git clone https://github.com/SensorsIot/Embedded-AI-Harness.git
cd Embedded-AI-Harness/pi
sudo bash install.sh

The installer sets up pyserial, hostapd, dnsmasq, bleak, esptool, OpenOCD, rtl-sdr/rtl_433, and mosquitto, configures udev hotplug rules, and starts the testbench portal as a systemd service.

From your development machine, find the bench's IP address. Use the discovery script rather than a .local hostname — mDNS does not resolve from inside a container:

BENCH=$(python3 .claude/skills/esp-idf-handling/discover-testbench.py | jq -r .ip)

Plug in an ESP32 board and confirm the slot appears:

curl http://$BENCH:8080/api/devices | jq

No configuration file is needed for slot detection. Create /etc/rfc2217/testbench.json only if you want to rename slots, pin port numbers, declare GPIO reset/boot pins, or register an ESP-Prog JTAG probe. The command sudo rfc2217-learn-slots prints a template.

If the device is not detected, check that you are using a data cable, then run lsusb on the Pi to confirm the board is visible at the USB level.

Flashing, Monitoring, and Running the AI Loop

Once the bench reports your board in a slot, point your existing tools at it. PlatformIO needs one line in platformio.ini:

upload_port = rfc2217://$BENCH:4001

esptool takes the same RFC2217 URL directly:

esptool --port rfc2217://$BENCH:4001 --chip esp32c3 \
  write-flash 0x10000 firmware.bin

To reset a board and watch it boot over plain HTTP — no client library required:

curl -X POST http://$BENCH:8080/api/serial/reset \
  -H 'Content-Type: application/json' -d '{"slot":"SLOT1"}'

For automated tests, the TestbenchDriver Python class wraps the HTTP API:

from testbench_driver import TestbenchDriver
wt = TestbenchDriver("http://$BENCH:8080")

wt.serial_reset("SLOT1")
wt.serial_monitor("SLOT1", pattern="WiFi connected", timeout=30)

wt.ap_start("TestAP", "password123")
station = wt.wait_for_station(timeout=30)
wt.http_get(f"http://{station['ip']}/status")

To bring Claude into the full loop, copy .claude/skills/ from this repo into your firmware project and open Claude Code. Run /define to interview Claude about your product — it asks questions one at a time and produces an FSD where every requirement states how it will be proven. Then /harness to wire up CI and the test plan, /commission to prove the board is responding correctly, and /build to start the autonomous loop. For Claude Desktop, drag mcp/embedded-ai-harness-testbench.mcpb onto Settings → Extensions and enter your testbench URL.

Extending the Setup and Honest Limits

The harness supports multiple boards simultaneously. Each slot is independent — its own serial buffer, its own OpenOCD/GDB port at 3333 + slot index — so two engineers can debug different boards on the same Pi at once, or you can dedicate a second slot to a peer board for two-node protocols like MQTT.

The testbench ships its own test-firmware/ image that it builds, versions, and flashes itself. This is not a device under test — it is a counterpart the bench measures itself against: it joins the test AP, hosts one of its own, answers HTTP, and replies on a serial console. It exists because the Pi has one radio and cannot simultaneously be the access point and the station testing that AP.

Optional SDR hardware — RTL-SDR dongle plus Si5351 and PE4302 — adds 433 MHz RF coverage for over-the-air firmware update tests and RF sensor simulation.

Limits to be aware of before you commit to the setup: Only one writing serial client per board at a time — RFC2217 gives one write session, though any number of readers can follow the fan-out. The SDR is one dongle, one user. The HTTP API has no authentication, so keep the testbench on a network you trust. Finally, the newest HTTP endpoints and slash-command skills are ahead of the MCP surface; some features are accessible only through the skills, not through the 70-tool MCP server yet.

Verdict

Embedded-AI-Harness is the most complete attempt yet at closing the feedback loop between an AI coding assistant and real embedded hardware, and the engineering behind the slot-based testbench and RFC2217 serial-over-network layer is genuinely solid. The setup overhead is real — a dedicated Raspberry Pi, a GitHub account wired into CI, and Claude Code with custom skills are all required before the first loop runs — so this is a tool for teams building a repeatable firmware pipeline, not for a one-off weekend project. If that matches your situation, the payoff is an autonomous agent that does not stop until the tests pass on the actual chip.

Sources

github.comSensorsIot/Embedded-AI-Harness — repository & README

Facts in this article come from the project's public README and GitHub metadata at the time of writing. Images belong to their respective owners and link back to the original source.