I made a xylophone that uses an Arduino Mega to detect when a note is struck, and generate MIDI output. This project is wondeful because I essentially made a xylophone, a drumkit, and any other MIDI controlled sound instrument, with one tool. The following steps  will outline what I used to make this xylophone.

Step 1: You Will Need...

To construct the xylophone I used the following parts from Radioshack:

(x1) Arduino Mega 2560 (Radioshack #276-127)
(x12) Piezo Element (Radioshack #273-073)
(x12) 1M Ohm resistors (Radioshack #271-1356)
(x1) Single Core wire (Radioshack #278-1221)
(x1) Printed Circuit Board (Radioshack #276-170)
(x1) USB 2.0 Cord (Radioshack #26-714)
(misc) Electrical Tape (Radioshack #64-2373)
(misc) Heat shrink (Radioshack #55048444)

The housing for the xylophone was easy to build. I used:
1/4" plywood
1/8" acrylic sheeting
wood glue
1/4" vinyl tubing
1 1/2" long machine screws.
2" masking tape

laser cutter
cotton swabs
small flat head screw driver

Step 2: Free the Piezos, Then Solder Longer Leads.

For this project, I used piezo elements to detect when each note is struck on the xylophone. These piezos detect vibration, or a knock. Often the elements come in a housing, to protect the disc from being bent or smashed - but for this project I needed to remove them from their plastic.

By gently pressing around the edges with my fingers, you could hear the glue crack apart from the plastic, I loosened the bottom of the casing. Carefully, I insterted a precision flat-head screw driver, and popped the bottom of the case off.

The piezo element could then be removed from the outside of the housing.

Because I am using an Arduino Mega Board, I could have up to 16 Analog inputs, or 16 Piezos. I decided to just include an octave & a half, 12 notes, so I used 12 piezos.

After they were free from their case, I soldered longer wires to each piezo element, to prepare them to be inserted into the xylophone. When I was done soldering longer leads on to each piezo, I wrapped my solder points with heat shrink or electrical tape.

Step 3: The Bars and Housing.

I used CorelDraw to draft vector files that would guide the laser cutter for the housing and bars of the xylophone.

The acrylic bars were each 10x2 inches. Each bar has two holes in them that will guide a machine screw through the bar, and mount to the top panel of the wooden housing.

The wooden housing I designed is 10.5x30x3 inches. It forms a shallow box that supports the electronics embedded within it. I used woodglue and a cotton swab to secure all of the corners, and allowed 24 hours to cure before I sanded down all of the edges.

The CorelDraw file for the base housing is attached to this step.

Step 4: Attach the Piezos to the Bars

I threaded the Piezo wires through the middle holes in the top panel of the housing. Then, I centered the piezo element on each acrylic bar, and used 2 inch blue masking tape to adhere the piezo to the bar.

Step 5: Attach the Bars to the Top Panel.

I used 1 1/2" machine screws and nuts to secure the bars to the wooden paneling.

To prevent excessive shake or vibration on each bar, I decided to use vinyl tubing as a shock absorber on each machine screw. With 12 bars, I used 24 machine screws and nuts, and 24 3/4" lengths of vinyl tubing. Thread the machine screw through the bar, then the vinyl, and slip it into the paneling. When the screw was through the panel, I was able to twist on the nut to fully secure it to the panel.

All of these should only be finger-tight, to avoid stress on the paneling, or on the bar.

Step 6: Build the Circuit.

Before connecting the piezos to the Arduino, I connected a 1-megohm resistor in parallel to the Piezo element to limit the voltage and current produced by the piezo, and to protect the analog input ports on the Arduino. On the PCB, I marked with a permanent marker which piezo goes to each analog input port on the Arduino. I also made the same markings on the back of the top wooden panel.

After I soldered the resistors into place, I ran a small jumper wire from one end of the resistor, to the longest rail on the PCB, and designated it my ground rail. Next, I soldered all of the piezos' ground wires into place, in line wtih the same end of each grounded resistor. The positive lead from the piezos is soldered in to the same rail as the other end of each resistor. 

I cut 12 lengths of green wire to be my "signal wire" to the Arduino. Each signal wire is soldered into the same positive resisted rail of the piezo.

The fritzing diagram file is attached to this step.

Step 7: Connecting to the Arduino

I took all of the signal wires, and the ground wire running from the PCB and marked each one with blue masking tape, writing which port each wire was designated to. I then fed all of the marked single core wire into the corresponding ports of the Arduino.

All remaining Analog ports must be grounded! Otherwise it will affect your serial output from the arduino. I used 4 black wires, running from the ground rail of the PCB directly to the open analog ports of the Mega board. (A12, A13, A14, and A15)

When you have completed your circuit, you can load the xylophone program, or sketch, onto the Arduino board from the Arduino Developing Environment.

Here is the sketch I used.

Step 8: Power and Communication.

The Arduino can be powered via USB, which doubles as a communication port. I ran a USB cable through the housing of the xylophone. By drilling a small hole, that was big enough for the ends of the cable, I could hide most of the USB cord in the housing.

I drilled a second hole to hold my mallots.

Step 9: Serial to Midi

To get the xylophone coupled with my comptuer I used software called Hairless. It converts the serial out signal from the Arduino into a MIDI signal that programs like GarageBand, Logic, and Ableton can read and record. Be sure that the bridge is running before you try and import MIDI data from the xylophone. 

Note: Disable the bridge while trying to update the sketch on the Arduino board. You cannot have the bridge running while trying to communicate to the board from the Arduino software.

Step 10: Jam It!

After you are up and running, you can play the xylophone like drums. Record your beat track. Then kick change the MIDI instrument to a bass synth, and record a rhythm track. Finally turn it back into a xylophone and create a melody track for the best song ever. This thing is a lot of fun!
<p>OK, so I have adapted the code to accommodate 36 keys. There were a couple of errors in the code, but they served to educate me on the commands. I have bought the Arduino Due, and a multiplexer. The Due has 12 analog inputs. Using the Arduino IDE I was able to verify the code for my board. It works and uploads flawlessly.</p><p>So far, I have correctly modified for the number of notes and range (F2 to E5). I am building a three-octave rig. I think I need one more (F5), but this will be no problem. </p><p>Here is he first section of the code. I have questions.</p><p><br><br>I have not yet done the physical build. However, it is my understanding that there is a bit of velocity sensitivity with the piezos. This is why resistors are needed across their terminals. They are so sensitive that they would otherwise produce very high values when struck. Doug Beney at diy.midcontroller.com discusses this in just enough more detail to not put a neophyte like me to sleep.</p>
<p>are these pads velocity sensitive? </p><p>And do we have to make any changes when we are making a drumkit in this way?</p>
<p>I'm a bit late to your comment, but here's an answer: No, they would not be velocity sensitive. Piezos are sensitive to a sharp taps, and then they'll produce a spike of electricity. It's possible you could get some minor velocity sensitivity, but I wouldn't think it would be very reliable. As for the drumkit, I wouldn't think so, but because I haven't done it myself, here's another instructable showing just that: </p><p>https://www.instructables.com/id/MIDI-Arduino-Drums/</p>
<p>I'm not so sure; I've got a system set up here with piezo sensors connected to an arduino uno and I'm getting variable input between 0-150 based and pretty responsive to how hard I tap. I see no reason it can't be velocity sensitive.</p>
<p>Well then! Good to hear! I (Sit) corrected! ;D</p>
is this circuit possible with direct midi din out ?
<p>Would using an FSR like this work in place of the piezo?</p><p><a href="https://www.amazon.com/Electronics123-com-Inc-Force-Sensitive-Resistor/dp/B00JAUT6BU/ref=sr_1_4?ie=UTF8&qid=1468785448&sr=8-4&keywords=force+sensing+resistor" rel="nofollow">https://www.amazon.com/Electronics123-com-Inc-Forc...</a></p>
<p>I know I'm a bit late to your comment, but hope it can help. It'll work, but you might need to modify the code and circuit slightly. However, the FSRs are <em>quite</em> a bit more expensive (That particular one is 16$, imagine that times 12), and on the other hand, piezos are pretty inexpensive on eBay. The only benefit I can see from using the FSRs would be you'd be able to output velocity. Hope that helps!</p>
<p>A quite interesting idea. Thanks.</p>
Hi. I followed all the steps of your project for the creation of the xylophone. I connected it to the Hairless MIDI and then to GarageBand, and everything seems well. The programs appear to be connected each other. But, the xylophone doesn't sound through de computer. I've tried many things to make it sound, but I don't know how to fixed it. I'll appreciate if you help us to make all its functions. Thank you.
<p>Hi, I'm having a problem getting the arduino to output midi. When I hit the keys I get this kind of reading on the serial monitor:&quot; &yuml;&Otilde;&egrave;&yuml;&yuml;&yuml;&yuml;&yuml;&thorn;&thorn;&yuml;&eth;&yuml;&deg;@&euro;&thorn;&thorn;&thorn;]&amp;&yuml;&ntilde;&quot; I'm assuming this isn't right. Also when I hit a note, nothing shows up in the hairless monitor or midiloop, they only show a value when I assign a port. Any ideas what's happening here?</p>
<p>hairless says no midi in connected</p>
Hey contact me on email address I have provided below
Hey.. I have successfully build it but I am facing a problem that my all the piezo are producing only one tone... So please tell me hoe to assign individual sounds to each piezo ... By the way I am using FL Studio as my working software.... <br>So please who so ever know how to solve it out.... Please tell me...
<p>yaar, I am using fls 10 in windows and hairless is not showing any midi in or out.</p><p>Please help</p>
U have to download loopmidi also if u r using Windows and hmngtm@gmail.com dats my email id feel free to approach me bcz I am also stucked some where so lets do it together... I m from Delhi...will be w8ng for ur response
<p>yaar, I am using fls 10 in windows and hairless is not showing any midi in or out.</p><p>Please help</p>
<p>One more thing.. I think there was a small typo in the code...I could only get it to work when I used this instead of the line that was in there: char pinAssignments[16] ={ </p>
Awesome! There very well could be - do you mind emailing me your finished .ino file? audrey@instructables.com<br /><br />I recently tried to revive this project in a different form and ran into some strange behavior. I thought it was because I was trying to use an arduino micro......<br /><br />Thanks!<br />Audrey
<p>Hi Audrey.</p><p>this code below seems to work. the only issue Im having now is that when I strike , it seems to trigger multiple notes. not sure if its because of excessive vibration or the code... The attached picture is what I get from hitting it twice, so instead of hearing clear tones, Im hearing a combination of xylophone tones in Logic. Did you ever have that problem? </p><p>Getting close!</p><p>int pinRead;</p><p>char pinAssignments[16] ={</p><p> 'A0','A1','A2','A3','A4','A5','A6','A7','A8','A9','A10','A11','A12','A13','A14','A15'};</p><p>byte PadNote[16] = {</p><p> 57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72}; // MIDI notes from 0 to 127 (Mid C = 60)</p><p>int PadCutOff[16] = </p><p>{</p><p> 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100}; // Minimum Analog value to cause a drum hit</p><p>int MaxPlayTime[16] = {</p><p> 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90}; // Cycles before a 2nd hit is allowed</p><p>#define midichannel 1; // MIDI channel from 0 to 15 (+1 in &quot;real world&quot;)</p><p>boolean VelocityFlag = true; // Velocity ON (true) or OFF (false)</p><p>//*******************************************************************************************************************</p><p>// Internal Use Variables</p><p>//*******************************************************************************************************************</p><p>boolean activePad[16] = {</p><p> 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // Array of flags of pad currently playing</p><p>int PinPlayTime[16] = {</p><p> 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // Counter since pad started to play</p><p>byte status1;</p><p>int pin = 0; </p><p>int hitavg = 0;</p><p>//*******************************************************************************************************************</p><p>// Setup</p><p>//*******************************************************************************************************************</p><p>void setup() </p><p>{</p><p> Serial.begin(115200);</p><p>}</p><p>//*******************************************************************************************************************</p><p>// Main Program</p><p>//*******************************************************************************************************************</p><p>void loop() </p><p>{</p><p> for(int pin=0; pin &lt; 16; pin++) //</p><p> {</p><p> //int pin = 3;</p><p> // for (pinRead=0; pinRead &lt; 16, pin++){</p><p> hitavg = analogRead(pinAssignments[pin]); </p><p> //Serial.println(hitavg); </p><p> // read the input pin</p><p> if((hitavg &gt; PadCutOff[pin]))</p><p> {</p><p> if((activePad[pin] == false))</p><p> {</p><p> if(VelocityFlag == true)</p><p> {</p><p> // hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)</p><p> hitavg = (hitavg / 8) -1 ; // Upper range</p><p> }</p><p> else</p><p> {</p><p> hitavg = 127;</p><p> }</p><p> MIDI_TX(144,PadNote[pin],hitavg); //note on</p><p> PinPlayTime[pin] = 0;</p><p> activePad[pin] = true;</p><p> }</p><p> else</p><p> {</p><p> PinPlayTime[pin] = PinPlayTime[pin] + 1;</p><p> }</p><p> }</p><p> else if((activePad[pin] == true))</p><p> {</p><p> PinPlayTime[pin] = PinPlayTime[pin] + 1;</p><p> if(PinPlayTime[pin] &gt; MaxPlayTime[pin])</p><p> {</p><p> activePad[pin] = false;</p><p> MIDI_TX(144,PadNote[pin],0); </p><p> }</p><p> }</p><p> } </p><p>}</p><p>//*******************************************************************************************************************</p><p>// Transmit MIDI Message</p><p>//*******************************************************************************************************************</p><p>void MIDI_TX(byte MESSAGE, byte PITCH, byte VELOCITY) </p><p>{</p><p> status1 = MESSAGE + midichannel;</p><p> Serial.write(status1);</p><p> Serial.write(PITCH);</p><p> Serial.write(VELOCITY);</p><p>}</p>
<p>It looks so cool. The red keys are gorgeous.</p>
<p>Hi.......I thought the sketch would be perfect for my drum pads but when I compiled it it said this - sketch_Piezo1.ino:11:64: error: too many initializers for 'char [6]'</p><p>Error compiling.</p><div>Mmmmmm I'm a newbe so not sure how to fix.</div><div>Claude</div>
<p>yep, it is a typo.</p><p>Because there are 16 elements in the defined array.</p>
<p>Change '<em>char pinAssignments[6]</em>' at the top of the code to '<em>char pinAssignments[16]</em>' and it'll work ;)</p>
<p>I am unable to select anything from the MIDI out and MIDI in drop down menus. Would could be the cause of this?</p>
<p>You should turn on the midi port on your mac.</p><p>Find &quot;Audio MIDI Setup&quot; application on your mac and then select &quot;window&quot; on the tab bar. Choose &quot;Show Midi Studio&quot; and you will see the below interface. And double click the IAC Driver to make it bright.</p><p>Then try the midi out port in hairless.</p><p>Good luck. </p>
<p>Hey Elaine, </p><p>I assume you didn't set up the midi configurations in the midi-setup panel in applications &gt; Utilities. </p>
<p>Hello, I can not find the diagram Fritzing ... where I can get it? Thank you!</p>
<p>hi.. </p><p>the piezo doesn't make a sound, how can i fixed ?</p>
<p> Is it possible to get only one note for each piezo?</p>
Must you use the exact piezo elements from Radioshack? Will any piezo elements work?
<p>there is plenty of &quot;ready to use&quot; project piezo elements for this project ) <a href="http://www.ebay.com/sch/i.html_odkw=10PCS+Piezo+Elements+Sounder+Sensor+Trigger+Drum+Disc&_from=R40%7CR40&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0&_nkw=10PCS+Piezo+Elements+Sounder+Sensor+Trigger+Drum+Disc&_sacat=0" rel="nofollow">http://www.ebay.com/sch/i.html_odkw=10PCS+Piezo+El...</a></p><p>but carefully make a choice of the size what you need</p>
<p>You don't need to use the Piezo elements from Radioshack (I hope). Here are the ones from Sparkfun: </p><p><a href="https://www.sparkfun.com/products/10293" rel="nofollow">https://www.sparkfun.com/products/10293</a></p><p>Hope this helped!</p>
<p>This is what I'm looking for. I have a Korg Nano Key controller that I use now to input notes into my Finale music composition program. It uses USB also. Being a percussionist, I am interested in building a midi &quot;marimba&quot; to input notes.</p><p>I see that you have used 12 notes in your project. I would like to make a 25 note, 2 octave chromatic (both naturals and accidentals) instrument to use when composing.</p><p>I know the Arduino Mega has 16 inputs. Would I need a multiplex to accommodate all the keys? Also, what would the code be to add more notes, including accidentals? Could it be so simple to connect the piezo from each bar to the corresponding keys on the controller that I already have? Any suggestions or pointers would be very appreciated. Thanks. </p>
<p>My son and I made this project together. We had a hard time getting the proper response from the note keys. When we watched the keyboard view in Garageband we noticed a few different notes were sometimes playing when we struck only one key. We isolated the problem to vibration. We replaced the vinyl tubing with rubber and felt pads with a through hole drilled into them. This isolated only the note we wanted to play.</p><p>We had to change the code a bit to get all 12 keys to play. I do not know why the changes worked since this was our first project, but we studied other code and experimented until everything worked as expected.</p><p>This is a great project, fun, interesting, challenging, and we ended up with this really cool device that can be easily switched to produce a wide range of instrument sounds as the original author explained.</p><p>The few lines of code we modified were as follows:</p><p>We changed the pinAssignments to [12]. In fact we switched all arrays to [12].</p><p>We changed the char pinAssignments to an int function.</p><p>We removed all single quotes from the pinAssignments [12] ={A0,A1, ...n}</p><p>Changed PadCutOff values to 40</p><p>Changed MaxPlaytime values to 70</p><p>Changed byte status1; to byte status;</p><p>Set hitavg = 127;</p><p>We used a note off value of 128 instead of the note on with velocity 0 in the MIDI_TX(128,PadNote[pin], 0)</p><p>And in the Transmit MIDI section we changed the status1 statement to status.</p><p>Again, I do not know if these were required to make our project work or why it made it work, but it did and we wanted to share and tell everyone that this is a great project to build.</p>
<p>So AWESOME! So glad it worked &lt;3 it's pretty fun. I am in the process of overhauling this project based on the code suggestions made on this comment thread. I really appreciate such an awesome community, its wonderful that this little project has become so collaborative :D</p>
<p>Hi guys. I made some progress on this . But I can't seem to figure out why my piezos and spitting out all kinds of wacky data. here is some the debug MIDI messages from the Hairless MIDI bridge application. </p><p>This is all from successive stries of the same xylophone key. I would thin it should always be putting out the same note number just with differing velocities. I seem to be getting all kinda of notes and ask pitch bending information, which makes for wacky sounds in my audio program (Logic). Any ideas? I have it hooked up like instructed..</p><p>john</p>
<p>I was having a similar problem to yours and this is what I did to get it working. </p><p>Hey Guys! I just finished this project. Few things to consider for those of you having problems.</p><p>First: you need to make sure that your pins are initialized as &quot;int&quot; NOT &quot;char&quot; otherwise you might only have a few of your keys work.</p><p>Second: make sure the baud number/ serial port number is set to 115200 both in the code and in your serial to MIDI converter. I used Hairless so it should be under File-&gt; Preferences</p><p>Third: (only applies to Ableton and Windows users users) Make sure that you use loopMIDI to create a virtual MIDI port and that serial to MIDI converter (Hairless) is set so that the MIDI Out is loopMIDI Port and MIDI In is set to loopMIDIPort. From there go into Ableton and set the Control Surface to &quot;None&quot; and Input as loopMIDI Port and Output as loopMIDI Port. .</p><p>Hope this helps!!</p><p>This is a super fun project</p>
<p>Huh....thats a new one. I wonder if boosting the resistors would curb that. or don't qualify 4 of the Analog ins in the beginning of the sketch - so try it with A0-A11 for your inputs?</p>
<p>Hey Guys! I just finished this project. Few things to consider for those of you having problems. </p><p>First: you need to make sure that your pins are initialized as &quot;int&quot; NOT &quot;char&quot; otherwise you might only have a few of your keys work.</p><p>Second: make sure the baud number/ serial port number is set to 115200 both in the code and in your serial to MIDI converter. I used Hairless so it should be under File-&gt; Preferences</p><p>Third: (only applies to Ableton and Windows users users) Make sure that you use loopMIDI to create a virtual MIDI port and that serial to MIDI converter (Hairless) is set so that the MIDI Out is loopMIDI Port and MIDI In is set to loopMIDIPort. From there go into Ableton and set the Control Surface to &quot;None&quot; and Input as loopMIDI Port and Output as loopMIDI Port. . </p><p>Hope this helps!!</p><p>This is a super fun project</p>
<p>Hi. Great project. One thing Id point out that I overlooked is the oversized tabs on the case. I know you made yours with wood and it indicates your sanded them down. I may have missed that important point. I went and had some plexiglass laser cut with the .cdr file you attached not realizing that. So, everything fits together but obviously the tabs extend longer than they need to. And this material doesnt sand as easily as wood. Just something to consider.</p>
<p>thank you for your information and detail project.</p>
We cant buy radio Shack parts in Canada, can you recommend an equivelant Piezo Element that we could maybe pick up elsewhere ? <br> <br>Thanks <br> <br>Mick
Is it possible to use an Arduino Uno? Sorry, I haven't read through your tutorial yet; maybe you explain there why the Mega is necessary. <br> <br>Robert
This uses 16 output pins, UNO has 14 so you could make a xylophone with 14 notes instead of 16.
Not exactly true, this uses a lot of _analog input_ pins and the Uno only got 6 of those. The compiled code does consume less then 5 KB though, with some creative programming and analog multiplexers like the 4051 or 4067 an Uno or even oldest 8KB-arduino would be up to the task.
Nice!!! I'll try to do this :D
I just cited this here: https://www.instructables.com/id/Simon-Game-Xylophone-Version/ <br> <br>Hope someone merges them :)
I love a project with a tool list that starts with &quot;laser cutter.&quot; I'll just pick that up at the local Home Depot. :-) <br> <br>Thanks for sharing the project.
That's tremendous!

About This Instructable




Bio: I'm an Instructables success story! After relying on the site to DIY my way through art school, I was able to join the Instructables ... More »
More by audreyobscura:Outdoor Adventure Projects DIY Kitchen and Bathroom Different Uses for Rubber Cement 
Add instructable to: