Xyluino – an Arduino Driven MIDI Marimba, Xylophone, Glockenspiel



What you need:

  • an arduino, I use an arduino Uno, Rev. 3
  • analog multiplexer, 74HC4067
  • piezos, diameter about 3cm
  • wood, bleech wood for the plates
  • knowledge how to solder
  • some electronic parts, wires, buttons, a display, midi socket

Step 1: Collect Information, Test the Basics

This step is just for your information and not really necessary. There are many sources on the internet concerning arduino, midi, piezo sensors, drum kits and so on. Here are mine:

MIDI Drum Kit:

E-Drum Set:




I really found a small xylophone made of plastic and some basic code:

Arduino xylophone:

and source code:


And for arduino and midi:

MIDI tutorial:

MIDI and arduino:






At the end I do not use any kind of midi library. There is too much overhead in the code just for sending some small commands from the device which I can program with a line of code and the serial interface.

A big challenge was the speed of the arduino. Will it be sufficient polling three and a half octave of piezo sensors in time? Yes, it is. I have tuned the analogue input a little bit for speeding it up and everything is fine.

The technical principle of this instrument are some piezo sensors, some analog multiplexers and analog inputs of the arduino.The tuning of the sensors is done by software. You can control sensitivity and delay of every input. I will go into details with the program code later on.

On the photo you see my first setup of one sensor generating one midi note on a breadboard.

Step 2: The Sensor Part

The input sensors are made of bleech wood. It’s a hard wood, so you are able playing it with different kind of sticks later on. I’ve glued the piezo plates with an epoxy glue at the bottom of the bleech wood plates. For reducing transmissions of vibrations between the sensors I put some small parts of sponge rubber on the plates.

Now I’ve done that 42 times for having three and a half octaves of tones at the end.

Step 3: Analog Multiplexer

For collecting the analogue signal I’m using analog multiplexers connected to the analogue inputs of the arduino. One multiplexer can collect 16 channels. For 42 sensors I used three of them. There’s a lot of repeating work to do. Be careful with the wiring. Label the sensors otherwise you will end up with a chaos of cables.

Step 4: The Main Electronics

The last step is wiring it all together. The analogue multiplexers, the arduino, a display, some buttons, midi buttons and an input for a sustain pedal.

Step 5: The Circuit Diagram

Here is the circuit diagram (the descriptions are in German – sorry for that). You need the multiplexer three times and the sensor hardware 42 times. The buttons for controlling the instrument are set up like the electronic for the sustain pedal, there is no difference.

Step 6: The Program

Let’s go deeper into the programming code.

The main program is devided in subroutines.

// midiLoopback();

This is not used yet, but could be added if some midi loopback is needed. Therefore you have to add an optocoupler and a midi-in socket.


This routine reads all sensors over the multiplex arrays. The routines reads the three input signals at once and stores it in the array.


This is for analyzing the values read before. If a sensor was hit, the program waits a small amount of time before analyzing the signal again. This is for reducing oscillations. The routine sets the duration for playing a midi note and dependig of the octave value set the appropriate note read from the array of notes.

A dynamic attack is possible to set. But for me it was not very useful. Therefore I’ve deactivated it.


This is for analyzing the sustain pedal. The routine is independent from playing a note.


As mentioned above, I am using a Ketron SD4 for generating sounds from the midi controls. I’ve stored some instruments in the user bank of the device which I loop with a program change midi control. Using another kind of sound processor you have to customize these lines of code.


The octave button is checked and loops MID-LOW-MID-HIGH-MID-… With this function the maximum octave range is five and a half octaves.

Let’s explain some subroutines.

This routine is for making the analogg readings faster

// Making analog readings faster (for drumrolls) works with this code
// read http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1… for more info #define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// set prescale to 16

The values of the notes being played over midi, the sensitivity and the cooldown time of the piezo sensors can be defined individually for every sensor. I’ve set these equal for all sensors. If you want you can do a lot of fine tuning.

// Midi-Notenwerte
unsigned char PadNote[72] = {36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,

// Threshold Werte, Anschlagsempfindlichkeit
// Tuning-Bedarf ! Ch 10
int PadCutOff[48] = {300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,

// time each note remains on after being hit
int MaxPlayTime[48] = {50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,

// array of flags of pad currently playing
boolean activePad[48] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

// counter since pad started to play
int PinPlayTime[48] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

The MIDI controls are in the last part of the code. The transmiaaion rate is set to 31.250 Baud.

// Transmit MIDI Message //*******************************************************************************************************************
void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{ status = MESSAGE + midichannel;

// MIDI Program Change
void MIDI_PC(unsigned char PROGRAMNUMBER)
{ status = 192 + midichannel;

// MIDI Control Change
void MIDI_CC(unsigned char State)
{ status = 176 + midichannel;

Source: Xyluino – an Arduino Driven MIDI Marimba, Xylophone, Glockenspiel

About The Author

Scroll to Top