πŸ¦†

Flash a Duck

Plug your duck into this computer over USB. Pick the product, then your hardware. No software to install.

Already have a duck plugged in? Identify it before flashing

Reads the chip's USB descriptors so you can tell what's already on it β€” Claude Code Duck, Bambu Duck, or unflashed β€” and which firmware version. Separate from flashing; safe to run any time.

The Mac companion duck β€” sits on your desk, watches your Claude Code session, reacts with voice + servo + LED. Pairs with the Duck Duck Duck widget app on macOS. This firmware handles audio, animation, and the serial protocol with the widget.

Ducky PCB

Ducky PCB

The official IDEO Duck product PCB β€” custom WROOM-1 board with full-duplex I2S, ChirpSynth audio engine, servo + addressable LED ring.

XIAO Seeed ESP32-S3

XIAO Seeed S3

Standard XIAO Seeed ESP32-S3 + cobbled mic / amp / servo. DIY build path for hobbyists who don't want to order the custom PCB. (No NeoPixel ring β€” that's the one hardware difference from the official PCB.)

The standalone 3D-printer companion. No Mac required β€” the duck talks to ElevenLabs Conversational AI through a small relay you run yourself, and the agent can query your Bambu printer's live state mid-conversation.

Step 1 β€” Deploy a relay (one-time, ~5 min)

The duck talks to a small server you run yourself. It bridges WebSocket conversation audio between the chip and ElevenLabs, and holds the per-printer MQTT subscription. The duck won't connect to anyone's relay but yours β€” these public binaries have no built-in default URL, on purpose. Your Bambu account credentials and ElevenLabs API key live on infrastructure you operate.

The runbook is written so Claude Code can drive most of it for you. Clone the repo, drop into bambu/, run claude, and ask "deploy a bambu duck for me":

git clone https://github.com/ideo/Rubber-Duck.git
cd Rubber-Duck/bambu
claude

You'll need flyctl + a Fly account (free tier covers it), an ElevenLabs API key, and a Bambu account. The DEPLOY.md runbook walks Claude through every step.

When the runbook hands you back, you'll have a URL like wss://<your-app>.fly.dev. Keep it handy β€” the duck's captive portal asks for it during onboarding (Step 3).

Step 2 β€” Pick a build + flash

Ducky PCB

Ducky PCB

Custom WROOM-1 board with full-duplex I2S. Strong PCB antenna, no audio quirks. Use this if you have the standard ducky hardware. Captive portal asks for your own ElevenLabs API key.

XIAO Seeed ESP32-S3

XIAO Seeed S3

Standard XIAO Seeed ESP32-S3 + cobbled mic / amp / servo. Weaker chip antenna; firmware uses a bigger mic ring buffer to absorb WiFi stalls. Captive portal asks for your own ElevenLabs key.

Step 3 β€” Onboard the duck

After the flash succeeds:

  1. Power-cycle the duck. It'll boot and play "press my button to start setup."
  2. Press the back button. The duck creates a WiFi network called DuckDuckDuck-XXXX.
  3. Join that network from your phone. The captive portal pops automatically (or browse to 192.168.4.1).
  4. Fill in: home WiFi, Bambu account, and the wss://...fly.dev URL from Step 1.
  5. Hit Save. The duck connects to your relay, walks you through printer selection, and you're done.
What if the button doesn't see my duck?
What does flashing actually do?

It copies new firmware into the chip's flash memory. The duck's WiFi credentials, Bambu account binding, and other settings live in a separate NVS partition β€” those stay intact across normal flashes. If you want a true factory reset (wipe NVS too), the captive portal has a "Factory Reset" button or you can use a full idf.py erase-flash from a development environment.

I want to run my own relay (not use yours)

By default the firmware connects to a community relay we host at duck-duck-print.fly.dev. If you'd rather run your own β€” keeping your Bambu account binding entirely on your own infrastructure, or because you want to control the ElevenLabs voice yourself β€” there's a runbook for that: bambu/DEPLOY.md.

It's written for Claude Code as the executor. Clone the repo, run claude inside bambu/, and ask "deploy a bambu duck for me." Claude walks through Fly app creation, secret generation, ElevenLabs agent creation, and hands off to you for the chip step. Takes about five minutes. After that, when you flash a duck via this page and onboard it, expand the captive portal's Advanced β€” relay URL field and paste wss://<your-app>.fly.dev. The duck connects to your relay instead of ours.

Source code, hardware, license

This page lives in the ideo/Rubber-Duck repo under docs/flash/. Firmware sources are in bambu/firmware/. Software is MIT-licensed; hardware designs are CERN-OHL-P-2.0.