Servo library and delay()

good day!
I have a question related to servo library (standard arduino library)
Servo - Arduino Reference

lets comment following istruction:

...
Servo myservo;
...
myservo.attach(9);       init servo pin
myservo.write(90);       start controlling position with digital pulses
delay(1000);                  waiting 1 sec
...

question is if delay is blocking myservo.write() instruction and digital pulses position reference to servo? or myservo.write() set the digital pulses at pin and pulses continues anyway during delay() and following instruction?

In similar way, we know that analogWrite() instruction is not blocked by delay() or following instruction, since analogWrite() set pin working with PWM arduino hardware.
I need to confirm if servo.write() is blocked or not by delay.
Thanks for your support

Increase the delay to 100000 to make its effect more obvious.

Unless you write() a different angle to a servo before attaching it attaching it then it will move to its default position of 90 degrees anyway when attach()ed so the write(90) in your code is not strictly necessary in any case

BTW

  • Do you know the servo library produces blocking code.
    Moving a servo by small amounts till the motor gets to the desired position is a workaround.

lets suppose to make following instruction list, it will explain better the question:

myservo.write(150);
delay(10000);                   during delay here, write(150) is still operating pulses?
myservo.write(90);
delay(10000);                   during delay here, write(90) is still operating pulses?
myservo.write(20);
delay(10000);                   during delay here, write(20) is still operating pulses?

question is if once you set write(), pulses will operate during delay() and following instructions, until a new instruction write() is set ? or pulses are blocked by delay() ?

thanks for your support.

myservo.write(150);        //servo moves to 150
delay(10000);              //does not execute until the servo gets to 150

I am not sure what your question is. Are you asking whether the signal to the servo to keep it at the commanded angle will be maintained or is it something else ?

delay(10000);              //does not execute until the servo gets to 150

How will the program know that the servo has reached its target angle ?

1 Like
  • Was worded poorly.
    I should have said when the servo code for myservo.write(150); is executed, we experience "a" delay from the code that generates pulse timing to go to 150.
    Once this code is finished executing, the output pin will be setup to the pulse timing necessary to go to 150; at which time the next line of code is executed, i.e. delay(10000);

I did wonder because I know that you know better :grinning:

The pulses that control the servo position are created by timer interrupts. All that the write() command does, is configuring the timer and its interrupt the correct way. Than it returns immediately. The delay() function does not inhibit interrupts, so the pulses are created correctly during the delay time.

Exactly this question I need to clarify. Thanks!

The control signal to the servo keep going during a delay.

Your question has been answered but it is easy to check. Write an angle to the servo then call delay() with a long period. If you can turn the servo output during the delay() then signal to keep the servo in position is not present. Even without trying to turn the servo during the delay() you will quite probably be able to hear the servo humming at 50Hz during the delay()

If the servo is powered from the Arduino, which it should not be, then be very gentle when turning the servo output by hand as the current used by the stalled servo may exceed the current that the Arduino is able to supply and damage to it may occur

Even this doesn't quite describe the servo code's activities, quite.
The OP may choose to ignore this, if the technical details cause eye-glaze.

I'm posting this only because I just rewrote Servo.h/Servo.cpp for my own purposes; I wanted more servos, and wanted to synchronize a pixel update with the end of the servo update; understanding the servo code was necessary before changing it (successfully).

Servo.write(angle) actually only dumps the value into a holding variable. Your first Servo.attach() actually initiates the underlying timer interrupt cycle that causes the generation of the pulses on any pins that have been attached.

Using the Uno as our platform(so we know exactly what form Servo.cpp/Servo.h, etc. will create), you can configure 12 servos. Servo.h declares maximum pulse width as 2400 us.

Each time the interrupt triggers, a pulse is terminated and a new pulse initiated, cycling through all 12 possible outputs. At the end, a residual timer value is written if the 20 ms update cycle time has not been exhausted. Since 12 servo ouputs can be configured, and the max pulse width is 2400 us, it is possible for a complete cycle to take 28.8 ms. The minimum cycle time will be 20 ms, because at the end of updating all the servo pulses, the timer is loaded with a residual value to consume the rest of the 20 ms.

So, if you happen to write a value to servo 1 an instant after it's interrupt event has been configured, it could take up to 28.8 ms before your change is actually applied to the Servo output. But "delay()" per se does not factor in to that delay, it's just due to the nature of the interrupt cycle.

Obviously, if you only configure one servo, the timing changes, BUT, be aware. The interrupt cycle is configured to honor the 20 ms update rate, even for just one servo. So, when you call Servo.write() to apply a new value to your pulse width, if the interrupt cycle was just in the middle of updating your servo, the pulse width will not change for 20 ms, the next time the cycle thinks it should update your output.

If you're sleuthing with an oscilloscope, and trying to figure out why there's an unpredictable delay between something else your code is doing, and the update of the pulse width for your Servo, this is your culprit.

Yes, I know. But I didn't want to explain all the details, because I think it's of no use for @arduinouser85 :thinking:.
The MoToServo class of my MobaTools works very similar to the standard Servo library :wink:.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.