Turning a MIDI File into Arduino Music with PlatformIO
🎵 Project Overview
In this project, we created a simple workflow to convert a standard .mid
MIDI file into binary note data suitable for playback on an Arduino Mega 2560 using PlatformIO.
The Arduino reads the notes from memory and plays them using the tone()
function on a PWM output pin.
📝 Step 1 — Convert MIDI to Arduino Header File
We used Python with the mido
library to parse MIDI files and extract note_on
events.
These were saved into a header file as an array of [note, duration]
pairs.
✅ Python MIDI Converter Code
import mido
MIDI_FILE = "input.mid"
TICK_DIV = 10 # ms per duration unit
OUTPUT_HEADER = "midi_song.h"
mid = mido.MidiFile(MIDI_FILE)
events = []
for msg in mid:
if not msg.is_meta and msg.type == 'note_on' and msg.velocity > 0:
note = msg.note
duration = int(msg.time * 1000 / TICK_DIV)
duration = max(1, min(duration, 255))
events.append((note, duration))
with open(OUTPUT_HEADER, "w") as f:
f.write("#pragma once\n\n")
f.write("#include <stdint.h> // ✅ This works on all Arduino platforms")
f.write(f"const uint16_t SONG_LENGTH = {{len(events)}};\n")
f.write("const uint8_t songData[][2] = {\n")
for note, duration in events:
f.write(f" {{{note}, {duration}}},\n")
f.write("};\n")
print(f"Generated {{OUTPUT_HEADER}} with {{len(events)}} notes.")
🛠️ Step 2 — Play the Notes with Arduino Code
This Arduino code reads the generated header file and plays each note using tone()
.
We used PlatformIO with the Arduino Mega 2560.
✅ Arduino Sketch Example
#include "midi_song.h"
const uint8_t speakerPin = 8;
uint16_t midiNoteToFreq(uint8_t note) {
return 440 * pow(2, (note - 69) / 12.0);
}
void setup() {
pinMode(speakerPin, OUTPUT);
Serial.begin(115200);
Serial.println("Starting MIDI Playback");
}
void loop() {
for (uint16_t i = 0; i < SONG_LENGTH; i++) {
uint8_t note = songData[i][0];
uint8_t duration = songData[i][1];
Serial.print("Note: "); Serial.print(note);
Serial.print(" Duration: "); Serial.println(duration);
if (note > 0) tone(speakerPin, midiNoteToFreq(note));
delay(duration * 10);
noTone(speakerPin);
}
delay(1000); // Pause before repeating the song
}
✅ Final Thoughts
This project gave us a simple way to turn a standard MIDI file into an embedded music box running on an Arduino Mega.
Using PlatformIO allowed for better workflow and serial debugging, and the Python script made conversion fast and repeatable.
Happy hacking!