Move servo to alternating positions with successive function calls

Hello, in short I am doing a project which involves several servos that strum guitar strings by moving between two predefined positions. I am attempting to make a function which will move a servo from one of said positions to the other with successive calls to a strum() function, without needing to give the desired position as an input. Here is the code I am using:

#include <Servo.h>


Servo servo;
int pos = 0;
void setup() {
  Serial.begin(9600);
  servo.attach(8);
}

void loop() {
  strum();
  delay(500);
  Serial.println(pos);

}


void strum() {
  if (pos < 100) {
    servo.write(110);
    pos = 110;
  }
  if (pos > 100) {
    servo.write(90);
    pos = 90;
  }
}

I am using an Arduino Mega, and a SG90 servo. My expectation is that the servo would move back and forth, however it moves once to the 90 position and then stays there. The serial monitor shows that the global variable "pos" is equal to 90 in each instance of loop() but I can't figure out why the " pos<100 " condition inside of strum() is not satisfied.

It is also important to note, that I plan to scale up this code to multiple servos using Adafruit's pca9685 board, which means I cannot use servo.read() as it uses I2C.

Any help is appreciated.

Consider what happens here.
Work it through, with a a pencil and paper

1 Like

Ah, thats slightly embarrassing. After the first if statement, instead of moving the servo, the next if statement is immediately triggered instead of ending the function. I've added return; to the end of each if statement and it works!

Correct!

That's not a great solution, in my opinion. In this case it works because there is nothing else you want the strum() function to do after changing the desired servo position. But what if there was? Using return like you did makes your code less well structured, I feel. A better solution would have been to use "else if".

Are you suggesting to use else if for the second condition? Wouldn't that lead to the same problem?

I think my preferred implementation for clarity would be:

void strum() 
{
  if (pos < 100) 
     pos = 110;
  else
    pos = 90;

  servo.write(pos);
}

for compactness you could replace the if/else with the ternary operator:
pos = (pos < 100) ? 110 : 90;

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.