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.

8 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!

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> <pre lang="" line="" escaped="">