Arduino-Controlled Robotic Drum
Intro: Arduino-Controlled Robotic Drum
For years I have been telling anyone who listens that I was going to build a robotic drum. Most people kind of shrugged indifferently. Even as I built it, most people kind of glanced over at it and conveyed doubtfulness. It seemed like no one but myself was convinced of just how awesome it was going to be.
I received a lot of snarky comments about how I was making a strange annoying noise maker. When I finally go it set up for the trial run, I quickly silenced the naysayers. This robotic drum blew everyone away. I was finally able to convey my vision and explain why someone would ever want to build a robotic drum.
The reason to build a robotic drum is because it is plain super-awesome. It keeps a beat like clockwork. You can slow down and speed up any drum beat with precision and ease. It can even play things a real human drummer could never do.
I intend to use mine for rocking out. The current plan is to program it with different drum beats and play guitar along with it.
I decided to use linear actuators (car door lock motors to be exact), and Arduinos with motor controller shields simply for ease of use and duplication. I am sure there are other more elegant ways to interface with the motors, but this is by far the easiest.
STEP 1: Go Get Stuff
You will need:
(x1) Drum set
(x12) Drum sticks
(x2) Cymbal stands
(x12) Car door lock actuator motor
(x6) Arduino Uno
(x6) Arduino Motor Shield
(x1) 7" x 5" x 3" project enclosure
(x1) Terminal strip
(x2) 18 AWG speaker wire
(x3) Panel mount power socket
(x1) 1/4" mono jack
(x1) 1/4" mono plug
(x1) 4" zip tie
(x1) Stranded 22 AWG red and black wire spools
(x1) Assorted shrink tube
(x3) 9V 2A power adapters
(x1) Power strip
(x1) 7 port USB hub
(x6) 6' USB A to B cable
(x1) 4' x 8' x 1/4" plywood sheet
(x4) 1/2" pipe mounting flange
(x1) 24" x 1/2" threaded pipe
(x1) 18" x 1/2" threaded pipe
(x8) 1/2" pipe L-bracket
(x2) 1/2" pipe T-bracket
(x2) 1" x 1/2" threaded pipe
(x4) 2" x 1/2" threaded pipe
(x4) 2-1/2" x 1/2" threaded pipe
(x2) 3" x 1/2" threaded pipe
(x3) 3/4" x 10' 22 gauge steel hanger strap
(x16) 8 - 1/2" wood screws
(x20) 1/4 x 5" bolts
(x4) 1/4 x 2" bolts
(x1) Box of 1/4 nuts
(x22) 6-32 x 2" nuts and bolts
(x4) 6-32 x 1" nuts and bolts
(x11) 1-1/2" binding posts
(x20) 1-1/2" (1/4" i.d.) spacers
(x18) 4-40 x 1-1.2" nuts and bolts
(x18) 1/4" (1/8" i.d.) spacers
You will also need to download the attached files and laser cut (or cut the old fashioned way) the following:
(x16) Drum brackets
(x6) Cymbal brackets
(x4) Cymbal bracket circle spacers
(x2) Kick drum brackets
Please note that some of the links on this page contain Amazon affiliate links. This does not change the price of any of the items for sale. However, I earn a small commission if you click on any of those links and buy anything. I reinvest this money into materials and tools for future projects. If you would like an alternate suggestion for a supplier of any of the parts, please let me know.
STEP 2: Attach the Motor
Take two of the pieces of the standard drum bracket (without Arduino mounting holes) and sandwich a motor in-between. Fasten it through the center mounting holes using 6-32 nuts and bolts.
STEP 3: Make Another
Once the bolts are passed through, make another motor bracket "sandwich" like you did in the last step.
STEP 4: Motor Pair
Repeat for all of the other holes.
Thread a nut all the way down one of the bolts to hold it in place, and then repeat for all of the other bolts
Slide a spacer over each of the bolts and then thread more nuts on to hold them all in place.
Slide the other motor bracket "sandwich" onto the bolt.
Fasten everything securely in place with another nut.
STEP 5: Drill a Hole
Make a mark at 5-1/8" and 7-1/4".
Drill down through all of these marks with a 3/16" drill bit, to leave an identical pair of holes in each stick
Repeat this process 5 more times, to make 6 sets of drilled drum sticks.
STEP 6: Attach Drum Sticks
Pass a binding post from the outside of the assembly through the corner pivot hole, through the hole in the drumstick closer to the tip, and then through the inner pivot hole.
Fasten the binding post shut.
Zip tie the drum sticks to the motor assembly using the other drilled hole.
Repeat this process for the other motor.
STEP 7: Build More
STEP 8: Glue and Clamp
To attach this wood piece, simply lay down a little bit of wood glue, align the pre-drilled 1/8" pilot holes, and then once aligned, clamp them in place.
Don't forget to make certain that one of the pieces you are gluing the wood piece to has holes for mounting the Arduino.
STEP 9: Motor Brackets
STEP 10: Assemble
STEP 11: Build the Mount
Connect L-brackets to each end of the respective threaded pipes.
Thread a 2" section of threaded pipe onto the end of each L-bracket.
Again, put L-brackets on the end of each respective threaded pipe.
Thread a 1" section of threaded pipe onto the end of each L-bracket.
Finally, attach flanges to the end of each threaded pipe.
STEP 12: Attach
Rotate the flanges as necessary so that the pilot holes are aligned with the flange's mounting holes.
Fasten the drumstick assembly to the mounting bracket place with wood screws.
STEP 13: 18" Pipe
STEP 14: Connect Drum Sticks
Again, zip tie the drum sticks to the linear motor assembly.
STEP 15: Clamp and Glue Again
Make sure that when you do this, the extra piece of wood will be on the outside when you make your motor "sandwich."
Simply lay down a little bit of wood glue, align the pre-drilled 1/8" pilot holes, and then once aligned, clamp them in place.
STEP 16: Assemble
Assemble it accordingly, with the extra bits of wood facing out.
Don't forget to install the Arduino mounting screws as well.
STEP 17: Build Another Mount
Connect L-brackets to each end of the respective threaded pipes.
Thread a 2-1/2" section of threaded pipe onto the end of each L-bracket.
Again, put L-brackets on the end of each respective threaded pipe.
Thread a 2" section of threaded pipe onto the end of each L-bracket.
Finally, attach flanges to the end of each threaded pipe.
STEP 18: Fasten
STEP 19: 24" Pipe
STEP 20: Connect the Drum Stick
STEP 21: Prepare the Kick Drum Pedal
Remove the spring that is keeping tension on the pedal's rotational assembly.
Using the mounting holes in the wooden bracket as a guide, drill 1/4" holes on both sides of the pedal. This should result in 2 holes on each side of the pedal.
STEP 22: Attach
STEP 23: Spacers
Insert 5" x 1/4 bolts through the bracket's structural mounting holes, using the pens as spacers in-between the two.
Fasten each bolt firmly in place with a nut.
STEP 24: Attach Motor
Attach the motor to the wooden bracket using 6-32 nuts and bolts.
Zip tie the motor shaft to the rotational pivot of the kick drum pedal.
STEP 25: Socket
If the motor does not have red or black wires, designate one of the colors to be ground and the other to be power. In this case, the green wire will be ground.
STEP 26: Jack
Solder the marked edge of the speaker wire to the ground terminal.
Solder the unmarked edge to the tip terminal.
Reassemble the plug when you are done.
STEP 27: Snare
STEP 28: Toms
STEP 29: Floor Tom
STEP 30: Cymbal Strikers
STEP 31: Kick Drum
STEP 32: Plug in the Shields
However, before you go and do this, bend the shields Vin pin so that it will not plug in to the Arduino. This is done to prevent the Arduino from getting directly connected to the voltage input on the motor controller, which is rather high and runs the risk of spiking.
Alternately, if you don't want to preserve this functionality on the shield, cut the pin away entirely.
STEP 33: Program the Arduinos
Hi Hat Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 129) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 130) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 144) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
Snare Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 131) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 132) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 160) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
Cymbal, and Kick Drum Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 133) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 134) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 176) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
Small Tom Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 135) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 136) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 192) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
Large Tom Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 137) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 138) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 208) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
Floor Tom Arduino:
/* This is code for a robotic drum created by Randy Sarafan. For more information, visit: https://www.instructables.com/id/Arduino-Controlled-Robotic-Drum/ This example code is in the public domain. */ int event = 0; int strikelegnth = 80; int incomingByte = 0; void setup() { //establish motor direction toggle pins pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards??? pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards??? //establish motor brake pins pinMode(9, OUTPUT); //brake (disable) CH A pinMode(8, OUTPUT); //brake (disable) CH B digitalWrite(9, LOW); //ENABLE CH A digitalWrite(8, LOW); //ENABLE CH B Serial.begin(57600); cli();//stop interrupts //set timer2 interrupt every 128us TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 // set compare match register for 7.8khz increments OCR2A = 255;// = (16*10^6) / (7812.5*8) - 1 (must be <256) // turn on CTC mode TCCR2A |= (1 << WGM21); // Set CS11 bit for 8 prescaler TCCR2B |= (1 << CS11); // enable timer compare interrupt TIMSK2 |= (1 << OCIE2A); sei();//allow interrupts } void loop() { if(event == 1){ if (incomingByte == 139) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 140) { //start down digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A event = 0; } if (incomingByte == 224) { //start down digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, LOW); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, LOW); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //strike time delay(strikelegnth); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A delay(10); //go back digitalWrite(9, LOW); //Disengage the Brake for Channel A digitalWrite(12, HIGH); //Sets direction of CH A analogWrite(3, 255); //Moves CH A digitalWrite(8, LOW); //Disengage the Brake for Channel A digitalWrite(13, HIGH); //Sets direction of CH A analogWrite(11, 255); //Moves CH A //recoil time delay(40); //stop digitalWrite(8, HIGH); //Engage the Brake for Channel A digitalWrite(9, HIGH); //Engage the Brake for Channel A event = 0; } } } ISR(TIMER2_COMPA_vect) { do{ if (Serial.available()){ incomingByte = Serial.read(); event = 1; }//end if serial available }//end do while (Serial.available() > 8); }
STEP 34: Attach
Remove the nuts from the Arduino mounting bolts that were inserted earlier.
Next, slide 1/4" spacers onto the bolts.
Finally, mount the Arduino using these bolts and fasten them firmly in place with nuts.
STEP 35: Extend
Cover any exposed wires with heat shrink tubing.
STEP 36: Plug
For the most part, it is not really important which is which, so long as it is a single motor to a single channel.
The one exception to this rule is the Arduino that controls the kick drum and the cymbal, but we will touch more on this in a moment.
STEP 37: Drill
Drill each of this marks with a 5/16" drill bit.
STEP 38: Jacks
Mount the jacks into three of the holes side-by-side on one side of the case.
STEP 39: Wire It Up
Wire them up such that it is alternating power and ground, and each jack is supplying power to two pairs on the strip. In other words, each jack should be supplying power and ground twice.
Connect the speaker wire to the first pair so that the marked edge of the wire is going to ground and the unmarked edge is going to power. Repeat this for all subsequent pairs.
STEP 40: Case Closed
Make sure the terminals strip is nicely situated inside the box.
Put the lid onto the power box and fasten it shut.
STEP 41: Set Up
The snare and floor tom (not pictured) can just stand on the floor in their typical places.
STEP 42: Cymbals
These cymbals and strikers can then be positioned in their normal drum kit location.
STEP 43: Plug Some Stuff In
Plug the marked edge of the 1/4" plug cable into the "Motor A" minus terminal on the cymbal assembly's motor shield. Plug the unmarked edge into the plus terminal of the cymbal assembly's motor shield. Insert the 1/4" plug into the 1/4" jack on the kick drum.
Plug the three 9V power adapters into the power strip, and insert their barrel plugs into the M-type jacks on the power supply box.
Plug a USB wire into each of the Arduinos and then plug them all into the USB hub.
STEP 44: Sequence
To use the drum kit, first connect the USB hub to your computer and make sure the power strip is powered on.
Next, visit the Max MSP site and download Max5 Runtime (Mac / Windows).
Download the attached zip file with the "robo drums sequencer57600" Max patch.
Run "robo drums sequencer57600.maxpat" using Max5 Runtime.
This Max patch was created by the amazing Amanda Ghassaei - Max MSP Ninja and loosely certified Instructables Genius. This project would have taken much longer, and probably have not been quite as awesome, without her world class Max MSP skills.
Did you find this useful, fun, or entertaining?
Follow @madeineuphoria to see my latest projects.
105 Comments
musiklusion 4 years ago
Thanks once more! Andy
todd4 1 year ago
randofo 1 year ago
todd4 1 year ago
randofo 1 year ago
Are you planning to control the motor with the Arduino and motor shield? Or something else?
todd4 1 year ago
My nephew will be able to use sensor that fits on his thumb and his eye gaze to trigger a "start" sequence for each piece. The possibilities are endless. I hacked some Arduino code to make this work but really need some help fine tuning the code. I am more than happy to pay someone to help by the way.
Here is the current result...
https://www.dropbox.com/s/fhekoyvh25lgheq/Brackets...
uxracer 1 year ago
I'm a home recordist looking for a way to 'play' my drums when I am placing mics or troubleshooting rogue rattles, resonances and other issues.
Wondering if you would ever consider selling one or two of these units?
todd4 1 year ago
vega3000 3 years ago
1. I don't want to see an electric cable. I suppose it's possible to replace to power supply by a battery ?
2. I want, by remote (bluetooth, radio, or other) start a sequence drum. Is it possible ?
Tx
orestisme123 3 years ago
By your experience, did these actuators overheat a lot? Would they have problems to hit 3 times per second for example? I see that you are using 2 per drum, so I'm afraid they cant be too fast..
randofo 3 years ago
I never had trouble with overheating.
etonblue 3 years ago
I put it together and adapted some of your code to test it with a simple button.
However, when I plug it in (I am using a +12v/1.5a DC wall wart I had lying around), the motor shield (specifically the chip in the middle) immediately gets extremely hot and is too hot to touch after about 10 seconds (I made sure to bend the vin pin so as not to fry my uno). The actuator/button combo works fine- but I can't figure out why it's heating up so fast and am afraid to leave it on too long for fear of frying it.
Any thoughts? Could it be my power supply? My wiring? The wall wart is wired directly to the shield and the actuator to Channel A. The button is plugged into the shield (one wire in pin 2 and the other in GND). The code I am using is pretty simple: https://pastebin.com/TwM1zaAs.
I assumed that with the motor "off" (brake channel set to HIGH), that it wouldn't be drawing any power- but that doesn't appear to be the case. If you are able to control so many actuators without an overheating problem- then the issue is obviously on my end.
Would appreciate any thoughts (and sorry for the long comment),
eb
randofo 3 years ago
lee.h.fox 3 years ago
lee.h.fox 3 years ago
Seems to me, though, that the one thing missing is the operation of the foot pedal for the hi-hat. Anyone have any ideas on how to tackle that issue?
randofo 3 years ago
That said, I thought about it originally but it seemed like a pain in the neck (at the time). I think a beefy solenoid might work. Alternatively, you would need some sort of lever mechanism to pivot up and down to get the mechanical advantage.
lee.h.fox 3 years ago
https://www.youtube.com/watch?v=VGCvinFlEjM&feature=youtu.be
Chad Bridgewater 3 years ago
MrErdreich 3 years ago
WadeE6 5 years ago