The results are unexpected, for me, so obviously I don’t understand servo motors properly.
Code:
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
myservo.write(35);
}
Results on pin 9:
The poster’s problem is slightly more complex than that, but I’m wondering why the 3-second gaps in output to the servo? I presume you aren’t supposed to use them that way?
Looking at the other thread as well as this, I wonder if things would work perfectly if the servo is only written to whenever its position needs to be changed, and not every loop. Presumably when you do servo.write() it goes through some sort of "resetting" process that may account for the gap. Is it possible that the size of the gap is just influenced by the Arduino being busy doing other stuff? Also, loop should repeat very quickly compared to servo signals.
The delays therefore mean the servo is being changed every two seconds, which doesn't really account for one-second gaps when no servo signal is being sent.
Sounds weird - the Servo library is entirely interrupt driven (write and writeMicroseconds
only update slots in the datastructures used by the interrupt handler.
Disabling interrupts would cause gaps of course, but delay() doesn't do that.
But yes, I'm prepared to believe anything right now. If someone else could reproduce this, or not reproduce it, that would at least confirm if I am going mad, or not.
I don't really buy the "loose connection" argument, it's not as if the cat is batting the test bed (although he's been known to do strange things, he isn't in the room at present).
I'll try compiling on another PC, and see if that changes things.
Having jumped in rather hastily earlier it occurs to me now to ask what your 'scope picture is showing?
What are the yellow bits, and what are the black bits?
The yellow bits look like a compressed square wave ... what are they like if you expand them?
I would expect that following servo.write() there would be an indefinite unbroken signal with pulses of a constant width between 1ms and 2ms (?) repeating at least every 20ms. On that basis there would be no gaps like in your image - unless, perhaps, you did servo.detach() (if that's the correct code).
The implication seems to be that something behind the scenes is interfering with the servo signal.
Have you connected a servo to your Uno to see how it behaves while the 'scope is producing that picture?
Simple servo test code you can use with the serial monitor to evaluate different servo command outputs.
// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.
String readString;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
Serial.begin(9600);
myservo.writeMicroseconds(1500); //set initial servo position if desired
myservo.attach(7, 500, 2500); //the pin for the servo control, and range if desired
Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
delay(2); //slow looping to allow buffer to fill with next character
}
if (readString.length() >0) {
Serial.println(readString); //so you can see the captured string
int n = readString.toInt(); //convert readString into a number
// auto select appropriate value, copied from someone elses code.
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
myservo.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
myservo.write(n);
}
readString=""; //empty for next input
}
}
I've written a short sketch on a Mega (because it was there) which records the state of pin 8 every 500 usecs.
I've also uploaded Nick's first sketch to an Uno and I have connected the servo output (pin 9) to pin 8 of the Mega.
Over 500 samples the Uno seems to be sending uninterrupted pulses to the servo every 20 msecs (every 40 samples). I also have a servo connected and it works fine.
I can't imagine it makes any difference but this was done with an XUbuntu netbook and Arduino IDE 1.0.5
I just put the code in the OP onto an Uno.
My scope (Rigol DS1052E) sees no gaps (as expected) on a 1 second/division range, though interestingly it doesn't correctly display the frequency (shows 5Hz) on this range, and I have to drop to 100ms/division to get it to display anything like 50Hz.
I don't actually have a servo connected.
Robin2:
Having jumped in rather hastily earlier it occurs to me now to ask what your 'scope picture is showing?
What are the yellow bits, and what are the black bits?
The yellow bits look like a compressed square wave ... what are they like if you expand them?
The yellow bits are the square wave, the black bits are no square wave. Zooming in:
I would expect that following servo.write() there would be an indefinite unbroken signal with pulses of a constant width between 1ms and 2ms (?) repeating at least every 20ms.
I'm glad to hear you say that, because it repeats every 20 mS.
The width of the pulse is 900 µS:
I presume that is about right for positioning to 35 degrees?
michinyon:
So, to be clear, you are getting this outcome without trying to do GPS or anything else, at the same time ?
That is correct. I am running the code in the original post with no hardware connected at all except for a scope on pin 9 (and Gnd of course). On a Uno, IDE 1.0.5.
Further testing indicates that this appears to be an aberration of this particular scope. Running in the "slow" mode it looks like it is capturing a batch of points, drawing them, and leaving a gap.
The logic analyzer shows no such gaps.
Oh well, back to the other thread to try to sort out the original problem.
Thanks to everyone that tested. Your results showed my testing itself was at fault.
When I run this and push the servo arm with my finger the force collapses when the signal stops (i.e. when myservo.attach(9) operates) and reasserts itself when the signal is restored. This is very obvious when the servo is under load, but not noticeable without a load.
AWOL:
I just put the code in the OP onto an Uno. My scope (Rigol DS1052E) sees no gaps (as expected) on a 1 second/division range, though interestingly it doesn’t correctly display the frequency (shows 5Hz) on this range, and I have to drop to 100ms/division to get it to display anything like 50Hz.I don’t actually have a servo connected.
Perhaps the 50hz used with the servo h-bridge is generated in the internals of the servo itself. Interesting servo info below.