# ESP32 Multi-Track MIDI Breadboard Instrument An embedded polyphonic buzzer synthesizer and OLED visualizer running on a dual-core ESP32 (`ESP-IDF v5.2.2`, FreeRTOS). Melodies are parsed from standard `.mid` files using a Python run-length encoding script (`scripts/midi_to_c.py`) into C struct arrays stored in flash. ## Hardware Pinout | Component | ESP32 GPIO | Notes | | :--- | :--- | :--- | | Passive Buzzer (Melody) | `GPIO 25` | Driven by hardware `LEDC` PWM timer | | Active Buzzer 1 (Kick) | `GPIO 26` | Percussion trigger output | | Active Buzzer 2 (Hi-Hat) | `GPIO 27` | Percussion trigger output | | LED 1 (Kick Indicator) | `GPIO 21` | Active on kick trigger | | LED 2 (Hi-Hat Indicator) | `GPIO 22` | Active on hi-hat trigger | | Rotary Encoder CLK / DT / SW | `GPIO 32 / 33 / 16` | Hardware `PCNT` quadrature decoding; button toggles volume/tempo mode | | Play / Pause Button | `GPIO 13` | Active-low input with internal pull-up | | Next Track Button | `GPIO 14` | Cycles through the 16-track array | | 1.3" SPI OLED (`SH1106`) | `CS: 5, DC: 2, RES: 4, MOSI: 23, SCK: 18` | 128x64 display rendered from Core 0 | ## Software Structure - `main/mmcontroller.c` — FreeRTOS application splitting UI rendering (`oled_visualizer_task` on Core 0) and audio timing (`buzzer_sequence_task` on Core 1). - `scripts/midi_to_c.py` — Python utility (`mido`) that converts MIDI note events into C `SequenceStep` arrays (`{frequency, duration, kick_drum, hi_hat}`). - `images/` — Breadboard wiring and OLED operation photos. ## Building and Flashing ```bash source ~/esp/esp-idf/export.sh idf.py set-target esp32 idf.py build idf.py -p /dev/ttyUSB0 flash monitor ``` To convert a MIDI file into a C array: ```bash python3 scripts/midi_to_c.py scripts/midillis/Alla_Turca/Alla_Turca.mid > track_output.h ```