Hello everyone!
I'm excited to share a project designed to solve a common pain point: playing custom, complex melodies on Arduino or ESP32 boards without the tedious work of manually transcribing sheet music or note frequencies. The manual conversion process is slow and often inaccurate—that's where this tool comes in!
I've developed the MIDI-to-Arduino-Converter, a simple Python script that takes any standard single-track MIDI file and automatically generates the necessary C/C++ arrays (melody_data.h) for the Arduino tone() function.
1.
Finding Your Single-Track MIDI File
The most critical step is the input file! Since the tone() function on Arduino boards is monophonic (it can only play one note at a time), your MIDI file must also be single-track. Polophonic files (multiple instruments or chords) will not convert correctly.
Look for MIDI files specifically labeled as "melody," "lead," or "solo."
| Site | Best For | Tip |
|---|---|---|
| BitMidi | General songs, video game music, classical pieces. | Look for files labeled "Melody" or "Lead." |
| MidiDB | Broad collection spanning various genres. | Crucial: Avoid files over 50KB if you plan to use an Arduino Uno (see hardware section below). |
| The Official Forums | Search the Arduino forums; sometimes users share MIDI files specifically for tone generation. | Always listen to the file first to ensure it’s monophonic and sounds right. |
2.
The Converter Tool (app.py) Explained
The heart of the project is the app.py script. It uses the Python mido library to efficiently parse the MIDI events:
- Note Extraction: It extracts the MIDI note number (0-127) and converts it into the corresponding standard frequency (Hz).
- Timing Calculation: It calculates the precise duration of each note and rest in milliseconds (ms).
- Output Generation: It compiles all this data into two aligned C arrays:
melody[](frequencies) anddurations[].
This output file (melody_data.h) is then ready to be dropped straight into your Arduino IDE project folder.
Step 1: Get the Code and Files
All source code, example sketches, and documentation (including full wiring diagrams) are hosted on my GitHub. Please consider giving the repository a star if you find it useful!
GitHub Repository (Source Code, Sketches, Docs):
https://github.com/VihangaNethmaka/MIDI-To-Arduino-Converter
Quick Usage Steps:
- Prerequisite: Install the Mido library:
pip install mido - Configure: Edit the
MIDI_FILENAMEvariable inapp.pyto match your MIDI file's name. - Generate: Run
python app.py. - Output: Include the generated
melody_data.hin your sketch.
3.
Hardware Setup and Key Differences
The project includes two dedicated sketch files (.ino) designed for optimal performance on each microcontroller, relying on a passive buzzer connected via a protective resistor.
| Board | Pin Used | Code Constant | Important Note |
|---|---|---|---|
| Arduino Uno | Digital Pin 8 | const int BUZZZER_PIN = 8; |
PROGMEM, long or complex songs will quickly max out the available storage. This board is best for short jingles. |
| ESP32 | GPIO Pin 25 | const int BUZZZER_PIN = 25; |
Recommended Board. Although the sketch uses the standard Arduino tone() API, the ESP32's underlying core automatically utilizes the powerful LEDC peripheral for high-precision tone generation, resulting in cleaner audio and no memory issues. |
Safety Reminder: Always use a current-limiting resistor (≈220Ω recommended) in series with your passive piezo buzzer to protect your microcontroller's digital output pin.
Included Files Overview
| File | Description |
|---|---|
app.py |
MIDI to C array converter script. (The Core Tool) |
Uno_Melody_Player.ino |
Dedicated playback sketch for the Arduino Uno. |
ESP32_Melody_Player.ino |
Dedicated playback sketch for the ESP32. |
melody_data.h |
Generated output file containing the note frequency and duration arrays. |
Please try it out! Being able to convert and play your own custom music opens up a ton of possibilities for projects, alarms, and musical displays. Share your feedback, questions, or any cool songs you manage to convert—I’m happy to help troubleshoot!