Pages: 1 2 [3] 4 5 ... 8   Go Down
Author Topic: how to create an array with both members and number of members undefined  (Read 5297 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks guys.
GoForSmoke you are correct and thanks for the remark.

Tom, actually I haven't paid attention to that part (...) and IDLE is indeed no longer needed.

Is there a way for me to now take the array and smooth its curve of values so as to get rid of small jitters?
Do you believe a stepper motor could do a better job of moving smoothly? The servo moves a focus ring on a lens.
Do you think an optical encoder w/high resolution will help that (or maybe the 180 degree resolution of the servo limits me?

Thank you
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm looking all over the place, and I guess it's just my lack of understanding  smiley-confuse, but I can't find a decent example of a continuous array being smoothed - not just averaged. What I mean is that if in the course of 300 values from 0 to 299 I have parts like:

234, 235, 238, 236, 239, 240, 241

I can smooth the curve to

234, 235, 236, 237, 238, 239, 240

Any pointer?
Thanks



Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just sort it?

Look up: qsort
Logged


Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No Nick - I mean smoothing the curve between the values so as to get rid of unwanted jitter
Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 217
Posts: 13717
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
234, 235, 238, 236, 239, 240, 241

I can smooth the curve to

234, 235, 236, 237, 238, 239, 240

should be smoothed to:  234, 235, 236, 238, 239, 240, 241


Nick was in the right direction, with sorting, but instead of sorting the whole array you must sort a small window.
you can use a single pass of bubble sort to remove jitter with a window size of 2 values.
You can create algorithms that do smoothing upon 2,3,4,..100 values that are basicly al the same.

get the idea?



Logged

Rob Tillaart

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

Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Unfortunately... far from it smiley-red
I mean, I understand the idea but not how to take my arrays and do this.
I hate to admit it but the whole "create algorithms" stuff is for me like "write a poem in Chinese"...
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, do a single pass through the array. If two values are in the wrong order, swap them.
Logged


Anchorage, AK
Offline Offline
Edison Member
*
Karma: 42
Posts: 1176
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think sorting is the right option.  How would it handle decrements?  Sounds like what he's looking for is more of a lowpass filter algorithm.

Maybe a good place to start would be to average three values at a time, and set the middle to the average.  Consider this sequence:

200 205 210 220 212 214 212 209 199 209 200

There are spikes up at 220 and down at 199.  If you wrote a procedure to take (index) and (index + 2) and average them, then write that to (index + 1), you end up with:

200 205 212 212 213 212 210 205 207 203 200

You end up distorting the actual values, but smooth the response considerably.  Maybe it's a good trade, maybe it isn't, but it's an easy loop to code:

Code:
// Loop from first entry to two-from-last entry
// (Can't use next-to-last or last indexes because i+2 is out of bounds)
for (int i = 0; i < max - 2; i++) {
  array[i + 1] = (array[i] + array[i + 2]) / 2;
}

edit: Ugh, I swear.. I need to learn to proof-read.  I've edited this like four times to fix things.
« Last Edit: March 27, 2012, 05:38:04 pm by SirNickity » Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 98
Posts: 4807
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm looking all over the place, and I guess it's just my lack of understanding  smiley-confuse, but I can't find a decent example of a continuous array being smoothed - not just averaged. What I mean is that if in the course of 300 values from 0 to 299 I have parts like:

234, 235, 238, 236, 239, 240, 241

I can smooth the curve to

234, 235, 236, 237, 238, 239, 240

Any pointer?
Thanks

You want curve fitting or can you live with a linear fit? That's possibly a major scope in itself.

The quick and easy for curve fitting would be to transfer the data to your PC and use an application there. Perhaps a spreadsheet or matlab?

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oohh, seems like I'm stepping into deep water here - for me at least...
Thank you all for replying  smiley

Nick - how do I do what you suggest? I'd be happy to try and see if it works.
SirNickity - I'm going to try and use your suggestion and see what comes at the other side. Thanks.
GoForSmoke - I think linear would suit me fine (and I don't want to use a pc). Does that mean using SirNickity's technique? Or are you talking about some other way of doing this?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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:

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


Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Why?

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


Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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...
Code:
//                                                                           
//    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;

  }
}





« Last Edit: March 28, 2012, 07:39:42 am by Soffer » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Pages: 1 2 [3] 4 5 ... 8   Go Up
Jump to: