Build a USB-MIDI Controller with Arduino: Buttons, Encoders, and Faders
Software instruments and DAW mixing both go faster with physical knobs and faders instead of dragging on-screen sliders with a mouse. Commercial MIDI controllers are inexpensive, but a custom one lets you match the exact layout your workflow needs — the right number of faders for your mix bus, encoders mapped to the plugin parameters you actually reach for, and a panel laid out and labeled for your own hands. This project builds a genuine class-compliant USB-MIDI controller that shows up in any DAW with no drivers, using an Arduino Pro Micro's native USB capability.
Why the Pro Micro (and Not a Full Uno)
The Arduino Pro Micro is built around the ATmega32U4, which has native USB hardware built into the chip itself — the same reason it's the standard low-cost choice for keyboard and mouse HID projects. That native USB is what lets it present itself as a real MIDI device without needing an external USB-to-serial bridge or a computer-side driver. A standard Uno, built around the ATmega328P, has no native USB and can't do this trick without extra hardware. If you'd rather work with an ESP32-S3 instead (also native USB, plus WiFi/BLE for potential BLE-MIDI later), the same wiring and firmware concepts apply with minor library differences.
Planning Your Layout
Before wiring anything, sketch your control layout and assign each control a MIDI Control Change (CC) number. This project builds a general-purpose layout — 8 buttons, 2 encoders, and 4 faders — but the same wiring pattern scales up or down.
ControlCountSuggested MIDI Message Momentary buttons8Note On/Off or CC toggle, channel 1 Rotary encoders2Relative CC (increment/decrement), channel 1 Sliders/faders4Absolute CC 0-127, channel 1Circuit Design
Buttons: wire each button between a digital pin and ground, using the Pro Micro's internal pull-up resistors (INPUT_PULLUP) so you don't need external resistors — a pressed button reads LOW. With 8 buttons and limited pins, either wire each to its own digital pin directly (simplest, uses more pins) or build a simple row/column button matrix if you need to scale beyond the Pro Micro's available I/O.
Rotary encoders: the KY-040 module has CLK, DT, and SW (push-button) outputs. Wire CLK and DT to two digital pins each (interrupt-capable pins make reading more reliable at speed) and SW to a third pin with pull-up enabled, same as the buttons.
Faders and potentiometers: wire each as a simple voltage divider — outer legs to 5V and GND, wiper to an analog input pin. The Pro Micro's analog pins read 0-1023, which you'll map down to MIDI's 0-127 range in firmware.
Firmware
Install the MIDIUSB library via the Arduino Library Manager — it handles the low-level USB-MIDI packet formatting so your sketch just calls simple functions to send notes and control changes.
- For each button, read its pin state and send a controlChange (or noteOn/noteOff) message only on a state change — not every loop iteration, which would flood the MIDI stream.
- For each encoder, track the previous CLK/DT state and compare against the current reading each loop to determine direction; send an incrementing or decrementing relative CC value accordingly.
- For each fader/pot, read the analog value, apply map() to scale 0-1023 down to 0-127, and only send a CC message when the mapped value actually changes from the last sent value — this avoids saturating the USB-MIDI connection with noise from ADC jitter on a fader that isn't moving.
- Call MidiUSB.flush() after queuing messages each loop to actually transmit them.
Debounce buttons and encoder reads in software (a simple 5-10ms time-based debounce is sufficient) — without it, a single physical press can register as several rapid note or CC toggles.
Enclosure
Lay out your control panel in your CAD tool of choice sized to your enclosure, with mounting holes for your specific buttons, encoders, and fader travel slots. A laser-cut panel (acrylic or plywood, cut on the Ray5 20W) is the fastest path to a clean layout with laser-engraved labels next to each control; a 3D-printed panel on the Kobra 3 gives you more flexibility for recessed mounting and integrated standoffs if you're not set up for laser cutting. Either way, dry-fit every component in the panel before final assembly — potentiometer shaft diameters and encoder mounting hole sizes vary between suppliers even for "standard" parts.
Wiring and Assembly
- Mount all components in the panel first, then wire from component to component on the bench before closing the enclosure — it's far easier to fix a wiring mistake with the panel open.
- Group wiring into ribbons or bundles by control type (all button grounds together, etc.) and use heat shrink over solder joints to prevent shorts inside a crowded enclosure.
- Mount the Pro Micro on standoffs or a small sub-plate with its USB port accessible through a cutout in the enclosure wall.
- Route a strain-relief loop in the USB cable where it enters the enclosure so cable flexing doesn't stress the solder joints on the board.
Testing and Calibration
Use a MIDI monitor utility (many free options exist for every OS) to confirm each control sends the expected CC number and a clean, non-jittery value range before wiring it into your DAW. Faders that show value "flicker" at rest usually need either a small amount of software hysteresis (ignore changes smaller than 2-3 units) or a cleaner ground connection. Once confirmed, map each CC number to the DAW or plugin parameters you actually want to control — this mapping step lives in your DAW's MIDI learn function, not in the controller's firmware.
Safety
This is a low-voltage USB project with no unusual hazards beyond standard soldering practice — use a fume extractor or good ventilation at the bench, and let the iron cool in its stand rather than resting it on the work surface.
Once the core firmware pattern is working, it scales easily — add more buttons through a matrix, add RGB backlighting to buttons for state feedback, or move to an ESP32-S3 if you want BLE-MIDI for a wireless controller. The wiring and MIDI message concepts here carry over directly to any of those upgrades.
Related Guides
- Rotary Encoders for Makers: Incremental vs Absolute, Debouncing, and Reading with Arduino/ESP32
- Potentiometers and Trimmers for Makers: Types, Tapers, Wiring, and Pots vs Encoders
- How to Program Addressable LED Strips: WS2812B Patterns, Effects, and Power Design
- How to Use the ESP32-CAM: Video Streaming, Motion Detection, and Time-Lapse
- I2C vs SPI vs UART: How to Choose and Use Serial Communication Protocols
- How to Use Sensors with Arduino and ESP32: Temperature, Distance, Load, Current, and Hall Effect
- How to Control Motors with Arduino and ESP32: Stepper, DC, and Servo Drivers
- ESP32: Setting Up for Arduino IDE