Components and supplies
Piezo Element
SG90 Micro-servo motor
Tactile Switch, Top Actuated
Slide Switch
Breadboard (generic)
SparkFun Electret Microphone Breakout
LAOMAO DC-DC Step-up Boost Power Supply Module Adjustable Power Apply 3V-32V to 5V-35V XL6009 400KHz 4A Max
Ultra-small LM2596 Power Supply Module DC / DC BUCK 3A adjustable buck Module Regulator Ultra LM2596S Compatible With Arduino by Atomic Market
Transistor - NPN, 60V 200mA (2N3904)
Rotary potentiometer (generic)
Arduino UNO
Tools and machines
Soldering iron (generic)
Mastech MS8217 Autorange Digital Multimeter
Apps and platforms
Arduino IDE
Project description
Code
DrumCube, a robot drummer
arduino
1// DrumCube - a robot drummer 2// written by Franco Molina @artefrancomolina 3 4// Setting servos 5#include <Servo.h> 6Servo servo1; 7Servo servo2; 8Servo servo3; 9 10// Servo positions 11// this will differ depending on your servos, please test yours to find out the values that best suit you 12byte restServo1 = 12; 13byte hitServo1 = 21; 14byte restServo2 = 123; 15byte hitServo2 = 114; 16byte restServo3 = 4; 17byte hitServo3 = 19; 18 19// Setting the HiHat white noise generator 20#define noiseGenerator 12 21#define noiseLed 13 //turn on led as a visual representation of the noise being generated 22 23// Setting servo times 24// this will also differ depending on your servos, please test yours to find out the values that best suit you 25byte timeSnare1 = 110; 26byte timeSnare2 = 108; 27byte timeKick = 71; 28byte timeHihat = 20; 29byte sustainTimeHihat = 70; 30 31// Setting previous Snare and Kick 32byte previousSnare = 2; 33byte previousKick = 0; 34 35 36// Setting cycle times 37static unsigned long timeStartCycle; 38static 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 39 40// Bar and Cycles variables 41int cycleNumber; 42int 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 43byte timeSignature = 44; 44int drumbeatID = 0; // ID number for each drumbeat 45 46// 47int i; // for counting the time in the "for loop" of the cyclePlayer function 48int b; // for the "for loop" that counts the number of cycles 49 50// control interface 51#define switchPlayStop 2 // switch bettween playing and stop 52#define buttonSelect 3 // tact button that select the drumbeat to play 53 54 55 56 57 58 59 60void setup(void) { 61 62 // define pins for each servo 63 pinMode (5, OUTPUT); 64 pinMode (6, OUTPUT); 65 pinMode (9, OUTPUT); 66 67 // attach servos to those pins 68 servo1.attach(5); //caja 1 69 servo2.attach(6); //caja 2 70 servo3.attach(9); //bombo 71 delay(150); 72 73 // put all servos on rest position 74 servo1.write(restServo1); 75 servo2.write(restServo2); 76 servo3.write(restServo3); 77 delay(300); 78 79 // Setting hihat and led pinmodes 80 pinMode (noiseGenerator, OUTPUT); 81 digitalWrite(noiseGenerator, LOW); 82 pinMode (noiseLed, OUTPUT); 83 digitalWrite(noiseLed, LOW); 84 85 // Setting control interface pinmodes 86 pinMode (switchPlayStop, INPUT_PULLUP); 87 pinMode (buttonSelect, INPUT_PULLUP); 88 89} 90 91 92 93void loop(void) { 94 if (switchPlayStop == LOW) { //if the play/stop switch is ON (logical LOW) 95 96 //We start a "for loop" to play a semiquaver cycle a maximum of 16 times, for every bar 97 for (b = 0; b < 16; b = b + 1) { 98 99 selectDrumBeat(); // select the drumbeat based on the drumbeatID selected 100 cyclePlayer(cycleNumbers[b]); //play the semiquaver cycle for each number stored in the cycleNumbers array 101 102 // if we reach the maximum number of cycles (16 for 4/4, 12 for 6/8, 12/8 or 3/4) we start again 103 if (b == 11 && (timeSignature == 68 || timeSignature == 128)) { 104 b = -1; 105 } 106 if (b == 15) { 107 b = -1; 108 } 109 } 110 111 } 112 // If the play/stop switch is OFF (logical HIGH) we enter settingMode 113 else { 114 settingMode(); // function that lets you choose between different drumbeats and wait for the play switch to be activated 115 } 116} 117 118 119 120 121 122// CYCLE PLAYER 123// this functions runs a semiquaver cycle every time is called. 124void cyclePlayer(int cycleNumber) { // we store every single value of the cycleNumbers array into the cycleNumber variable 125 timeStartCycle = millis(); // we save the starting time, to compare it later with the actual time and get the time past 126 127 //set both snare servos to rest position in case they were on hit position 128 servo1.write(restServo1); 129 servo2.write(restServo2); 130 131 //we star a "for loop" for the entire duration of every semiquaver cycle 132 for (i = 0; i < timeTotalCycle; i++) { 133 134 //now we send the hitting commands on time so they reach their destination on time (the end of the semiquaver cycle) 135 136 // 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. 137 if ((millis() - timeStartCycle >= timeTotalCycle - timeSnare1)) { 138 // we check if this is the one snare of the two, that has to be played, 139 // 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) 140 if ((previousSnare == 2) && ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) { 141 servo1.write(hitServo1 + 5); // we send the servo command 142 } 143 // if we reach the time to send the command to the snare on servo2 144 if (millis() - timeStartCycle >= timeTotalCycle - timeSnare2) { 145 // 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 146 if ((previousSnare == 1) && ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) { 147 servo2.write(hitServo2 - 5); // we send the servo command 148 } 149 // we now check if we reached the time to send the command to the third servo, the kick 150 if ((millis() - timeStartCycle >= timeTotalCycle - timeKick)) { 151 // we check if in this cycle a snare has to be played 152 if ( (cycleNumber == 9) || (cycleNumber == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) { 153 // we check on what position was previosly the servo, either hiting the left or the right piezo, this state will be saved later 154 if (previousKick == 0) { 155 servo3.write(hitServo3); 156 } 157 else if (previousKick == 1) { 158 servo3.write(restServo3); 159 } 160 } 161 // finally, we check if the time to turn on the white noise generator was reached, for the hihat 162 if (millis() - timeStartCycle >= (timeTotalCycle - timeHihat)) { 163 // we check if in this cycle the hihat has to be played 164 if ( (cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 6) || (cycleNumber == 5) ) { 165 digitalWrite(noiseLed, HIGH); 166 digitalWrite(noiseGenerator, HIGH); 167 } 168 } 169 } 170 } 171 } 172 // This is where the semiquaver cycle ends. 173 174 // HIHAT DURATION 175 // turn off hi-hat noise generator, but only under the following conditions: 176 // //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 177 if ( (digitalRead(noiseGenerator) == HIGH) && (millis() - timeStartCycle >= sustainTimeHihat) && (millis() - timeStartCycle < (timeTotalCycle - (timeHihat + 10))) ) { 178 digitalWrite(noiseGenerator, LOW); 179 digitalWrite(noiseLed, LOW); 180 } 181 182 // Check if the play/stop switch is switched OFF 183 if (digitalRead(switchPlayStop) == HIGH) { 184 i = timeTotalCycle; //reset time counting 185 digitalWrite(noiseGenerator, LOW); //turn off noise 186 digitalWrite(noiseLed, LOW); //turn off noise 187 servo1.write(restServo1); //stop servos 188 servo2.write(restServo2); //stop servos 189 } 190 191 delay(1); 192 } 193 194 // If one of the Snares was hit, then declare it as the previous one, in order to hit the other one the next time 195 if ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber == 4) || (cycleNumber == 3)) { 196 switch (previousSnare) { 197 case 1: 198 previousSnare = 2; 199 break; 200 case 2: 201 previousSnare = 1; 202 break; 203 default: 204 break; 205 } 206 } 207 208 // 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 209 if ( (cycleNumber == 9) || (cycleNumber == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) { 210 switch (previousKick) { 211 case 0: 212 previousKick = 1; 213 break; 214 case 1: 215 previousKick = 0; 216 break; 217 default: 218 break; 219 } 220 } 221} 222 223 224 225 226// SETTING MODE 227// this mode is activated when the play/stop switch is swiched OFF (logical LOW) 228void settingMode() { 229 while (digitalRead(switchPlayStop) == HIGH) { // keep doing the following actions while the play/stop switch is OFF 230 if (digitalRead(buttonSelect) == LOW) { // if the selection button is pressed (logical LOW), we change the drumbeat 231 drumbeatID ++; // we select the next drumbeat each time the button is pressed 232 selectDrumBeat(); // select the drumbeat based on the drumbeatID 233 // OPTIONAL 234 // Here you can add whatever piece of code to indicate which drumbeat is being selected, 235 // this could be turning in a led, sending a serial.print(), etc. 236 if (drumbeatID > 7) { //in case we exceed the total number of drumbeats availabe (), we go back to 0. 237 drumbeatID = 0; 238 } 239 delay(100); //delay to avoid detecting button twice when pressed once 240 } 241 } 242} 243 244 245 246 247 248 249// SELECT DRUMBEAT 250// this functions uses the value stored in drumbeatID, to modify all the variables needed in order to choose between drumbeats. 251void selectDrumBeat() { 252 switch (drumbeatID) { 253 case 1: // DiscoBasic 254 timeTotalCycle = 124; 255 timeSignature = 44; 256 cycleNumbers[0] = 1; 257 cycleNumbers[1] = 0; 258 cycleNumbers[2] = 5; 259 cycleNumbers[3] = 0; 260 cycleNumbers[4] = 4; 261 cycleNumbers[5] = 0; 262 cycleNumbers[6] = 5; 263 cycleNumbers[7] = 0; 264 cycleNumbers[8] = 1; 265 cycleNumbers[9] = 0; 266 cycleNumbers[10] = 5; 267 cycleNumbers[11] = 0; 268 cycleNumbers[12] = 4; 269 cycleNumbers[13] = 0; 270 cycleNumbers[14] = 5; 271 cycleNumbers[15] = 0; 272 break; 273 case 2: // NewBugalú 274 timeTotalCycle = 155; 275 timeSignature = 44; 276 cycleNumbers[0] = 6; 277 cycleNumbers[1] = 0; 278 cycleNumbers[2] = 5; 279 cycleNumbers[3] = 0; 280 cycleNumbers[4] = 8; 281 cycleNumbers[5] = 0; 282 cycleNumbers[6] = 5; 283 cycleNumbers[7] = 3; 284 cycleNumbers[8] = 5; 285 cycleNumbers[9] = 3; 286 cycleNumbers[10] = 6; 287 cycleNumbers[11] = 0; 288 cycleNumbers[12] = 8; 289 cycleNumbers[13] = 0; 290 cycleNumbers[14] = 5; 291 cycleNumbers[15] = 0; 292 break; 293 case 3: // HiHat16 294 timeTotalCycle = 134; 295 timeSignature = 44; 296 cycleNumbers[0] = 6; 297 cycleNumbers[1] = 5; 298 cycleNumbers[2] = 5; 299 cycleNumbers[3] = 5; 300 cycleNumbers[4] = 8; 301 cycleNumbers[5] = 5; 302 cycleNumbers[6] = 5; 303 cycleNumbers[7] = 5; 304 cycleNumbers[8] = 6; 305 cycleNumbers[9] = 5; 306 cycleNumbers[10] = 5; 307 cycleNumbers[11] = 5; 308 cycleNumbers[12] = 8; 309 cycleNumbers[13] = 5; 310 cycleNumbers[14] = 5; 311 cycleNumbers[15] = 5; 312 break; 313 case 4: // SwingGroove 314 timeTotalCycle = 153; 315 timeSignature = 128; // (12/8) 316 cycleNumbers[0] = 6; 317 cycleNumbers[1] = 0; 318 cycleNumbers[2] = 0; 319 cycleNumbers[3] = 6; 320 cycleNumbers[4] = 0; 321 cycleNumbers[5] = 5; 322 cycleNumbers[6] = 6; 323 cycleNumbers[7] = 0; 324 cycleNumbers[8] = 0; 325 cycleNumbers[9] = 6; 326 cycleNumbers[10] = 0; 327 cycleNumbers[11] = 5; 328 break; 329 case 5: // BossaNova 330 timeTotalCycle = 200; 331 timeSignature = 44; 332 cycleNumbers[0] = 6; 333 cycleNumbers[1] = 5; 334 cycleNumbers[2] = 5; 335 cycleNumbers[3] = 9; 336 cycleNumbers[4] = 6; 337 cycleNumbers[5] = 5; 338 cycleNumbers[6] = 8; 339 cycleNumbers[7] = 6; 340 cycleNumbers[8] = 6; 341 cycleNumbers[9] = 5; 342 cycleNumbers[10] = 8; 343 cycleNumbers[11] = 6; 344 cycleNumbers[12] = 9; 345 cycleNumbers[13] = 5; 346 cycleNumbers[14] = 5; 347 cycleNumbers[15] = 6; 348 break; 349 case 6: // ShuffleGroove 350 timeTotalCycle = 134; 351 timeSignature = 128; // (12/8) 352 cycleNumbers[0] = 6; 353 cycleNumbers[1] = 0; 354 cycleNumbers[2] = 5; 355 cycleNumbers[3] = 9; 356 cycleNumbers[4] = 0; 357 cycleNumbers[5] = 5; 358 cycleNumbers[6] = 6; 359 cycleNumbers[7] = 0; 360 cycleNumbers[8] = 5; 361 cycleNumbers[9] = 9; 362 cycleNumbers[10] = 0; 363 cycleNumbers[11] = 5; 364 break; 365 case 7: // Franco's beat 366 timeTotalCycle = 142; 367 timeSignature = 44; 368 cycleNumbers[0] = 6; 369 cycleNumbers[1] = 0; 370 cycleNumbers[2] = 5; 371 cycleNumbers[3] = 1; 372 cycleNumbers[4] = 8; 373 cycleNumbers[5] = 0; 374 cycleNumbers[6] = 6; 375 cycleNumbers[7] = 0; 376 cycleNumbers[8] = 5; 377 cycleNumbers[9] = 1; 378 cycleNumbers[10] = 6; 379 cycleNumbers[11] = 0; 380 cycleNumbers[12] = 8; 381 cycleNumbers[13] = 0; 382 cycleNumbers[14] = 6; 383 cycleNumbers[15] = 0; 384 break; 385 default: // Basic 4/4 386 timeTotalCycle = 144; 387 timeSignature = 44; 388 cycleNumbers[0] = 6; 389 cycleNumbers[1] = 0; 390 cycleNumbers[2] = 5; 391 cycleNumbers[3] = 0; 392 cycleNumbers[4] = 8; 393 cycleNumbers[5] = 0; 394 cycleNumbers[6] = 5; 395 cycleNumbers[7] = 0; 396 cycleNumbers[8] = 6; 397 cycleNumbers[9] = 0; 398 cycleNumbers[10] = 5; 399 cycleNumbers[11] = 0; 400 cycleNumbers[12] = 8; 401 cycleNumbers[13] = 0; 402 cycleNumbers[14] = 5; 403 cycleNumbers[15] = 0; 404 break; 405 } 406}
DrumCube, a robot drummer
arduino
1// DrumCube - a robot drummer 2// written by Franco Molina @artefrancomolina 3 4// 5 Setting servos 6#include <Servo.h> 7Servo servo1; 8Servo servo2; 9Servo 10 servo3; 11 12// Servo positions 13// this will differ depending on your servos, 14 please test yours to find out the values that best suit you 15byte restServo1 = 16 12; 17byte hitServo1 = 21; 18byte restServo2 = 123; 19byte hitServo2 = 114; 20byte 21 restServo3 = 4; 22byte hitServo3 = 19; 23 24// Setting the HiHat white noise 25 generator 26#define noiseGenerator 12 27#define noiseLed 13 //turn on led as a 28 visual representation of the noise being generated 29 30// Setting servo times 31// 32 this will also differ depending on your servos, please test yours to find out the 33 values that best suit you 34byte timeSnare1 = 110; 35byte timeSnare2 = 108; 36byte 37 timeKick = 71; 38byte timeHihat = 20; 39byte sustainTimeHihat = 70; 40 41// 42 Setting previous Snare and Kick 43byte previousSnare = 2; 44byte previousKick 45 = 0; 46 47 48// Setting cycle times 49static unsigned long timeStartCycle; 50static 51 unsigned long timeTotalCycle; // changing this, change how fast/slow the rhythm 52 is, you can set a specific value for each drumbeat in the selectDrumBeat() function 53 54// 55 Bar and Cycles variables 56int cycleNumber; 57int cycleNumbers[] = {6, 0, 5, 0, 58 8, 0, 5, 0, 6, 0, 5, 0, 8, 0, 5, 0}; // this array stores the drum elements combination 59 for each cycle (semiquaver or sixteenth) of the drumbeat 60byte timeSignature 61 = 44; 62int drumbeatID = 0; // ID number for each drumbeat 63 64// 65int i; 66 // for counting the time in the "for loop" of the cyclePlayer function 67int 68 b; // for the "for loop" that counts the number of cycles 69 70// control interface 71#define 72 switchPlayStop 2 // switch bettween playing and stop 73#define buttonSelect 3 74 // tact button that select the drumbeat to play 75 76 77 78 79 80 81 82void 83 setup(void) { 84 85 // define pins for each servo 86 pinMode (5, OUTPUT); 87 88 pinMode (6, OUTPUT); 89 pinMode (9, OUTPUT); 90 91 // attach servos to those 92 pins 93 servo1.attach(5); //caja 1 94 servo2.attach(6); //caja 2 95 servo3.attach(9); 96 //bombo 97 delay(150); 98 99 // put all servos on rest position 100 servo1.write(restServo1); 101 102 servo2.write(restServo2); 103 servo3.write(restServo3); 104 delay(300); 105 106 107 // Setting hihat and led pinmodes 108 pinMode (noiseGenerator, OUTPUT); 109 digitalWrite(noiseGenerator, 110 LOW); 111 pinMode (noiseLed, OUTPUT); 112 digitalWrite(noiseLed, LOW); 113 114 115 // Setting control interface pinmodes 116 pinMode (switchPlayStop, INPUT_PULLUP); 117 118 pinMode (buttonSelect, INPUT_PULLUP); 119 120} 121 122 123 124void loop(void) 125 { 126 if (switchPlayStop == LOW) { //if the play/stop switch is ON (logical LOW) 127 128 129 //We start a "for loop" to play a semiquaver cycle a maximum of 16 130 times, for every bar 131 for (b = 0; b < 16; b = b + 1) { 132 133 selectDrumBeat(); 134 // select the drumbeat based on the drumbeatID selected 135 cyclePlayer(cycleNumbers[b]); 136 //play the semiquaver cycle for each number stored in the cycleNumbers array 137 138 139 // if we reach the maximum number of cycles (16 for 4/4, 12 for 6/8, 12/8 140 or 3/4) we start again 141 if (b == 11 && (timeSignature == 68 || timeSignature 142 == 128)) { 143 b = -1; 144 } 145 if (b == 15) { 146 b = 147 -1; 148 } 149 } 150 151 } 152 // If the play/stop switch is OFF (logical 153 HIGH) we enter settingMode 154 else { 155 settingMode(); // function that lets 156 you choose between different drumbeats and wait for the play switch to be activated 157 158 } 159} 160 161 162 163 164 165// CYCLE PLAYER 166// this functions runs a semiquaver 167 cycle every time is called. 168void cyclePlayer(int cycleNumber) { // we store every 169 single value of the cycleNumbers array into the cycleNumber variable 170 timeStartCycle 171 = millis(); // we save the starting time, to compare it later with the actual time 172 and get the time past 173 174 //set both snare servos to rest position in case 175 they were on hit position 176 servo1.write(restServo1); 177 servo2.write(restServo2); 178 179 180 //we star a "for loop" for the entire duration of every semiquaver cycle 181 182 for (i = 0; i < timeTotalCycle; i++) { 183 184 //now we send the hitting commands 185 on time so they reach their destination on time (the end of the semiquaver cycle) 186 187 188 // if we reach the time to send the command to the snare on servo1. We start 189 checking the element that takes the longest time to move, in this case is servo1, 190 in yours could be different. 191 if ((millis() - timeStartCycle >= timeTotalCycle 192 - timeSnare1)) { 193 // we check if this is the one snare of the two, that 194 has to be played, 195 // and also, if in this cycle a snare has to be played 196 at, all based on the cycleNumber number (this number define the cobination of drum 197 elements) 198 if ((previousSnare == 2) && ((cycleNumber == 9) || (cycleNumber 199 == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) { 200 servo1.write(hitServo1 201 + 5); // we send the servo command 202 } 203 // if we reach the time to 204 send the command to the snare on servo2 205 if (millis() - timeStartCycle >= 206 timeTotalCycle - timeSnare2) { 207 // we check if this is the one snare of 208 the two, that has to be played, and also if in this cycle a snare has to be played 209 at all 210 if ((previousSnare == 1) && ((cycleNumber == 9) || (cycleNumber 211 == 8) || (cycleNumber == 4) || (cycleNumber == 3)) ) { 212 servo2.write(hitServo2 213 - 5); // we send the servo command 214 } 215 // we now check if we 216 reached the time to send the command to the third servo, the kick 217 if 218 ((millis() - timeStartCycle >= timeTotalCycle - timeKick)) { 219 // we 220 check if in this cycle a snare has to be played 221 if ( (cycleNumber == 222 9) || (cycleNumber == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) { 223 // 224 we check on what position was previosly the servo, either hiting the left or the 225 right piezo, this state will be saved later 226 if (previousKick == 0) 227 { 228 servo3.write(hitServo3); 229 } 230 else 231 if (previousKick == 1) { 232 servo3.write(restServo3); 233 } 234 235 } 236 // finally, we check if the time to turn on the white noise 237 generator was reached, for the hihat 238 if (millis() - timeStartCycle 239 >= (timeTotalCycle - timeHihat)) { 240 // we check if in this cycle the 241 hihat has to be played 242 if ( (cycleNumber == 9) || (cycleNumber == 243 8) || (cycleNumber == 6) || (cycleNumber == 5) ) { 244 digitalWrite(noiseLed, 245 HIGH); 246 digitalWrite(noiseGenerator, HIGH); 247 } 248 249 } 250 } 251 } 252 } 253 // This is where the semiquaver 254 cycle ends. 255 256 // HIHAT DURATION 257 // turn off hi-hat noise generator, 258 but only under the following conditions: 259 // //if the noise-generator was 260 ON //the time past exceed the time set as sustain //the time past 261 does not reach yet the point where a new noise could start 262 if ( (digitalRead(noiseGenerator) 263 == HIGH) && (millis() - timeStartCycle >= sustainTimeHihat) && (millis() - timeStartCycle 264 < (timeTotalCycle - (timeHihat + 10))) ) { 265 digitalWrite(noiseGenerator, 266 LOW); 267 digitalWrite(noiseLed, LOW); 268 } 269 270 // Check if the 271 play/stop switch is switched OFF 272 if (digitalRead(switchPlayStop) == HIGH) 273 { 274 i = timeTotalCycle; //reset time counting 275 digitalWrite(noiseGenerator, 276 LOW); //turn off noise 277 digitalWrite(noiseLed, LOW); //turn off 278 noise 279 servo1.write(restServo1); //stop servos 280 servo2.write(restServo2); 281 //stop servos 282 } 283 284 delay(1); 285 } 286 287 // If one 288 of the Snares was hit, then declare it as the previous one, in order to hit the 289 other one the next time 290 if ((cycleNumber == 9) || (cycleNumber == 8) || (cycleNumber 291 == 4) || (cycleNumber == 3)) { 292 switch (previousSnare) { 293 case 1: 294 295 previousSnare = 2; 296 break; 297 case 2: 298 previousSnare 299 = 1; 300 break; 301 default: 302 break; 303 } 304 } 305 306 307 // If one of the piezo kick was hit, then declare it as the previous one, in order 308 to hit the other one the next time 309 if ( (cycleNumber == 9) || (cycleNumber 310 == 4) || (cycleNumber == 6) || (cycleNumber == 1) ) { 311 switch (previousKick) 312 { 313 case 0: 314 previousKick = 1; 315 break; 316 case 317 1: 318 previousKick = 0; 319 break; 320 default: 321 break; 322 323 } 324 } 325} 326 327 328 329 330// SETTING MODE 331// this mode is activated 332 when the play/stop switch is swiched OFF (logical LOW) 333void settingMode() { 334 335 while (digitalRead(switchPlayStop) == HIGH) { // keep doing the following actions 336 while the play/stop switch is OFF 337 if (digitalRead(buttonSelect) == LOW) { 338 // if the selection button is pressed (logical LOW), we change the drumbeat 339 340 drumbeatID ++; // we select the next drumbeat each time the button is pressed 341 342 selectDrumBeat(); // select the drumbeat based on the drumbeatID 343 // 344 OPTIONAL 345 // Here you can add whatever piece of code to indicate which drumbeat 346 is being selected, 347 // this could be turning in a led, sending a serial.print(), 348 etc. 349 if (drumbeatID > 7) { //in case we exceed the total number of drumbeats 350 availabe (), we go back to 0. 351 drumbeatID = 0; 352 } 353 delay(100); 354 //delay to avoid detecting button twice when pressed once 355 } 356 } 357} 358 359 360 361 362 363 364// 365 SELECT DRUMBEAT 366// this functions uses the value stored in drumbeatID, to modify 367 all the variables needed in order to choose between drumbeats. 368void selectDrumBeat() 369 { 370 switch (drumbeatID) { 371 case 1: // DiscoBasic 372 timeTotalCycle 373 = 124; 374 timeSignature = 44; 375 cycleNumbers[0] = 1; 376 cycleNumbers[1] 377 = 0; 378 cycleNumbers[2] = 5; 379 cycleNumbers[3] = 0; 380 cycleNumbers[4] 381 = 4; 382 cycleNumbers[5] = 0; 383 cycleNumbers[6] = 5; 384 cycleNumbers[7] 385 = 0; 386 cycleNumbers[8] = 1; 387 cycleNumbers[9] = 0; 388 cycleNumbers[10] 389 = 5; 390 cycleNumbers[11] = 0; 391 cycleNumbers[12] = 4; 392 cycleNumbers[13] 393 = 0; 394 cycleNumbers[14] = 5; 395 cycleNumbers[15] = 0; 396 break; 397 398 case 2: // NewBugalú 399 timeTotalCycle = 155; 400 timeSignature = 401 44; 402 cycleNumbers[0] = 6; 403 cycleNumbers[1] = 0; 404 cycleNumbers[2] 405 = 5; 406 cycleNumbers[3] = 0; 407 cycleNumbers[4] = 8; 408 cycleNumbers[5] 409 = 0; 410 cycleNumbers[6] = 5; 411 cycleNumbers[7] = 3; 412 cycleNumbers[8] 413 = 5; 414 cycleNumbers[9] = 3; 415 cycleNumbers[10] = 6; 416 cycleNumbers[11] 417 = 0; 418 cycleNumbers[12] = 8; 419 cycleNumbers[13] = 0; 420 cycleNumbers[14] 421 = 5; 422 cycleNumbers[15] = 0; 423 break; 424 case 3: // HiHat16 425 426 timeTotalCycle = 134; 427 timeSignature = 44; 428 cycleNumbers[0] 429 = 6; 430 cycleNumbers[1] = 5; 431 cycleNumbers[2] = 5; 432 cycleNumbers[3] 433 = 5; 434 cycleNumbers[4] = 8; 435 cycleNumbers[5] = 5; 436 cycleNumbers[6] 437 = 5; 438 cycleNumbers[7] = 5; 439 cycleNumbers[8] = 6; 440 cycleNumbers[9] 441 = 5; 442 cycleNumbers[10] = 5; 443 cycleNumbers[11] = 5; 444 cycleNumbers[12] 445 = 8; 446 cycleNumbers[13] = 5; 447 cycleNumbers[14] = 5; 448 cycleNumbers[15] 449 = 5; 450 break; 451 case 4: // SwingGroove 452 timeTotalCycle = 153; 453 454 timeSignature = 128; // (12/8) 455 cycleNumbers[0] = 6; 456 cycleNumbers[1] 457 = 0; 458 cycleNumbers[2] = 0; 459 cycleNumbers[3] = 6; 460 cycleNumbers[4] 461 = 0; 462 cycleNumbers[5] = 5; 463 cycleNumbers[6] = 6; 464 cycleNumbers[7] 465 = 0; 466 cycleNumbers[8] = 0; 467 cycleNumbers[9] = 6; 468 cycleNumbers[10] 469 = 0; 470 cycleNumbers[11] = 5; 471 break; 472 case 5: // BossaNova 473 474 timeTotalCycle = 200; 475 timeSignature = 44; 476 cycleNumbers[0] 477 = 6; 478 cycleNumbers[1] = 5; 479 cycleNumbers[2] = 5; 480 cycleNumbers[3] 481 = 9; 482 cycleNumbers[4] = 6; 483 cycleNumbers[5] = 5; 484 cycleNumbers[6] 485 = 8; 486 cycleNumbers[7] = 6; 487 cycleNumbers[8] = 6; 488 cycleNumbers[9] 489 = 5; 490 cycleNumbers[10] = 8; 491 cycleNumbers[11] = 6; 492 cycleNumbers[12] 493 = 9; 494 cycleNumbers[13] = 5; 495 cycleNumbers[14] = 5; 496 cycleNumbers[15] 497 = 6; 498 break; 499 case 6: // ShuffleGroove 500 timeTotalCycle = 134; 501 502 timeSignature = 128; // (12/8) 503 cycleNumbers[0] = 6; 504 cycleNumbers[1] 505 = 0; 506 cycleNumbers[2] = 5; 507 cycleNumbers[3] = 9; 508 cycleNumbers[4] 509 = 0; 510 cycleNumbers[5] = 5; 511 cycleNumbers[6] = 6; 512 cycleNumbers[7] 513 = 0; 514 cycleNumbers[8] = 5; 515 cycleNumbers[9] = 9; 516 cycleNumbers[10] 517 = 0; 518 cycleNumbers[11] = 5; 519 break; 520 case 7: // Franco's beat 521 522 timeTotalCycle = 142; 523 timeSignature = 44; 524 cycleNumbers[0] 525 = 6; 526 cycleNumbers[1] = 0; 527 cycleNumbers[2] = 5; 528 cycleNumbers[3] 529 = 1; 530 cycleNumbers[4] = 8; 531 cycleNumbers[5] = 0; 532 cycleNumbers[6] 533 = 6; 534 cycleNumbers[7] = 0; 535 cycleNumbers[8] = 5; 536 cycleNumbers[9] 537 = 1; 538 cycleNumbers[10] = 6; 539 cycleNumbers[11] = 0; 540 cycleNumbers[12] 541 = 8; 542 cycleNumbers[13] = 0; 543 cycleNumbers[14] = 6; 544 cycleNumbers[15] 545 = 0; 546 break; 547 default: // Basic 4/4 548 timeTotalCycle = 144; 549 550 timeSignature = 44; 551 cycleNumbers[0] = 6; 552 cycleNumbers[1] 553 = 0; 554 cycleNumbers[2] = 5; 555 cycleNumbers[3] = 0; 556 cycleNumbers[4] 557 = 8; 558 cycleNumbers[5] = 0; 559 cycleNumbers[6] = 5; 560 cycleNumbers[7] 561 = 0; 562 cycleNumbers[8] = 6; 563 cycleNumbers[9] = 0; 564 cycleNumbers[10] 565 = 5; 566 cycleNumbers[11] = 0; 567 cycleNumbers[12] = 8; 568 cycleNumbers[13] 569 = 0; 570 cycleNumbers[14] = 5; 571 cycleNumbers[15] = 0; 572 break; 573 574 } 575}
Downloadable files
HiHat Generator Schematic
White noise generator and high-pass filter to replicate the cymbals sound.
HiHat Generator Schematic
Kick Schematic
Amplifier circuit for the piezos in the kick system
Kick Schematic
Snare Schematic
Amplifier circuit for the electret microphone in the Snare system
Snare Schematic
Full Diagram
Full diagram of the project
Full Diagram
Audio signal mixer
Audio signal mixer
Full Diagram
Full diagram of the project
Full Diagram
Kick Schematic
Amplifier circuit for the piezos in the kick system
Kick Schematic
Snare Schematic
Amplifier circuit for the electret microphone in the Snare system
Snare Schematic
HiHat Generator Schematic
White noise generator and high-pass filter to replicate the cymbals sound.
HiHat Generator Schematic
Audio signal mixer
Audio signal mixer
Comments