Simultaneous but independent speed control of 2 servos

however you are assuming that I have some level of basic programming foundations.

No, I'm assuming you have some idea how you would perform the task, and that the difficulty lies in converting that thinking into code that the Arduino can execute.

That's why I steered the discussion away from how to make the Arduino perform the task.

I am afraid that you think I am smarter then what i seem to be, he he.

That could definitely be a problem. On the other hand, if someone trusts you with a loaded gun, there must be some hope.

Lets say that at 13H00 we want the servos to start moving.
we check the watch to see what time it is.
If it is 13H00 the servos will be told to start moving.

Of on the wrong foot already. The time to start is when the function is called. That time doesn't matter, except that it is the reference point for all future times.

If you were using continuous rotation servos that moved until told to stop, then your approach would work. The servos you have though are like teenagers. You tell them to do something, and they work while you watch. Turn your back for a minute, and they stop.

So, you determine that it will take servo P 110 minutes to sweep the whole range (of 110 degrees), so, once a minute you need to kick it, and say "Hey, lazy, move to position n", where, of course, you have to figure out what n is, based on how many times you've kicked the lazy servo.

You determine that servo M will take 88 minutes to sweep the whole range (of 110 degrees), so, once a minute you need to kick it, and say "Hey, lazy, move to position n", where, of course, you have to figure out what n is, based on how many times you've kicked the lazy servo.

Now, clearly, the amount that servo P moves to each time you kick it will be different from the amount that servo M moves to each time you kick it. So, you need to keep track of two different positions, one for M and one for P.

You will also note that it is not necessary to kick servo M every time you kick servo P, since M will be done before P is.

In this story, the things that Double() does not know are how long P is supposed to take to sweep, and how long M is supposed to take. The rest of the information that it needs IS known (which servo pins to kick, and how far to step each time it is necessary to step.

So, does this help you see how to make the Arduino move the two servos in different periods of time? The key is that each servo moves a different amount in a given period of time. The end of that period of time can be determined by millis(), and Double would be called many, many times before the servos reached the end of the travel, some times doing nothing (OK, most times), but occasionally, kicking the servo into gear to move a little.

Or, the end of that period of time could be determined by delay(), in which case Double() would block until both servos had moved the required amount.

I would prefer the one degree steps as I want it to go from 0-110 in one degree increaments so that it may have a smooth sweep and not choppy.
However the time it would take to move one degree would be a ridiculously short time.
Assuming that its quantifiable would i than tell it to do each one degree movement at a particular millisecond speed until it reaches the 110 degree mark in the time frame required.
Would that not require some kind of loop?
I told you I would get confused.
I am trying to run here and I dont even know how to crawl yet.

However the time it would take to move one degree would be a ridiculously short time.

Not from the Arduino's perspective. The Arduino perceives that an eon has passed while that ssslllooowww servo gets it's act together and moves one degree.

Assuming that its quantifiable would i than tell it to do each one degree movement at a particular millisecond speed until it reaches the 110 degree mark in the time frame required.

Of course it is quantifiable. You know how long you want the servos to take to complete the whole sweep. Divide that time by the number of steps. That is how long to wait between steps.

It will be different for each servo, since you want them to move at different speeds.

Would that not require some kind of loop?

It could. A while loop would work, since the number of iterations is not known.
Some psuedo code:

while(not yet at end)
{
   Is it time to kick P again? If so,
     kick P and note the time.
   Is it time to kick M again? If so,
     kick M and note the time.
   update position of P and M.
}

I am trying to run here and I dont even know how to crawl yet.

I think you are underestimating yourself.

I promise I am much better at shooting Skeet than at this!! He he.
I really appreciate all your help and to be honest I am suprised that a bunch of buffs like you guys gave me the time of day.
I am nowhere near completing my function , however I do understand what needs to be done much better now.
I thank you all very much for your assistance and I will be back online in about one hour to keep battling.

Hi I am back for part 2 the revenge.
Sorry I was not online yesterday afternoon thanks to a blown pc power supply at home, compliments of my electricity provider.
To pickup from yesterday, I would need to put in arduino-ese a function that does the following:

sets both servos to position 0
I figured out that if I want the Pull servo to sweep from 0-110 degrees at a speed of 1.5 sec I would have to tell it to move one degree every 13.63mils and
the Mark servo will do the same but at a slower pace(1.7 sec) so that would have to move one degree every 15.45 mils.
the position of the servos would need to be updated every one degree and once they each reach 110 degrees the whole loop of some sort will stop, until the function is called again.
I imagine that it would have a while each servo position is smaller than 110 degrees loop.
note the time using millis and when that time is equal to 13.63mils for the Pull and 15.45mils for the Mark write servo position of 1 degree, than check the time again and move the Pull and Mark servos one degree every 13.63 and 15.45 mils respectively.
The big question is how do I do that?
Sorry to bore you with trivial stuff,but its anything but trivial to me.
Thanks

First thing you need to understand is that time is an integer value. You can't do things every 15.45 or 13.63 milliseconds. Every 13 or 15, yes.

Something like this should work:

unsigned long lastMove = millis();
unsigned long lastPull = millis();

unsigned long moveInterval = 15;
unsigned long pullInterval = 13;

int movePos = 0;
int pullPos = 0;

while(pullPos < 110 || movePos < 110)
{
   unsigned long now = millis();
   if(now - lastMove > moveInterval)
   {
      movePos++;
      servoM.write(movePos);
      lastMove = now;
   }

   if(now - lastPull > pullInterval)
   {
      pullPos++;
      servoP.write(pullPos);
      lastPull = now;
   }
}

You can make the 110 constants variables, and you can compute, rather than hard-code, the intervals, to increase the flexibility of the program.

I thank you kindly for your assistance and puting up with me.
I will incorperate this code with mine ,try it on my little machine and let you know how it goes.
Thanks again

You can't do things every 15.45 or 13.63 milliseconds.

But you can get quite close by calling them 1545 and 1363 microseconds.

But you can get quite close by calling them 1545 and 1363 microseconds.

True (except you are off by an order of magnitude).

A 0.63 millisecond discrepancy in step time, for 110 steps, will only result in completing the move 69.3 milliseconds early, though.

you are off by an order of magnitude

It's been one of those mornings :frowning:

I tried it on its own so that none of my existing code could effect it.
It seem to make the slower motor move past 110 degrees(so its covering more ground therfore it seems slower?).
I also thought that thw while loop having the 110 degree limit would prevent the servos from going past 110 degrees.
Is it me again, or do i need to change something else?

It seem to make the slower motor move past 110 degrees(so its covering more ground therfore it seems slower?).

Yes, because I forgot to test that it is also necessary to step again.

if(now - lastMove > moveInterval && movePos < 110)
{
movePos++;
servoM.write(movePos);
lastMove = now;
}

if(now - lastPull > pullInterval && pullPos < 110)
{
pullPos++;
servoP.write(pullPos);
lastPull = now;
}

I hate the fact that the answer to that was so simple to you.He he
But I love the fact that I can now finish the function and put my much more realistic skeet simulator to good use!!
I thank you all once again and hope not to bug you with such trivial things in the future.
Time to SHOOT.

AWOL:
It's been one of those mornings :frowning:

What, you mean really REALLY short? :smiley: