There were 2 or 3 recent queries about the Arduino servo pulses and their timing and control. I wasn’t sure what the answer was so I went off to look at the source code for the servo stuff. While I saw comments mentioning some refresh time it appeared to me that whenever the call for a servo.write happens, it immediately changes the timer and thus the resulting PW. Since I’m not familiar with all the ATMega registers I wasn’t sure whether this meant that a new output pulse would happen right then or wait until after the cycle running ran it’s course. So I set-up a simple sketch and used the Arduino to measure (grossly) the output PW and it’s timing. Specifically I output a servo pulse on pin 9 and wired that directly to pin 2. I then used the pulseIn() function to measure the PW for 2 pulses. Here’s the initial sketch (gaack) and a short sample of the output.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int inPin = 2;
int PW = 0;
unsigned long time = 0;
void setup()
{
Serial.begin(38400);
myservo.attach(9); // attaches the servo on pin 9 to the servo object]
Serial.println("Measuring servo PW");
}
void loop()
{
time = millis();
myservo.write(0);
Serial.print("P1 = ");
PW = pulseIn(inPin, HIGH);
Serial.println(PW);
Serial.println(millis()-time);
myservo.write(180);
Serial.print("P2 = ");
PW = pulseIn(inPin, HIGH);
Serial.println(PW);
Serial.println(millis()-time);
}
17
P2 = 2376
40
P1 = 532
17
P2 = 2370
40
P1 = 531
17
P2 = 2368
40
P1 = 532
18
P2 = 2370
39
P1 = 531
19
P2 = 2370
40
P1 = 531
19
P2 = 2370
The first thing that pops out is that the PW’s (P1 and P2, in usecs above) are different from my expectation. While I knew the Arduino servo function could output PWs shorter and longer than the usual 1 and 2 msec, I had expected that the defaults would be those limits. Turns outs, at least with IDE 1.01, that’s not the case. FYI … a command of 90 deg yielded a PW of ~ 1450 usec, close enough to the expected 1.5 msec. I also infer that the pulse happens as soon as the servo.write() executes and so the pulseIn() function, because of the delay in “printing” "Px = ", is actually measuring the PW of the 2’nd pulse output and thus the ~20 msec between pulses. That, BTW, is also good to confirm … that the servo.write() runs at the expected 50 Hz rate (20 msec period).
I then ran the code below to confirm my belief that the pulse is output immediately upon executing the servo.write(). The slight difference below is that there’s a write(0) immediately followed by a write(180). The PW is then measured. Would it be the short PW or the long PW ?
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int inPin = 2;
int PW = 0;
unsigned long time = 0;
void setup()
{
Serial.begin(38400);
myservo.attach(9); // attaches the servo on pin 9 to the servo object]
Serial.println("Measuring servo PW");
}
void loop()
{
time = millis();
myservo.write(0);
myservo.write(180);
Serial.print("P1 = ");
PW = pulseIn(inPin, HIGH);
Serial.println(PW);
Serial.println(millis()-time);
myservo.write(180);
Serial.print("P2 = ");
PW = pulseIn(inPin, HIGH);
Serial.println(PW);
Serial.println(millis()-time);
}
20
P2 = 2376
40
P1 = 2376
20
P2 = 2376
40
P1 = 2376
20
P2 = 2370
40
P1 = 2375
20
P2 = 2370
40
The data shows it’s always the long PW and the timing btw pulses remains the expected 20 msec. In another sketch I measured the “low” PW for each of the commanded 0, 90 and 180 positions. As expected the HIGH and LOW durations add up to ~20 msec for each command (530/19324 us, 1450/18347 us, 2370/17445 us)
So if you don’t want to confuse your servo, your code should ensure some minimum wait btw updating the servo commands. When the code calls for a servo.write(), the outgoing pulse happens right then.