Problems with Delay() and Servo motors

Hello, I am new with Servo motors and when I was trying to make two of them move simultaneously, but to different positions with different speeds, only one of them would move at a time, even if I called the 2 functions one after the other. I thought it might be because I am using the Delay() function, but I am unsure if it is really because of this, and of how I could use delayMicroseconds() or Micros() instead. I would really appreciate it if someone knew what to do, thank you.

#include <Servo.h>
Servo servoMotor; 
Servo servoMotor2;
int pos = 90; 
int pos2 = 90;
int intensity;
int captor = A0;

void setup() {
  Serial.begin(9600);
  servoMotor.attach(7); 
  servoMotor2.attach(8);
}

void loop() {
  intensity = analogRead(captor); 
  if (intensity>5) //
  { // Stuff with ligths here 
  }
  else 
  { 
   moveMotor();
   moveMotor2();
  }
delay(100); 
}

void moveMotor() { 
  for (pos = 90; pos <= 140; pos += 1) { 
    servoMotor.write(pos);            
    delay(15);                       
  }
 for (pos = 140; pos >= 90; pos -= 1) { 
    servoMotor.write(pos);  
    delay(15);
  }
}

void moveMotor2()  {
  for (pos2 = 90; pos2 <= 95; pos2 += 1) { 
    servoMotor2.write(pos2);      
    delay(15);             
  }
  for (pos2 = 95; pos2 >= 90; pos2 -= 1) {
    servoMotor2.write(pos2);
    delay(15); 
  }
  for (pos2 = 90; pos2 >= 85; pos2 -= 1) {
    servoMotor2.write(pos2);
    delay(15); 
  }
    for (pos2 = 85; pos2 <= 90; pos2 += 1) {
    servoMotor2.write(pos2);
    delay(15); 
  }
}
  • Correct.

  • If you want both servo motors to advance a bit at a time, you need to advance the motors one after the other until they arrive at their destinations.

  • You should look into making non-blocking TIMERs using the millis()/micros() function.

  • This would be an application fit for a state machine.

Adding to this - to make the two servos, starting from individual, arbitrary angles, and arriving at two individual, arbitrary angles, add to the "millis() non-blocking timer" some math using ratios.

That is to say, if servo1 is at X and will go to Y, and servo2 is at W and will go to Z

  • find the distance from X to Y (rise)
  • find the distance from W to Z (run)
  • You now have a ratio of S1 over S2 ratio = abs(X-Y) / abs(W-Z) (slope)
  • In the millis() timer, step either servo by your chosen step and...
  • step the other servo by step * ratio
  • If S1 was at 10 with target 20, and S2 is at 170 with target 100...
  • the ratio would be `ratio = 10 / -70 or -1/7 (or,- 7/1)
  • When moving the servos, S1 would move to "10 + 1"
  • S2 would move to "170 - 7"
S1 S2
10 170
11 163
12 156
13 149
14 142
15 135
16 128
17 121
18 114
19 107
20 100 (but.... if it was 99 or less due to fractions/decimals)

This needs a constraint at both ends, like:

if (angle < target) // negative moving servo
  angle = target;
if (angle > target) // positive moving servo
  angle = target;

Al-jabr for the win.

1 Like