servo won't run counterclockwise or stop when delayed
Dear people, I am working with the Robotics Shield Kit as an absolute beginner. I tried below code from Parallax (http://learn.parallax.com/node/188), but what I don't understand is, how does the servo know if it should run clockwise or counterclockwise rotation? Is it just the servoLeft or servoRight? So if I want to change the clockwise rotation to counterclockwise rotation, I just change servoLeft to Servoright? If so, I do not understand below code, because first both servos run cl.ockwise, then they should stop and run counterclockwise. I'm missing here how the direction of rotation is chnaged. Now I also have a problem with delaying the servos, because if I want the servo to stop I can use delay(3000), it doesn't delay. <code>/*
Robotics with the BOE Shield ServoRunTimes
Generate a servo full speed counterclockwise signal with pin 13 and
full speed clockwise signal with pin 12.
*/
#include <Servo.h> // Include servo library
Servo servoLeft; // Declare left servo signal
Servo servoRight; // Declare right servo signal
void setup() // Built in initialization block
{
servoLeft.attach(13); // Attach left signal to pin 13
servoRight.attach(12); // Attach right signal to pin 12
servoLeft.writeMicroseconds(1300); // Pin 13 clockwise
servoRight.writeMicroseconds(1300); // Pin 12 clockwise
delay(3000); // ..for 3 seconds
servoLeft.writeMicroseconds(1700); // Pin 13 counterclockwise
servoRight.writeMicroseconds(1700); // Pin 12 counterclockwise
delay(3000); // ..for 3 seconds
servoLeft.writeMicroseconds(1500); // Pin 13 stay still
servoRight.writeMicroseconds(1500); // Pin 12 stay still
}
void loop() // Main loop auto-repeats
{ // Empty, nothing needs repeating
}
</code>
Robotics with the BOE Shield ServoRunTimes
Generate a servo full speed counterclockwise signal with pin 13 and
full speed clockwise signal with pin 12.
*/
#include <Servo.h> // Include servo library
Servo servoLeft; // Declare left servo signal
Servo servoRight; // Declare right servo signal
void setup() // Built in initialization block
{
servoLeft.attach(13); // Attach left signal to pin 13
servoRight.attach(12); // Attach right signal to pin 12
servoLeft.writeMicroseconds(1300); // Pin 13 clockwise
servoRight.writeMicroseconds(1300); // Pin 12 clockwise
delay(3000); // ..for 3 seconds
servoLeft.writeMicroseconds(1700); // Pin 13 counterclockwise
servoRight.writeMicroseconds(1700); // Pin 12 counterclockwise
delay(3000); // ..for 3 seconds
servoLeft.writeMicroseconds(1500); // Pin 13 stay still
servoRight.writeMicroseconds(1500); // Pin 12 stay still
}
void loop() // Main loop auto-repeats
{ // Empty, nothing needs repeating
}
</code>
Comments
This leads into your next question, how does a servo know to rotate clockwise or counter clockwise? The answer is that pulses are allowed to be between 1000 and 2000 wide. Pulses between 1000-1500 rotate one direction while pulses between 1500-2000 rotate the other direction. The difference between the centering pulse and your pulse is roughly proportional to the speed of rotation. I say roughly because servos have individual variations so the center pulse and the limits (1000) or (2000) differ from servo to servo. Generally you'll need to do some experiments to determine which values work best for your servos.
If you still have problems let me know. BTW it's a really good idea to get a piezo speaker and add an output tone to the start of your program. Sometimes weak batteries cause a restart and your program only runs to the first servo pulse and restarts. It looks like subsequent servo manipulation calls don't work because the code never gets there. I've been bitten by this several times and I'm experienced with this stuff. Since the Arduino requires a higher source voltage than a BS2 it happens more frequently.
I expected the servo to clockwise and the other counterclockwise, then stop, then turn the other way.
This is not what happened, both wheels went clockwise and the servo's did not stop and change direction.
Maybe i have not centered the servo's correctly, because I have twisted the screwdriver, but the servo's were alreay still.
For the connection to the GRN, see attached pics.
I'm lost here
Regards! Ruby
[/HTML]
Thanks for your suggestion about connecting a speaker!
Regards, Ruby
John Abshier
I'll second that. What the code is doing right now is turn one way, stop, turn the other way. But computers are fast compared to physical events, so from the servos point of view it only sees the last command.
My problem is still not solved, but I am understanding the concept of servo's better now. I should use the delay command if I want some command to be executed for a period of time. So, I wrote below code and tested it. The upper servo is turning (what i also expected it to do), but won't stop at the end. The other servo just turns one direction.
Maybe I should center the servo's again, but besides twisting the screwdriver, I'm not really sure how to do it. Should it turn when I twist the screwdriver?
<iframe width="640" height="360" src="http://www.youtube.com/embed/adhzVuhXTTQ?feature=player_detailpage" frameborder="0" allowfullscreen></iframe>
I can't try your program right now, but later this weekend I should have a chance. My servos are centered so we can eliminate that variable.
John Abshier
Funny, the OP's code in his very first post shows the right servo on pin 12. Something got mashed up after that.
Since i don't have a speaker to test if all code is executed, I tried with the leds. When the servo's start turning, the leds are on. When the servo's should stop, the leds go off.
I taped it: http://youtu.be/39YMWulgSxU
It looks like only the first 8 lines of code is executed:
Now, what can one do, when code is not being executed?
/*
Robotics with the BOE Shield – LeftServoClockwise
Generate a servo full speed clockwise signal on digital pin 13.
*/
#include <Servo.h> // Include servo library
Servo servoLeft; // Declare left servo
Servo servoRight; // Declare left servo
void setup() // Built in initialization block
{
pinMode(13, OUTPUT); // Set digital pin 13 -> output
pinMode(12, OUTPUT); // Set digital pin 13 -> output
servoLeft.attach(13); // Attach left signal to pin 13
servoRight.attach(12); // Attach right signal to pin 13
digitalWrite(13, HIGH); // Pin 13 = 5 V, LED emits light
digitalWrite(12, HIGH); // Pin 13 = 5 V, LED emits light
servoLeft.writeMicroseconds(1300);
servoRight.writeMicroseconds(1300);
delay(3000); // ..for 1 seconds
digitalWrite(13, LOW); // Pin 13 = 0 V, LED no light
digitalWrite(12, LOW); // Pin 13 = 0 V, LED no light
servoLeft.writeMicroseconds(1500);
servoRight.writeMicroseconds(1500);
delay(3000); // ..for 1 seconds
digitalWrite(13, HIGH); // Pin 13 = 5 V, LED emits light
digitalWrite(12, HIGH); // Pin 13 = 5 V, LED emits light
servoLeft.writeMicroseconds(1700);
servoRight.writeMicroseconds(1700);
delay(3000); // ..for 1 seconds
digitalWrite(13, LOW); // Pin 13 = 0 V, LED no light
digitalWrite(12, LOW); // Pin 13 = 0 V, LED no light
servoLeft.writeMicroseconds(1500);
servoRight.writeMicroseconds(1500);
}
void loop() // Main loop auto-repeats
{ // Empty, nothing needs repeating
}
But there are two pins with number 12 and two pins with numbver 13, how should I change my code, so my test would be correct?
Move the LED resistors over to pins 10 and 11, then changed the code which changes the LED's to those pins.
/*
Robotics with the BOE Shield – LeftServoClockwise
Generate a servo full speed clockwise signal on digital pin 13.
*/
#include <Servo.h> // Include servo library
Servo servoLeft; // Declare left servo
Servo servoRight; // Declare left servo
void setup() // Built in initialization block
{
pinMode(11, OUTPUT); // Set digital pin 13 -> output
pinMode(10, OUTPUT); // Set digital pin 13 -> output
servoLeft.attach(13); // Attach left signal to pin 13
servoRight.attach(12); // Attach right signal to pin 13
digitalWrite(11, HIGH); // Pin 13 = 5 V, LED emits light
digitalWrite(10, HIGH); // Pin 13 = 5 V, LED emits light
servoLeft.writeMicroseconds(1300);
servoRight.writeMicroseconds(1300);
delay(3000); // ..for 1 seconds
digitalWrite(11, LOW); // Pin 13 = 0 V, LED no light
digitalWrite(10, LOW); // Pin 13 = 0 V, LED no light
servoLeft.writeMicroseconds(1500);
servoRight.writeMicroseconds(1500);
delay(3000); // ..for 1 seconds
digitalWrite(11, HIGH); // Pin 13 = 5 V, LED emits light
digitalWrite(10, HIGH); // Pin 13 = 5 V, LED emits light
servoLeft.writeMicroseconds(1700);
servoRight.writeMicroseconds(1700);
delay(3000); // ..for 1 seconds
digitalWrite(11, LOW); // Pin 13 = 0 V, LED no light
digitalWrite(10, LOW); // Pin 13 = 0 V, LED no light
servoLeft.writeMicroseconds(1500);
servoRight.writeMicroseconds(1500);
}
void loop() // Main loop auto-repeats
{ // Empty, nothing needs repeating
}
Now the leds do their work, only the servo's do not. They turn, and just keep doing that.
Here's the video: http://www.youtube.com/watch?feature=player_detailpage&v=lNvOMya-BKw
No idea what I could try next
At head of Setup.
Pulse servos with 1300 for 3 seconds.
Pulse servos with 1500 for 3 seconds
Pulse servos with 1700 for three seconds
stop servos with a 1500 pulse.
Tweaked program below:
Since this code works on my robot, if it produces bad behavior on yours we know that either your servos need centering, or your batteries have a problem.
I believe in that example the LEDs are intended to provide a visual feedback that the servos are actually getting the pulses. If you move the LEDs to different pins that would defeat that purpose. In the most basic sense the LEDs help troubleshooting by narrowing down the cause of servos not moving to the I/O pin/code or the servos being bad/miswired/not powered/etc.
However, you should not be using HIGH/LOW commands on the pins sharing the servos/LEDs to force them on/off.
I tested the code Martin gave me, but although the output is printed, the servo's don't change directions or stop at all. The problem must be with the servo's and I will try centering them again.
Just wondering if it would be better to clear the servo's from all the code that I've been sending? How can I do this? Should I use some kind of reset command, because now they are turning as soon as they get power.
About there being two pins with number 12 and 13, why is that? I understand that I should not be using HIGH/LOW commands on the servo pins, but what if I'm out of pins, and need to use them all, how can I identify them? I just would like to understand
Regards, Ruby
Servos don't have a memory, so each time you upload a new program they'll respond to it. If your servos don't change directions then it sounds like they need centering.
If you look at the edge of the BOE shield next to the servo headers you'll see the numbers 13 12 11 10. The signal pin on those headers is connected to digital headers 13 12 11 10 next to the breadboard. So when you are not using servos you can hook LED's to those headers. The servo headers are there to make connecting easier for devices that use them.
Chris, he's using the BOE Shield with an Arduino, so the servo headers are connected to 10 through 13.
You're right...trying to reply to the forums and getting tech calls at the same time (on the BoE). The main thing I was trying to emphasize was that why the I/O pins are shared and why the LEDs should be plugged into the same ports used by the servos. I didn't want the OP thinking that was the issue when it is a useful debugging tool.
When I watched one of the videos I could have sworn that the LEDs were pulsing and then when they stopped one of the servos kept going. If the servo is going without receiving pulses that is not proper operation.
I do understand why you cannot connect a servo and a led to the same port number. What I do not understand is why not give all the ports a diffrenet number, so they can all be used. Seems a bit unlogical to me, but maybe in time I'll see the benefit of this solution.
If I'm digging to deep, just let me know, but if servos don't have a memory, how do they "remember" the uploaded program, once it gets disconnected from my computer?
I will center the servo's again. Now as I switch on the power, they start turning. So what I'll do is, put on the power [the servo's start turning]. While they turn I twist the screwdriver until the servo's stop turning. This is how I understood centering. Just need to know if that is correct, so I don't break my servo's.
Regards, Ruby
All the Arduino pins are already allocated on the BOE shield, there aren't any other pins.
The Parallax tutorial site will explain:
http://learn.parallax.com/node/185
Note that the sketch on that site only signals one servo. I updated it below to center both servos.
I centered the servo's they way i thought it had to be done, uploaded your code (added some lines) and it did exactly what I expected.
Thanks a lot for your help!!
Regards, Ruby