1

I have an Arduino Uno and two Hi-tec servos (HS-40 & 5055 digital) that I'm using for a basic robot build. I'm trying to have one servo(HS-40) turn the head back and forth (left to right) slightly faster than the other servo (HS-5055) controlling the upper torso.

I would like to have each servo working at the same time but not at the same speed without waiting for one servo to complete its movement.

I tried a sketch with a delay of 45-50 which seems to work fine for the movement speed and 0-75 degrees is ideal for the head travel and 0-65 degrees for the torso travel. I would like to have this movement to be repeated continuously so the robot mimics like it is looking side to side or left to right naturally.

Please help as I tried many sketches but can't find one that works like this. I tried modifying other code but can't get them work. Any help will be greatly appreciated.

How do modify this code so just the second servo runs at 40 which will slow down just enough? Also this is not my code, but it's one that seems to be close to what I'm trying to do.

#include <Servo.h>

Servo servo1; 
Servo servo2;

int i = 0;

void setup() {
  servo1.attach(8);
  servo2.attach(9);   
}

void loop() {
  for (i = 0; i < 70; i++) { 
    servo1.write(i);              
    servo2.write(i);     
    delay(50);                      
  }
  for (i = 70; i > 0; i--) { 
    servo1.write(i);                
    servo2.write(i);     
    delay(50);                      
  }
}
3
  • Please post some code that you are using. Without a starting point it is difficult to offer any help. But do a google search for "blink without delay" for an approach that might work.
    – tavis
    Commented May 11, 2021 at 0:00
  • Here is the code. Can a "Delay" command be added to the second servo to slow it down to 40? #include <Servo.h> Servo servo1; Servo servo2; int i = 0; void setup() { servo1.attach(8); servo2.attach(9); } void loop() { for (i = 0; i < 70; i++) { servo1.write(i); servo2.write(i); delay(50); } for (i = 70; i > 0; i--) { servo1.write(i); servo2.write(i); delay(50); } } Commented May 11, 2021 at 2:42
  • change the line to servo1.write(2*i);
    – jsotola
    Commented May 11, 2021 at 5:49

2 Answers 2

1

Heres a little sketch you can try. It uses timing to accomplish the different servo speeds. It won't give you the exact servo travel each loop but it sounds like you might not mind if it randomly is off by a few degrees each loop.

#include <Servo.h>
Servo servo1;
Servo servo2;
int i = 0;
void setup() {
  Serial.begin(9600);
  servo1.attach(8); 
  servo2.attach(9); 
} 

int sweep_time = 3500; // 70 * 50ms = 3500

int head_degrees = 75; // sweep degrees for the head to move
int body_degrees = 65; // sweep degrees for the body to move

int millis_per_head_move = sweep_time / head_degrees;
int millis_per_body_move = sweep_time / body_degrees;

void loop() {
  int i = 0; int j = 0;
  unsigned long now_millis = 0;
  unsigned long start_sweep = millis(); // mark the time when we start the first sweep
  
  while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
    if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
  
  start_sweep = millis();  // mark the time when we start the second/back sweep
  while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0) servo1.write(i--);
    if (now_millis % millis_per_body_move == 0) servo2.write(j--);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
}
3
  • Thank you so much for this. I was getting some jittering with the previous code as the head swept back but I think I need to add some weight for ballast to the head & torso to help stabilize them. This code seems to minimize some of the jittering. I did test it with some added weight and it seems to be better now. Hopefully, once I get this project done I'll post a link where you can see it in action. Again, thanks for all the help! Much appreciated. Commented May 13, 2021 at 0:23
  • Happy that it works! If my answer solved the issue then please mark it as the accepted answer.
    – tavis
    Commented May 13, 2021 at 22:18
  • You do that by clicking the check mark by someone's answer.
    – Austin
    Commented Jun 12, 2021 at 17:54
0

Thanks for the answer from @tavis

Here is the simulation of their code and it answers your questions aptly. enter image description here

The code (same as above, except the sweep time change)

#include <Servo.h>
Servo servo1;
Servo servo2;
int i = 0;
void setup() {
  Serial.begin(9600);
  servo1.attach(8); 
  servo2.attach(9); 
} 

int sweep_time = 1000; // 70 * 50ms = 3500

int head_degrees = 75; // sweep degrees for the head to move
int body_degrees = 65; // sweep degrees for the body to move

int millis_per_head_move = sweep_time / head_degrees;
int millis_per_body_move = sweep_time / body_degrees;

void loop() {
  int i = 0; int j = 0;
  unsigned long now_millis = 0;
  unsigned long start_sweep = millis(); // mark the time when we start the first sweep
  
  while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
    if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
  
  start_sweep = millis();  // mark the time when we start the second/back sweep
  while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
    now_millis = millis() - start_sweep;
    if (now_millis % millis_per_head_move == 0) servo1.write(i--);
    if (now_millis % millis_per_body_move == 0) servo2.write(j--);
    delay(1);
  }
  Serial.print(i); Serial.print(" "); Serial.println(j);
}

Link to the simulation:
https://wokwi.com/arduino/projects/303847722463527490

Here is another example with three Servo motors running at three different sweep times:
https://wokwi.com/arduino/projects/299552195816194570

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.