Hi All,
I am building a simple Robot but this time thought I'd try servos as motors, saving a few pins as you only need one pin per motor. That part works well and I can move it around OK.
But when I add a 3rd servo for the U/S distance detector, things go wrong, instead of going forward at first it does a turn, or the motors are jittery!! I am powering them from the Uno so that could be a problem? I'm doing what I tell others not to do!! I am using 2 Lipo 18650 so got 7.4v. But could it be anything to do with what pins use what timers? What if I'm asking a timer to do two things at once?
Any ideas or suggestions would be welcome, I've seen Hexapods with lots of servos running on modest battery power.... So why?
Here's my Code:
Regards
Mel.
/*
*******************************
Filename: ServoDrive-2
Date: 05/06/2014
File Version:
Written by: MS
Function: Driver for Servo-Bot
Last Revision: 07/07/2015
Target: Uno
*******************************
* Use 2 continous rotation Servos as motors, needing only 1 signal pin each.
*/
#include <Servo.h>
int Aspeed,Bspeed,speed,Halt=90,center=90; // motor speeds
Servo servoLeft,servoRight,servoscan; // create servo object to control the servo/s
void setup()
{
servoLeft.attach(11); // attaches the servo/motor on pin 11 Left motor
servoRight.attach(12); // attaches the servo/motor on pin 12 right motor
servoscan.attach(3); // U/S sensor scanner
}
void loop()
{
********************************These lines below cause the problem
delay(500);
servoscan.write(center);
delay(500);
for (int i=0; i <= 180; i++)
{
servoscan.write(i);
delay(30);
}
for (int i=180; i >= 0; i--)
{
servoscan.write(i);
delay(30);
}
servoscan.write(center);
********************************These lines above cause the problem
delay(1500);
forward(95);
delay(3000);
backward(5);
delay(3000);
stop();
delay(3000);
turn(45);
delay(3000);
turn(135);
delay(3000);
}
//==================================================================================================
int stop()
{
servoLeft.write(90);
servoRight.write(90);
}
//==================================================================================================
void forward(int Aspeed)
{
servoLeft.write(Aspeed);
speed=Halt-Aspeed;
Bspeed=Halt+speed;
servoRight.write(Bspeed);
}
//==================================================================================================
int backward(int Aspeed)
{
servoLeft.write(Aspeed);
speed=Halt-Aspeed;
Bspeed=Halt+speed;
servoRight.write(Bspeed);
}
//==================================================================================================
int turn(int Aspeed)
{
servoLeft.write(Aspeed);
servoRight.write(Aspeed);
}
//==================================================================================================
Hi Robin2,
No it's not a power problem! Because I get it when running just the two wheel driving servos, and the scan-servo disconnected and I un-REM the code between the two lines as shown. I can't see anything wrong here and it compiles OK. Not that, that means it is OK.
Cactusface:
No it's not a power problem! Because I get it when running just the two wheel driving servos, and the scan-servo disconnected
In view of earlier comments I presume you mean that, with a separate servo power supply and with only two servos connected you are getting strange behaviour when your code tries to control a 3rd servo even though that servo is not connected in any way?
I also presume there is nothing else connected to the Arduino apart from the two wheel servos ? ? ?
I don't see anything obviously wrong with your code apart from the profligate use of the delay() function.
While it is OK for testing you will never get a robot to work responsively with even a single delay() in your code. You need to use millis() for timing as illustrated in several things at a time.
I also wonder why you have nice little functions for driving the wheel motors but not for the scan servo - though that won't have anything to do with the problem.
I never use this style
int Aspeed,Bspeed,speed,Halt=90,center=90;
I always put each on its own line. Are you sure it is setting all the values correctly ?
Cactusface:
Hi Robin2,
No it's not a power problem! Because I get it when running just the two wheel driving servos, and the scan-servo disconnected and I un-REM the code between the two lines as shown. I can't see anything wrong here and it compiles OK. Not that, that means it is OK.
Regards
Mel.
You don't know its not a power problem till you actually look at the supply voltage with
a meter (or prefferably a 'scope)
If you are powering the motors/servos from the Vcc of the Arduino, then it is guaranteed to
be a problem because you are blasting the Arduino with spikes and dips on the power rail
which can only cause problems or even damage.
Hi Robin2,
I seem to have solved part of the problem, in that I have discovered you need to stop the 2 wheel servos with:
servoLeft.write(90);
servoRight.write(90);
otherwise they take up a random value and move accordingly (usually a turn) why this should happen only with the scan code up front I'm not sure. I have now moved the scan code to it's own function and call it with: scan() I now get the scan movement first and wheel movement after, which is correct.
As for using delay! that's a quick fix as I have no sensors connected as yet, but it will be U/S for eyes, line following with IR, etc.
Regards
Mel.
PS. As I said at the beginning! I don't power motors or servo directly from the Uno (in this case) As I'm sure it would be a problem.
Robin2,
Sorry! yes confusing. I was in the first inst powering them from the Uno, against my better judgement and others too! But with only 2 wheel servos, I had the problem, with that section of code, removing it also removed the problem. I can't say but if starting servo 3 first, would that start a timer that might cause the others to move??
Cactusface:
But with only 2 wheel servos, I had the problem, with that section of code, removing it also removed the problem. I can't say but if starting servo 3 first, would that start a timer that might cause the others to move??
This is also confusing. What precisely happens when "the others ... move" ?
If all the servos are powered separately from the Arduino I can't see any reason why it should matter whether you have 2 or three (or more) servos controlled by the Arduino. I presume the servo GND is connected to the Arduino GND.
Can you write a short program that does nothing but move your 3 servos in an orderly manner - orderly so that it will be obvious if they are not moving as intended. Then I could try the same code with my servos.
I have discovered you need to stop the 2 wheel servos with:
servoLeft.write(90);
servoRight.write(90);
If these are continuous rotation servos, you probably will get better control by using us values instead of degrees. Below is some code code you can try with the serial monitor/keyboard to find the stop movement value for your servos. If the servos drift a lot, you can use servo detach when you need them to stop.
// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a
// to decrease) and enter to change servo position
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.
#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continous rotation servo
//int pos=90;
void setup()
{
myservo.attach(7, 400, 2600); //servo control pin, and range if desired
Serial.begin(9600);
Serial.println("serial servo incremental test code");
Serial.println("type a character (s to increase or a to decrease)");
Serial.println("and enter to change servo position");
Serial.println("use strings like 90x or 1500x for new servo position");
Serial.println();
}
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) {
if(readString.indexOf('x') >0) {
pos = readString.toInt();
}
if(readString =="a"){
(pos=pos-1); //use larger numbers for larger increments
if(pos<0) (pos=0); //prevent negative number
}
if (readString =="s"){
(pos=pos+1);
}
if(pos >= 400) //determine servo write method
{
Serial.println(pos);
myservo.writeMicroseconds(pos);
}
else
{
Serial.println(pos);
myservo.write(pos);
}
}
readString=""; //empty for next input
}