Serial communication and control. HELP!

Hello, I am new to Arduino and coding in general, so I delayed posting this in the hopes that I can just learn to do it myself. But I am running out of ideas and really need some help. What I want to do is pretty simple: I would like to input an angle into the serial monitor and have my servo motor turn to that angle.

The problem is that I can't seem to get the Arduino to read the numbers I input together, which makes sense because it IS "serial" communication, but there must be a way to do this right? I am able to get the Arduino to print many different characters at once, but that doesn't help because I need to be able to use the entire value to control my servo. Please help me!

Below is the code I found and was trying to use

int serIn; //var that will hold the bytes in read from the serialBuffer

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

}

int thing;

void loop () {
if(Serial.available() > 0 && Serial.available() < 4){
//inform that Arduino heard you saying something
Serial.print("Angle value recieved:");

//keep reading and printing from serial untill there are bytes in the serial buffer
while (Serial.available()>0){
serIn = Serial.read(); //read Serial
Serial.print(serIn, BYTE); //prints the character just read
}

//the serial buffer is over just go to the line (or pass your favorite stop char)
Serial.println(BYTE);
}

//slows down the visualization in the terminal
delay(1000);
}

First fix:

if(Serial.available() > 0 && Serial.available() < 4){

If you somehow get behind in reading from serial, then this if will stop it from reading once you are more than 4 bytes behind.

I suspect you wanted to have a 4 character number, but you must do your own buffering, not use the serial buffer.

Woah wait, buffering? how do I do that? And I do only want 3 bytes to get read; the angle will go from 1 degree to 359 degrees. Are you saying that having that condition in there impedes my ability to read and use more than one byte at a time?

Well, I do not know what you thought, but I have seen a number of interesting attempts on this Forum, and your first try was leaning in that direction.

Anyhow, a bit of solution. I often have small sketches where I want to tweak something while testing, and rather than recompile and upload a sketch with a new value I use the Serial. I'll just cut-n-paste bits from my last one.

boolean SerGet( ) {
  while ( Serial.available()>0 ) {
    SerC = Serial.read() ;
    if ('a'<=SerC&&SerC<='z') SerC &= B01011111 ; // forces uppercase (for 7bit ASCII)
    switch (SerC) {
      case '0' : case '1' : case '2' : case '3' : case '4' :
      case '5' : case '6' : case '7' : case '8' : case '9' :
        SerV = SerV*10 + byte(SerC)-byte('0') ; //Serial.print(SerV) ;
        break ;
      case 'Z' : ValZ = constrain(SerV,0,12) ; return (true) ;
      case 'A' : ValA = constrain(SerV,0,180) ; return (true) ;
  }
  return ( false ) ;
}

This will accumulate a number of digits in SerV as an integer. The function returns false until it sees the terminating char. So when it returns true you have a valid command char in SerC and a value in SerV. (This code also keeps the value in a dedicated variable... for some other reasons)

So on my terminal I enter 5Z or 234A or 66a4z and the code can ten use that for a servo (A for angle ...)

(Edited a cut-n-paste error in the code)

This looks great, thank you so much. For some reason it isn't able to compile when I put it into my sketch. That should go behind the setup and loop parts correct?

You have void function returning a bool value "false".

"return" isn't a function - the parentheses are unnecessary.

Actually, occasionally it returns true, too :slight_smile:

Cut-n-paste error :roll_eyes: - thats the header of a differnt function. I have edited the post above.

(Edit to correct the tense of above sentence)

Sorry, but I am not sure I understand your code. Could you comment on it a little more or tell me what I should input and what I should expect as an output?

What I want to do is pretty simple: I would like to input an angle into the serial monitor and have my servo motor turn to that angle.

The below should do what you ask.

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray); 
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  } 
}

Wow thank you so much zoomkat. Now all I have to do is understand it, but I think I can handle that part. The sketch works great! :^)