Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #45 on: March 28, 2012, 08:17:21 am » |
took care of that array problem by making sure each recording begins at index 0  Now I need be able to playback again and again without smoothing every time... Done! here's the latest: // // FILE: servoRecorder.pde // AUTHOR: Adi Soffer // DATE: 28-3-2012 // // PUPROSE: servo recorder //
#define IDLE 0 #define FREE 1 #define RECORD 2 #define PLAYBACK 3 #define STOP 4 #define REWIND 5 #define RECORDCONT 6
int mode; int idx, lastidx, firstidx, newidx; int maxidx = 800;
#include <Servo.h>
Servo myservo; // create servo object to control a servo char buffer [2]; //variable to hold keystrokes int potpin = 0; // analog pin used to connect the potentiometer unsigned int val; // variable to read the value from the analog pin const unsigned int valNumber = 800; //variable to contain number of array members int incomingByte; //declare variable to hold incoming letter unsigned int servoPos[valNumber]; //create array of values for servo position const int waitForServo = 15; //delay time to let servo get to position
int smooth;
const byte recordModeLed = 3; // defining pins for ui leds const byte homeModeLed = 4; const byte playModeLed = 5; const byte freeModeLed = 6; const byte freeSwitch = 7; //defining pins for switches const byte recSwitch = 8; const byte homeSwitch = 9; const byte playSwitch = 10;
void setup() { Serial.begin(9600); Serial.flush(); myservo.attach(2); // attaches the servo on pin 2 to the servo object pinMode (freeModeLed, OUTPUT); //defining LED pins as output pinMode (recordModeLed, OUTPUT); pinMode (homeModeLed, OUTPUT); pinMode (playModeLed, OUTPUT); pinMode (freeSwitch, INPUT); //defining switch pins as input pinMode (recSwitch, INPUT); pinMode (homeSwitch, INPUT); pinMode (playSwitch, INPUT); }
void loop () { digitalWrite (freeModeLed, LOW); digitalWrite (recordModeLed, LOW); digitalWrite (homeModeLed, LOW); digitalWrite (playModeLed, LOW);
// HANDLE IO
if (Serial.available( ) > 0) { incomingByte = Serial.read ( );
switch(incomingByte) { case 'f': mode = FREE; Serial.println ("Free mode"); break;
case 'r': mode = RECORD; for (int c=6;c>3;c --) // three sec LED countdown to recording { digitalWrite (recordModeLed, HIGH); digitalWrite (c, HIGH); delay (700); digitalWrite (recordModeLed, LOW); digitalWrite (c, LOW); delay(300); } Serial.println ("Record"); smooth = 1; //"smoothing req." break;
case 's' : mode = STOP; Serial.println ("STOP"); break;
case 'w' : mode = REWIND; digitalWrite (homeModeLed, HIGH); //turn on rewind LED Serial.println ("Rewind"); break;
case 'p': mode = PLAYBACK; digitalWrite (playModeLed, HIGH); //turn on playback LED Serial.println ("Playback"); break;
} }
switch(mode) {
case STOP: for (int x=3;x>6;x++) { digitalWrite (x, LOW); //turn off all LEDs } break;
case FREE: digitalWrite (freeModeLed, HIGH); val = analogRead (potpin); val = map(val, 0, 1023, 0, 179); // val = val * 45/256; // <==> val * 180/1024 myservo.write (val); Serial.println (val); //print val for checking newidx == val; delay (waitForServo); // should be refactored away -> like blink without delay break;
case RECORD:
digitalWrite (recordModeLed, HIGH); //keeps LED on Serial.println ("Record function"); // if so - prints record val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180) myservo.write(val); // sets the servo position according to the scaled value Serial.println (val); // print values for checking idx = 0; //making sure array will start filling up from index 0 servoPos [idx]=val; // stores val in array "servoPos" firstidx = idx; idx ++; mode = RECORDCONT;
break;
case RECORDCONT:
digitalWrite (recordModeLed, HIGH); //keeps LED on val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180) myservo.write(val); // sets the servo position according to the scaled value servoPos [idx]=val; // stores val in array "servoPos" idx ++ ; lastidx = idx; if (idx == maxidx) mode = STOP; delay(waitForServo); // waits for the servo to get there Serial.println(val); // print values for checking
break;
case REWIND: //need to build rewind from new point in free mode //why first val is 0??? for (int i=lastidx;i>firstidx;i--) { val = servoPos [i]; myservo.write (servoPos [i]); delay (waitForServo); Serial.println (val); // print values for checking }
mode = STOP; for (int x=3;x>6;x++) { digitalWrite (x, LOW); //turn off all LEDs }
break;
case PLAYBACK: if (smooth == 1) //if I just recorded "smoothing req." { for (int x = 0;x<lastidx - 2; x++) // smoothing values { servoPos [x+1] = (servoPos [x] + servoPos [x+2] ) /2; } smooth = 0; //change value back to "no smoothing req." for (int i=firstidx; i< lastidx; i++) { myservo.write (servoPos[i]); val = servoPos [i]; delay (waitForServo); Serial.println (val); //print val for checking } mode = STOP; for (int x=3;x>6;x++) //turn off all LEDs { digitalWrite (x, LOW); } break; }
else //if "no smoothing req." { for (int i=firstidx; i< lastidx; i++) { myservo.write (servoPos[i]); val = servoPos [i]; delay (waitForServo); Serial.println (val); //print val for checking } mode = STOP; for (int x=3;x>6;x++) //turn off all LEDs { digitalWrite (x, LOW); } break; } } }
|
|
|
|
« Last Edit: March 28, 2012, 01:37:05 pm by Soffer »
|
Logged
|
|
|
|
|
Anchorage, AK
Offline
Sr. Member
Karma: 10
Posts: 494
|
 |
« Reply #46 on: March 28, 2012, 01:52:00 pm » |
So, after all your corrections with the array index, is the smoothing working the way you want now? Or are you still seeing bad starting values?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #47 on: March 28, 2012, 01:59:10 pm » |
So, after all your corrections with the array index, is the smoothing working the way you want now? Or are you still seeing bad starting values?
Now it seems to work perfectly, thank you.  Next I have to 1.find a way to rewind not from the recorded array's last value, but from wherever the servo is at the moment (if I use free mode and than wish to go back to the first recorded value, I shouldn't go through the lastidx...) 2. find a way to be able to "free mode" while counting down with LEDs for recording. (last minute adjustments) When this is done - replace serial input with real buttons! Oh - and that probably means I'll be asking more questions... 
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9553
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #48 on: March 28, 2012, 02:07:14 pm » |
latest version looks quite well! replace serial input with real buttons! Advice: start with one button and read the tutorial about debouncing.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #49 on: March 29, 2012, 08:22:01 am » |
Advice: start with one button and read the tutorial about debouncing.
robtillaart - will do, thanks. Do you guys think that I should change the structure of the code to "functions" instead of "case" because I'm switching from serial input to buttons? I'm asking just to be on the safe side although I see no reason for doing that...
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9553
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #50 on: March 29, 2012, 12:14:11 pm » |
Do you guys think that I should change the structure of the code to "functions" instead of "case" because I'm switching from serial input to buttons? Not because you are switching but to give you oversight; void loop() { handleInput();
switch(mode) { switch(mode) {
case STOP: stop(); break; case FREE: free(); break; case RECORD: record(); break; case RECORDCONT: recordcont(); break; case REWIND: rewind(); break; case PLAYBACK: playback(); break; } }
void handleInput() { handleButtons(); handleSerial(); } etc
the 6 recorder functions have lower level common parts. That can be functions too, like void turnOffLeds() { for (int x=3;x>6;x++) { digitalWrite (x, LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #51 on: March 29, 2012, 12:19:22 pm » |
Aha! You helped me figure the flow I think. Thanks. I will update and upload the next version naturally  Thank you.
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 33
Posts: 3020
I only know some basic electricity....
|
 |
« Reply #52 on: March 29, 2012, 12:23:09 pm » |
void turnOffLeds() { for (int x=3;x>6;x++) { digitalWrite (x, LOW); } }
I think you have a typo there. x>6 ?
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9553
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #53 on: March 29, 2012, 12:25:28 pm » |
That was intentional as an exercise for the reader 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #54 on: March 29, 2012, 12:28:10 pm » |
Can I do something like
switch (digitalRead)
case = (pinNum1, HIGH): mode = record; break;
case = (pinNum2, HIGH): mode = rewind; break;
And so forth?
|
|
|
|
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #55 on: March 29, 2012, 12:31:54 pm » |
No, you can't.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #56 on: March 29, 2012, 12:52:30 pm » |
Well than, in that case I do have to switch to functions...  Not too good since the "switch case" structure helped me with a lot of things, one of which was the option to stop recording without being stuck in a loop...  Oh well, I'll figure something out...
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9553
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #57 on: March 29, 2012, 12:54:34 pm » |
build an if then else if ladder, take care that the most important one is tested first! void HandlePins() { if (digitalRead(stopPin) == HIGH) mode = STOP; else if (digitalRead(rewindPin) == HIGH) mode = REWIND; ... }
void handleSerial() { #include existing code ;) }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 161
|
 |
« Reply #58 on: March 29, 2012, 01:15:51 pm » |
robtillaart - you're my hero! Thank you (again and again and again...) 
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9553
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #59 on: March 29, 2012, 02:02:09 pm » |
You're welcome, one day you will be able to answer the questions asked here 
|
|
|
|
|
Logged
|
|
|
|
|
|