User:Laurier Rochon/prototyping/arduino recorder: Difference between revisions
(→SOFT) |
No edit summary |
||
Line 5: | Line 5: | ||
*Program starts | *Program starts | ||
*User starts using pushbutton to determine a pattern (up to 100 clicks before array goes out of bounds) | *User starts using pushbutton to determine a pattern (up to 100 clicks before array goes out of bounds) | ||
*After 5 seconds of silence | *After 5 seconds of silence (there can be 1min at the beginning though, that's fine) | ||
*Play the pattern back | *Play the pattern back | ||
*And then erase it from memory, begin recording again | |||
== HARD == | == HARD == | ||
Line 17: | Line 16: | ||
== SOFT == | == SOFT == | ||
''' | |||
'''Self-resetting / state-run / compact version''' | |||
The realization with this version was that there are actually not 3 states, but more like 2 & 1/2. Counting the 'waiting' period as state 1, pressed as state 2 - but the 'released' state not being an actual state in itself, rather the un-doing of the 'pressed' one. To paraphrase, you can't really 'hold' the unpressed state, it just delimits/completes the 'pressed' action. It also seemed weird to have a for/while loop inside the loop() statement, creating somewhat of a nested loop. | The realization with this version was that there are actually not 3 states, but more like 2 & 1/2. Counting the 'waiting' period as state 1, pressed as state 2 - but the 'released' state not being an actual state in itself, rather the un-doing of the 'pressed' one. To paraphrase, you can't really 'hold' the unpressed state, it just delimits/completes the 'pressed' action. It also seemed weird to have a for/while loop inside the loop() statement, creating somewhat of a nested loop. | ||
With that in mind, I built a simple IF structure (could easily of been a case/switch) that changes states depending on the previous state, and button position. Since all the combinations have discrete properties, it is possible to only mark the difference in state change, and let the loop run 'in between the cracks' (i.e. when none of the conditions are met) of the program, triggering only the recording function when we need it. | With that in mind, I built a simple IF structure (could easily of been a case/switch) that changes states depending on the previous state, and button position. Since all the combinations have discrete properties, it is possible to only mark the difference in state change, and let the loop run 'in between the cracks' (i.e. when none of the conditions are met) of the program, triggering only the recording function when we need it. | ||
So the 'state' var controls the flow of recordings. | |||
I've somewhat compacted the variables and code a bit for readability, sorry. | I've somewhat compacted the variables and code a bit for readability, sorry. |
Revision as of 15:38, 12 November 2010
Rough arduino pattern recorder/playback #1
Simple code to emulate a pattern recording device. It has a few little glitches, but the main idea works.
- Program starts
- User starts using pushbutton to determine a pattern (up to 100 clicks before array goes out of bounds)
- After 5 seconds of silence (there can be 1min at the beginning though, that's fine)
- Play the pattern back
- And then erase it from memory, begin recording again
HARD
- Piezo in ground/pin 13
- Pushbutton in 10K resistor => pin 2 / 5V power
SOFT
Self-resetting / state-run / compact version
The realization with this version was that there are actually not 3 states, but more like 2 & 1/2. Counting the 'waiting' period as state 1, pressed as state 2 - but the 'released' state not being an actual state in itself, rather the un-doing of the 'pressed' one. To paraphrase, you can't really 'hold' the unpressed state, it just delimits/completes the 'pressed' action. It also seemed weird to have a for/while loop inside the loop() statement, creating somewhat of a nested loop.
With that in mind, I built a simple IF structure (could easily of been a case/switch) that changes states depending on the previous state, and button position. Since all the combinations have discrete properties, it is possible to only mark the difference in state change, and let the loop run 'in between the cracks' (i.e. when none of the conditions are met) of the program, triggering only the recording function when we need it.
So the 'state' var controls the flow of recordings.
I've somewhat compacted the variables and code a bit for readability, sorry.
const int b = 2;
int bs=0;
int state=0; //0 is waiting, 1 is pressed, 2 is released
boolean sr=false;
unsigned long time;
int t[100];
int c=0;
void setup() {
pinMode(b, INPUT);
tone(13,600,10);
Serial.begin(9600);
Serial.println("Start recording...");
}
void loop(){
bs = digitalRead(b);
if(!sr){ if(bs==1) sr=true; }else{
if(bs && state==0){ state=1; t[c] = millis(); c++; Serial.println("tstamped"); }
if(!bs && state==1){ state=2; t[c] = millis(); c++; Serial.println("tstamped"); }
if(!bs && state==2){ state=0; }
if((millis() - t[c-1])>5000){ p(); }
}
}
void p(){
Serial.println("Playing back");
for(int a=1;a<c-1;a++){
tone(13, 600,t[a]-t[a-1]);
delay(t[a+1]-t[a]);
}
sr = !sr;
memset(t,0,100);
c=0;
Serial.println("You can start recording again");
}
(better than below)
const int buttonPin = 2;
const int nb=100;
int bs = 0;
int cs = 0;
unsigned long time;
int values[nb];
int c=0;
boolean startrec = false;
void setup() {
pinMode(buttonPin, INPUT);
tone(13,600,10);
Serial.begin(9600);
Serial.println("Start recording...");
}
void loop(){
bs = digitalRead(buttonPin);
time = millis();
char buffer[255];
if(cs!=bs){
startrec=true;
cs=bs;
values[c] = time;
sprintf(buffer,"Recorded : %d",time);
Serial.println(buffer);
c++;
}
if(startrec){
int deadtime = time-values[c-1];
if(deadtime>5000) playback();
}
}
void playback(){
Serial.println("Playing back");
int cc = 0;
for(int a=1;a<c-1;a++){
int playtime = values[a]-values[a-1];
int delaytime = values[a+1]-values[a];
tone(13, 600,playtime);
delay(delaytime);
}
Serial.println("Finished playing back");
delay(1000);
restart();
}
void restart(){
startrec = false;
memset(values,0,nb);
c=0;
Serial.println("You can start recording again");
}
(old version)
//globals
const int buttonPin = 2;
int values[100];
int c=0;
unsigned long time;
boolean startrec = false;
int buttonState = 1;
int newstate = 1;
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop(){
//time counter
time = millis();
buttonState = digitalRead(buttonPin);
//this prevents the button from recording 2-3 times in the same push...
delay(10);
//if state has changed
if(buttonState != newstate){
startrec = true;
//store in the array, print to screen and increment array index
newstate = buttonState;
values[c] = time/100;
Serial.println(values[c]);
c++;
}
if(startrec){
//if it's been more than 5 seconds doing nothing, after you've started pushing
int deadtime = (time/100)- values[c-1];
if(deadtime > 50){
int cc = 0;
//loop through values, and interpret the time difference as delays
for(int a=0;a<c-1;a++){
tone(13, 600,10);
int dtime = (values[a+1]-values[a])*100;
delay(dtime);
}
//gimme something to look at
Serial.println("waiting 2 secs...replaying");
delay(2000);
}
}
}