Counter for Servo positions

Hi there,

I have 2 servos, using for XY positioning of a laser-I'm building a cat laser toy.

I have been struggling with this problem for awhile and just can't figure it out. Below is my simple code fragment of my predicament: I select 2 random numbers for Servo1 & Servo2, then tell servos to go to that position. My goal is to control the servo repositioning from Position A/B to Position B/C, then loop.

I am trying to give it a speed control, and a more organic feel, rather than a fast as possible movement from AB to CD. I tried that already, works fine, but cats hate it. It is too fast and squarey movements. I want curved organic moves. Any help would be appreciated. I've tried using 'for' loops, but can't get the movement of both servos to synchronize as I can't figure out how to set counters for both servos properly.

Thanks,
Brian

randomA=random(100);
randomB=random(500);
servo1.write(A); //sets 0 point
servo2.write(B); //sets 0 point
delay(150);

//Need to build a function to count from (A to C) & (B to D) at the same time.

randomC=random(200);
randomD=random(300);
servo1.write(C); //sets 0 point
servo2.write(D); //sets 0 point
delay(150);

//Need to build a function to count from (C to A) & (D to B) at the same time.

How are you tracking the cat and is the laser powerful enough to cut through?

Sorry couldnt resist :slight_smile:

Ha, no. My cats don't like being cut by lasers as far as I can tell. :wink:

My next goal is to create some kind of random curves and circular patterns. My cats love chasing things around in circles.

With sin() and cos() you should be able to inscribe any arc you'd care to. Modulating the radius while drawing will make curves that aren't perfectly circular. .

Could I get you to post a picture of your setup? Sounds neat.

Something like this?

void loop()
{
  int from1=300;
  int to1=400;
  int from2=700;
  int to2=200;
  int val1=a,val2=c;

  count( val1,val2,from1, to1, from2, to2 );
}

void count( int& from1, int& from2, int fromTarget1, int toTarget1, int fromTarget2, int toTarget2 )
{
      int diff1 = toTarget1 - fromTarget1; //100
      int diff2 = toTarget2 - fromTarget2; //200
      int rel1 = diff1 / diff2; //0.5
      int rel2 = diff2 / diff1; //0.5
      if(rel1<1&&rel1>=0){rel1=1;}
      if(rel2<1&&rel2>=0){rel2=1;}
      from1+= rel1;
      from2+= rel2;
}

Here is an example of 'hopeful' curves I can maintain between points-this was done in Illustrator, obviously more difficult with random points, but you get the drift. I didn't add any circlular motions in there, but that would be cool too. I'd like to add some code in there to randomly stop the point selections and just start circling on a wider and wider radius. That would be pretty cool.

http://web.me.com/m1interactive/Sample/Curves.html

For the code from AlphaBeta, that is awesome, but I'm a little confused. What does the fromTarget and toTarget int's represent, the distance? Sorry, for one, I am bad at math :cry: And I'm new-ish to Arduino and Javascript programming. Add those up and whew!

What do I do with the last 2 statements,
from1+= rel1;
from2+= rel2;

Thanks,
Brian

What you want is a small bezier interpolator. You can then set the linear speed or the speed limit of the laser track in both dimensions, and ease the motion in and out. I have some pseudocode for a Bresenham-like algorithm that would easily fit in the program space.

What you want is a small bezier interpolator. You can then set the linear speed or the speed limit of the laser track in both dimensions, and ease the motion in and out. I have some pseudocode for a Bresenham-like algorithm that would easily fit in the program space.

I love it when software people talk dirty like this :wink:

Lefty

What do I do with the last 2 statements,
from1+= rel1;
from2+= rel2;

//GIVEN:
  int from1=300;
  int to1=400;
  int from2=700;
  int to2=200;
  int val1=a;
  int val2=c;

/*
|| int& from1      - the adress of the variable that contains current pos for servo 1
|| int& from2      - the adress of the variable that contains current pos for servo 2
|| int fromTarget1 - a variable containing the minimum servo 1 position
|| int toTarget1   - a variable containing maximum servo 1 position
|| int fromTarget2 - a variable containing the minimum servo 2 position
|| int toTarget2   - a variable containing maximum servo 2 position
*/
void count( int& from1, int& from2, int fromTarget1, int toTarget1, int fromTarget2, int toTarget2 )
{
    // 400-300 = 100
    int diff1 = toTarget1 - fromTarget1

    // 200 - 700 = -500
    int diff2 = toTarget2 - fromTarget2; 

    // 100 / -500 = -0.2
    int rel1 = diff1 / diff2;

    // -500 / 100 = -5
    int rel2 = diff2 / diff1; 

    //this sets rel1 to 1
    if(rel1<1&&rel1>=0){rel1=1;} 

    //evaluates false
    if(rel2<1&&rel2>=0){rel2=1;} 

    //original servo 1 pos increases with 1
        //  this syntax is equal to:
        //  from1 = from1 + rel;
    from1+= rel1; 

    //original servo 2 pos increases with -5
    from2+= rel2; 
}

Hi Guys, thanks for all the awesome help-sorry it's taken me so long to reply-been too busy to get back to the project until now. Here is where I'm at (confused), below:

I am confused as to what this does?
int val1=a;
int val2=c;

**Also, not sure how to set these? Do these represent the distance traveled? **
|| int fromTarget1 - a variable containing the minimum servo 1 position
|| int toTarget1 - a variable containing maximum servo 1 position
|| int fromTarget2 - a variable containing the minimum servo 2 position
|| int toTarget2 - a variable containing maximum servo 2 position

randomSeed(millis());

// Choose Point A
randomXR=random(50,100); //creates random X position
randomYR=random(50,200); //creates random Y position

//creates an random position area to move servos around, based on preset XY position
randomxa=random((panVal-randomXR),(panVal+randomXR));
randomya=random((tiltVal-randomYR),(tiltVal+randomYR));

//Move Servo XY positions to A
servo1.write(randomxa);
servo2.write(randomya);

// Set delay between next move
randomDice=random(8); //sets a random longer delay to happen, if diceroll is 3
Serial.println(randomDice);
if (randomDice == 3){
randomDelay2 = random(1000);
}
else {
randomDelay2 = 0;
}

//random HOLD delay function, add even more randomness for intervals of slow/fast movement
randomDelay1 = random(250,500); //pick a random number for delay
delay(randomDelay1 + randomDelay2); //normal delay plus diceroll random of much longer delay

// Choose Point B
Serial.println(" forward ");
randomXR=random(50,100); //creates random X position
randomYR=random(50,200); //creates random Y position
randomxb=random((panVal-randomXR),(panVal+randomXR));
randomyb=random((tiltVal-randomYR),(tiltVal+randomYR));

//GIVEN:
** int from1=randomxa;**
** int to1=randomxb;**
** int from2=randomya;**
** int to2=randomyb;**
** int val1=a;**
** int val2=c;**
/*
|| int& from1 - the adress of the variable that contains current pos for servo 1
|| int& from2 - the adress of the variable that contains current pos for servo 2
|| int fromTarget1 - a variable containing the minimum servo 1 position
|| int toTarget1 - a variable containing maximum servo 1 position
|| int fromTarget2 - a variable containing the minimum servo 2 position
|| int toTarget2 - a variable containing maximum servo 2 position
*/

** // 400-300 = 100**
** int diff1 = toTarget1 - fromTarget1**
** // 200 - 700 = -500**
** int diff2 = toTarget2 - fromTarget2;**
** // 100 / -500 = -0.2**
** int rel1 = diff1 / diff2;**
** // -500 / 100 = -5**
** int rel2 = diff2 / diff1;**
** //this sets rel1 to 1**
** if(rel1<1&&rel1>=0){rel1=1;}**
** //evaluates false**
** if(rel2<1&&rel2>=0){rel2=1;}**
** //original servo 1 pos increases with 1**
** // this syntax is equal to:**
** // from1 = from1 + rel;**
** from1+= rel1;**
** //original servo 2 pos increases with -5**
** from2+= rel2;**

// SETS DELAY UNTIL IT LOOPS BACK to A
randomDice=random(8); //sets a random longer delay to happen, if diceroll is 3
Serial.println(randomDice);
if (randomDice == 3){
randomDelay2 = random(1000);
}
else {
randomDelay2 = 0;
}

//random HOLD delay function
randomDelay1 = random(250,500); //pick a random number for delay
delay(randomDelay1 + randomDelay2); //normal delay plus diceroll random of much longer delay

int val1=a;
int val2=c;

These was just some variables to test the void count( int& from1, int& from2, int fromTarget1, int toTarget1, int fromTarget2, int toTarget2 ) function.

I think you'll have to explain what you want to do (again?) :slight_smile:

I want to help, but at this point it is a bit difficult.

BTW, the purpose of count() function is to recieve tho positions (called from1 and from2) and then increase or decrease these positions according to the from and to variables. [from1 increases or decreases to reach the value of fromTarget1, and uses the ratio between fromTarget1 and toTarget1 to get there [this ensuer a constant speed])

Thanks for the reply. My goal is to move the servos in a nice line, rather than all herky-jerky as they are now. Here is what I have now:

set & move servos to Positon A:
// Choose Point A
randomXR=random(50,200); //creates random X position with a variance between 50-200
randomYR=random(50,400); //creates random Y position with a variance between 50-400
randomxa=random((panVal-randomXR),(panVal+randomXR));
randomya=random((tiltVal-randomYR),(tiltVal+randomYR));

//Move Servos to position A
servo1.write(randomxa);
servo2.write(randomya);

//Then move to servos to position B
// Choose Point B
randomXR=random(50,200); //creates random X position with a variance between 50-200
randomYR=random(50,400); //creates random Y position with a variance between 50-400
randomxb=random((panVal-randomXR),(panVal+randomXR));
randomyb=random((tiltVal-randomYR),(tiltVal+randomYR));

//Move Servos to position A
servo1.write(randomxb);
servo2.write(randomyb);

Then I need to move to a new A position. . I added this to my actual code to try to integrate your code:

int from1=randomxa;
int to1=randomxb;
int from2=randomya;
int to2=randomyb;

How can I use this properly. Do I have the above variables correct?
toTarget1
fromTarget1
toTarget2
fromTarget2

...and in these statements, doesn't it imply that the toTarget will always be a larger value than fromTarget? This is what has really got me stumped.

int diff1 = toTarget1 - fromTarget1;
int diff2 = toTarget2 - fromTarget2;

Also, not sure which value equals the servo position??

It seems that maybe you do not know how to use functions? Very sorry if this is not the case, but it seems that way from viewing your code.

A function provides programmers a way write something once, and use it over and over again.

A simple example is the add function, if your program uses a lot of addition you could write a function for it:

int add(int x,int y){
return x+y;
}

Now you can write:

int sum = add(3,4);

And sum will contain the integer 7.

My function count() recieves two variables that represents servo position, and four 'bounds' variables. [I have not testet this function other than serial.println() and it seems to count correctly, in a linear matter]

Yet again sorry if this in any way was offencive.

Thanks, oh I'm not offended at all! I understand how to use functions in general, but wasn't clear on how to pass variables back and forth, I think I get it now. Great mini tutorial!

Is it possible to see how you used your function in a working example-that would help me figure out which variables refer to what I'm trying to do. I'm still quite confused as to how to do this properly with the random numbers I'm generating.

Thanks so much!
Brian

Here is a video of the 'Robot Cat Toy' in Bird Mode-this part is just fine, I'm building 2 modes, the Bird Mode and Laser Mode. Laser Mode will be much less jerky and super smooth. That's the part I still need help with.
Brian