Trying to create non-blocking Servo code

I would like to create servo code that allows the Arduino to set multiple servos in parallel. The code in the servo library is somewhat opaque though.

write() calls writeMicroseconds(). Microseconds calls cli() to turn off interrupts, but I don't see it doing any changes to the pin itself.

I can't find where it actually puts out a pulse. But I saw elsewhere on this forum (http://forum.arduino.cc/index.php/topic,10537.0.html) that pwm could be assigned in hardware directly to pins.

  1. Can I program the pin to turn on for the appropriate duration, and off, without further CPU involvement?
  2. Is it ok if the pin keeps on doing the same thing over and over? I don't really know the pulse requirements of a servomotor. Does the pulse have to go just once?
  3. Why is the current Servo class blocking? Does it have to be for some reason I don't know?

but I don't see it doing any changes to the pin itself.

It's done in the ISR(s).

What do you mean by "blocking" in this context?

I mean when you write to a servo it waits until the motion is complete before execution goes on. It's horribly slow. To make a hand with 5 servos (one per finger), ideally:

s1.write(20); s2.write(35); s3.write(30); s4.write(10); s5.write(20);

What happens in practice is that the fingers move sequentially.

You could always move each servo a small distance in turn until it reached the target using the BlinkWithoutDelay technique. A further improvement would be to arrange the size of the increments to make each servo arrive at its target position at the same time if that is what you wanted.

I mean when you write to a servo it waits until the motion is complete before execution goes on

Are you using the standard servo library provided with the IDE? That library cannot know when the motion is complete (there's no feedback from the servo), so blocking would be futile, and so it doesn't.

hydrodog:
I mean when you write to a servo it waits until the motion is complete before execution goes on.

The standard servo library doesn’t do that. When you call servo.write() it returns immediately and the servo will subsequently move to the new position. There’s no position feedback from a standard servo so in fact the library couldn’t tell when the servo had completed the movement even if it wanted to.

You didn't post your code, we are just guessing - please post all your code, it saves everyone time.

I hadn’t done any this time around to show, but I’ve seen this numerous times:
This kind of code triggers one servo, then a second when the first is done. But since you’re telling me it doesn’t, I’m going to try this out and do the circuits myself, making sure they are powered external to the Arduino.

#include <Servo.h>
Servo s1;
Servo s2;

void setup() {
  s1.attach(9);
  s2.attach(3);
}

int ang0 = 0, ang1 = 30;
int d0 = 10, d1 = 10;
void loop() {
  s1.write(ang0);
  s1.write(ang1);
  delay(100);
  ang0 += d0;
  ang1 += d1;
  if (ang0 > 180) {
    ang0 = 180;
    d0 = -d0;
  }
  if (ang1 > 180) {
    ang1 = 180;
    d1 = -d1;
  }
}

hydrodog: This kind of code triggers one servo, then a second when the first is done

No, it absolutely doesn't. It explicitly moves both servos in incremental steps concurrently. It's not especially good code and looks to me as if it would get stuck after the first full cycle, but there is nothing there that demonstrates the problem you're describing.

Hi guys,

I believe that if you have this kind of problem, you must use a external microcontroller like Pololu servo controller.

Indeed, I use a very useful register information

get_moving_state

that return 0 only one all servo are stopped.

sonique:
I believe that if you have this kind of problem, you must use a external microcontroller like Pololu servo controller.

Not at all. All that’s doing is moving the servos at a controlled speed - it does not get any positional feedback from the servo and you can achieve just the same thing using an Arduino.

Hi Peter,

How you can control the servo Speed with Arduino?

In Servo.h library I know only .write() and .wtireMicroseconds().

How you can control the servo Speed with Arduino?

Write a new position that is only a small distance from the current position. Wait a while. Write a new position. Wait a while. Repeat as needed to get to the desired position. The longer you wait, the slower the servo moves.

Ok thanks,

I't s clear. Personally I prefer use a specific functionality that handle speed and acceleration too.

sonique: Personally I prefer use a specific functionality that handle speed and acceleration too.

Well, that seems simple enough to implement, if that's what you want.

Well, that seems simple enough to implement, if that's what you want

I'm not sure how simple this will be, for someone that can't even imagine how to control speed.

Personally, I think you, OP, are expecting too much of your servos.

Integrating acceleration into the Servo class will not be a trivial task. You'll need to know where the servo is at all times, to get speed to be part of the class. Incorporating acceleration will not be trivial. Keep in mind that the current Servo class supports more than just hobby servos. It supports continuous rotation "servos" (which really aren't servos) and ESCs, among other things. Not all of them will understand acceleration the same way.