Go Down

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


Soffer

Something weird that is obviously due to my ignorance is happening...
As you can see in the code, I've created a variable to hold the latest servo position. It is meant to help the REWIND case to do so from the latest position and not to jump to the last recorded one only to go to 1st position.
Now, the weird thing is that when I try to put If...Else inside the case REWIND, the thing gets stuck...
Aren't I allowed to do this? And if so, how can I work around this thing?

Code: [Select]

//              TRYING TO FIX REWIND                                                             
//    FILE: servoRecorder.pde
//  AUTHOR: Adi Soffer
//    DATE: 30-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, lastPosition;
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");
      Serial.print ("lastPosition is:  ");                  //check change in var
      Serial.println (lastPosition);
      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
    lastPosition = val;                                      //save last position for REWIND fixing
    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"
    lastPosition = val;                                       // save last position for REWIND fixing
    lastidx = idx;
    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 lastPosition in free mode
   
   
    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 than "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;
    }
  }
}









wildbill

Post the broken code. You've still got this issue going on too:
Code: [Select]
    for (int x=3;x>6;x++)

Soffer

yes, that's kind of dumb...Thanks.  :smiley-red:

Here's the broken code - under case REWIND I just asked it to print the various situations to make sure my logic is correct, but it crashes the rest...

Code: [Select]

//              TRYING TO FIX REWIND                                                             
//    FILE: servoRecorder.pde
//  AUTHOR: Adi Soffer
//    DATE: 30-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, lastPosition;
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");
      Serial.print ("lastPosition is:  ");                  //check change in var
      Serial.println (lastPosition);
      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
    lastPosition = val;                                      //save last position for REWIND fixing
    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"
    lastPosition = val;                                       // save last position for REWIND fixing
    lastidx = idx;
    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 lastPosition in free mode
   
   if (lastPosition == servoPos [lastidx])
  {
    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
    }
  }
 
  else if (lastPosition < servoPos [lastidx])
  {
    Serial.println ("lastPosition < servoPos [lastidx]");
  }
else if (lastPosition > servoPos [lastidx])
{
  Serial.println ("lastPosition > servoPos [lastidx]");
}
    break;


  case PLAYBACK:
    if (smooth == 1)                                                                            //if I just recorded than "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;
    }
  }
}








wildbill

That servoPos array is going to occupy 1600 bytes. Assuming you're using an UNO, that's a good chunk of your RAM - you may be running out of memory. Try reducing it.

Soffer

It crashes even before i start filling the array. Simply when uploading is done

dxw00d

Space is reserved for the array as soon as the program starts. Try making it smaller, just to see if it helps.

wildbill

Indeed. Moreover, when you introduced this change, you added these:
Code: [Select]

"lastPosition < servoPos [lastidx]"
"lastPosition > servoPos [lastidx]"


They occupy RAM too and it looks like they pushed you over the edge


Soffer

Thank you guys, it seems you're right.
I'm attaching the code once again and if you could point to more things that I can still do in order to diminish my RAM usage I would be thankful.

Code: [Select]

//              TRYING TO FIX REWIND                                                             
//    FILE: servoRecorder.pde
//  AUTHOR: Adi Soffer
//    DATE: 30-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;
unsigned int idx, lastidx, firstidx, lastPosition;
unsigned int maxidx = 500;

#include <Servo.h>

Servo myservo;                                                      // create servo object to control a servo
char buffer [2];                                                      //variable to hold keystrokes
unsigned 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 = 500;            //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 = 5;                            //delay time to let servo get to position

unsigned 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");
      Serial.print ("lastPosition is:  ");                  //check change in var
      Serial.println (lastPosition);
      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
    lastPosition = val;                                      //save last position for REWIND fixing
    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"
    lastPosition = val;                                       // save last position for REWIND fixing
    lastidx = idx;
    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 lastPosition in free mode

    if (lastPosition == servoPos [lastidx])
    {
      Serial.println ("lastPosition == servoPos [lastidx]");  //print values for checking
      for (int i=lastidx;i>firstidx;i--)
      {
        val = servoPos [i];
        myservo.write (servoPos [i]);
        lastPosition = val;
        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
      }
    }

    else if (lastPosition < servoPos [lastidx])
    {
      Serial.println ("lastPosition < servoPos [lastidx]");
    }
    else if (lastPosition > servoPos [lastidx])
    {
      Serial.println ("lastPosition > servoPos [lastidx]");
    }
    break;


  case PLAYBACK:
    if (smooth == 1)                                                                            //if I just recorded than "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];
        lastPosition = val;
        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];
        lastPosition = val;
        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;
    }
  }
}









dxw00d

If you are using IDE 1.0, you can use the F() macro in your Serial.print() statements that have quoted literals.

Code: [Select]
      Serial.println ("Free mode"); 
becomes
Code: [Select]
      Serial.println (F("Free mode")); 

This keeps the string in flash, rather than copying it to SRAM.

Soffer

Interesting and good to know, thanks.  :)
In the final sketch all the serial inputs will be replaced by switches, but I will use your tip for now.
What worries me is that I will have to add a variable in order to calculate the different REWIND situations and I hope I won't find myself facing a memory dead end again...

dxw00d

There are some free memory functions on the site somewhere that might be of use.

Soffer

Quote

There are some free memory functions on the site somewhere that might be of use.

Do you mean functions that take no memory and can help with the various calculations I'll need?

robtillaart

Code: [Select]
unsigned int servoPos[valNumber];
declare the array with 8 bit ints iso 16bit ints, as the value of the servo is always 0..179  WIll halve the size of the array

uint8_t servoPos[valNumber];
Rob Tillaart

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

Go Up