tamagotchi

Wiring the hardware

One component at a time — wire it, verify it, then move on.

Your toolchain is set up from Setup — now build the real thing. This is the full pet on a half-size breadboard: the OLED again (this time on the breadboard), plus a buzzer for sound and an IMU so it reacts when you pick it up or shake it.

Add one component, run the verify command, then move on. Mistakes are much easier to debug when you only just added one wire.

What you're building with

PartNotes
ESP32-C3 SuperMiniNative USB-C
SSD1306 OLED, 0.96"I²C, address 0x3C
GY-521 / MPU-6050 IMUI²C, address 0x68
Passive piezo buzzerMust be passive, not active
Half-size breadboard400 tie-points is plenty
~14 dupont jumpers (M-M)Short ones (5–10 cm) work best
USB-C cableData, not power-only

Before you start

You'll verify each component with a small bring-up test that lives in the firmware repo. Every test is a single make target — it compiles a tiny sketch, flashes it, and exercises just the sensor you just wired:

TargetWhat it does
make test-ledBlinks the ESP32-C3's onboard blue LED
make test-oledDraws "Hello" on the OLED
make test-buzzerPlays a short tone
make test-mpuStreams IMU data + opens a live browser visualizer

No CLI install needed yet — these run straight from arduino-cli. The gochi CLI comes at the end, once the hardware is proven.

Pin map

The full wiring, for reference. Don't try to do it all at once — follow the steps below.

ESP32-C3Goes to
5Vbreadboard + rail
GNDbreadboard rail
GPIO5OLED SDA
GPIO6OLED SCK
GPIO7MPU SDA
GPIO8MPU SCL
GPIO10Buzzer signal

Why two I²C buses? The OLED runs on the C3's hardware I²C (GPIO5/6). The MPU runs on a separate software I²C bus (GPIO7/8). Stacking both on one bus dropped pull-up resistance too low for fast-mode and corrupted address bytes.

Step 1 — Power rails

Plug the SuperMini into the breadboard so its pins straddle the centre gap.

Wire 5V+ rail.

Wire GND rail.

Plug in USB. The SuperMini's tiny red power LED should light up.

Verify:

make test-led

After flashing, the blue LED on the SuperMini starts blinking. That confirms power, USB data, and the toolchain are all wired up correctly before you add anything else.

For reference — where the pins sit on the board, and the two jumpers you run in this step. USB powers the board, and the board feeds the breadboard: jumper 5V+ rail and GND rail (shown on the left). Once it's pushed into the breadboard you can't read the silkscreen, so note that 5V and GND are the top two on the left, and GPIO5/GPIO6 (the OLED's SDA/SCK) are the top two on the right:

USB-CESP32-C3Super Mini5V+5VGGND3.33V34GPIO43GPIO32GPIO21GPIO10GPIO05GPIO5OLED SDA6GPIO6OLED SCK7GPIO78GPIO89GPIO910GPIO1020GPIO2021GPIO21PowerGNDI²C (OLED)other

The kit's OLED and MPU are breakout modules with onboard regulators, so 5V on the + rail is what they expect. If you swapped in a bare 3.3 V-only OLED panel, feed it 3V3 instead — 5 V will kill it.

Step 2 — OLED

Place the OLED on a free row. Read the silkscreen — pin order varies between modules.

Wire it up:

  • GND rail
  • VDD+ rail
  • SCKGPIO6
  • SDAGPIO5

Verify:

make test-oled

The OLED should light up and draw "Hello". If it stays dark, double-check SDA/SCK aren't swapped and VDD is on the right rail.

Step 3 — Buzzer

Place the buzzer on the breadboard.

Wire it up:

  • + (signal) → GPIO10
  • rail

Verify:

make test-buzzer

You should hear a short tone. Silence usually means an active buzzer slipped into the kit — see the callout below.

Passive piezo only. Active buzzers ignore tone signals and only beep at a fixed pitch — they will not reproduce the firmware's jingles. If you hear nothing, that's the first thing to check.

Step 4 — MPU-6050 IMU

The GY-521 has eight pins. You only use four.

Place the MPU module on a free row.

Wire it up:

  • VCC+ rail
  • GND rail
  • SCLGPIO8
  • SDAGPIO7

Leave XDA, XCL, AD0, and INT unconnected.

Verify:

make test-mpu

This flashes the IMU streaming sketch and opens a live visualizer in your browser (Chrome or Edge — uses the Web Serial API). Tilt and shake the board and the values should move in real time.

GPIO8 is a strapping pin. The C3 samples it at reset to choose between normal boot (HIGH) and flash-download mode (LOW). The MPU holds it HIGH while connected. Plug the MPU in before USB, and never reset the board with the MPU unplugged — otherwise the firmware won't run.

If 0x69 shows up instead of 0x68, the AD0 pin is being pulled HIGH. Change MPU_ADDR to 0x69 in firmware/src/config.h and reflash.

Flash the full firmware

All four bring-up tests passed — the hardware is good. Now flash the actual pet firmware so the device runs the real face, sounds, and gesture loop:

make flash

The OLED wakes up a second or two later with the pet's eyes blinking and drifting around.

Drive it from the gochi CLI

With the hardware proven and the firmware flashed, the gochi CLI gives you a friendlier interface to talk to the device — query state, trigger sounds, set faces, and let agents drive the pet through its local HTTP daemon. Install it from the repo you already cloned, not the published package:

cd cli                 # inside the gochi repo
bun install
bun link               # registers `gochi` globally
gochi setup            # installs the daemon — it auto-starts at login
gochi ping             # should print PONG

If gochi: command not found after bun link, Bun's global bin directory probably isn't on your PATH. Add it:

export PATH="$HOME/.bun/bin:$PATH"   # add to ~/.zshrc or ~/.bashrc to persist

There's no build step: the CLI runs its TypeScript sources directly (via tsx), so editing anything under cli/src takes effect the next time you run gochi.

Final end-to-end check:

gochi test all

It walks through serial → OLED → buzzer → IMU, asking a yes/no question after each. All green means you're done.

Troubleshooting

SymptomFirst thing to check
make test-led fails to uploadUSB cable (data, not power); try holding BOOT, tapping RESET, release BOOT
OLED dark after make test-oledSDA/SCK swapped; VDD on wrong rail; or the panel itself is dead
Buzzer silent after make test-buzzerIt's an active buzzer, not passive
make test-mpu shows no movementSDA/SCL swapped, or AD0 pulled HIGH — see config note above
Board enters flash-download mode at bootGPIO8 floated LOW — MPU got unplugged
gochi ping doesn't return PONGgochi daemon status — daemon may not be running
Port busy / port already in useSomething else holds the serial port. Run gochi stop to release it (or gochi kill to terminate the daemon). Still busy? Unplug and replug the board, or try a different USB port.