Make servo move by serial commands

Hi guys! I am trying to make a servo move in different ways (180 degree) depending on the input of the serial monitor, but it is not working. It grabs the first letter, but does not update the other one. If I write “S” for example, it will do what is in S, then not update if I press R or the like!

What is wrong with the code?

Thank you!

Further, it works if I use “if” statements, but it will only execute the code once - maybe there is a workaround with it?

#include <Servo.h>

Servo myservo;
int pos = 0;

void setup()
{
  Serial.begin(9600);
  myservo.attach(2);
  myservo.write(0);
}

void loop() {
  while (Serial.available()) {
    char comdata = char(Serial.read());
    while (comdata == 'S') {
      myservo.write(0);
      delay(1000);
      myservo.write(180);
      delay(1000);
      Serial.println(comdata);
    }
    while (comdata == 'R') {
      myservo.write(0);
      delay(2000);
      myservo.write(90);
      delay(2000);
      Serial.println(comdata);
    }
  }
}






what’s updating comdata once you are in the while loop? (you end up stuck there)

you need to separate getting the command and operating on the last command and of course get rid of the delays

For extra information and examples look at Using millis() for timing. A beginners guide and Several things at the same time

    while (comdata == 'S')
    {
      myservo.write(0);
      delay(1000);
      myservo.write(180);
      delay(1000);
      Serial.println(comdata);
    }

Once the code is in this while loop the value of comdata will not change so it will not exit the loop

Try replacing the while with an if so that the code can move on

I did, but it only does it once. That is, moves the servo to 0, then 180.

How can I make it loop?

Only read a new value into comdata if Serial data is available()

and the usage of a case/switch() may help, too

that’s kinda what we mean

#include <Servo.h>
Servo myservo;
char currentCommand = 'N'; // Nothing until we get a command

void setup() {
  Serial.begin(9600);
  myservo.attach(2);
  myservo.write(0);
}

void loop() {

  if (Serial.available()) {
    char r = Serial.read();
    if (r == 'S') currentCommand = 'S';
    else if (r == 'R') currentCommand = 'R';
    else Serial.println(F("command ignored"));
  }

  if (currentCommand == 'S') {
    myservo.write(0);
    delay(1000);
    myservo.write(180);
    delay(1000);
  } else if (currentCommand == 'R') {
    myservo.write(0);
    delay(2000);
    myservo.write(90);
    delay(2000);
  }
}

(written here untested)

the challenge with this approach is latency: you’ll have to wait the end of one cycle to get the next command since delay() is blocking.

A more user friendly version would require to remove the delay and handle the servo’s movement using millis()

Hello
I´ve made a sketch using switch/case. If needed you can simply extent this sketch with a time function to by now not using the delay() function, as above mentioned by J-M-L Jackson.

#include <Servo.h>
Servo myservo;
void setup() {
  Serial.begin(9600);
  myservo.attach(2);
  myservo.write(0);
  Serial.println(F("\nlet´s go - enter either [S] or [R]"));
}
void loop() {
  if (Serial.available()) {
    switch (Serial.read()) {
      case 'S':
        Serial.print(F("command S "));
        myservo.write(0);
        delay(1000);
        myservo.write(180);
        delay(1000);
        Serial.println(F("ready"));
        break;
      case 'R':
        Serial.print(F("command R "));
        myservo.write(0);
        delay(2000);
        myservo.write(90);
        delay(2000);
        Serial.println(F("ready"));
        break;
      case '\n':  break;
      default:
        Serial.println(F("command ignored"));
        break;
    }
  }
}

I think OP wanted the movement to be permanent and you could change it with a command.as per his Comment

it works if I use “if” statements, but it will only execute the code once - maybe there is a workaround with it?

Your code will only do one movement each time you type a command,

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