How motor music works
Every modern brushless ESC running BLHeli-style firmware can chirp tones through its motor before arming. It is a fun side-effect of how brushless motor commutation works and a clever piece of firmware engineering. This page explains what is going on at three different levels: the physics of turning a motor into a speaker, the RTTTL byte format the firmware actually stores, and the polyphony scheduling beepmyquad does to spread a complex MIDI score across multiple motors.
1. A brushless motor is a (terrible) loudspeaker
A brushless DC motor has three stator phases (U, V, W) wound around a soft-iron stator core. To make the rotor spin the ESC switches each phase between +V and ground in a precise six-step or sinusoidal commutation pattern, usually at PWM frequencies between 24 kHz and 48 kHz. The magnetic field these switches create rotates and drags the permanent-magnet rotor with it.
A loudspeaker works on the same physics in reverse: a coil of wire in a magnetic field, driven by a varying current, exerts a force on a diaphragm and pushes air. So if you drive the motor's coils with an audio-frequency signal instead of a commutation signal, the stator laminations vibrate at the same frequency. The motor frame radiates that vibration as a faint but clearly audible tone — typically somewhere between 200 Hz and 4 kHz, which conveniently is the heart of the human speech range.
The trick that makes ESC music possible is that the firmware can produce these audio-frequency switching patterns without actually energising the motor enough to rotate. The PWM duty cycle is low and the switching pattern is symmetric, so the average torque is zero, the rotor stays still, and you hear a tone instead of seeing a spin-up.
Some quick consequences of this physics:
- Bigger motors are louder. A 2207 produces more sound than a 1404.
- The tonal character depends on the motor's mechanical resonance. A stiff, well-built motor sounds clean; a loose bell sounds buzzy.
- Carbon-fibre frames couple the vibration well and act as soundboards. Plastic frames damp it. A 5-inch freestyle quad sounds noticeably louder than a Tinywhoop in a sealed plastic shell.
- Each ESC drives one motor, so each ESC plays one voice at a time. A standard quad has four motors → four-part harmony. A hexacopter does six voices, an octocopter eight.
- The playable note range is constrained on both ends. Below ~100 Hz the motor barely moves; above ~4 kHz the inductance of the windings limits how fast the current can rise and fall.
2. RTTTL: a 1990s ringtone format that found a second life
RTTTL stands for Ring Tone Text Transfer Language. Nokia introduced it in 1996 so users could share monophonic ringtones over SMS without needing a binary file format. A complete tune fits on one line and looks like this:
tetris:d=4,o=5,b=140:e6,8b,8c6,8d6,16e6,16d6,8c6,8b,a,8a,8c6,e6,8d6,8c6,b,8b,8c6,d6,e6,c6,a,a,8p
It has three colon-separated parts:
- Name — up to ten ASCII characters. Used by the firmware (and configurators) to display which tune is loaded.
- Defaults — comma-separated
key=valuepairs.dis the default note duration (1, 2, 4, 8, 16, 32 — same convention as music notation),ois the default octave (4–7),bis the tempo in beats per minute. - Notes — comma-separated tokens. Each token is
[duration]note[#][.][octave]: an optional duration override, the note letter (a–gorpfor pause), an optional sharp, an optional dot for dotted note, and an optional octave override.
Bluejay (and most BLHeli-style firmwares) accept RTTTL via the configurator's "Melody Editor". Internally the firmware parses the string into a packed byte array:
byte 0–3 : RTTTL defaults (duration, octave, tempo, flags) byte 4–127 : up to 62 (frequency, duration) pairs
The frequency byte is an index into a lookup table that covers roughly four octaves at semitone resolution. The duration byte counts firmware timer ticks. Together they pack one note into two bytes, which is why beepmyquad caps each output at 62 notes by default — that's exactly what fits in Bluejay's 128-byte slot after the header.
3. From polyphonic MIDI to multi-motor RTTTL
MIDI files are inherently polyphonic. A single track can contain ten notes playing at the same time; a typical Western pop song has 4–8 tracks each with their own simultaneous notes. Each ESC, however, plays only one note at a time. beepmyquad's job is to take a polyphonic score and squeeze it onto N monophonic motor lanes.
The algorithm runs in two phases.
Phase 1: pinned notes
If you have manually pinned any notes to a specific motor via the editor, those notes are placed first. They always win their slot — if two pinned notes overlap on the same motor, the most recently pinned one keeps the slot and the other is deactivated. This is sorted by a per-note pin sequence number so "newest pin wins" is consistent.
Phase 2: greedy interval scheduling
Remaining notes are walked through in time order (ties broken by descending pitch). For each note we look at which motor lanes currently have no overlapping note at this time and pitch:
- If at least one lane is free, pick it. If "track-to-motor affinity" is on, prefer the lane that last played a note from the same MIDI track. This keeps a melody line on the same motor instead of bouncing around the frame.
- If no lane is free, look at the overlapping notes already placed. If any of them is lower in pitch than the current note, evict the lowest one and steal its slot. The evicted note is dropped (it shows in the editor as "muted dropped").
- If all overlapping notes are higher pitch than the current one, drop the current note instead.
The result is up to N parallel monophonic streams, each emitted as its own RTTTL string via a quantisation pass: each note's duration is snapped to the nearest valid RTTTL duration (whole, half, quarter, eighth, sixteenth, thirty-second), optionally with a dot for dotted notes; each pitch is mapped to its octave; rests bridge the gaps. The 24-bit header (default duration + octave + tempo + name) is shared across all motors.
4. Why songs sound the way they do
Three predictable artefacts you'll hear once you start running this in real life:
- Vibrato from motor mechanical resonance. Each motor has a few prominent resonant frequencies. Notes near those frequencies sound noticeably louder and richer; notes far from resonance sound thin.
- Octave clamping. MIDI files written for orchestra or piano often contain notes below the playable range. Without an octave shift, those notes get clamped to the nearest playable octave, which is what produces the "wrong-octave" jumps you sometimes hear.
- Voice stealing. When a busy chord exceeds the motor count, the scheduler drops the lowest pitches. So a four-note chord on a quadcopter sounds intact, but a six-note chord loses its bottom two notes.
5. The 128-byte budget in practice
62 notes is more than you'd think — most recognisable hooks fit comfortably. Some examples we've measured from the curated song library:
- The Star Wars main theme fanfare: 28 notes per motor across 4 motors.
- Tetris (Korobeiniki, first 8 bars): 24 notes lead + 18 notes bass = fits on two motors.
- Mario Bros. main theme (first 4 bars): 26 notes lead + 22 notes bass on two motors.
- Imperial March: 18 notes per motor on three motors for a three-part harmony.
Practical tip: keep your dotted notes for the bass line. The header's
d=4 default duration matches most quarter-note hooks, which means quarter
notes encode as a single character instead of three (just c instead of
4c5). Each saved character is a saved byte.
6. Going further
If you found this interesting, useful jumping-off points:
- Bluejay firmware on GitHub — the open-source ESC firmware that started the modern motor-music era.
- bluejay-rtttl-parse — the JavaScript library that converts between RTTTL strings and Bluejay's binary 128-byte representation.
- esc-configurator.com — open-source web app that flashes Bluejay / BLHeli_S / AM32 over USB and writes melodies to your ESCs.
- The original RTTTL spec, written by Nokia in 1998 — easy to find via web search; the format is genuinely tiny and self-explanatory.
Ready to try it? Open the converter, drop in a MIDI, hit Convert, and see your motors sing.