I'm trying to control 3 servos at once with an Arduino Mega. Right now, I just want to move one servo at a time. My code works minus one bug. When I switch the name of the servo being ran, the previous servo moves to that position. However, the correct servo moves every time after that. I don't know how to make the correct servo move the first time after I change the object name. Here is my code:
#include <Servo.h>
Servo bob; // create servo object to control a servo
Servo billy;
Servo joe;
void setup() {
Serial.begin(9600);
bob.attach(9); // attaches the servo on pin 9 to the servo object
billy.attach(10);
joe.attach(11);
bob.writeMicroseconds(1300); //servo currently moving (I change the name and rerun the code)
delay(1000);
bob.detach();
billy.detach();
joe.detach();
}
void loop() {
}
For example, if I changed "bob.writeMicroseconds(1300)" to "joe.writeMicroseconds(1500)", the servo named bob would move to the 1500 us position and not joe. Then if I changed the value to 1600, the servo named joe would move to the 1600 us position.
My hardware setup has each servo receiving its own power and ground from the power supply (the power supply has 3 terminals for V+ and V- each). Then I connected the Arduino's ground to each of the servos' grounds to serve as a common ground.
Is this a software or hardware issue? How can I fix this problem?
What happens if you move all to a known location, then only move one?
#include <Servo.h>
Servo bob; // create servo object to control a servo
Servo billy;
Servo joe;
void setup() {
Serial.begin(9600);
bob.attach(9); // attaches the servo on pin 9 to the servo object
billy.attach(10);
joe.attach(11);
billy.write(0);
joe.write(0);
bob.write(0);
delay(1000);
bob.writeMicroseconds(1300); //servo currently moving (I change the name and rerun the code)
delay(1000);
bob.detach();
billy.detach();
joe.detach();
}
void loop() {
}
I just tried your code. It fixed the problem of the wrong servo going to the desired position. The first write command still ran the previous servo, but returning it to the same position as the others hid the problem enough.
Do you have any ideas on just moving one servo and leaving the other two where they are versus returning all the servos to the same location? My application is a continuum robot, and ideally by the end of the project, I will adjust each servo individually to get the specific movement that I want.
At the end of your sketch, move the all servos "home" (your choice of us) or set them LOW.
I guess that the PWM is always present unless you set the pin low, and when you attach() to a new pin, you see the old PWM sent to the old pin. Does the new attached pin also move to the position?
[edit] I wonder if detatch() function in the library sets the PWM to a non-PWM level or if it just opens a circuit to the pin (leaving the last PWM signal on the mpu active).
Right now, I just want to prove I can move one servo to a specific position at the time while keeping the other two where they are. This is a mini progress goal for my overall application. The servos control pulleys which have strings wrapped around them that control the bending of a robot. My ultimate end goal is to move each servo individually right after each other to get the movement that I want.
I detach all the servos at the end because previously they were moving when power was applied, and this solved the issue. Everything is in the setup because right now I only want things to run once versus running multiple times in the void loop part. This just makes testing a lot easier for me.
The only problem that I'm encountering now is that the first write command never writes to the servo specified but to the last servo mentioned in the previous execution of the code.
I hope this provides more clarity to what I'm trying to accomplish.
that will be what happens. Servos will go where you tell them, and stay there until you tell them otherwise.
Testing by editing the code and uploading and rerunning the sketch is a waste of time, as you will just be making yourself an expert on all kindsa stuff that will ultimately be irrelevant - you will not be changing the code on the fly, nor even reset/rebooting when the device is out there doing whatever.
If a servo repositions itself without a different value being written to it, you may have a hardware issue of some kind, because the hole idea of a servo is it stays where you told it to go.
I understand your use of setup() to avoid the looping of loop(), there's no problem continuing with that line of inquiry.
Sooner or later, however, you will need to use the loop() function as it was designed to be and…
...if you are ultimately going to want to make N servos run more or less in concert, you will need to start knowing about
arduino blink without delay
and
arduino two things at once
which I call out as quotes and offer as suggested google search terms.
If for example you would be rubbing your stomach with one servo whilst patting your head with another. Or the equivalent in your project.
which may be tossing you into the deep end of the ocean.
The wokwi simulator is a very faithful tool. When using hardware that can introduce its own set of problems, lashing up something in the simulator can help you focus on software issues, as the only real problem with the wokwi would be if you wired it wrong.
No noise or power issues!
One thing you will note about the sketch - no (zero) use of the delay() function, and one call to millis() to get the time all functions agree and use as "now".
Thank you! The simulator was very helpful. I inserted my code to control the first three servos, and it did exactly what I want. This makes me think there might be a power, noise, or ground issue in my setup.
On my original code, I removed the detach() statements and moved the write statement to the loop() part. When physically testing that new code, the servo that moved was not consistent. Some times the correct servo moved, other times the wrong one moved, and then some times two servos moved at once. The servos would also rotate to the center position before rotating to value in the write statement every time, which made things even more chaotic. This same code worked perfectly in the simulator though.
I'm going to look into my hardware setup more. I can get 1 servo to work perfectly, so I'll slowly work up from there.
I just noticed this rereading the thread. If you are Routing power through the breadboard, you may just be asking for trouble.
Try wiring for the power and ground of the servos that does not depend on the breadboard. Soldered or screw terminals or whatever.
But at least you've certainly identified a problem area! And can choose whether to work on that, or the software, as they are now separately considerable.