Thing-a-day, Day 11: ‘Physical’ drum loop machine

Todays project is another little experiment in different ways to interact with the Arduino. It was inspired by a project I saw a while ago, which consisted of these blocks that you could bang on, that then remembered that beat and would play it back. Mine isn’t quite so sophisticated, I just used a common switch for the input, but I think it was interesting as a proof of concept. You might notice that in the video, one of the ‘beats’ is missing from the output near the beginning- this is a consequence of only polling the input every so often. Source code is after the break.
Update: You could add a potentiometer to adjust the timebase after recording it!

/******************************************************************************************************
 *  Simple beat recorder/actuator
 *
 * by Matt Mets
 * Created 9 Feb. 2008
 *
 * For example usage and circuit schematic, see http://www.cibomahto.com/?p=148
 *
 * This code is released as public domain.
 *  
 ******************************************************************************************************/
 
/***** Variable Definitions ***************************************************************************/
int recordButtonPin = 10;          // Record button
int inputAPin =  7;                // Input button A
int outputAPin = 4;                // Output A
int statusPin =  13;               // Status LED
 
#define SAMPLE_PERIOD 10           // Period between samples (ms)
#define MAX_STATES 700             // Total number of samples to be taken
char stateTable[MAX_STATES];       // Table to hold all of the tracks
int currentState = 0;              // State currently being excercised
int totalStates = 0;               // Total number of states recorded.
 
/***** Functions ************************************************************************************/
void setup()
{
 
  pinMode(recordButtonPin, INPUT);
  pinMode(inputAPin, INPUT);
  pinMode(outputAPin, OUTPUT);
  pinMode(statusPin, OUTPUT);
 
  stateTable[0] = 0;
 
  Serial.begin(9600);
}
 
 
void loop()
{ 
  // There are two modes of operation- record and playback.  When in playback mode, simply 'play'
  // the current output by setting the output, and then wait until the time expires or the user
  // presses the play button, in which case we switch to the record mode...
 
  // We are in play mode by default.  Write out the current state, and advance the state counter
  digitalWrite(outputAPin, stateTable[currentState++]);
 
  // If we have reached the last state, start over to repeat the loop.
  if(currentState == totalStates)
    currentState = 0;
 
  // Wait for one sample time before continuing.  This is slightly innacurate because it doesn't
  // take into account the amount of time that the other instructions in the loop take, so it will
  // always be a little longer than SAMPLE_PERIOD.  A more sophisticated approach would be to use
  // the millis() function to track the start time of each loop.  This is proof-of-concept code :-)  
  delay(SAMPLE_PERIOD);
 
  // User pressed record button, enter record loop.  
  if(digitalRead(recordButtonPin) == HIGH)
  {
    digitalWrite(statusPin, HIGH);
    totalStates = 0;       // Set the total state counter to zero, 'erasing' previous data.
 
    // Keep looping until the record button is 
    while(digitalRead(recordButtonPin) == HIGH)
    {
      // If there is still space to record this time period, record the curent input and increment
      // the total state counter.  Note that multiple inputs could be recorded here- we are only using
      // one of the eight bits available for this state.  For that to work, some additional binary
      // manipulation would be required here.
      if(totalStates < MAX_STATES)
      {
        stateTable[totalStates] = digitalRead(inputAPin);
        digitalWrite(outputAPin, stateTable[totalStates]);
        totalStates++;
      }
 
      // Innacurate- see the note at the delay() statement above.
      delay(SAMPLE_PERIOD);
    }
 
    currentState = 0;    // Reset the position to zero, so the loop starts at the beginning
    digitalWrite(statusPin, LOW);
  }  
}
This entry was posted in tech, thingaday. Bookmark the permalink.

9 Responses to Thing-a-day, Day 11: ‘Physical’ drum loop machine

  1. Alan says:

    Fantastic idea. The code is nice and compact also!

  2. mahto says:

    Thanks! I’m really excited about how clean these programs can be made using the Arduino environment :-)

  3. booyaa says:

    dude that is pretty fricken cool!

  4. Pingback: Arduino based Drum Loop Machine - Hacked Gadgets - DIY Tech Blog

  5. Woody says:

    Awesome, how good is that?! You have to make a multichannel one now! I don’t know much about the Arduino but looking at your fanastic example I’m going to do some research! Great work Mahto!

  6. Pingback: Physical drum loop machine, how to make a microphone from a speaker, and Steve Lodefink built an amp in a coconut

  7. StevieP says:

    Hello, im trying to recreate your example, but can’t figure out how to change the output to use a servo instead. it would be great if you could help thanks

    • mahto says:

      Hmm, can you post your code? You probably need to change the code so that instead of turning a solenoid on and off, it switches a servo between one position and a second one. Let me know if you get it working!

  8. Nahshon says:

    Hey awesome project! I’m working on something similar but am stuck with repeating the beat. If the drum pattern is only played once how do you define the time interval between the last and first beat?

Leave a Reply

Your email address will not be published. Required fields are marked *

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=""> <strike> <strong>