Introduction: 3D Printed Arduino Xylophone
As part of my final project for my Electronics class I decided to create a small electronic xylophone using the Arduino Uno. This idea came from the desire to have some kind of practice mallet set for mallet percussionists, such as myself.
The xylophone uses piezo sensors to sense vibration when a key is struck. Keys were 3D printed using the Makerbot Replicator. The note played is created by pulling from a program using a MIDI to Serial converter software called Hairless. In this example the software for the music is Max MSP but Garage Band can also be used.
You will need the following supplies:
Electronics:
-Breadboard (x1)
-Piezo elements (x6)
-1M ohm resistors (x6)
-A lot of jumper wire
-Arduino Uno
-Arduino Uno USB cable
Key Creation:
-Makerbot Replicator 3D printer
-ABS or PLA printing material
Software:
-Arduino Software
-Arduino MIDI Library (for Mac)
Step 1: Creating the Keys
I modeled my keys using Solidworks and 3D printed them on a Makerbot Replicator. This was the most unique element of my project. I wanted to create my keys using the resources I've seen in the schools I've visited and in a way that offered another design element. If a teacher were to use this in their class students would be able to design and print their keys however they wanted.
For my project I modeled my keys directly after those found on a marimba or xylophone.
Modeling:
- I first sketched a rectangle and extruded it to be 0.5 in
- To round out the middle I drew a slot and used it cut through the rectangle
- To round the edges I used the fillet tool on each side (the settings are shown above)
- The legs were drawn on the bottom side of the key also extruded 0.5 in
Printing:
Keys were printed using a raft to prevent wrapping at 20% infill. Because of the size of the keys it is important to keep an eye on them as they print to make sure they don't wrap.
After printing I tore off the raft (one key it stuck too much).
Step 2: The Piezo Sensors
The Piezo sensors most commonly come in a plastic casing and can be purchased from places like Sparkfun or Radioshack.
To strip these sensors out of the case simply use a flat-headed screw driver inserted near the wires to pry off the outer shell. The sensors seem to work fine either way, but taking them out of the case allows you to solder longer wires if you so choose.
How they work:
Piezo sensors are made up tiny crystals (typically quartz) that are perfectly balanced in charge. When something, such as as apply pressure or knocking the element, causes a disruption forcing the charges out of balance. This causes the piezo to create a small amount of voltage across its opposite face until the crystals balance again.
These sensors can be used either to receive input and cause a change or read out, such as in this project, or as an output, such as a small speaker able to produce small buzzing noises.
Step 3: The Circuitry
The entire board is grounded to the Arduino using the GND port on the Analog side. The two sides of the board reflect each other. I used small jumper wires to ground each sensor and the 1M ohm resistors between the sensors and the microcontroller.
Each sensor is wired individually to one of the analog ports. I used analog since it is better for the code trying to actively receive information from the sensors.
Step 4: Serial to MIDI
Serial to MIDI:
In order to communicate with the music software a MIDI to Serial converter program must be used. For this project I used Hairless. You will need to have your Arduino plugged in to select it as the "Serial Port". On windows select MIDI In and Out as the same loop. In this case I created my loop using loopMIDI. On some computers it will find the software you are using by default.
Alternative directions for Mac can be found here.
Warning: The "Serial <-> MIDI Bridge On" box must be unchecked when uploading a new sketch or your computer may crash.
Making Music:
Since I am on a Windows computer I used Max MSP since it comes ready to communicate using MIDI. The code file for the piano I used can be found here along with a full explanation of MIDI or attached. Make sure the MIDI input is set to whatever you named it in loopMIDI.
Attachments
Step 5: The Code:
The Code:
The sketch I used for this project came from Audrey Obscura and was modified to fit the Arduino Uno since the Uno only offers 6 analog pins instead of the 16 on the Arduino Mega.
//Xylophone
//Adapted for an ArduinoUno
//originally from Jenna deBoisblanc and Spiekenzie Labs initial code
//*******************************************************************************************************************
// User settable variables //*******************************************************************************************************************
int pinRead; char pinAssignments[6] =
{ 'A0','A1','A2','A3','A4','A5'};
byte PadNote[6] =
{ 57,58,59,60,61,62}; // MIDI notes from 0 to 127 (Mid C = 60)
int PadCutOff[6] =
{ 400,400,200,800,400,400}; // Minimum Analog value to cause a drum hit
int MaxPlayTime[6] =
{ 90,90,90,90,90,90}; // Cycles before a 2nd hit is allowed
#define midichannel 1; // MIDI channel from 0 to 15 (+1 in "real world")
boolean VelocityFlag = true; // Velocity ON (true) or OFF (false)
//******************************************************************************************************************* // Internal Use Variables //*******************************************************************************************************************
boolean activePad[6] =
{ 0,0,0,0,0,0}; // Array of flags of pad currently playing
int PinPlayTime[6] =
{ 0,0,0,0,0,0}; // Counter since pad started to play byte status1;
int pin = 0;
int hitavg = 0; //*******************************************************************************************************************
// Setup
//*******************************************************************************************************************
void setup()
{ Serial.begin(57600); // connect to the serial port 115200
}
//*******************************************************************************************************************
// Main Program //*******************************************************************************************************************
void loop() { for(int pin=0; pin < 6; pin++) //
{
//int pin = 3;
// for (pinRead=0; pinRead < 16, pin++){
hitavg = analogRead(pinAssignments[pin]);
//Serial.println(hitavg);
// read the input pin
if((hitavg > PadCutOff[pin]))
{ if((activePad[pin] == false))
{ if(VelocityFlag == true)
{
// hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)
hitavg = (hitavg / 8) -1 ; // Upper range
}
else
{
hitavg = 127;
}
MIDI_TX(144,PadNote[pin],hitavg); //note on
PinPlayTime[pin] = 0;
activePad[pin] = true;
}
else
{
PinPlayTime[pin] = PinPlayTime[pin] + 1;
}
}
else if((activePad[pin] == true))
{
PinPlayTime[pin] = PinPlayTime[pin] + 1;
if(PinPlayTime[pin] > MaxPlayTime[pin])
{ activePad[pin] = false;
MIDI_TX(144,PadNote[pin],0);
}
}
}
}
//*******************************************************************************************************************
// Transmit MIDI Message //*******************************************************************************************************************
void MIDI_TX(byte MESSAGE, byte PITCH, byte VELOCITY)
{ status1 = MESSAGE + midichannel;
Serial.write(status1);
Serial.write(PITCH);
Serial.write(VELOCITY);
}
Step 6: Putting It All Together
To attach the piezo elements I simply taped them to the bottom of my keys. Ideally the keys would be better laid out if the sensors had longer wires but you can see a basic idea of the final set up.
To increase the effectiveness of the sensors you can place a bar or stopper below them to ensure they are getting hit when the key is hit.
Other Resources:
- Alternative Xylophone Projects: 1 and 2
- Working with Piezo Sensors
- More info on Piezo Sensors