/* littleBits Sequence Recorder advanced version This project will repeat the sequence that you tap into the morse button and then play your sequence back on the output bits! It will loop until you press the record mode button again. Instructions on how to use it: Go into record mode by pressing the button on the d0 input. While pressing the record button or switch, press sequences on the morse button on a0. Let go the record button to play back your sequence! Press the record button once to stop playback. Rotate the dimmer counter clockwise to speed up the your playback, rotate the dimmer clockwise to slow the playback down. Have fun with different littleBits on the output! https://littlebits.cc/projects/sequence-recorder Written by Glenn Mossy, May 10, 2014 http://littlebits.cc/ This example code is under Creative Commons CC-BY-SA A good resource is at http://arduino.cc/en/Reference/HomePage */ /* littleBits needed power bit p1 fork w7 arduino w6 two buttons i3 dimmer i6 bright led o14 x2 rgb led o3 filter i32 synth speaker o24 a4 micro usb cable snap the power bit p1 to a fork snap a button on d0 of the arduino bit snap a button on a0 of the arduino bit snap a dimmer on a1 of the arduino bit snap a bright led on d1 of the arduino bit snap a rgbled on d5 of the arduino bit snap a bright led on d9 of the arduino bit snap a filter frequency input to the rgbled output snap a synth speaker onto the output of the filter */ byte morseBtn = A0; // Assign pin as the Button that is your input to record the sequence. byte modeBtn = 0; // Assign pin as the Button that you will push and hold for RECORDING. int recording_indicator_led = 1; // Assign pin d1 as a pin that will do digital output to indicate recording mode byte pin_d5 = 5; // Assign pin d5 as a pin that will do digital output. int pin_d9 = 9; // Assign pin d9 as a pin that will do digital output. int pin_a1 = 1; // Assign pin a1 as a pin that will be an anlog input pin boolean inRecordMode = false; // Create a boolean variable that will hold current state of the Record mode. boolean wasInRecordMode = false; // Create a boolean variable that will hold previous state of the Record mode. // buffers to record state/duration combinations int maxSamples = 100; // This is the maximum number of samples in bytes that can be stored. boolean states[100]; // Create a states array to record up to this number of on and off states. int durations[100]; // Create a durations array and we can have up to this many duration times. int idxPlayback = 0; // Initialize the index for the Playback array to 0 int idxRecord = 0; // Initialize the index for the Record array to 1 int sampleLength = 1; // 1 ms float playbackRate = 1; // 2=>half speed, 0.5=>double speed, change this if you want to play back slower or faster than the recorded rate. void setup() { //Serial.begin(9600); // Uncomment this line for setup to use the Serial Monitor for troubleshooting your software changes. pinMode(modeBtn, INPUT); // Setup the mode Button as an INPUT pinMode(morseBtn, INPUT); // Setup the input Button as an INPUT pinMode(recording_indicator_led, OUTPUT); // Setup the pin d1 the recording_indicator_led as an OUTPUT, // when the record led is HIGH you will also be providing power to your morse sequence recorder button pinMode(pin_d5, OUTPUT); // Setup the pin d5 pin_d5 as an OUTPUT pinMode(pin_d9, OUTPUT); // Setup the pin d9 pin_d9 as an OUTPUT //pinMode(pin_a1, INPUT); // Setup the pin a1 pin_a1 as an INPUT } void loop() { digitalWrite(recording_indicator_led, LOW); // inRecordMode = digitalRead(modeBtn); // read the mode button if(inRecordMode == true) { // test if the mode button is pressed in record mode digitalWrite(recording_indicator_led, HIGH); // When in record mode, turn on the led if(!wasInRecordMode) { // if the button was not pressed in record mode, reset the arrays and index for playback // reset record buffers memset(states, 0, sizeof(states)); // Set the size of the states array memset(durations, 0, sizeof(durations)); // Set the size of the durations array idxRecord = 0; // reset record idx just to make playback start point obvious } recordLoop(); // perform the recording loop function } else { // or else playbackLoop(); // perform the playback loop function } wasInRecordMode = inRecordMode; // record prev state for next iteration so we know whether to reset the record array index } void recordLoop() { boolean state = digitalRead(morseBtn); // read the state of the input sequence recorder button. digitalWrite(pin_d5, state); // change the state of the output with the input to give feedback to person recording the loop if(states[idxRecord] == state) { // if the state is not changed, add to duration of current state durations[idxRecord] += sampleLength; } else { // if the state is changed, go to next index (idx) and set default duration of 1ms idxRecord++; if(idxRecord == maxSamples) { idxRecord = 0; } // reset idx if max array size reached states[idxRecord] = state; // save the state to the states array by index durations[idxRecord] = sampleLength; // save the duration of the sample to the durations array by index } delay(sampleLength); // slow the loop to a time constant so we can reproduce the timelyness of the recording } void playbackLoop() { // playback rate control, remove the following three lines if you don't want speed control float dimmerVal = analogRead(pin_a1); dimmerVal = map(dimmerVal, 0, 1023, .5, 2); playbackRate = constrain(dimmerVal, .5, 2); // limits range of sensor values to between 0 and 2 //Serial.print("PlaybackRate= "); //Serial.println(playbackRate); // Uncomment these print statements to use the Serial Monitor to observe your playbackRate // play the loop back at the desired speed digitalWrite(pin_d5, states[idxPlayback]); // playback output to pin_d5 digitalWrite(pin_d9, states[idxPlayback]); // playback output to pin_d9 delay(durations[idxPlayback] * playbackRate); // leave the output pin in that state for duration (* desired rate) idxPlayback++; // increment the playback index so we can play the next value if(idxPlayback == maxSamples) { idxPlayback=0; } // repeat the recorded loop when we reach the maximum number of samples }