# Need an example

I've got these http://www.budgetrobotics.com/shop/?shop=1&cart=545395&cat=1&itemid=158& I'm trying to get one moving, but not having any luck... can someone show me how to do this? I just want to make it turn...heh

The signal (orange) is going to the arduino pwm6, the +/- are going to 4 AAA's (running about 5.5volts at the moment). I've tried varations of this, but no dice...

``````int LeftWheelPin = 6;    //Left servo
int RightWheelPin = 5;   // Right servo

void setup() {
pinMode(LeftWheelPin, OUTPUT);
}

void loop() {
analogWrite(LeftWheelPin, 255);
}
``````

your link didn't work for me, but if its this item: http://www.budgetrobotics.com/shop/?shop=1&cat=1&itemid=%20158& then it doesn't work because its a servo that needs pulses between 1ms and 2ms, not the PWM signal you are driving it with.

your link didn't work for me, but if its this item: http://www.budgetrobotics.com/shop/?shop=1&cat=1&itemid=%20158& then it doesn't work because its a servo that needs pulses between 1ms and 2ms, not the PWM signal you are driving it with.

huh, sure doesn't. It's the servos that come with the Scooterbot II. I'll give that a shot... thanks.

The servo library should drive them. Note that they are modified for continuous rotation. That means that the servo wheel will be stationary when writing 90 degrees and it will rotate in one direction at speeds increasing as you write angles greater than 90 degrees, and increasing in speed the other direction as you write angles less than 90 degrees.

In other words the speed is proportional to 90 minus the angle you write to the servo.

I hope that makes sense.

hmm… I wish I wasn’t such a noob ;D
Ok, this is what I’ve got so far. I’m not sure what to put in the loop to make it do anything though. Can you provide an example?

``````#include <Servo.h>     // includes the servo libs
Servo LeftServo;            // name the servo

void setup(){
LeftServo.attach(2);       // I'm guessing this mens pin2, I'm not clear on if it's analog or a nonpwm digital though?
}

void loop(){
// stuff happens here, but clueless about it :(
}
``````

Here is an example of a function to move a servo

``````void moveServoLeftTo(int angle, int duration){
// command the servo to move to the given angle for the given number of milliseconds

LeftServo->Write(angle);                  // tell the servo service code the angle we want
for( ; duration > 0; duration -= 20){     // loop for the given number of milliseconds by subtracting 20ms each iteration
Leftservo->refresh();                  // call the service routine to move the servo
delay(20);                             // wait 20 milliseconds  between each refresh
}
}

loop() {
moveLeftTo(45,500);   // move the left servo to 45 degrees for 500 milliseconds
moveRightTo(45,1000);  // now move the right servo to the same angle for 1 seconds
// moveRightTo function is left as an excercise ;)
}
``````

Edit: Note the semicolon before duration in the for loop. Usually for loops have three elements but we don't need the first one because duration is passed into the function so is already initialised. This use of a for statement to do a while loop is one of my many coding quirks. Feel free to modify it to suit your own style.

hmm... so is this to be added along with the code I already have? I've tried a few things, and get a lot of compile errors. Any chance there is an easier way (less code) so I can understand more of the basics as to whats going on?

The error I'm getting:

error: expected constructor, destructor, or type conversion before '->' token

Sorry to be such a pain ;)

Woops, that’s my fault. I was thinking about passing a servo class pointer so that you could have a single function to call that would work for all your servos. I decided not to because I thought it would be a little confusing. Looks like I was right about that .

Anyway, replace the → with dots and make sure the capitalisation is correct.

``````void moveServoLeftTo(int angle, int duration){
// command the servo to move to the given angle for the given number of milliseconds
LeftServo.write(angle);
for( ; duration > 0; duration -= 20){     // loop for the given number of milliseconds by subtracting 20ms each iteration
LeftServo.refresh();  // call the service routine to move the servo
delay(20);                // wait 20 milliseconds  between each refresh
}
}
``````

Ok, this is what I’ve got, and am maybe starting to understand a little bit. It compiles and uploads, but nothing moves :-/

``````#include <Servo.h>     // includes the servo libs
Servo LeftServo;            // name the servo

void setup(){
LeftServo.attach(2);       // I'm guessing this mens pin2, I'm not clear on if it's analog or a nonpwm digital though?
}

void moveServoLeftTo(int angle, int duration){
// command the servo to move to the given angle for the given number of milliseconds
LeftServo.write(angle);
for( ; duration > 0; duration -= 20){     // loop for the given number of milliseconds by subtracting 20ms each iteration
LeftServo.refresh();  // call the service routine to move the servo
delay(20);                // wait 20 milliseconds  between each refresh
}
}

void loop() {
moveServoLeftTo(45,500);   // move the left servo to 45 degrees for 500 milliseconds
// moveRightTo function is left as an excercise ;)
}
``````

I kind of feel like I’m missing something in the void setup() block… Also, ‘LeftServo.attach(2);’ means that the signal is on digital output pin number 2, correct?

Thanks for all the help, btw.

Yes, pin 2 digital. don't forget to add pinMode(2,OUTPUT); in setup.

also, put in a few more calls to moveServoLeftTo with different angles (between 0 & 180) and different amounts of duration in milliseconds (between 1000 and 1000 are typical values)

once you have that going you can write the function for the right servo ;)

Should I be able to move the servo without adding more calls? I've tried to add more, but I'm not real sure which bit is actually the call... I'm guessing it's the for loop, but anything I've done with this throws errors. EDIT: ok, I think these bits are the calls " moveServoLeftTo(90,500);", but adding more isn't moving it. /sighs

So I can understand what it's doing... LeftServo.attach(2); // I'm not sure what the '2' is doing here... I originally thought it was providing the pin number pinMode(2,OUTPUT); // seems to clearly state that pin 2 is an output, the LeftServo.attach(2) confuses me.

No changes to my sketch yet that effect anything. To cover my bases again, I uploaded the code here (Because it's almost an identical setup): http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1173623665/0 And it moves about, but seems to be random, and apparently not using the ping, I suspect it has a lot to do with not having a 3rd servo. Also perplexing, very little of that sketch resembles anything we're doing here. I'm ok with that, but it's making it hard to grasp.

the code in post #10 in your link is not using the servo library, it driving the pins directly. I would have thought the servo library would be easier to use but either will do the job. Pick the one that you think will be easier to understand and modify.

Should I be able to move the servo without adding more calls? The servo should move to the angle given in the call. It will stay there until you make another call with a different angle

I've tried to add more, but I'm not real sure which bit is actually the call... The servo library functions are as follows:

attach assigns a pin for the given servo write tells the low level code what angle you want (but does not do the move) refresh tells the servo to move to the angle given in write, but it must be called a number of times to complete the motion.

I'm guessing it's the for loop, but anything I've done with this throws errors. Yes, the for loop has the necessary repeated calls to refresh

LeftServo.attach(2); Yes, that is providing the pin number

pinMode(2,OUTPUT); This tells the arduino that pin 2 is an output (not sure its necessary but does no harm)

Well, this stuff is making more sense to me that the sketch in the other post, sadly though, I haven't gotten any movement out of it yet. I'll stick with this though. I've been playing around with it, but no luck yet.

Am I missing something obvious? Does anything in the servo lib need to be edited?

Looking at this http://www.arduino.cc/playground/ComponentLib/Servo, do I need the LeftServo.setMaximumPulse(2200); in there? It's got to be something I'm just overlooking due to my noobness.

Make sure that the grounds on the arduino, servo and battery are all connected together.

Make sure that the grounds on the arduino, servo and battery are all connected together.

hmm... maybe that has something to do with it? I've got the arduino on a 9v, and the 2 servos on some AAA's. The signal from the servos are going to the outputs on the arduino, and it's +/- going to the battries. Like I said, they work with that other code...

... they work with that other code...

can you post the code that works and describe what the servos do when you run that code.

You bet. With this sketch, the robot starts moving in a circle. The left servo moves forward, slightly faster than the right servo. IF I’ve got the ping in the equation, that’s about all it does (It doesn’t seem to actually use it however), if I pull the ping off, it does the circle, but on occasion it will stop, and turn about 90 degrees and start moving about in a circle again.

As stated previously, this guys bot is very similar to mine, the only difference being he’s using a different kind/brand of servos, and he has a third servo that moves the ping around.

Note enough characters left to post the sketch, so I’ll post again with it.

This is does what’s described in the above post:

``````#define LeftWheelPin 6
#define RightWheelPin 5
#define ArmServoPin 4
#define SonarPin 0

#define runningLED 2
#define errorLED 7

short ArmAngle, dAngleMax,dAngleMin, dAngleMaxTemp, dAngleMinTemp;
short ArmAngleRange, ArmAngleTarget;
short LeftSpeed;
short RightSpeed;
short ArmTrim = 0;
int distance, dmax, dmin, dmaxtemp, dmintemp;

unsigned long lastPulseL;
unsigned long lastPulseR;
unsigned long lastPulseA;

int i, k;
unsigned short refreshTime = 15;
unsigned long timeLast, timeLastFast;
unsigned long timeLastSlow;
unsigned int timeStart;

// --------------------------------------------------- LED flashing
void flashLED(short pin, short times) {
for (i = 0; i<=times; i++) {
digitalWrite(pin, HIGH);
delay(100);
digitalWrite(pin, LOW);
delay(500);
}
}

// ---------------------------------------------------- Refreshes all servo pulses

if (millis() - lastPulseL >= refreshTime) {
digitalWrite(LeftWheelPin, HIGH);
delayMicroseconds((LeftSpeed+90)*11+500);
digitalWrite(LeftWheelPin, LOW);
lastPulseL = millis();
}

if (millis() - lastPulseR >= refreshTime) {
digitalWrite(RightWheelPin, HIGH);
delayMicroseconds((-RightSpeed+90)*11+500);
digitalWrite(RightWheelPin, LOW);
lastPulseR = millis();
}

if (millis() - lastPulseA >= refreshTime) {
digitalWrite(ArmServoPin, HIGH);
delayMicroseconds((ArmAngle+ArmTrim+90)*11+500);
digitalWrite(ArmServoPin, LOW);
lastPulseA = millis();
}

// ----------------------------------------------------- Rover move and turn function
void move(int speed, int turnSpeed) {
//LeftSpeed = speed - turnSpeed;
//RightSpeed = speed + turnSpeed;

if (LeftSpeed < 30 && LeftSpeed < (speed - turnSpeed)) {
LeftSpeed++;
//LeftSpeed = ((LeftSpeed*10)+1)/10
}
else if (LeftSpeed > -30 && LeftSpeed > (speed - turnSpeed)) {
LeftSpeed--;
//LeftSpeed = ((LeftSpeed*10)-1)/10;
}

if (RightSpeed < 30 && RightSpeed < (speed + turnSpeed)) {
RightSpeed++;
}
else if (RightSpeed > -30 && RightSpeed > (speed + turnSpeed)) {
RightSpeed--;
}

//if (speed == 0 && turnSpeed == 0) {
//  LeftSpeed = 0;
//  RightSpeed = 0;
//}
}    // End move

// -------------------------------------------------- Update ArmAngle
void armturn() {

if (ArmAngle < 90 && ArmAngle < ArmAngleTarget) {
ArmAngle = ArmAngle ++;
}
else if (ArmAngle > -90 && ArmAngle > ArmAngleTarget) {
ArmAngle = ArmAngle --;
}
}

// ------------------------------------------------- sonar distance function
long ping() {
long raw;

raw = raw/4;
return raw + raw*123/512;
}

void roving() {
int speed, turn;
randomSeed(millis());

if (dmax > 300 && abs(dAngleMax) < 10) {
ArmAngleRange = 15;
speed = 20;
turn = -dAngleMax;
}
else if (dmax > 60) {
ArmAngleRange = 60;
speed = 16;
turn = -dAngleMax/4;
}
else if (dmax > 30) {
ArmAngleRange = 70;
speed = dmax/5 - 6;
turn = -dAngleMax/24;
}
else if (dmax <= 30) {
ArmAngleRange = 80;
speed = 0;
turn = -dAngleMax/20;
digitalWrite(runningLED, HIGH);
}
if ((dmin <= 19)&&(abs(dAngleMin)<60)) {
ArmAngleRange = 80;
digitalWrite(errorLED, HIGH);
speed = -4;
if (dAngleMin !=0) {
turn = dAngleMin/20;
}
else {
if (random(0,1)) {
turn = -2;
}
else {
turn = 2;
}
}
}
/*
else {
move(0,0);
flashLED(errorLED,5);
}
*/
move(speed, turn);
}

void setup() {
pinMode(LeftWheelPin, OUTPUT);
pinMode(RightWheelPin, OUTPUT);
pinMode(ArmServoPin, OUTPUT);
pinMode(errorLED, OUTPUT);
pinMode(runningLED, OUTPUT);
pinMode(SonarPin, INPUT);
Serial.begin(9600);

LeftSpeed = 0;
RightSpeed = 0;
ArmAngleRange = 80;
ArmAngleTarget = 80;
distance = 50;
dmaxtemp = 20;
dmintemp = 1000;

flashLED(runningLED,5);

timeStart = millis();

move(0,0);
}

// -------------------------------------------------- Main Loop
void loop() {

digitalWrite(errorLED, LOW);

if (millis() - timeLast > 100) {
distance = ping();

if (distance < dmintemp) {
dmintemp = distance;
dAngleMinTemp = ArmAngle;
}
if (distance > dmaxtemp) {
dmaxtemp = distance;
dAngleMaxTemp = ArmAngle;
}
roving();
timeLast = millis();
}

if ((millis() - timeLastSlow > 500) && (abs(ArmAngle) >= abs(ArmAngleTarget))) {
if (ArmAngleTarget > 0) {
ArmAngleTarget = ArmAngleRange*-1;
}
else {
ArmAngleTarget = ArmAngleRange;
}
dAngleMax = dAngleMaxTemp;
dAngleMin = dAngleMinTemp;

dmax = dmaxtemp;
dmin = dmintemp;
dmaxtemp = 10;
dmintemp = 1000;

/*
Serial.print("Angles: ");
Serial.print(dAngleMax,DEC);
Serial.print(", ");
Serial.print(dAngleMin,DEC);
Serial.print(" - Distances: ");
Serial.print(dmax,DEC);
Serial.print(", ");
Serial.println(dmin,DEC);
*/
timeLastSlow = millis();
}

if (millis() - timeLastFast > 4) {
armturn();
timeLastFast = millis();
}

//Serial.println(distance,DEC);
digitalWrite(runningLED, LOW);

}
``````

try the code in post #8 replacing LeftServo.attach(2); with: LeftServo.attach(6);

if that doesn't work, check which pins the servos are attached to.

try the code in post #8 replacing
LeftServo.attach(2);
with:
LeftServo.attach(6);

if that doesn’t work, check which pins the servos are attached to.

I’ve got movement! ;D I took the batteries out of the equation, and used the 5v/Gnd from the arduino, and I’m able to not only control the speed, but the direction as well by modifying the values specified in the loop: moveServoLeftTo(45,500);

So, my questions are now these: Is it a bad idea to power both servos with the arduino’s power (I kinda feel like there might be current concerns), OR, is it ok for the batteries ground to share a ground with the arduinos (Will that even work?? I don’t want to fry anything).

And again, thanks mem!