Project showcase
DrumCube, an Arduino Robot Drummer

DrumCube, an Arduino Robot Drummer © CC BY-NC-SA

An Arduino-based robot drummer. It works with a transistor noise-generator and an arrangement of servos hitting a can and a pair of piezos.

  • 8,716 views
  • 29 comments
  • 74 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

Live music gigs are always a very special thing, but to produce it, you need humans, and humans are not always available. I occasionally play gigs equipped by my guitar and my voice, but music generally features many others instruments, like percussion, and these instruments tend to only sound when played by humans. This problem could be solved by just using a recording and playing over it, but that would somehow feel against the idea of the “live” concept.

So, I decided to get rid of the human element entirely, and build a robot drummer... The idea would be to make something portable, which could move and play sounds in different rhythms with no use of samples/recordings, that could be played or stopped at will, and that its sound could be amplified in a gig/band situation.

The General Idea

In first place, it is necessary to define what the drumkit elements will be. Following the logic of the frequency range, the standard drum-kit is usually conformed by three basic elements; the kick (low frequency range), the snare (mid range), and the hi-hat (high range). After a couple weeks of experimentation, I decided to replicate this sounds with the following arrangements:

Kick/LowRange: 2 piezos, covered with a small piece of sponge material, which are hit by a servo controlled stick with a soft rubber end.

Snare/MidRange: A can of pringles, with a small square sheet of tin for resonation, which is also hit by servo controlled sticks with a rubber end. The sound is then captured by an electret microphone.

HiHat/HighRange: A transistor-based white noise generator circuit, which is controlled directly by the Arduino.

All of the above mentioned systems are set in time by the Arduino board, and the audio signal generated by them is then amplified to an instrument level signal by three simple amplifier circuits for each one of them.

The Kick Drum

This works by taking advantage of the low frequency sound which is produced when a piezo pickup is directly touched or hit with a soft object. To make this work, first we need to automatise the hitting of the piezo, and secondly, we need to amplify the audio signal generated by said piezo.

As I mentioned above, I used a servo controlled stick to hit two different piezos located at each end of the servo's movement range (in order to make use of all the movement). To help damp high frequencies, the piezos are covered with sponges and the stick has a soft rubber end.

It is important, at this point, to define the angle at which the servo will be when it is hitting each end of its range of movement. This information will be necessary later, and It can be easily obtained using a basic piece of Arduino code (like the one described here) and the Serial.print(); command.

The audio signal from the piezos is then amplified by the circuit described on the image above, powered by 5v - 7v from a voltage regulator, which is fed from the main power supply (not the Arduino board). This is important because, although the amplifier itself would be able to work with the 5v provided by the Arduino, it is ideal to maintain the analog audio signal as separated as possible from the digital circuitry, in order to avoid any digital noise interference making its way into the final audio signal.

Again, I have no formal (or any lol) electronics education, and I've struggle a lot with this last problem. Noise is virtually impossible to get absolutely rid of in any audio application, but I've found that the filtering in the voltage regulator (as well as the analogue and digital separation, and a proper electrical shielding of the project) reduces noise to very acceptable levels.

The Snare

This is a very complicated sound to replicate, even now I'm still not absolutely happy with the sound I’ve achieved. To pickup this sound, I decided to use an electret microphone, as they're usually more sensitive, and the unique acoustic nature of a snare sound makes this necessary.

As we did with the kick system, we need a mechanical part, and an audio one. I've attached a drawing of the mechanical system I designed. Yes, I used a Pringles can upside down, it was the perfect shape, had the best sound I could find, and the crisps were delicious.

Just like we did with the kick, we need to get the angle at which each servo will be when resting and when hitting. Again, tinkering with the Potentiometer+Servo tutorial, we can get that information.

The audio signal from the electret is amplified by another instance of the same circuit used in the kick's amplifier, although in this case with a few modifications to power the electret microphone, and without the low-pass filter used in the kick.

The HiHat

I used a different approach to this sound, a transistor-based white noise generator circuit, and a led indicator, are activated by the Arduino when it is required. White noise is a random signal with equal intensity at different frequencies. Roughly speaking, just as white light contains all colours, white noise contains all frequencies, and it sound like a nonexistent radio station (static). This is a noise commonly used in electronic music and audio synthesis, I read that it was even used to make the classic sound of the 80's snares and cymbals.

As the diagram shows, after the noise is generated, it then goes through a high-pass filter to eliminate the unwanted frequencies and to accentuate the drum cymbal sensation.

The white noise generator needs 12v or higher to function, that are provided by a step up voltage elevator, which itself is powered directly by an Arduino pin. This is the only instance in which an audio system is attached directly to the Arduino, because noise has to be generated only in certain times, and noise seems not to be an issue in a circuit that generates noise. You can't make white more white can you?

The Signal Mix & Complete Diagram

After all of three drum-kit sounds are generated, each signal goes through a potentiometer and a basic passive mixer circuit, which mixes the final audio signal.

We also need a way to select what drumbeat to play and when to start and finish playing. For this tutorial, we will use a tact button connected and a simple switch for each function respectively (connected to the Arduino pins 2 and 3, as the image above shows)

Explaining the Code I - Servo Time Calibration

Now, given that this project is a musical instrument, it needs to generate sound in the right time. So, before we start coding different rhythms and functionalities, specially in the case of the kick and the snare, we need to program the movement of the servos to start some milliseconds before their turn to sound, in order to compensate the time the stick takes to go from resting to hitting, and make the sticks hit their destination just in time.

To solve this problem, I improvised a simple system to measure the time it took every servo to go from its resting position to the exact point of hitting its destination. I covered the sticks and the areas where they hit with aluminum foil, and attached alligator clips to the foil, creating a connection only measurable by the arduino when the stick hits its target. Then I wrote a simple bit of code, which did two things: firstly, make the servo sticks hit repeatedly their target, going from resting angle, to hitting angle. And secondly, print the time when the servo command was sent, and the time when the stick close the connection with its target. Subtracting this two values will give us the time it takes the sticks to make a sound, from resting to hitting.

After doing this enough times, you'll end up with a lot of roughly similar numbers, which you can then average, and obtain a pretty much usable time of anticipation for every servo.

Explaining the Code II - Drum Combinations

Now, we define a number code for every combination of kick, snare, and hihat in a beat. We assign the first odd numbers to each of our three drumkit elements:

Kick	Snare	HiHat
1	3	5

And then, if we need to play more than one element at the same time, we simply add the numbers of each element. Kick and snare would be 4, kick and HiHat 6, and so on. Nought/zero is a silence. Now we have a number for every possible drum elements combination, and we can store them in a variable (cycleNumber variable).

5 HiHat		x 	-	x	x
3 Snare		-	x	x	x
1 Kick		x	x	-	x
_________________________________________
COMBINATION:	6	4	8	9

Explaining the Code III - Semiquaver Cycle (Hitting on Time)

We now know that is necessary to anticipate the commands for the kick and snare servos, but we also have to play the hi-hat on time, which is a circuit that work almost instantly.

To approach this problem, which might get a bit confusing down the road, I decided to establish a system of checkpoints inside every semiquaver (or sixteenth note) of every bar. I chose a sixteenth because in the tempo of most common rhythms, a sixteenth of a note last about 100 to 150 milliseconds, which is also the speed at which the slower servo (in my case) can go from rest to hitting, or vice verse. We can change the speed of the tempo by simply changing the amount of milliseconds assigned to the timeTotalCycle variable. Here Is a useful table of tempo, notes, and milliseconds equivalence. If we tried to play something faster, and we reduce the total time of the cycle lower than the time the slower servo takes to move, this servo might be unable to reach hitting position from rest, and therefore no sound would be produced. A more detailed look at the diagram I've posted, will explain this better.

As shown in the diagram, at the start of what I called the semiquaver-cycle we send the command for positioning the snare servos on their rest position, in case that they had been commanded to hit in a previous cycle. Also at this point, we begin counting the milliseconds that has been set for the duration of the entire semiquaver cycle.

After that, the Arduino will start checking if the amount of time left for the cycle to end, is equal to any of the times that each servo needs to produce sound. The idea here, is to detect the point in time at which we have to send the hitting command so that every servo reach and hit their target (and make their sound) at the exact end of the cycle. Every element will therefore have to start its movement at different checkpoints in the cycle, depending on how fast the servo and its mechanism are. The hihat white noise circuit, on the other hand, can be just turned on at the very end of the cycle or a few milliseconds earlier (20 recommended). Its ending will be commanded on the next cycle in a checkpoint defined by you, how long after the start of the cycle you set it, will be how long the hihat sound is (I set mine between 30 and 40 milliseconds, but that is up to you).

Every time one of these checkpoints are met, the Arduino will check if its corresponding element is intended to action, by comparing it with the drum combination number stored on the cycleNumber variable (the number code system explained earlier). Example, if the snare's checkpoint is met, the snare's number is 3, so the hitting command will only be sent if the drum combination has the numbers 3, 4 (3+1), 8 (3+5) or 9 (3+1+5).

5 HiHat		x 	-	x	x
3 Snare		-	x	x	x
1 Kick		x	x	-	x
_________________________________________
COMBINATION:	6	4	8	9

Why using two sets of sticks and servo in the snare mechanism?

Well, if you think about it, if only one servo would have been used, and lets say its rest-to-hitting time was 100 milliseconds, the shortest amount of time that our semiquaver cycle could last would be 200 milliseconds. 100 to allow going back from hitting to rest, and then 100 more from rest to hiting. 200 millisecond for each sixteenth note equals to a tempo of around 75 bpm (“dream on” by aerosmith), which is pretty slow and limiting in terms of possible rhythms.

Using two separate sets of sticks and servos, and alternating their use, making one go back from hitting to rest in its 100 milliseconds, while the other goes hitting in the same amount of time, reduces the minimum semiquaver cycle time from around 200 to 100 milliseconds approximately (“Call me” by blondie), much faster. In other words, the time of the slower servo, is also the minimum time the semiquaver cycle can last.

Explaining the Code IV - Making the Drum Beat

We now have a way to define exactly what sounds to generate, and also, to do it all at the exact same time. We just need to play 16 of these sixteenth note cycles, one after another, with the desired drum combinations for each one, and we have a bar. We repeat that bar as long as we want, and voliá, we have a musical drum beat.

With a simple bit of code, we store our bar-sequence of 16 semiquaver in an array, and make the Arduino go through over and over. Different drum beats can be stored and played by setting different arrays of 16 numbers, as shown in this diagram:

5 HiHat		x-x-x-x-x-x-x-x-
3 Snare		----x-------x---
1 Kick		x-------x-------
ARRAY:		6050805060508050
  
5 HiHat		x-x-x-x-x-x-x-x-
3 Snare		----x-------x---
1 Kick		x--x--x--xx---x-
ARRAY:		6051806051608060

To switch between these arrays, we'll use the tact switch button connected to pin 3.

Code

DrumCube, a robot drummerArduino
// DrumCube - a robot drummer
// written by Franco Molina @artefrancomolina

// Setting servos
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;

// Servo positions
// this will differ depending on your servos, please test yours to find out the values that best suit you
byte restServo1 = 12;
byte hitServo1 = 21;
byte restServo2 = 123;
byte hitServo2 = 114;
byte restServo3 = 4;
byte hitServo3 = 19;  

// Setting the HiHat white noise generator
#define noiseGenerator 12
#define noiseLed 13 //turn on led as a visual representation of the noise being generated

// Setting servo times
// this will also differ depending on your servos, please test yours to find out the values that best suit you
byte timeSnare1 = 110;
byte timeSnare2 = 108;
byte timeKick = 71;
byte timeHihat = 20;
byte sustainTimeHihat = 70;

// Setting previous Snare and Kick
byte previousSnare = 2;
byte previousKick = 0;


// Setting cycle times
static unsigned long timeStartCycle;
static unsigned long timeTotalCycle; // changing this, change how fast/slow the rhythm is, you can set a specific value for each drumbeat in the selectDrumBeat() function

// Bar and Cycles variables
int cycleNumber;
int cycleNumbers[] = {6, 0, 5, 0, 8, 0, 5, 0, 6, 0, 5, 0, 8, 0, 5, 0}; // this array stores the drum elements combination for each cycle (semiquaver or sixteenth) of the drumbeat 
byte timeSignature = 44;
int drumbeatID = 0; // ID number for each drumbeat

// 
int i; // for counting the time in the "for loop" of the cyclePlayer function
int b; // for the "for loop" that counts the number of cycles

// control interface
#define switchPlayStop 2  // switch bettween playing and stop
#define buttonSelect 3    // tact button that select the drumbeat to play







void setup(void) {

  // define pins for each servo
  pinMode (5, OUTPUT);
  pinMode (6, OUTPUT);
  pinMode (9, OUTPUT);

  // attach servos to those pins
  servo1.attach(5); //caja 1
  servo2.attach(6); //caja 2
  servo3.attach(9); //bombo
  delay(150);

  // put all servos on rest position
  servo1.write(restServo1);
  servo2.write(restServo2);
  servo3.write(restServo3);
  delay(300);

  // Setting hihat and led pinmodes
  pinMode (noiseGenerator, OUTPUT);
  digitalWrite(noiseGenerator, LOW);
  pinMode (noiseLed, OUTPUT);
  digitalWrite(noiseLed, LOW);

  // Setting control interface pinmodes
  pinMode (switchPlayStop, INPUT_PULLUP);
  pinMode (buttonSelect, INPUT_PULLUP);

}



void loop(void) {
  if (switchPlayStop == LOW) { //if the play/stop switch is ON (logical LOW)
    
    //We start a "for loop" to play a semiquaver cycle a maximum of 16 times, for every bar
    for (b = 0; b < 16; b = b + 1) {
      
      selectDrumBeat(); // select the drumbeat based on the drumbeatID selected
      cyclePlayer(cycleNumbers[b]); //play the semiquaver cycle for each number stored in the cycleNumbers array

      // if we reach the maximum number of cycles (16 for 4/4, 12 for 6/8, 12/8 or 3/4) we start again
      if (b == 11 && (timeSignature == 68 || timeSignature == 128)) {
        b = -1;
      }
      if (b == 15) {
        b = -1;
      }
    }
    
  }
  // If the play/stop switch is OFF (logical HIGH) we enter settingMode
  else {
    settingMode(); // function that lets you choose between different drumbeats and wait for the play switch to be activated
  }
}





// CYCLE PLAYER
// this functions runs a semiquaver cycle every time is called.
void cyclePlayer(int cycleNumber) { // we store every single value of the cycleNumbers array into the cycleNumber variable
  timeStartCycle = millis(); // we save the starting time, to compare it later with the actual time and get the time past

  //set both snare servos to rest position in case they were on hit position
  servo1.write(restServo1);
  servo2.write(restServo2);

  //we star a "for loop" for the entire duration of every semiquaver cycle
  for (i = 0; i < timeTotalCycle; i++) {

    //now we send the hitting commands on time so they reach their destination on time (the end of the semiquaver cycle)

    // if we reach the time to send the command to the snare on servo1. We start checking the element that takes the longest time to move, in this case is servo1, in yours could be different.
    if ((millis() - timeStartCycle >= timeTotalCycle - timeSnare1)) {
      // we check if this is the one snare of the two, that has to be played,
      // and also, if in this cycle a snare has to be played at, all based on the cycleNumber number (this number define the cobination of drum elements)
      if ((previousSnare == 2) && ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) {
        servo1.write(hitServo1 + 5); // we send the servo command
      }
      // if we reach the time to send the command to the snare on servo2
      if (millis() - timeStartCycle >= timeTotalCycle - timeSnare2) {
        // we check if this is the one snare of the two, that has to be played, and also if in this cycle a snare has to be played at all
        if ((previousSnare == 1) && ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) {
          servo2.write(hitServo2 - 5); // we send the servo command
        }
        // we now check if we reached the time to send the command to the third servo, the kick
        if ((millis() - timeStartCycle >= timeTotalCycle - timeKick)) {
          // we check if in this cycle a snare has to be played
          if ( (cycleNumber == 9) || (cycleNumber == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) {
            // we check on what position was previosly the servo, either hiting the left or the right piezo, this state will be saved later
            if (previousKick == 0) {
              servo3.write(hitServo3);
            }
            else if (previousKick == 1) {
              servo3.write(restServo3);
            }
          }
          // finally, we check if the time to turn on the white noise generator was reached, for the hihat
          if (millis() - timeStartCycle >= (timeTotalCycle - timeHihat)) {
            // we check if in this cycle the hihat has to be played
            if ( (cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 6) || (cycleNumber == 5) ) {
              digitalWrite(noiseLed, HIGH);
              digitalWrite(noiseGenerator, HIGH);
            }
          }
        }
      }
    }
    // This is where the semiquaver cycle ends.

    // HIHAT DURATION
    // turn off hi-hat noise generator, but only under the following conditions:
    //    //if the noise-generator was ON        //the time past exceed the time set as sustain          //the time past does not reach yet the point where a new noise could start
    if ( (digitalRead(noiseGenerator) == HIGH) && (millis() - timeStartCycle >= sustainTimeHihat) && (millis() - timeStartCycle < (timeTotalCycle - (timeHihat + 10))) ) {
      digitalWrite(noiseGenerator, LOW);
      digitalWrite(noiseLed, LOW);
    }

    // Check if the play/stop switch is switched OFF
    if (digitalRead(switchPlayStop) == HIGH) {
      i = timeTotalCycle;                //reset time counting
      digitalWrite(noiseGenerator, LOW);  //turn off noise
      digitalWrite(noiseLed, LOW);        //turn off noise
      servo1.write(restServo1);           //stop servos
      servo2.write(restServo2);           //stop servos
    }

    delay(1);
  }

  // If one of the Snares was hit, then declare it as the previous one, in order to hit the other one the next time
  if ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) {
    switch (previousSnare) {
      case 1:
        previousSnare = 2;
        break;
      case 2:
        previousSnare = 1;
        break;
      default:
        break;
    }
  }

  // If one of the piezo kick was hit, then declare it as the previous one, in order to hit the other one the next time
  if ( (cycleNumber == 9) || (cycleNumber == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) {
    switch (previousKick) {
      case 0:
        previousKick = 1;
        break;
      case 1:
        previousKick = 0;
        break;
      default:
        break;
    }
  }
}




// SETTING MODE
// this mode is activated when the play/stop switch is swiched OFF (logical LOW)
void settingMode() {
  while (digitalRead(switchPlayStop) == HIGH) { // keep doing the following actions while the play/stop switch is OFF
    if (digitalRead(buttonSelect) == LOW) { // if the selection button is pressed (logical LOW), we change the drumbeat
      drumbeatID ++; // we select the next drumbeat each time the button is pressed 
      selectDrumBeat(); // select the drumbeat based on the drumbeatID
      // OPTIONAL
      // Here you can add whatever piece of code to indicate which drumbeat is being selected,
      // this could be turning in a led, sending a serial.print(), etc.
      if (drumbeatID > 7) { //in case we exceed the total number of drumbeats availabe (), we go back to 0.
        drumbeatID = 0;
      }
      delay(100); //delay to avoid detecting button twice when pressed once
    }
  }
}






// SELECT DRUMBEAT
// this functions uses the value stored in drumbeatID, to modify all the variables needed in order to choose between drumbeats.
void selectDrumBeat() {
  switch (drumbeatID) {
    case 1: // DiscoBasic
      timeTotalCycle = 124;
      timeSignature = 44;
      cycleNumbers[0] = 1;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 0;
      cycleNumbers[4] = 4;
      cycleNumbers[5] = 0;
      cycleNumbers[6] = 5;
      cycleNumbers[7] = 0;
      cycleNumbers[8] = 1;
      cycleNumbers[9] = 0;
      cycleNumbers[10] = 5;
      cycleNumbers[11] = 0;
      cycleNumbers[12] = 4;
      cycleNumbers[13] = 0;
      cycleNumbers[14] = 5;
      cycleNumbers[15] = 0;
      break;
    case 2: // NewBugalú
      timeTotalCycle = 155;
      timeSignature = 44;
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 0;
      cycleNumbers[4] = 8;
      cycleNumbers[5] = 0;
      cycleNumbers[6] = 5;
      cycleNumbers[7] = 3;
      cycleNumbers[8] = 5;
      cycleNumbers[9] = 3;
      cycleNumbers[10] = 6;
      cycleNumbers[11] = 0;
      cycleNumbers[12] = 8;
      cycleNumbers[13] = 0;
      cycleNumbers[14] = 5;
      cycleNumbers[15] = 0;
      break;
    case 3: // HiHat16
      timeTotalCycle = 134;
      timeSignature = 44;
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 5;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 5;
      cycleNumbers[4] = 8;
      cycleNumbers[5] = 5;
      cycleNumbers[6] = 5;
      cycleNumbers[7] = 5;
      cycleNumbers[8] = 6;
      cycleNumbers[9] = 5;
      cycleNumbers[10] = 5;
      cycleNumbers[11] = 5;
      cycleNumbers[12] = 8;
      cycleNumbers[13] = 5;
      cycleNumbers[14] = 5;
      cycleNumbers[15] = 5;
      break;
    case 4: // SwingGroove
      timeTotalCycle = 153;
      timeSignature = 128; // (12/8)
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 0;
      cycleNumbers[3] = 6;
      cycleNumbers[4] = 0;
      cycleNumbers[5] = 5;
      cycleNumbers[6] = 6;
      cycleNumbers[7] = 0;
      cycleNumbers[8] = 0;
      cycleNumbers[9] = 6;
      cycleNumbers[10] = 0;
      cycleNumbers[11] = 5;
      break;
    case 5: // BossaNova
      timeTotalCycle = 200;
      timeSignature = 44;
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 5;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 9;
      cycleNumbers[4] = 6;
      cycleNumbers[5] = 5;
      cycleNumbers[6] = 8;
      cycleNumbers[7] = 6;
      cycleNumbers[8] = 6;
      cycleNumbers[9] = 5;
      cycleNumbers[10] = 8;
      cycleNumbers[11] = 6;
      cycleNumbers[12] = 9;
      cycleNumbers[13] = 5;
      cycleNumbers[14] = 5;
      cycleNumbers[15] = 6;
      break;
    case 6: // ShuffleGroove
      timeTotalCycle = 134;
      timeSignature = 128; // (12/8)
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 9;
      cycleNumbers[4] = 0;
      cycleNumbers[5] = 5;
      cycleNumbers[6] = 6;
      cycleNumbers[7] = 0;
      cycleNumbers[8] = 5;
      cycleNumbers[9] = 9;
      cycleNumbers[10] = 0;
      cycleNumbers[11] = 5;
      break;
    case 7: // Franco's beat
      timeTotalCycle = 142;
      timeSignature = 44;
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 1;
      cycleNumbers[4] = 8;
      cycleNumbers[5] = 0;
      cycleNumbers[6] = 6;
      cycleNumbers[7] = 0;
      cycleNumbers[8] = 5;
      cycleNumbers[9] = 1;
      cycleNumbers[10] = 6;
      cycleNumbers[11] = 0;
      cycleNumbers[12] = 8;
      cycleNumbers[13] = 0;
      cycleNumbers[14] = 6;
      cycleNumbers[15] = 0;
      break;
    default: // Basic 4/4
      timeTotalCycle = 144;
      timeSignature = 44;
      cycleNumbers[0] = 6;
      cycleNumbers[1] = 0;
      cycleNumbers[2] = 5;
      cycleNumbers[3] = 0;
      cycleNumbers[4] = 8;
      cycleNumbers[5] = 0;
      cycleNumbers[6] = 5;
      cycleNumbers[7] = 0;
      cycleNumbers[8] = 6;
      cycleNumbers[9] = 0;
      cycleNumbers[10] = 5;
      cycleNumbers[11] = 0;
      cycleNumbers[12] = 8;
      cycleNumbers[13] = 0;
      cycleNumbers[14] = 5;
      cycleNumbers[15] = 0;
      break;
  }
}

Schematics

Full Diagram
Full diagram of the project
Instructable graphics full diagram qphzjjgsal
Kick Schematic
Amplifier circuit for the piezos in the kick system
Instructable graphics kick schematic wlanvpss9y
Snare Schematic
Amplifier circuit for the electret microphone in the Snare system
Instructable graphics snares schematic cswjvzu59n
HiHat Generator Schematic
White noise generator and high-pass filter to replicate the cymbals sound.
Instructable graphics hihat schematic tjwtp8mc5t
Audio signal mixer
D audio pm3 2ihuruh0ti

Comments

Similar projects you might like

Amazing 6WD Off-Road Robot | Arduino RC Robot

Project tutorial by Jithin Sanal

  • 4,098 views
  • 1 comment
  • 33 respects

Arduino Bluetooth Robot for Android Device

Project showcase by

  • 2,935 views
  • 1 comment
  • 15 respects

Tito - Arduino UNO 3D-printed robot

Project tutorial by Camilo Parra Palacio

  • 13,913 views
  • 13 comments
  • 43 respects

Obstacles Avoiding Robot With Servo Motor

Project tutorial by Sora JY

  • 8,441 views
  • 3 comments
  • 26 respects

Arduino Robot w/ GoPro and FPV iPhone Control via Bluetooth

Project in progress by

  • 4,822 views
  • 5 comments
  • 33 respects
Add projectSign up / Login