# 3 Servo hexapod robot with millis, need help!

Hi I’m new to the forum and have spent alot of time trying to learn from all the information posted out there and thank everyone who contributes, I’ve learned alot! I have been having trouble figuring out how to use the millis function with multiple servos. Eventually I’m going to use a ultrasonic sensor on it and am just trying to wrap my head around a simple walk using millis. Here’s my code!

#include <Servo.h>

Servo servoM, servoL, servoR; // middle, left and right servo

unsigned long previousMillis = 0;

int threezero = 0; // These variables are just
int onezero = 0; // to make sure none of the servos
int sixfive = 0; // get conflicting commands, a check
int twofive = 0; // and balance, maybe not needed.
// They are also named after the
// degree they cause the servo to move
void setup()
{
Serial.begin(9600);

servoM.attach(5);
servoL.attach(4);
servoR.attach(6);

servoM.write(20);
servoL.write(45);
servoR.write(45);

}

void loop()
{

unsigned long currentMillis = millis();

if (threezero == 0 && currentMillis - previousMillis >400)
{
previousMillis = currentMillis;
servoM.write(30); // mid servo up
threezero = 1;
onezero = 0;
}

if (sixfive == 0 && currentMillis - previousMillis > 500)
{
previousMillis = currentMillis;
servoL.write(65); // L servo forward
servoR.write(65);
sixfive = 1;
twofive = 0;
}

if (onezero == 0 && currentMillis - previousMillis >900)
{
previousMillis = currentMillis;
servoM.write(10); // mid servo down
threezero = 0;
onezero = 1;
}

if (twofive == 0 && currentMillis - previousMillis >1000)
{
previousMillis = currentMillis;
servoL.write(25); // R servo forward
servoR.write(25);
sixfive = 0;
twofive = 1;
}

}

I can get the middle servo to alternate up and down but the L/R servo will not move with it, any help is appreciated, I’m looking for some code that will work with possibly a dumbed down explanation so I can understand the concept and where I went wrong.

You’ve got 4 different things you are timing, so you’ll need to keep up with the last time you did each one. Right now, the first code to move servoM in the first code catches first because it has the smallest interval. Then previousMillis gets updated to the current value of millis, so in the next checks it can never be true.

As it looks like what you want to do, I think you just need 4 different previousMillis variables. But I don’t know that will actually make your robot walk right.

I’ve tried making 4 “previousMillis” labeled 1,2,3,4 and changed it up but still no luck, I’m going to keep playing around with it though and if I get it to work I’ll give an update. I just realized leaving the code that gives me what I want containing delays may help. I just need to get it in millis form. I also tried attaching a video to give a visual of what I’m doing and working with but it might have been too large IDK, it’s an MP4 and failed 3 times when trying to post. This is working code with the final delay timing I want, the previous code I slowed down to be able to better observe what was working and what wasn’t.

#include <Servo.h>

Servo servoM, servoL, servoR;

void setup()
{
Serial.begin(9600);

servoM.attach(5);
servoL.attach(4);
servoR.attach(6);

servoM.write(20);
servoL.write(45);
servoR.write(45);

}

void loop()
{
servoM.write(30);
delay(50);

servoL.write(65);
servoR.write(65);
delay(200);

servoM.write(10);
delay(50);

servoL.write(25);
servoR.write(25);
delay(200);
}

Well I feel silly now because I got it to work perfectly now :D. Thank you for the help, I’ll post the code in hopes it may help another. The move1,2,3,4 variables are like gates not allowing the next movement until the one before it is fulfilled.

#include <Servo.h>

Servo servoM, servoL, servoR; // middle, left and right servo

unsigned long previousMillis = 0;

int move1 = 0; // These variables are just
int move2 = 0; // to make sure none of the servos
int move3 = 0; // get conflicting commands, a check
int move4 = 0; // and balance, maybe not needed.
// They are also named after the
// degree they cause the servo to move
void setup()
{
Serial.begin(9600);

servoM.attach(5);
servoL.attach(4);
servoR.attach(6);

servoM.write(20);
servoL.write(45);
servoR.write(45);

}

void loop()
{

unsigned long currentMillis = millis();

if (move1 == 0 && currentMillis - previousMillis >200)
{
previousMillis = currentMillis;
servoM.write(30); // mid servo up
move1 = 1;
move2 = 0;
}

if (move2 == 0 && currentMillis - previousMillis >50)
{
previousMillis = currentMillis;
servoL.write(65); // L servo forward
servoR.write(65);
move2 = 1;
move3 = 0;
}

if (move3 == 0 && currentMillis - previousMillis >200)
{
previousMillis = currentMillis;
servoM.write(10); // mid servo down
move3 = 1;
move4 = 0;
}

if (move4 == 0 && currentMillis - previousMillis >50)
{
previousMillis = currentMillis;
servoL.write(25); // R servo forward
servoR.write(25);
move4 = 1;
move1 = 0;
}
}

# 7 below:

http://forum.arduino.cc/index.php/topic,148850.0.html

Instead of 4 different flags, you could just have one variable and set it equal to 0, 1, 2, or 3 to tell you which move you are on. That might save a lot of code when moves get more complex.

You still have the problem that you change "previousMillis" in many places. If you are trying to keep track of how long since you did each particular movement, that is going to cause problems.

TY all for your help, I cut the 4 flag variables down to the one and used a different variable for previousmillis with the sensor, to keep the confusion to a minimum. Here's how it turned out,