why am I losing data over serial communication between arduino and pc

hello, I'm working on a project for school. I'm trying to rotate a servo by writing the letter that identify the servo and then the angle.

the problem is that sometimes the last number of the angle is lost or the whole angle all together. for example i want to rotate servo "a" 50 degrees. i enter a50 this works most of the time but sometimes i only get a 5 without the zero and sometimes i just get a zero. can anyone help, thanks.

please keep in mind i only did computer science in high school and intro to c++ in college. go easy on me please.

attached is the code and an image illustrating my problem.

#include <Servo.h>

Servo servo1;  
Servo servo2;
Servo servo3;

String angle1="";
String angle2="";

char serialbuffer[4];
int index=0;
int charcount=0;

int lastangle;
int dif;
  

void setup() {
  servo3.attach(3);  // attaches the servo on pin 9 to the servo object

  Serial.begin(9600);

  serialbuffer[0]='0';
  serialbuffer[1]='0';
  serialbuffer[2]='0';
  serialbuffer[3]='0';
}

void loop() {

  
       charcount=0;
       index=0;
       serialbuffer[0]=99;

   while (Serial.available() > 0) {
   
      char charbuffer = Serial.read();
       if(charbuffer=='\n'){
          index=0; 
        }
        else{
          
           serialbuffer[index]=charbuffer;
           index++;
           charcount++;
          }
     
      }
      
  angle1="";    
  if(serialbuffer[0]=='a'){
      
      for(int i=1;i<charcount;i++){
         angle1+=serialbuffer[i];
      }
      move_servo3(angle1);
      index=0;
      serialbuffer[0]=99;
    }
  delay(15);
}

void move_servo3(String angle2){
  
 
   Serial.println(angle2.toInt());   
   servo3.write(angle2.toInt()); 
   
  }

Glitch_remover.ino (1.27 KB)

Are you using the Serial Monitor to enter your values?

try read this post... should help

http://forums.trossenrobotics.com/tutorials/how-to-diy-128/complete-control-of-an-arduino-via-serial-3300/

My best guess, after some testing, is that this happens when you type a50:
1)when you press enter to send "a50", the serial monitor has to send 'a' '5' '0'
2)the program is still in the delay() function
3)the program exits the delay() after 15ms and begins looking for a serial input
4)the program finds 'a' and '5', but '0' has not been received yet
5)based on how your program works, you do not allow just an 'a' or just a number such as '5' or '5' '0' and simply deletes any incorrect entries
6)the program thinks you are done with your entry (if it starts with an 'a' and has another character after it) and writes to the servo and serial monitor what it found, after that it tries again, finding a '0' which is a problem and eventually gets deleted...

You will notice more errors if you make your delay function less, such as delay(5)

Try this code, if it sees something in the serial buffer, it will wait up to 20ms for a newline, if none is received, it stops looking and displays an error.

void loop() {
  // if(Serial.available()>0){
  // Serial.flush();
  charcount = 0;
  index = 0;
  serialbuffer[0] = 99;
  //   }
  static byte timeout = 20;
  if (Serial.available() > 0) {
    char charbuffer = 0;
    unsigned long startTime = millis();
    while (charbuffer != '\n' && millis() - startTime < timeout) {
      while (Serial.available() <= 0 && millis() - startTime < timeout)
        ;
      if (millis() - startTime >= timeout) {
        Serial.println("Input timeout, no complete entry detected!");
        break;
      }
      charbuffer = Serial.read();
      if (charbuffer != '\n') {
        serialbuffer[index] = charbuffer;
        index++;
        charcount++;
      }
    }
  }
  
  angle1 = "";
  if (serialbuffer[0] == 'a') {
    for (int i = 1; i < charcount; i++) {
      angle1 += serialbuffer[i];
    }
    move_servo3(angle1);
    index = 0;
    serialbuffer[0] = 99;
  }
  delay(5);
}

You may never rely on all bytes being transmitted 'as one block'. There might be a short delay between two bytes somewhere in the transmission. Also remember that transferring a byte at 9600 bits/second takes a bout 1 millisecond. Your loop is faster than that so the last byte might not have been received yet.

As a result, your while (Serial.available() > 0) will stop.

It's advisable to read serial input basics - updated, understand it and apply the principles.