<- Back

Try it yourself: Für Elise on your own ESP and motor

Hi! The long log explains how and why a DC motor can play Beethoven - the physics, the maths, the heat. This page is just the doing. Wire three things, click a button in this browser tab, type two lines. About five minutes. ♥️

What you need

  1. An ESP32 board - any of them. The original ESP32, S2, S3, C2, C3, C5, C6, C61, H2 or P4. The firmware leans on the LEDC peripheral, which every ESP32-family chip has, so there is a build for each one.
  2. An H-bridge motor driver - DRV8833, TB6612FNG, L9110S, L298N. Anything with two input pins per motor.
  3. A small brushed DC motor - N20, TT gearmotor, an old toy motor, a fan motor. It does not need to be a good one.
  4. Chrome or Edge, on a desktop. The flashing happens over Web Serial, which Firefox and Safari do not have, and phones cannot do at all.

Plus a motor supply. A USB power bank, a 5 V wall adapter, 4×AA - whatever your motor is happy with. Do not power the motor from the ESP’s 3V3 pin.

Step 1 - Wire it

Three wires from the ESP to the driver, two from the driver to the motor, and the motor’s own power into the driver:

ESP32 board any variant GPIO 4 → IN1 GPIO 5 → IN2 GND → GND H-bridge DRV8833 / TB6612 / ... VM ← motor supply (NOT the ESP's 3V3) OUT1 OUT2 motor On the DRV8833, nSLEEP must be pulled high or the driver stays asleep. Grounds must be common: the ESP's GND and the motor supply's GND tied together.

GPIO 4 and 5 are only the defaults - you can change them after flashing, so use whatever pins your board has free. Avoid the strapping pins (GPIO 0, 45, 46 on an S3) and anything wired to onboard flash or PSRAM.

Step 2 - Flash it

Plug the board in, then click the button that matches it.

The quick rule, which is right nearly every time:

Or pick by looking at the board:

A · There is a bridge chip
A small chip beside the USB socket marked CP2102, CH340 or FT232. Or, on a two-socket board, the one labelled UART / COM. Every original ESP32 and ESP32-S2 devkit is this.
Your browser cannot flash. Use Chrome or Edge on a desktop. Flashing needs an https page.
B · USB goes straight to the chip
One USB socket and no bridge chip next to it. Or, on a two-socket board, the one labelled USB. Most single-port S3 / C3 / C6 devkits are this.
Your browser cannot flash. Use Chrome or Edge on a desktop. Flashing needs an https page.

A port-picker appears - choose your board and let it run. It takes a minute or so and it detects which chip you have on its own.

If you are not sure which variant, just pick one. Flashing works either way; only the console differs. If you end up with a serial port that connects but never prints anything, that is the symptom of the wrong variant - come back and click the other button. Nothing is harmed by flashing twice.

Rather not flash from a browser? (manual download)

Every image is a single file that flashes at offset 0:

esptool.py --chip auto --port COM5 write_flash 0x0 fur-elise-esp32s3-usb.bin

Files are at /files/firmware/fur-elise/, named fur-elise-<chip>-<variant>.bin.

<chip> is one of esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c5, esp32c6, esp32c61, esp32h2, esp32p4.

<variant> is uart or usb. Only chips with a native USB-Serial-JTAG peripheral have a usb build - the original ESP32, the S2 and the C2 are UART only, because they have no such peripheral to put a console on.

If you have one of the newer chips (C5, C61, H2, P4) the browser flasher may not recognise it yet - the buttons above depend on what ESP Web Tools supports, which trails the silicon. This manual route always works.

Step 3 - Open the console

When flashing finishes, click Logs & Console in the same dialog. (Or use any serial terminal at 115200 baud - PuTTY, screen, the Arduino IDE’s serial monitor, whatever you have.)

Press Enter and you should get a prompt:

furelise>

If you see the prompt, everything worked.

Two symptoms both mean “wrong variant” - go back to step 2 and click the other button:

Step 4 - Tell it your pins, then play

set in1 4
set in2 5
save
play

That is the whole thing. save writes the pins to flash so the board remembers them next time. Use stop to stop it.

If you wired to different GPIOs, put those numbers in instead. show prints everything the firmware knows.

Before you turn it up

The motor is stalled the entire time it plays. It is not spinning, so there is no back-EMF limiting the current and no rotation moving air over the winding. The amplitude setting is a current limit before it is a volume control, and the heat grows as its square - doubling it quadruples the dissipation.

It ships at a deliberately quiet 96 out of 255. Raise it in steps if you want more:

set amplitude 140

The test that matters: touch the motor after a couple of playthroughs. Warm is fine. If you cannot hold a finger on it for five seconds, turn it back down. The firmware also stops for a one-minute rest after two minutes of playing, which you can disable but really should not.

The full reasoning, with the numbers, is part 9 of the long log.

Making it louder - the free way first

Clamp the motor to something large and thin. A biscuit tin, a project box lid, a sheet of cardboard, the underside of your desk. A bare motor is a voice coil with no cone, and giving it one is by far the biggest improvement available - bigger than any setting.

Then hunt the resonance:

sweep

It walks a chromatic scale from 100 Hz to 1600 Hz and prints each frequency. Listen for where it suddenly leaps out, then move the piece there:

set transpose 12

Small motors are usually deaf below about 200 Hz, so transpose 12 (up one octave) helps almost every setup. Do the sweep after mounting - the mount is half of what sets the resonances.

Want it to spin while it plays?

set spin 100

The shaft turns and the tune keeps going. Sign picks the direction, range is −255 to 255. Around 100 gets you about 39% of full speed while keeping 82% of the volume - the maths for why that trade is so generous is in part 8 of the long log.

If something goes wrong

What you see Why Fix
No port in the browser dialog Charge-only cable, or missing driver Use a data cable. For CP2102/CH340 boards, install the bridge driver
Port connects, nothing prints Wrong console variant Flash the other button in step 2
Text prints but typing does nothing Wrong console variant - it can print to one port while listening on the other Flash the other button in step 2
Flashing fails partway Board not in bootloader Hold BOOT, tap RESET, release BOOT, retry
Prompt works, no sound at all Pins, sleep pin, or motor supply Check show, check nSLEEP is high, check VM has power
Motor spins instead of buzzing spin is not zero set spin 0
Very faint Not mounted, or too quiet Clamp it to something big; raise amplitude in steps
Board resets when it plays Motor supply browning out the ESP Separate supply for VM, grounds still common
Sound is there but wrong pitch Nothing - that is your motor Try set transpose 12, and run sweep

Commands

Command Does
play / stop Start and stop the piece
show Print state and every setting
set <name> <value> Change one setting
save Keep the current settings across reboots
defaults Back to factory settings
sweep Chromatic sweep for finding resonances
help List everything
Setting Default Does
in1 / in2 4 / 5 H-bridge input GPIOs
amplitude 96 Loudness and heat. Read the warning above
spin 0 Rotate while playing, −255…255
spinmode antiphase antiphase louder, unipolar cooler
transpose 0 Semitones; 12 is up an octave
tempo 140 Milliseconds per sixteenth note
gap 18 Silence between notes
pause 2500 Silence between repeats
once 0 1 plays through once and stops
guardplay / guardrest 120 / 60 The forced cooling rest, in seconds

And then read why it works

None of the above explains anything - it just gets a motor playing Beethoven. If you want to know why a motor can make a musical note at all, why the obvious way to do it makes the motor drive off with the tune, and how you get it to spin and sing at the same time:

Für Elise on a DC motor: the N20 learns to sing

That one has the physics, the Fourier maths, and an honest accounting of what this does to your motor.

If you get it playing, I would genuinely love to hear it. Send me a video on instagram. ♥️