Arduino – making a basic drum machine

arduino piezo

Had a quick look round at turning a piezoelectric speaker in to a sensor that will detect a tap or knock. I also then had a search around for setting the output of a speaker to a different note. Combining this has given me a small basic Arduino drum machine and a headache to my girlfriend.

First of all a piezoelectric speaker works kind of like a guitar string in that it vibrates to generate sound. Typically we pass a current through the 2 pins and this then vibrates the piezo element accordingly, using Pulse Width Modulation allows us to alter the volume and the frequency of the sound wave by altering how frequent we vibrate the piezo material.

So if we reverse this we get a knock sensor which means we vibrate the piezo element by hitting it this then creates a signal that we detect as an input. By sensing the vibrations we can crudely detect how hard it was hit. But because we constantly read the input and the vibrations will reach a peak we need to take the peak value to get a decent result rather than the first or last reading. To do this we write a small chunk of code to take the highest reading.

Next we have a normal speaker as our output, by altering the frequency we can alter the note that it produces, much like creating an Infrared signal in my tutorial here. The frequency is basically created by the microsecond time length of the soundwave and we rapidly pulse the speaker to this length so half the length is on, the other is off. Different notes and octaves have different wave lengths on the chromatic scale. A basic 12 note scale is shown below with the chromatic notes and their frequency along with the timings:

Chromatic Note Frequency Hz Time of soundwave (micro seconds) ?s Pulse On/Off (divide time by 2) ?s
C 261 Hz 3830 ?s 1915 ?s
C# 277 Hz 3610 ?s 1805 ?s
D 294 Hz 3400 ?s 1700 ?s
D# 311 Hz 3216 ?s 1608 ?s
E 329 Hz 3038 ?s 1519 ?s
F 349 Hz 2864 ?s 1432 ?s
F# 370 Hz 2702 ?s 1351 ?s
G 392 Hz 2550 ?s 1275 ?s
G# 415 Hz 2410 ?s 1205 ?s
A 440 Hz 2272 ?s 1136 ?s
A# 466 Hz 2146 ?s 1073 ?s
B 493 Hz 2028 ?s 1014 ?s

To calculate the time of a wave we can use the following calculation:

Time (T) = 1 / frequency (Hz)

This will give us the value in seconds. To obtain microseconds multiply this value by 1,000,000 (There are a million microseconds to 1 second). Conversely we can obtain the frequency by dividing 1 by the Time (in seconds).

I’m going to have 2 piezo speakers as knock sensors which will light up a corresponding LED and play a different note, in this case a C or a D.

Arduino Drum Machine Parts

2x 220 Ohm resistor (Red, Red, Brown, Gold)
2x 1Mega Ohm resistor (Brown, Black, Green, Gold) – that’s 1,000,000 Ohms
2x piezoelectric speakers
1x speaker
2x LED
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board
Jumper/ Connector wires
Optional 9V DC power supply or use the USB power for the Arduino

Arduino Piezo Speaker Drum Machine Circuit


Piezo Sensor Drum Machine Code

[ad#Google Ad in content]


LUCKYLARRY.CO.UK - Very basic drum machine/ knock sensors and chromatic scale

We measure the force at which the piezo speakers are hit, the maximum on time is 1024 so when
this is lower than a set threshold we execute our code. In order to take the peak reading we
continously monitor the values and everytime it's lower we save that value. At the end of the loop
we reset the value.

The soundwave function uses a custom monitor for counting microseconds as this seems to be
a bit more accurate for measuring the delays needed. We produce our count by making a value
of microseconds, 35,000, which seems to give a good range of note lengths when multiplied by
how hard the sensor was hit.

We output the sound to another speaker, creating a soundwave based on the Hertz of any given
note in the chromatic scale. Taking this value we calculate the times in microseconds needed
to oscillate and generate the required frequency. Time = (1 / Hz) * 1,000,000.


int leftPadPin = 2;                                             // set the pins for the piezo speakers
int rightPadPin = 5;                                            // these are analog pins for input
int leftLEDPin = 9;                                             // set the LED pins which are digital
int rightLEDPin = 10;
int speakerPin = 6;                                             // set the speaker pin on digital pin 6
int padLimit = 1010;                                            // the limit/ threshold at which to activate the logic
int howHard = 1024;                                             // variable to store how hard the sensor is hit, the lower the value the harder the hit
int  Cnote = 1915;                                              // set the pulse on/off time for each note.
int  Dnote = 1700;  

void setup(){
  pinMode(speakerPin, OUTPUT);                                  // set the speaker as output
  pinMode(leftLEDPin, OUTPUT);                                  // set the LEDs as outputs
  pinMode(rightLEDPin, OUTPUT);
  pinMode(leftPadPin, INPUT);                                   // set the piezo speakers as inputs
  pinMode(rightPadPin, INPUT);

void soundwave(int note, int howHard ) {                        // function that takes 2 parameters, the note we want to play and how hard the sensor has been hit
  unsigned long endSoundWave = micros() + (35000 * howHard);    // start a count from the microseconds currently registered since the program first ran. And add on an arbitary value multiplied by howHard value
  while(micros() < endSoundWave){                               // while the count is not reached
    analogWrite(speakerPin, 1023);                              // set the speaker to on/ high
    delayMicroseconds(note);                                    // wait the number of microseconds for the note
    analogWrite(speakerPin, 0);                                 // set the speaker to off/ low
    delayMicroseconds(note);                                    // wait for the same number again to complete our oscillation/ soundwave.
  }                                                             // repeat for the length of time.

void loop(){

   if (analogRead(leftPadPin) < padLimit) {                     // if the sensor is hit and the reading is less than our threshold
     digitalWrite(leftLEDPin, HIGH);                            // turn an LED on.
     while (analogRead(leftPadPin) < padLimit) {                // while the analog reading is less than the limit
       if (analogRead(leftPadPin) < howHard) {                  // if the reading valueis less than our howHard value (1024)
         howHard = padLimit - analogRead(leftPadPin);           // then rewrite howHard with the new value
       }                                                        // this allows us to capture the peak value.
       soundwave(Cnote, howHard);                               // now generate the soundwave with our note and how had the sensor was hit

  if (analogRead(rightPadPin) < padLimit){
     digitalWrite(rightLEDPin, HIGH);
     while (analogRead(rightPadPin) < padLimit) {
       if (analogRead(rightPadPin) < howHard) {
       howHard = padLimit - analogRead(rightPadPin);
       soundwave(Dnote, howHard);

  digitalWrite(rightLEDPin, LOW);
  digitalWrite(leftLEDPin, LOW);                                // set the LED's back to low
  howHard = 1024;                                               // set the variable back to the original value


[ad#Google Ad in content]

Well what we could do is to add in extra speakers to allow for chords or alternatively work out the frequency of the chord but then you wouldn't get harmonics and it may sound a bit funny. And perhaps I shouldn't have spent all day playing with this annoying my girlfriend.


  • Your parts list says “2x 1Mega Ohm resistor (Brown, Black, Green, Gold) – that’s 1,000,000K Ohms”, but that ‘K’ is probably a typo. 1 MOhm = 1,000,000 Ohm.

    • d’oh!, yes thats a M! I’ll amend that now – cheers for pointing that one out.

  • Wouldn’t this be a basic synthesizer or keyboard? This device plays tonal sounds corresponding to different buttons. A drum machine allows one to sequence a series of rhythmic patterns made up of synthesized or prerecorded drum sounds. It is not normally “played” in real time, but pre-programmed by the user.

    • This is true and perhaps I should have referred to it as a basic electronic drum kit? But the fact is you can record ‘hits’ if I were to hook it up to Processing etc.. and there are a quite few drum machines that let you do the same e.g play a pattern, recording it for looping etc… In fact on most drum machines you can record a loop in real time by setting the tempo and then pressing the various buttons to record, rather than pre-programming them, granted this is pressing buttons and not hitting them, I’ll dig out the model names if you’re interested (think one I used was by Roland). So I actually don’t think that the use of the term ‘drum machine’ is a mis-use. With a keyboard you press a key, not hit it – so I’m using a percussive method as the piezo sensor registers force of impact not a press – the harder I hit, the louder the note.

      Course what I would like to do is to take apart the piezo sensor and then build a trigger system for my drum kit (a real one!) to record, etc.. when I play my drums – no idea how I’d do cymbals yet though…

  • Forgive my noobishness after returning to EE after over 10 years (and given I was about 9 at the time) what are those 1M resistors actually for? I see it in every knock sensor diagram but no real explanation is ever given.

    • The reading comes from a voltage divider.
      The piezo buzzer that changes it resistance value (when pressed) in series with the 1 M Ohm resistor.
      Under this arrangement, if one of the resistors is too small (compared to the other), then the change in voltage is not significant and the reading is more difficult.
      Since the piezo buzzer handles values around the 1 M Ohm, then it makes sense to use a 1 M Ohm resistor in series with the piezo buzzer.

    • Ok, sorry… the piezo buzzer goes in parallel with the 1 M Ohm Resistor. And that’s because Ohm’s Law V = IR.
      When the piezo vibrates, it induces a small current into the 1M Ohm resistor, giving you a decent value of V, to be read by a microcontroller.

Join the Discussion

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>