I've been working on a school project trying to switch the microcontroler on an old robot out for an Arduino Uno. I decided to start by playing around with the servos (GWS03/STD), which are continuous rotation. When trying to program the servos I initially did tests that would have the servo spin continuosly in one direction, those worked fine. Next I tried to use the delay function to get the robot to drive forward than back the loop part of that code looked like this:
In this instance the servos would spin forward for a second than stop for a second over and over. I posted that on the forums yesterday and was told not to use the delay function and instead use millis function. I then implemented this code:
//This is a program to test servos on Bluebot
#include <Servo.h>
#define LEFT_SERVO_PORT 5
#define RIGHT_SERVO_PORT 3
Servo leftServo;
Servo rightServo;
unsigned long currentTime;
unsigned long directionIndicator;
void setup(){
Serial.begin(9600);
leftServo.attach(LEFT_SERVO_PORT);
rightServo.attach(RIGHT_SERVO_PORT);
directionIndicator = 0;
}
void loop(){
directionIndicator=millis();
directionIndicator=directionIndicator/2000;
directionIndicator=directionIndicator%2;
if (directionIndicator==0){
leftServo.write(179);
rightServo.write(0);
}
else{
leftServo.write(0);
rightServo.write(179);
}
Serial.print(directionIndicator);
}
This code should have the servos switch direction every two seconds. The same exact thing that happens with the delay happens here. I tried switching out the servos with the ones that came with my Arduino starter kit to see if it made a differnce, it didn't. I thought maybe it was an issue with Ubuntu (I'm running 13.10) so I tried it on my teacher's Macbook and the same thing happened. Both Servos are getting the 5 volts they require and are connected to PWM ports. Here's a photo of the wiring setup:
Both me and my teacher are totally stumped, any help is gretly appreciated!
In order to test the hardware, write a sketch that does nothing except move both servos continuously by calling attach() and write() in setup().
If you have problems with both servos connected, try disconnecting one of them (without changing the software). The Arduino power supply is very marginal for powering a servo although it is often OK if you have a small servo which is only lightly loaded. Quite possibly the extra load of the second servo is just too much for it. If the project works correctly with just a single servo connected but not with two, this supports the theory it's a power supply issue.
Wiring and power issues aside,although they do need addressing,your use of millis() for timing is unconventional.
I have taken the liberty of re-writing your program as follows
//This is a program to test servos on Bluebot
#include <Servo.h>
#define LEFT_SERVO_PORT 5
#define RIGHT_SERVO_PORT 3
Servo leftServo;
Servo rightServo;
unsigned long currentTime;
unsigned long prevChangeTime=millis();
const unsigned long interval = 2000;
boolean forward = true;
void setup()
{
Serial.begin(9600);
leftServo.attach(LEFT_SERVO_PORT);
rightServo.attach(RIGHT_SERVO_PORT);
}
void loop()
{
currentTime =millis();
if (prevChangeTime - currentTime >= interval)
{
forward = !forward;
prevChangeTime = millis();
}
if (forward)
{
leftServo.write(179);
rightServo.write(0);
}
else
{
leftServo.write(0);
rightServo.write(179);
}
}
It might work, but it strikes me as bad practice to call the Arduino API before init() has completed. Better IMO to initialise it to zero since that is what we expect millis() to return here. Given that globals are initialised to zero by default, there's no need for the initialiser.
I take your point Peter and setting prevChangeTime to zero would certainly work.
When does the hidden init() function run as the IDE weaves its magic behind the scenes ?