Arduino MIDI Synth (In Progress)

Arduino MIDI Synth (In Progress)

Arduino MIDI Synth (In Progress)

This projects uses the MIDI protocol to send musical notes via USB-HID connection to a computer, where it can be used to play virtual instruments.

The project is in progress and will be updated as it progresses.

Publication : 09 nov 2018


This projects uses the MIDI protocol to send musical notes via USB-HID connection to a computer, where it can be used to play virtual instruments.


  • Arduino Micro
  • 74HC165N
  • Push Buttons
  • Resistors: 1 kΩ
  • Breadboard
  • Wires
  • USB cable

Arduino Micro

The Micro is a microcontroller board based on the ATmega32U4, developed in conjunction with Adafruit. It has 20 digital input/output pins (of which 7 can be used as PWM outputs and 12 as analog inputs), a 16 MHz crystal oscillator, a micro USB connection, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a micro USB cable to get started. It has a form factor that enables it to be easily placed on a breadboard. The Micro board is similar to the Arduino Leonardo in that the ATmega32U4 has built-in USB communication, eliminating the need for a secondary processor. This allows the Micro to appear to a connected computer as a mouse and keyboard, in addition to a virtual (CDC) serial / COM port.


Serial Connection

According to the documentation for the official Arduino Pro Micro:

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data using the ATmega32U4 hardware serial capability. Note that on the Micro, the Serial class refers to USB (CDC) communication; for TTL serial on pins 0 and 1, use the Serial1 class.

Therefore, to send the data over the TTL serial connection via digital pins 0 and 1, we should use the following commands:

void setup(){ 

void loop(){ 

This will be relevant in the later section, when we will send native MIDI commands via serial connection directly to a hardware MIDI instrument.


The SN74HC165N is an 8-bit parallel-load or serial-in shift registers with complementary serial outputs available from the last stage. When the parallel load (PL) input is LOW, parallel data from the D0 to D7 inputs are loaded into the register asynchronously. When PL is HIGH, data enters the register serially at the Ds input and shifts one place to the right (Q0 → Q1 → Q2, etc.) with each positive-going clock transition. This feature allows parallel-to-serial converter expansion by tying the Q7 output to the DS input of the succeeding stage. Source:

To provide a maximum of 32 inputs (synth keys), 4 shift registers will be used, connected in a serial chain. The connections are the same as in the photo below except the number of shift registers. The output from the first stage is connected to the serial input of the next stage and the output of the last stage is connected to the Arduino. In this example, 13 push buttons will be used to represent all the notes with an addition of the octave (12 semitones + 1 octave).

Board Layout

The board was tested using the Arduino sketch found on the shift-register Arduino tutorial page (link above) and was confirmed working.


MIDI Serial:


MIDI note names -> note values

MIDI serial output

MIDI Synth V1 Arduino sketch (MIDI USB only)

// include MIDI library
#include "MIDIUSB.h"
#include "PitchToNote.h"

void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};

void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};

// How many shift register chips are daisy-chained.

// Width of data (how many ext lines).

// Width of pulse to trigger the shift register to read and latch.

// Optional delay between shift register reads.

#define BYTES_VAL_T unsigned long // was int before!!

long ploadPin = 8; // Connects to Parallel load pin the 165
long clockEnablePin = 9; // Connects to Clock Enable pin the 165
long dataPin = 11; // Connects to the Q7 pin the 165
long clockPin = 12; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
* serial Data from the shift register chips and representing
* the state of those pins in an unsigned integer (or long).
BYTES_VAL_T read_shift_regs()
long bitVal;
BYTES_VAL_T bytesVal = 0;

// Trigger a parallel Load to latch the state of the data lines,
digitalWrite(clockEnablePin, HIGH);
digitalWrite(ploadPin, LOW);
digitalWrite(ploadPin, HIGH);
digitalWrite(clockEnablePin, LOW);

// Loop to read each bit value from the serial out line
// of the SN74HC165N.
for(int i = 0; i < DATA_WIDTH; i++)
bitVal = digitalRead(dataPin);

// Set the corresponding bit in bytesVal.
bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

// Pulse the Clock (rising edge shifts the next bit).
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);


void setup()

// Initialize our digital pins...
pinMode(ploadPin, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);

digitalWrite(clockPin, LOW);
digitalWrite(ploadPin, HIGH);

// Read in and display the pin states at startup.
pinValues = read_shift_regs();
oldPinValues = pinValues;

void loop()
// Read the state of all zones.
pinValues = read_shift_regs();

// If there was a chage in state, display which ones changed.
if(pinValues != oldPinValues)
for(int i = 0; i < DATA_WIDTH; i++){

int old = bitRead(oldPinValues, i);
int nou = bitRead(pinValues, i);

if(nou > old){
noteOn(0, 48+i+12, 64);
else if(nou < old){
noteOff(0, 48+i+12, 64);

oldPinValues = pinValues;

Egalement dans cette section


Design - Fabrication
Conçu et fabriqué par:
Tomi Murovec
FabLab Manager - UBO Open Factory



DI-Box (Direct Input Box)

A DI-Box is a device usually used between a musical instrument and a mixing desk/console.

Its main role is to transform an asymmetric input signal of high impedance (e.g. from a guitar pickup) to a symmetric signal of low (or medium) impedance.



Spatialiseur Binaural

L'objectif de ce projet est de créer à la fois un programme permettant placer une source sonore dans un espace tridimensionnel et un contrôleur permettant d'avoir une commande manuelle sur ce programme.

Le projet a été créé par Yannick Magnin pour son stage à UBO Open Factory.

Le documentation du projet (en PDF) peut être télécharge sur le lien sur cette page.



Arduino Media Keys

In this project, an Arduino Micro is used as a USB-HID (Human Interface Device). The same standard is used for computer devices that take input from humans and/or gives output to humans, such as a computer keyboard, mouse or joystick.




Entourloop is an audio looper for raspberry pi, autonome, easy to use and to rebuilt. It works thanks to : PureData patch, working with sync audio loops Python program, reading serial from Arduino extra web UI, which allows people to easily understand what is going on into the looper, and interact without the hardware.




Ce projet a été lancé pour démontrer que des instruments acoustiques encore plus complexes peuvent être construits dans un environnement FabLab à l'aide d'outils manuels et numériques.

Currently in construction (the website and the ukulele :) )



UBO Openfactory

Salle D133 Bâtiment D


Fait avec  par la Team UOF