serial data problem

Hi. I want to control a servo through serial port. An idea is sending angle 0-180 to arduino. I wrote this code, but when I use Serial Monitor to see what arduino is receiving I got this:
2ÿu (I typed 2)
44ÿ( (I typed 44)
100ÿ (I typed 100)
555ÿ
5ÿA (I typed 5555)
2ÿB^
2ÿ÷R
2ÿøR (I typed 222)

char a[2];
int starttime=0;
int n;
 
void setup() 
{ 
  Serial.begin(9600);
} 
 
void loop() 
{ 
  while(Serial.available() == 0); //Waiting serial data
  
  starttime = millis();
  
  while(Serial.available() < 3 && (millis()-starttime < 800));  //Only 3 characters is read
  n = Serial.available();
  if(Serial.available() > 3)
    {
    n=2;
    }
    
        for(int i = 0; i <= n ; i++)  //Reading serial data to char
        {
        a[i] = Serial.read();
        }
        
      while(Serial.available() > 0) //Clearing serial buffer
      {
      Serial.read();
      }
        
  Serial.println(a);  //Printing number
  char a[2];  //Clearing char
  
}

What is wrong in my code? What are these strange characters? :frowning:

You are still trying to read serial data when there is none.

You are trying to read three characters and store them in a 2 character array.

You are not NULL terminating the array of characters, to make it a string, which is what the Serial.println() method expects.

  char a[2];  //Clearing char

That code does not do what the comment says.

What are these strange characters?

The 'ÿ' represents -1, which is returned when you try to read from serial when there is nothing there.

You could test on whether user has pressed the enter key.
By that time you know that there will no more numbers entered, and you can use the result
Hitting Enter generates ascii value 13 and 11 (CR and NL), if you set the serial monitor to: Both NL and CR.

a suggest sketch using this techniq:

int i=0;
char buf[3];

void setup() 
{ 
   Serial.begin(19200);
  
} 
 
void loop() 
{ 
  if (Serial.available()>0){
    
   
    buf[i]= Serial.read(); 
   
    if (int(buf[i])==13 || int(buf[i])==11 ){  //If Carriage return has been reached
     
      int result=atoi(buf);
      Serial.print("angle ");    
      Serial.println(result);     //print the converted char ar
      if(result>180){
      Serial.println("Warning number too big");
      }
        
    for(int x=0;x<=3;x++){
    buf[x]=' ';
    }
    i=0;  //start over again
    } //if enter
     i++; 
    } //IF Serial.available
  
  

}//LOOP

Hitting Enter generates ascii value 13 and 11 (CR and NL), if you set the serial monitor to: Both NL and CR.

Should be 13 and 10, not 11.

Thanks! I did some changes to my code, but it seems that my Clearing serial buffer code doesn't still work.

while(Serial.available() > 0) //Clearing serial buffer
      {
      Serial.read();
      }

Why this code doesn't clear serial buffer? I tried also Serial.flush(), but that doesn't work either.

222 (I typed 2222)
2
555 (I typed 55555)
55

I typed 2222

Into what application? The Serial Monitor? If so, that application has the ability to append stuff to the stream you want to send, like carriage return and line feed.

You should then read and store all serial data until that end of packet marker arrives, only then should you print the received data.

Hi I understand this is quite late for me to reply but for anyone who googles and comes here only to see that the code above doesnt work dont be disheartened the code is perfect. What my good man did was:

  for(int i = 0; i <=n ; i++)  //Reading serial data to char
        {
        a[i] = Serial.read();
        }

so the problem here is the i<=n which shld actually be i<n

  for(int i = 0; i <n ; i++)  //Reading serial data to char
        {
        a[i] = Serial.read();
        }

there are other problems in the code too but if u just change this and keep on typing 3 characters as input to the serial moniter it should work. It wont work for 1,2 ,4,5,6,… characters as input to serial. Hope i am clear!! this is not a reply to the actual question. Its just a little insight from my side :wink:

Hi. I want to control a servo through serial port. An idea is sending angle 0-180 to arduino.

Some servo test code you can try. Note that the default serial monitor settings do not send a cr/lf at the end of what is being sent.

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 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.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n = readString.toInt();  //convert readString into a number

    // auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    readString=""; //empty for next input
  } 
}

try putting:
a="";
after your <Serial.println(a); //Printing number>

Serial.println(a); //Printing number
a="";