Slight delay in panning/rotating program


hello everybody,

just bought arduino , busy project of controlling rotation , tilt of camera using kit bought (see image attached)

the kit uses 2 servos, 1 rotational movement (x-axis) , 1 tilting movement (y-axis). using arduino, trying make these move in order create timlapses example.
the arduino have arduino mega 2560, , after playing around code, got working program want, slight delay.

the program wrote relies on multidimensional array put in x-coordinate, y-coordinate (in degrees) , time every point want camera pass. example, @ 2 seconds, want x-servo @ 100 degrees, , y-servo @ 20 degrees, can fill in 100,20,2 (see code more details).


code: [select]

#include <servo.h>

servo xasservo;
servo yasservo;

//int datamatrix[3][amountofpositions] = {  {xposition1, xposition2},
//                                          {yposition1, yposition2},
//                                          {time1, time2}};

unsigned long datamatrix[3][2] = {  {0, 180,3},
                                    {0, 180,56},
                                    {0, 180,187}
};

void setup() {
  serial.begin(9600);
  xasservo.attach(9);
  yasservo.attach(8);
  pinmode(13, output);
  int numcols = sizeof(datamatrix[0]) / sizeof(datamatrix[0][0]); //check how many datapoints present

  //set initial positions of servos 0 , 0 degrees , set time 0 seconds
  int nextx = 0;
  int nexty = 0;
  unsigned long nexttime = 0;

  //move servos initial positions (x-axis mirrored).
  xasservo.write(187);
  yasservo.write(0);
  //give them enough time positions.
  delay(15);


  (int = 0; < numcols; i++) { //for every datapoint
    //set previous positions current positions , previous time current time
    int currentx = nextx;
    int currenty = nexty;
    unsigned long currenttime = nexttime;

    //set next positions , time
    nextx = datamatrix[0][i];
    nexty = datamatrix[1][i];
    nexttime = (datamatrix[2][i] * 1000);

    //calculate how long move until next datapoint
    unsigned long totaltime = nexttime - currenttime;

    movexy((currentx * 10), (currenty * 10), (nextx * 10), (nexty * 10), totaltime);
  }
}


void movexy(int currentx, int currenty, int nextx, int nexty, unsigned long totaltime) {
  //calculate how time per 0.1 degree needed x-and y-axis.
  unsigned long timeperx = totaltime / abs(nextx - currentx);
  unsigned long timepery = totaltime / abs(nexty - currenty);

  serial.print("current x = "); serial.print(currentx); serial.print(" next x = "); serial.println(nextx);
  serial.print("current y = "); serial.print(currenty); serial.print(" next y = "); serial.println(nexty);
  serial.print(" timeper x = "); serial.print(timeperx); serial.print(" total time = "); serial.println(totaltime);

  //make counter counts 0 till end of datapoint time
  (unsigned long j = 0; j < totaltime; j++) {

    //move x-axis if amount of time 0.1 degrees passed
    if ((j % timeperx) == 0) {
      if (nextx < currentx) {
        currentx = currentx - 1;
      }
      else if (nextx > currentx) {
        currentx = currentx + 1;
      }
      else {
        currentx = currentx;
      }
      //because x-axis mirrored, , servo works best 7 187 degrees, mirror here
      xasservo.write(abs(187 - (currentx / 10)));
    }

    //move y-axis if amount of time 0.1 degrees passed
    if ((j % timepery) == 0) {
      if (nexty < currenty) {
        currenty = currenty - 1;
      }
      else if (nexty > currenty) {
        currenty = currenty + 1;
      }
      else {
        currenty = currenty;
      }

      yasservo.write((currenty / 10));
      //serial.print("y set to: "); serial.print(currenty); serial.println(" degrees");
    }

    //wait 1 millisecond
    delaymicroseconds(1000);

    //blink led check timing
    if (j % 1000 == 0) {
      //serial.print(j/1000); serial.println("seconds");
      digitalwrite(13, high);   // turn led on (high voltage level)
    } else if (j % 1010 == 0) {
      digitalwrite(13, low);   // turn led on (high voltage level)
    }
  }
  serial.println("moving step done");
}

void loop() {
}


to explain code doing, calculating time between 2 datapoints in milliseconds (from multidimensional array), , counting 0 till time. in time, x-and y-servos move witht speed determined amount of degrees needs turn in time, in steps of 0.1 degrees.
after counting done, program moves next datapoint, same.
the result smooth movement 1 point next both x-and y-axis, though speeds may differ.

as mentioned, program works fine, problem has delay. state 1 millisecond delay between each loop, total loop takes 1 milliseconds. turns out that, when run program 3 minutes, there 15 second delay (this without communication through serial port). not sound much, if want run program hour, delay approximately 5 minutes of course.

since started studying electrical engineering year ago, , had introductions in vhdl , code synthesis, understand doing in code right time consuming, making counter , comparing (huge) values appear, problem originates from. also, not smart make servos move @ 0.1 degrees, since 1 degree gives less of error. i've tried well, , approach still has small error (about 9 seconds per 3 minutes).

therefore, want ask if there smarter way make 2 servos move specified degrees @ independent speeds, has less delay method tried.

thank in advance!
tom salden

i'm not understanding code, looks fishy:
code: [select]

unsigned long currenttime = nexttime;

normally currenttime set millis(), or can use millis() directly.  (see blink without delay example.)

millis() runs continuously in background errors don't accumulate.

with delay() timing errors accumulate because every programming step takes time , time added delay() time.   shorter delay , more times loop more errors accumulate.  

millis() not perfect because no clock perfect, , arduino's resonator not accurate watch crystal, long term accuracy no worse resonator's frequency-accuracy.


Arduino Forum > Using Arduino > Project Guidance > Slight delay in panning/rotating program


arduino

Comments

Popular posts from this blog

Error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode - Raspberry Pi Forums

class MPU6050 has no member named begin

missing filename after '-o'