how to create an array with both members and number of members undefined

Soffer:
Nick - how do I do what you suggest? I'd be happy to try and see if it works.

Something like this does some local smoothing:

int test [] = { 1, 2, 3, 5, 4, 6, 7, 234, 235, 238, 236, 239, 240, 241, 40, 41, 44, 43, 42, 45, 46, 47 };
// number of items in an array
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
void setup ()
 {
 Serial.begin (115200);
 Serial.println ();
 for (int i = 0; i < NUMITEMS (test) - 2; i++)
   {
   if (test [i + 1] > test [i + 2] && test [i] < test [i + 2])
     {
     // swap this and next
     int temp = test [i + 1];
     test [i + 1] = test [i + 2];
     test [i + 2] = temp;
     } // end of if   
   } // end of for
 for (int i = 0; i < NUMITEMS (test); i++)
    Serial.println (test [i]);
 } // end of setup
void loop () {}

Output:

1
2
3
4
5
6
7
234
235
236
238
239
240
241
40
41
43
44
42
45
46
47

Thanks Nick, I think I understand, only it seems quite a problem to do this for an array containing 500 values...
I'll also check qsort as you recommended.

Thanks Nick, I think I understand, only it seems quite a problem to do this for an array containing 500 values...

Why?

I'll also check qsort as you recommended.

qsort will only sort the whole thing into sequence. That may or may not be what you want.

Hey SirNickity - I'm using your idea and something weird is happening...
It does indeed smooth the values, but on "playback mode" I get weird values at the start...

I'm attaching the code and would appreciate your observance...

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


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");
      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
    servoPos [idx]=val;                                          // stores val in array "servoPos"
    firstidx = 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

    newidx = analogRead (potpin);
  if (newidx = lastidx)
  {
    for (int i=lastidx;i>firstidx;i--)
    {
      myservo.write (servoPos [i]);
      val = servoPos [i];
      delay (waitForServo);
      Serial.println (val);                                                           // print values for checking
    }
  }
  else                                                                                                //need to build rewind from new point in free mode
  {
    
  }
    mode = STOP;
    for (int x=3;x>6;x++)
    {
      digitalWrite (x, LOW);                                                         //turn off all LEDs
    }
    
    break;

  case PLAYBACK:
      for (int x = 0;x<lastidx - 2; x++)                                      // smoothing values
       {
     servoPos [x+1] = (servoPos [x]  + servoPos [x+2] ) /2;
   }
    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;

  }
}

I'm not sure but I think my code doesn't take care of erasing the values in array in every new recording.
Is there a way to do that?

took care of that array problem by making sure each recording begins at index 0
:slight_smile:
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;
    }
  }
}

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?

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?

Now it seems to work perfectly, thank you. :slight_smile:
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... :wink:

latest version looks quite well!

replace serial input with real buttons!

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

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

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

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

I will update and upload the next version naturally :wink:

Thank you.

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

I think you have a typo there. x>6 ?

That was intentional as an exercise for the reader :slight_smile:

Can I do something like

switch (digitalRead)

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

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

And so forth?

No, you can't.

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

:roll_eyes:
Oh well, I'll figure something out...

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

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

You're welcome, one day you will be able to answer the questions asked here :wink: