Scoping servo code output

Since I bought my o'scope I'm measuring all sorts of stuff. Tonight it was the turn of servo output.

One thing I noticed in the forum, is that there are often questions about what happens when a servo is attached and detached, and does it hold the written position in any way. Well I checked that all out with my scope.

The code below, and variations eg with and without detaching, was used for the test. Everything's in setup() just so I could be sure than any repetitive signals were not due to loop().

Attached is a typical 'scope screen.

Here's what I found....

  • A servo attach causes a 1500us (1.5ms) pulse to be sent, 1500 being the midway or 90 degrees.
  • That pulse is repeated at 50Hz (ie 20ms, 1.5 on 18.5 off) and the repeat goes as long as the code lets it.
  • A servo detach causes that repeating pulse to stop
  • A servo write in microseconds causes a 50Hz repeating pulse of whatever width specified as microseconds
  • Implication is that the servo is held at the position by the attach at 1500 first and then the written position, by the 50Hz pulse, until a detach which will release it because there is no repetitive pulse.
  • A write before attach causes the first batch of pulses to be of the specified width, not the default 1500.
  • An attach after a detach, causes the pulses to be at the last written value, not the default 1500
  • Implication of that is you can presumably save energy with a detach and reattach at the same position, but of course the servo will be "loose" during the attach

Here's some test code, and check out the scope shot below.

//some servo test code for 'scoping

#include <Servo.h> 

Servo myservo;


void setup()
{ 
  Serial.begin(9600);
  Serial.println("writing 1000 us before attach");
  myservo.writeMicroseconds(1000);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.println("servo attached");
  delay(5000);
  Serial.println("writing 2000 us");
  myservo.writeMicroseconds(2000);
  delay(5000);
  myservo.detach();
  Serial.println("servo detached");
  delay(5000);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.println("servo re-attached");
}

void loop()
{
}

servo attached.bmp (219 KB)

Good info. Thanks .

And a rare example of a Servo with an adequate power supply here :slight_smile:

Yes, that's the "standard" servo protocol - the exact rate of pulses isn't too critical,
the pulse-width is. Servos will hold for a while if the pulses go missing, they are
designed for RC aircraft where the best thing to do on a drop-out is hold position.
Eventually they may power down - although this sort of thing is upto to the
manufacturer.

Aren't 'scopes wonderful?! One day the standard Arduino board will have one
built-in I hope :slight_smile:

Thanks. I have bookmarked this Thread.

...R

Aren't 'scopes wonderful?

I never leave home without it.... XD

raschemmel:

Aren't 'scopes wonderful?

I never leave home without it.... XD

Every home should have one, for sure. Next purchase will be a function gen.

(All, you must understand, in the interests of my daughter's undergrad career which starts in the new year. She's got school finals coming up in a few weeks- "matric" as we call it here. Just finished the prelim exams- sort of "mock matric" to test the water. Already accepted for 4 engineering u'grad programs at two universities. One's my alma mater, needless to say she's going to the other one. My alma mater is 10km from the house, the other is 1000 miles.... easy choice I suppose.)

By the way I also scoped the pulses when using servo.write with degrees.

As expected, 0 degrees came out 500us up to 180 degrees at 2500us.

Random value in between of 118 degrees came out at 1.76ms, bit less than expected 1.81. Screenshot attached.

//some servo test code for 'scoping

#include <Servo.h> 

Servo myservo;

byte pos=118;


void setup()
{ 
  Serial.begin(9600);
  myservo.attach(9);
  Serial.println("servo attached");
  delay(1000);
  Serial.print("writing ");
  Serial.print(pos);
  Serial.println(" degrees");
  myservo.write(pos);
}

void loop()
{
}

sservo 118 degrees.bmp (219 KB)