The Maker’s Companion to the PO-33 ESP32-S3 Firmware

A study guide for Make: Electronic Music from Scratch × Ravine: Phoenix

Audience: complete novices. Every technical term is defined the first time it appears. If you’ve never written a line of code or soldered a single joint, you are the intended reader.

How to use this book. Each chapter pairs one chapter of Kirk Pearson’s Make: Electronic Music from Scratch (Dogbotic, 2024) with one slice of our PO-33 firmware. The first half of each chapter is a friendly recap of Pearson’s chapter in plain language. The second half shows you how to make our firmware do the same thing — usually in a UART shell session, since that’s how a headless developer tests the firmware. There are no math prerequisites and no C-code-reading prerequisites; the few lines of code we do quote are heavily commented.


Table of contents

  1. How to use this book
  2. Setup: from zero to a beeping ESP32 in fifteen minutes
  3. Companion to Pearson Chapter 1 — A People’s History of Electronic Music
  4. Companion to Pearson Chapter 2 — Musical Electricity for Electrophobes
  5. Companion to Pearson Chapter 3 — The Hello World Oscillator
  6. Companion to Pearson Chapter 4 — Amps, Reverbs, and Talkboxes
  7. Companion to Pearson Chapter 5 — Soldering, Enclosures, and UI
  8. Companion to Pearson Chapter 6 — Chaining Oscillators
  9. Companion to Pearson Chapter 7 — Schematics and Mass Transit
  10. Companion to Pearson Chapter 8 — Filters
  11. Companion to Pearson Chapter 9 — Harmonization
  12. Companion to Pearson Chapter 10 — Modulation
  13. Companion to Pearson Chapter 11 — Sequencers
  14. Companion to Pearson Chapter 12 — Electronic Percussion
  15. Companion to Pearson Chapter 13 — Phase-Locked Loops
  16. Companion to Pearson Chapter 14 — The Dogbotophone MK1
  17. Companion to Pearson Chapter 15 — Thoughts on Automation
  18. Companion to the Appendices
  19. Glossary
  20. Index

How to use this book

This book assumes you have either:

  • a flashed ESP32-S3 board with our firmware running, or
  • a copy of the firmware source you can build and flash yourself.

If neither is true yet, jump straight to the Setup chapter below. It walks you through getting a board talking to your computer over USB.

Once you’re set up, you have two reasonable ways to read this book:

  • Sequential, in lock-step with Pearson. Read Pearson chapter N, then our chapter N. The two are designed to be read together; the conceptual debt from one chapter is paid by the next.
  • Topical, dipping in as you need it. If you already know Pearson and just want to see how a particular concept maps to our firmware, the Glossary lists every concept Pearson introduces and points to the chapter of ours that explains the digital equivalent.

There are three kinds of paragraphs in this book, and they’re marked so you can skip the parts that don’t interest you:

  • 🎓 Background. Conceptual explanation. Read these if you’re new to the topic. Skip them if you’ve already read Pearson.
  • 🔧 Try it. A concrete exercise using the UART shell on the ESP32. These are short — usually under five commands — and they’re the most valuable part of the book. Do them, even if you read nothing else.
  • 🛠 Code reference. A small pointer into our firmware source. These exist so an engineer reading this book can find the implementation quickly. Skip them if you’re not an engineer.

A note about honesty: this book is not a marketing document. Where our firmware can simulate a Pearson project, we’ll show you. Where it can’t, we’ll tell you and link to the relevant section of our design document so you know why.


Setup

This chapter assumes you’ve never touched an ESP32 before. If you have, skim to the Quick start at the end.

What you’ll need

  1. An ESP32-S3-WROOM-1-N16R8 dev board. This is the specific variant we support. It has 16 MB of flash and 8 MB of PSRAM, both of which we need. The board costs about $5 from any major electronics supplier (Mouser, Digikey, AliExpress). Look for the words “WROOM-1-N16R8” silkscreened on the metal shield on the back of the module.
  2. A USB-C cable. The board uses USB-C for both power and serial communication. Any data cable will do; some charge-only cables will silently fail to enumerate as a serial device, so try a different cable if you can’t connect.
  3. A computer with a serial terminal. Any of:
    • Linux or macOS: minicom, screen, or just cat over /dev/ttyUSB0 (Linux) or /dev/tty.usbserial-* (macOS).
    • Windows: PuTTY, Tera Term, or the built-in Windows Terminal.
    • Browser-based: the one-click web flasher on ravine.1une.cc can open a serial terminal in your browser. This is the easiest option.
  4. (Optional) Headphones or an external speaker. The ESP32-S3 dev board has no built-in speaker; the firmware outputs audio via the I²S pins. Our hardware guide (hardware/HARDWARE.md) shows how to wire a $2 PCM5102A DAC chip to the board and connect it to a 3.5 mm jack.

If you bought a fully assembled Ravine: Phoenix device rather than building your own, you can skip the hardware steps entirely. The firmware already works on the off-the-shelf hardware.

Plug it in

  1. Plug the USB-C cable into the board and your computer.
  2. If a red or blue LED lights up on the board, congratulations — the power section is working. If nothing lights up, try a different cable or USB port.
  3. The board will enumerate as a serial device. The exact name depends on your operating system:
    • Linux: /dev/ttyUSB0 or /dev/ttyACM0. You may need to add yourself to the dialout group: sudo usermod -a -G dialout $USER and then log out and back in.
    • macOS: /dev/tty.usbserial-*. No driver install needed.
    • Windows: COM3, COM4, etc. You may need to install the Silicon Labs CP210x driver from silabs.com/developers/usb-to-uart-bridge-vcp-drivers.

Open a serial terminal

Set your terminal to 115 200 baud, 8 data bits, no parity, 1 stop bit (115200-8-N-1). No flow control. No line ending translation.

In minicom:

minicom -D /dev/ttyUSB0 -b 115200

In screen:

screen /dev/ttyUSB0 115200

In cat (read-only — for testing):

cat /dev/ttyUSB0

Press the reset button on the board (or send Ctrl+T Ctrl+R via the ESP-IDF monitor, if you’re using idf.py monitor). You should see something like this scroll by:

I (312) boot:  ESP-IDF v6.1.2 2nd stage bootloader
I (421) cpu_start: Pro cpu start user code
...
I (1024) main: Ravine: Phoenix PO-33 firmware v0.6.0 starting.
I (1025) amy: AMY 1.0 ready.
I (1026) main: >

The > is the shell prompt. You are now talking to the firmware. Type help and press Enter:

> help

The firmware prints a list of every shell command it understands. There are about 30. This book will only use a handful of them, and we’ll introduce each one the first time we need it.

Quick start

If you already have a flashed board and a working serial connection:

  1. Type help and read the output.
  2. Type status to see what the firmware currently knows about (active pattern, BPM, slot count, etc.).
  3. Type play to start the empty pattern. Type stop to stop it.
  4. You’re ready to begin Chapter 1.

Your work is auto-saved: every 5 minutes of inactivity (and on the sleep UART verb) the firmware writes the active sketch’s patterns + chain + samples to flash. The next boot brings them back automatically — the device is “where you left it”. The explicit save / load verbs and sketch new / sketch load <id> are belt-and-braces; you don’t need to think about saving.

If anything goes wrong, the firmware has a panic log printed to the serial port. Copy-pasting the last 30 lines into a search engine or a GitHub issue is almost always enough to diagnose the problem.

The shell verbs this book uses

Here’s the cheat sheet for every UART command this book will use. We introduce them one at a time in the chapters where they matter, but if you skim ahead, this table tells you what’s available.

Verb Args What it does Pearson analog
play (none) Start the active pattern Chapter 11 sequencers
stop (none) Stop playback Chapter 11
record_mic <slot> <seconds> Record from the I²S mic into a slot Chapter 2 (speaker as mic)
slot_play <slot> Play a recorded slot Chapter 11 (sequencer steps)
slot_clear <slot> Erase a slot, free the audio buffer Chapter 12 (drum sample delete)
slot_copy <dst> <src> Copy a slot’s audio into another slot Chapter 4 (amp + reverb = layered sample)
slot_info (none) List all slots: empty vs recorded, length in ms Chapter 5 (UI: see what you have)
pattern_info (none) Show the active pattern’s 16 steps Chapter 11 (sequencer readout)
pattern_copy <dst> <src> Copy one pattern into another slot Chapter 14 (Dogbotophone “pattern-changing sequencer”)
chain_show (none) Print the chain (which patterns play in order) Chapter 11 (sequencer)
chain_append <pattern> Add a pattern to the end of the chain Chapter 11
chain_swap <i> <j> Swap two entries in the chain Chapter 11 (live re-order)
chain_insert <at> <pattern> Insert a pattern into the chain at a given index Chapter 11
chain_remove <i> Remove a chain entry Chapter 11
chain_clear (none) Wipe the entire chain Chapter 11
bpm <value> Set the sequencer tempo (60–240) Chapter 11 (clock)
fx <name> Pick the next-step effect (e.g. LOOP_16, STUTTER_4) Chapter 6 (vactrol arpeggiator), Chapter 10 (modulation)
tweak_filter <cutoff> <resonance> Apply a low-pass filter on the next triggered note (knob units, 0–255) Chapter 8 (filters)
note <slot> <midi_note> Play a slot at a specific pitch (MIDI note number, 0–127) Chapter 9 (octave harmonizer)
alarm_set <HH> <MM> <slot> Schedule a sample to fire at a wall-clock time Chapter 6 (timing circuits), bonus feature
sync_in_toggle (none) Toggle whether incoming sync pulses drive the sequencer Chapter 13 (PLL — same idea, different medium)
save (none) Belt-and-braces: write the active sketch to flash (auto-save already covers this) “Chapter 0”
load (none) Belt-and-braces: re-read the active sketch from flash (boot already did this) “Chapter 0”
sketch list (none) List every saved sketch with its 4-hex id “Chapter 0”
sketch new (none) Save the active sketch under a new 4-hex id (becomes the new active sketch) “Chapter 0”
sketch load <4-hex id> Load a saved sketch into PSRAM; future boots land here “Chapter 0”
sketch del <4-hex id> Delete a sketch from flash (samples are in PSRAM only) “Chapter 0”
status (none) Dump everything the firmware knows “Chapter 0”

Two of these verbs — fx and tweak_filter — are the most-used in this book. They directly correspond to Pearson’s chapters 6, 8, 10, and 12.