Go Down

Topic: how to create an array with both members and number of members undefined (Read 5922 times) previous topic - next topic

Soffer

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:

Code: [Select]

//                                                                            
//    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;
   }
 }
}






SirNickity

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?

Soffer


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... ;)

robtillaart

latest version looks quite well!

Quote
replace serial input with real buttons!

Advice: start with one button and read the tutorial about debouncing.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Soffer

Quote

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...

robtillaart

Quote
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;

Code: [Select]

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

Code: [Select]

void turnOffLeds()
{
  for (int x=3;x>6;x++)                                                             
  {
    digitalWrite (x, LOW);
  }
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Soffer

Aha!
You helped me figure the flow I think.
Thanks.

I will update and upload the next version naturally ;)

Thank you.

GoForSmoke

Code: [Select]

void turnOffLeds()
{
  for (int x=3;x>6;x++)                                                             
  {
    digitalWrite (x, LOW);
  }
}


I think you have a typo there.  x>6 ?
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Soffer

Can I do something like

switch (digitalRead)

case = (pinNum1, HIGH):
mode = record;
break;

case = (pinNum2, HIGH):
mode = rewind;
break;

And so forth?


Soffer

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...

:smiley-roll:
Oh well, I'll figure something out...

robtillaart

build an if then else if ladder, take care that the most important one is tested first!

Code: [Select]

void HandlePins()
{
 if (digitalRead(stopPin) == HIGH) mode = STOP;
 else if (digitalRead(rewindPin) == HIGH) mode = REWIND;
 ...
}

void handleSerial()
{
 #include existing code ;)
}

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Soffer

robtillaart - you're my hero!
Thank you (again and again and again...)
:)

robtillaart

You're welcome, one day you will be able to answer the questions asked here ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up