Help with dual servos

I have 2 servos to control, and need a bit of help with the code being that I'm not a programmer.

I would like to know if it's possible to first of all run both motors at the same time, instead of running one, then the other and back to the first one.

Secondly, is it possible to make one of them stop midway through the sweep, pause, then resume the sweep?

this is what I have now and it's close to what I need, but I don't know how to do what I want them to do.

#include <Servo.h> 

Servo wiper;   // create servo object to control a servo 
Servo turnstile;                // a maximum of eight servo objects can be created 

int pos = 0;    // variable to store the servo position 
int pos2 = 0; 
void setup() 
{ 
  wiper.attach(14);  // attaches the servo on pin A0 to the servo object 
  turnstile.attach(15); // attaches the servo on pin A1 to the servo object 
} 


void loop() 
{ 
  for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 25 degrees 
  {                                 // in steps of 1 degree 
    wiper.write(pos);               // tell servo to go to position in variable 'pos' 
    delay(5);                      // waits 15ms for the servo to reach the position 
  } 
  for(pos = 90; pos>=1; pos-=1)     // goes from 25 degrees to 0 degrees 
  {                                
    wiper.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(5);                       // waits 15ms for the servo to reach the position 
  } 
 //===============
   for(pos2 = 0; pos2 < 180; pos2 += 1)  // goes from 0 degrees to 25 degrees 
  {                                 // in steps of 1 degree 
    turnstile.write(pos2);               // tell servo to go to position in variable 'pos' 
    delay(5);                      // waits 15ms for the servo to reach the position 
  } 
  for(pos2 = 180; pos2 >=1; pos2-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    turnstile.write(pos2);              // tell servo to go to position in variable 'pos' 
    delay(5);                       // waits 15ms for the servo to reach the position 
  }
}

Hi Ground Pounder,

I would like to know if it's possible to first of all run both motors at the same time, instead of running one, then the other and back to the first one.

Yes, they can be run concurrently. You'll probably need to use a separate power supply -- and not power it from the Arduino, due to their power draws. Be sure to connect the grounds together.

Secondly, is it possible to make one of them stop midway through the sweep, pause, then resume the sweep?

You'll need to divide the rotation into segments with a pause in the middle. A servo will go straight to its requested angle as soon as you tell it to. Of course it will take a little time, but you really can't stop it in the middle without giving it a different command (angle). This may be more complicated than you are expecting.

Just a few comments on the code:

  • your comments say you are rotating the servos 25 degrees, but the code will turn them to 90 and 180 degrees, respectively
  • the code will wait 5ms between each move, not the 15 that your comments indicate.
  • I can't see your setup, but be sure to program the servos to their initial positions (0 degrees) before this loop starts. Otherwise the motion may be pretty jerky at first as the servos try to go to 0, from wherever, in the first 5ms

Pat.

This is my problem, I'm not a programmer.... so I don't know how to do that stuff.
That code was just the modified example for a servo motor which is why the comments are wrong.

I need help with the programming because this needs to be done asap, and I don't have the time or luxury to sit around messing with it for weeks to learn it all.

I have about 3 days to perfect the code to do what I want it to do.

We'll see if we can help.

Here are a few things we'll need to know:

  • What exactly do you want it to do?
  • Is the hardware already built?
  • Describe your concurrency requirements and how long you want to pause during a movement.
  • How do you know to pause? Do you have another sensor, or do you always need to pause at some specific point(s)
  • How fast do they need to move? Are you happy with the 15ms per degree steps?

Pat.

I can tweak the timing. There are no sensors. Since this is just kind of a quick and dirty job it's all down to timing.

Wiper starts at 0, moves X degrees (this one is geared, i was using 25deg just for testing) pause.

Turnstile starts at 0, moves 90deg, pause.... Wiper begins moving from X deg back to 0, as it's moving back to 0 turnstile un-pauses and begins moving to 180deg.

Then that process basically reverses.... here is a video showing roughly what the servos need to do.

Ignore the plunger at the back, the only thing I'm concerned with is the two round parts moving.

The PROPER functionality starts at about 0:28 in the video.

This looks feasible, how about something like this pseudo code? It will provide a smooth, continuous, and simultaneous operation:

1. Start both servos at 0 degrees
2. wait a little bit to make sure they get there.

in loop:

3. move servo 1 (from 0 to 45 degrees) in loop (15ms per step)

4. move both servos in loop (x=0 to x=90) in loop (15ms per step)
    4.1 move servo 1 (x+45)
    4.2 move servo 2 (x)

5. move servo 1 (from 135 to 180 degrees) in loop (15ms per step)

Repeat in reverse if necessary, or move both to their initial positions again and repeat.

The pseudo code I get, but I honestly have not even the beginning of an idea of how to do it in the code. I don't actually know any languages I can usually only just modify them.

I can give it some more thought.

Like you said, it all comes down to the timing and the specifics of your unique setup:

  • What are the actual angles you want to rotate the wiper and turnstile?
  • At what point(s) should they / can they move simultaneously?

Pat.

Have you gotten your servos to move using servo code?

The wiper being the larger of the two rotating parts in the video, and the turnstile being the other, it should function similar to this.

The wiper starts it's rotation, moves 338*, then stops and pauses while the turnstile rotates 90*.

Once the turnstile reaches 90* the wiper begins moving back to 0*, while the wiper is on it's way back to 0* the turnstile will rotate another 90*, putting it at 180* until the wiper reaches 0*. Then the process basically reverses.

Gotcha. FYI - Most servo motors only rotate from 0 to 179 degrees (or -90 to +89 degrees). I am not aware of any that rotate beyond 180 degrees.

Is this a problem?

You could use stepper motors instead of servos, but that is more complicated.

I am not aware of any that rotate beyond 180 degrees.

I've got standard type servos that will rotate ~190 deg. A lot may depend on the internal pot and the internal hard stops. Note that the servo library has some default us timing limits that might affect a particular servo.

Understand. But I think he is looking for some that rotate from 0 to 338 degrees, unless that's a typo. I'm not aware of any that go anywhere near that range.

Gndpndr, is 180 ok? It sounds like you already have them. Are you good with them? ...and what are their ranges?

Winch servos usually can make several turns, but position accuracry might be reduced.

http://www.robotshop.com/ca/hitec-hs785hb-servo-motor-2.html

Very nice! I just bookmarked that for a future project. Thanks for the link.

I don't get the sense that accuracy will be the limiting factor with this challenge. I think he's only got 2 days left to finish it, and might not have a servo that can turn the required angle.

Now... If 180 degrees is ok, then he is golden.

One can make a 180 deg servo turn something 360 deg, the servo output just needs to be geared up by 2x. Gears or DIY pully type setups can be used.

I did mention earlier that one of the motors was geared, the "wiper" servo, which is why I'm not certain of the angle because the guy who bought the gears went WAY over 2:1 I think so that servo is only going to have to move like 25*.

We originally went with steppers but because the device we have is made from a rapid prototyper it's heat sensitive and the steppers were getting hot enough to re-melt the plastic......so we had to move to servos.

and yes I do have the servos working with servo code.

I think heating of stepper motors may be reduced by starting movement with max current, then reducing the current to a holding current when the stepper isn't moving.

Ground Pounder,

Here is a draft of what I think the code would look like.

  • CAVEAT #1 - I did not compile it, and you'll need to double-check that the for loop limits and ++/-- are correct.
  • CAVEAT #2 - I did not attempt to move the servos simultaneously. In order to do this effectively, we'll need to really understand the gearing for the wiper. Does it really have to move simultaneously? Because they aren't geared the same, one servo may appear to stutter when it moves. (This is due to the fact that each will move different "actual" degrees in each 5ms step.)
//
// 2 servos operate as depicted (without plunger) in https://www.youtube.com/watch?v=yhlfb8BLzMk
//

#include <Servo.h> 

Servo wiper;     // create servo object to control a servo 
Servo turnstile; // a maximum of eight servo objects can be created 

const int MIN_WIPER_DEGREES = 0;
const int MAX_WIPER_DEGREES = 25;  // actually geared to 338*
const int MID_WIPER_DEGREES = (MIN_WIPER_DEGREES + MAX_WIPER_DEGREES)/2;

const int MIN_TURNSTILE_DEGREES = 0;
const int MAX_TURNSTILE_DEGREES = 180;
const int MID_TURNSTILE_DEGREES = (MIN_TURNSTILE_DEGREES + MAX_TURNSTILE_DEGREES)/2;

const int STEP_DELAY = 5; // ms

void setup() 
{
  wiper.attach(14);  // attaches the servo on pin A0 to the servo object 
  turnstile.attach(15); // attaches the servo on pin A1 to the servo object 

  //
  // start in position 1 -- wiper in max position, turnstile in max position (:28 in video)
  //

  wiper.Write(MAX_WIPER_DEGREES);
  turnstile.Write(MAX_TURNSTILE_DEGREES);
  delay(100);  // wait to get there
} 

void loop() 
{ 
  int degree; // for loop counter
  //
  // move to position 2 -- wiper in min position, turnstile in max position (:35 in video)
  //

  for (degree = MAX_WIPER_DEGREES; degree >= MIN_WIPER_DEGREES; degree--)
  {
    wiper.write(degree);
    delay(STEP_DELAY);
  }

  //
  // move to position 3 -- wiper in min position, turnstile at mid-point (:37 in video)
  //

  for(degree = MAX_TURNSTILE_DEGREES; degree >= MID_TURNSTILE_DEGREES;  degree--)
  {
    turnstile.write(degree);
    delay(STEP_DELAY);
  }

  //
  // do something here?  here is where the plunger acts
  //

  //
  // move to position 4 -- wiper in min position, turnstile at min position (:38 in video)
  //

  for(degree = MID_TURNSTILE_DEGREES; degree >= MIN_TURNSTILE_DEGREES;  degree--)
  {
    turnstile.write(degree);
    delay(STEP_DELAY);
  }

  //
  // move to position 5 -- wiper at max position, turnstile at min position (:45 in video)
  //

  for (degree = MIN_WIPER_DEGREES; degree <= MAX_WIPER_DEGREES; degree++)
  {
    wiper.write(degree);
    delay(STEP_DELAY);
  }

  //
  // move to position 6 -- wiper at max position, turnstile at mid-point (:47 in video)
  //

  for(degree = MIN_TURNSTILE_DEGREES; degree <= MID_TURNSTILE_DEGREES;  degree++)
  {
    turnstile.write(degree);
    delay(STEP_DELAY);
  }

  //
  // move back to position 1 -- wiper at max position, turnstile at max position (:53 in video)
  //

  for(degree = MID_TURNSTILE_DEGREES; degree <= MAX_TURNSTILE_DEGREES;  degree++)
  {
    turnstile.write(degree);
    delay(STEP_DELAY);
  }

  // repeat...

}

Thanks, I'll check it out today and find out how it works and if I need to tweak it a bit.

I've been reviewing it and the code looks easy to follow, I can see what it's doing and how :slight_smile:

it looks easy, but I would have spent weeks trying to come up with the same thing.