a little problem with my program

Hi every body,
I'm just a beginner in Adruino. I learn a example in book like this:

Hier is a example about Input value from Serial. I input a value by Serial INPUT function and it control Adruino, with a LED -> HIGH,x-> LOW and bx LED -> HIGH in x second. But it's not working like this.

int led =13;
void setup() {
  // put your setup code here, to run once:
  pinMode(led,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if( Serial.available()){
    char com = Serial.read(); 
   // char sec = Serial.read();
   // Serial.println(sec);
     //Serial.println(Serial.peek());
    if(com=='x'){
      digitalWrite(led,LOW);
      }
      else if(com=='a'){
        digitalWrite(led,HIGH);
        }
        else if(com== 'b'){
          Serial.println(Serial.peek());
          if(Serial.peek()>'0' && Serial.peek()<='9'){
            digitalWrite(led,HIGH);
            delay((Serial.read()-48)*100);
            digitalWrite(led,LOW);
            }
          }
    }
}

It has problem with bx function. When i input b9 ( LIGHT UP in 9 second) . In fact LED light up only 1,2 ms and after that i print the value after b( in this case ist 9) . The value i get ,it's -1

Please someone explain for me, why my program is not working and why the value is always -1

Imagine the first "Serial.available" returns 1, so you read the character and put it in "com".
Imagine it was a 'b', so you do a Serial.peek.
This is only a few microseconds after the 'b' arrived, so the '9' hasn't got here yet.
It takes over a millisecond to transmit a character at 9600 bits per second.

Please someone explain for me, why my program is not working and why the value is always -1

       else if(com== 'b'){
          Serial.println(Serial.peek());

If the character that came in is a 'b', there is no reason to assume that there are any more characters to peek at.

Serial data arrives ssslllooowwwlllyyy. If the 'b' is to be followed by a digit, you need to wait for the digit to arrive.

That's because you only check if Serial is available, not how many! The Arduino is a hell lot faster then 9600 baud serial. So when you send "b7" Serail.available() is already true when in the background the hardware is still dealing with the 7.

So lesson learned, never use more serial data (aka Serial.read/peek()) then you verify you have :wink:

And now some extra lessons :smiley:

ms * 100 is not seconds :wink:

Keep track of your indentation. A if or a else should align with it's closing bracket }. Press ctrl + T in the Arduino IDE and see how it looks way better :wink:

And a white space in you code is free but makes it more readable for us humans. So

    if(com == 'x'){
      digitalWrite(led, LOW);
    }
//etc

And you subtract 48 to go from ASCII to int. That's fine but why not simply do

(Serial.read() - '0') * 1000; // use '0' instead of 48. Same result but now it's immediately clear we're dealing with ASCII

thanks guy

@septillion: thank you so much!I just jump into "Adruino" only 10 days , so it has always so many errors :slight_smile:

a last question from me : what should i do now,my program can work normally ?

Just check for more available when you need more. And peek to know how many we need.

const bye led =13;
void setup() {
  // put your setup code here, to run once:
  pinMode(led,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if( Serial.available()){
    char com = Serial.peek();
   // char sec = Serial.read();
   // Serial.println(sec);
     //Serial.println(Serial.peek());
    if(com == 'x'){
      Serial.read(); //because we already peeked
      digitalWrite(led,LOW);
    }
    else if(com=='a'){
      Serial.read(); //because we already peeked
      digitalWrite(led,HIGH);
    }
    else if(com == 'b' && Serial.available() >= 2){
      Serial.read(); //because we already peeked
      Serial.println(Serial.peek());
      if(Serial.peek()>'0' && Serial.peek()<='9'){
        digitalWrite(led,HIGH);
        delay((Serial.read() - '0') * 1000);
        digitalWrite(led,LOW);
      }
    }
  }
}

Next up, get rid of the delay(). While waiting in the delay you can't do anything. Most of the time that's not what you want.

@thuyle, have a look at the examples in Serial Input Basics - simple reliable ways to receive data without blocking.

...R