0

what i am trying to do: using arduino, 1- start with the LED on pin 13 off 2- read from serial monitor 3- if entering "1" => LED on, if 0 => LED off, else => print "incorrect" I am new to Arduino, and I have tried my best. However, when I key in "1", the LED does not turn on. can somebody spot my mistake and teach me why it is wrong?

here is my code:

    String command;
void setup(){
    Serial.begin(9600);
    command.reserve(5);
    command = "1";
    command += "0";
    pinMode(13,OUTPUT);
  }
  void loop(){
  digitalWrite(13,LOW);
  if(Serial.available()){
    command = Serial.readStringUntil('\n');
    if(command.equals("1")){
      digitalWrite(13,HIGH);
      }
      else if(command.equals("0")){
      digitalWrite(13,LOW);
      }
      else{
            Serial.println("Invalid command");
      }
    }
  }
  • add `command.trim();` after reading. there can be a \r at the end of the input. and remove `digitalWrite(13,LOW);` from the start of the loop(), because it immediately turns off the LED after "1" – Juraj Jul 26 '22 at 05:32
  • By default, String is already has the NULL terminator. Your String is "10", not "1" as your think it to be. There is a difference between "0" (which is a string, an ASCII "0" + a NULL terminator) and '0' (which is a `char` with a value of ASCII 0). – hcheung Jul 26 '22 at 11:05
  • @hcheung your comment doesn't seem to be for this question – Juraj Jul 27 '22 at 06:19
  • @Juraj, I'm referring to OP's code in `command = "1";` and `command += "0";`, that's `"10"`, I think OP is thinking that's is `"1\0"` but it is not. – hcheung Jul 28 '22 at 01:39
  • Thank you all for your comments, they were all eye-openers. I had to move the command line digitalWrite(13,LOW); before the loop, that was all what was needed for the LED to start in off-mode. thank you again – Alsadek Alkhayer Jul 28 '22 at 10:58
  • You could have removed that line completely, and using String objects makes your code just more complicated – datafiddler Jul 30 '22 at 10:21

1 Answers1

1

It has to be buffered first because the serial is read byte after byte. to do that we use a "character type c" aka char c. we loop that until we have the entire serial read (byte after byte).

After that we need the readstring (which is the total of all bytes we read) and compare it with a String. The thing we got between the "". Im not 100% sure why we use ".indeof" but I believe the reason is because they are not the same type so instead it looks for comparison, so if more then 1 comparison is found it will return true.

Now we still want to see if we have invalid input but to do that we need to detect if something is not 1, 2, or 3. I made a comparison which handles the readString as an int and looks if that int is lower then 1 || (or) higher than 3 so it will ignore everything between 1 and 3 but act on everything else.

String readString;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(13,OUTPUT);

  digitalWrite(13,LOW); //led off at start
}

void loop() {

  

  while (Serial.available()) {
    delay(10);  //small delay to allow input buffer to fill
    if (Serial.available() > 0) {
      char c = Serial.read();  //gets one byte from serial buffer
      if (c == ',') {
        break;
      }  //breaks out of capture loop to print readstring
      readString += c;
    } //makes the string readString
  }
  if (readString.length() > 0) {
    Serial.println(readString); //prints string to serial port out

    if (readString.indexOf("1") >= 0) {
      Serial.println("LED ON");
      digitalWrite(13,HIGH);

    }
    if (readString.indexOf("2") >= 0) {                      
      Serial.println("LED OFF");
      digitalWrite(13,LOW);
    }
    if (readString.indexOf("3") >= 0) {
      Serial.println("LED TOGGLE");
      digitalWrite(13,!digitalRead(13));
    }
    if ((readString.toInt() < 1 ) || (readString.toInt() > 3)) {
      Serial.println("INVALID INPUT");
    }
  }
  readString = ""; // empty readString so the next Serial input can be stored in there
}