Maker Pro
Maker Pro

Arduino to control LED using serial monitor

My project is to control the LED by send '1' or '0' via serial monitor.
My task for this project is when '1' is send via serial monitor, the Led ON PIN 3 need to blink until '0' is send via serial monitor, the LED will be turn off. Then, when next '1' is send , the Led ON PIN 3 will blink again. But it doesn't work for my code. This is my first time to use arduino, can anyone tell me what is wrong in my code and help me to do some correction . Below is my code:

Code:
char data = 0;            //Variable for storing received data
void setup()
{
    Serial.begin(115200);   //Sets the baud for serial data transmission                               
    pinMode(3, OUTPUT);  //Sets digital pin 13 as output pin
}
void loop()
{
   if(Serial.available()>0 )      // Send data only when you receive data:
   {
      data = Serial.read();        //Read the incoming data & store into data
    Serial.print(data);          //Print Value inside data in Serial monitor
     Serial.print("\n");       
    

            while(data == '1')
            {
                digitalWrite(3, HIGH);   //If value is 1 then LED turns ON
                delay(2000);
               digitalWrite(3, LOW);
               delay(2000);
              
              

            }   

      while(data == '0')         //  Checks whether value of data is equal to 0
      {
         digitalWrite(3, LOW);    //If value is 0 then LED turns OFF
        
      }
        
        
}
}
 

Harald Kapp

Moderator
Moderator
Code:
while(data == '1')
            {
                digitalWrite(3, HIGH);   //If value is 1 then LED turns ON
                delay(2000);
               digitalWrite(3, LOW);
               delay(2000);
              
              

            }   

      while(data == '0')         //  Checks whether value of data is equal to 0
      {
         digitalWrite(3, LOW);    //If value is 0 then LED turns OFF
        
      }
One obvious issue is with this part of the code. After having received the first value, data is 0 or 1 (assuming you send only 0 and 1, obviously you don't check for other values). With this value you enter one of the two while loops but there is no way to exit these loops as data doesn't change the value within the loop. Use simply "if" instead.
 
Code:
while(data == '1')
            {
                digitalWrite(3, HIGH);   //If value is 1 then LED turns ON
                delay(2000);
               digitalWrite(3, LOW);
               delay(2000);
             
             

            }  

      while(data == '0')         //  Checks whether value of data is equal to 0
      {
         digitalWrite(3, LOW);    //If value is 0 then LED turns OFF
       
      }
One obvious issue is with this part of the code. After having received the first value, data is 0 or 1 (assuming you send only 0 and 1, obviously you don't check for other values). With this value you enter one of the two while loops but there is no way to exit these loops as data doesn't change the value within the loop. Use simply "if" instead.
I know what sir mean, but what i want is to let the LED to blink continuously without stop until a '0' is send via serial monitor. If i just simply use 'if' statement, the LED will only blink for 1 times only and turn off itself.
So, is there anything i can add into my loop or so on to made the led LED to blink continuously without stop.
 
Try this instead:
Code:
/*
   Serial LED blinker
   this sketch is for blinking an LED on an Arduino board.
*/

char data = 0;            //Variable for storing received data
char previousData = 0;
bool enableBlinker = false;
int blinkState = 0;

int LEDpin = 13;

int blinkInterval = 100; // This is a milliseconds value that controls how fast the LED will blink.
// ---------------- 100 milliseconds is on & off five times per second.
unsigned long ledTimeBegin = 0;
unsigned long ledTimeCurrent = 0;

void setup()
{
  Serial.begin(115200);   //Sets the baud for serial data transmission
  pinMode(LEDpin, OUTPUT);  //Sets digital pin 13 as output pin
}


void loop()
{
  if (Serial.available() > 0)   // Send data only when you receive data:
  {
    while (Serial.available()) {
      data = Serial.read();        //Read the incoming data & store into data
      if (data == '1' || data == '0') { // This ignores everything but '0' and '1'.
        if (data != previousData) { // This ignores the new char unless it is different from the last one.
          previousData = data;
          if (data == '1') {
            enableBlinker = true;
            blinkState = 1;
            digitalWrite(LEDpin, HIGH); // Turn the LED on.
            ledTimeBegin = millis(); // Start the blink timer by setting the ledTimebegin value.
          }
          if (data == '0') {
            enableBlinker = false;
            digitalWrite(LEDpin, LOW); // Turn off the LED so it does not stay on.
          }
        }
        // If the character was one of the two acceptable types,
        // then it gets returned in the serial monitor here:
        Serial.print("accepted char = ");          //Print Value inside data in Serial monitor
        Serial.println(data);
      }
      else {
        // If the character was NOT one of the two acceptable types,
        // then it gets returned in the serial monitor here.
        // The ASCII code number is printed for you here, since some characters are non-printing!
        Serial.print("rejected char = char[");          //Print Value inside data in Serial monitor
        Serial.print(data, DEC);
        Serial.println("]");
      }
    }
  }


  if (enableBlinker == true) { // This whole section blinks the LED if it should be blinking.
    ledTimeCurrent = millis();
    if (ledTimeCurrent > ledTimeBegin) {
      if (ledTimeCurrent >= (ledTimeBegin + blinkInterval)) {
        if (blinkState == 1) {
          digitalWrite(LEDpin, HIGH);
          blinkState = 0;
        }
        else {
          digitalWrite(LEDpin, LOW);
          blinkState = 1;
        }
        ledTimeBegin = millis();
      }
    }
    else {
      ledTimeBegin = millis(); // millis() rollover condition test (not likely, but anyway)
    }
  }

} // end of main loop()
There's a lot not there in those attempts, so I will make it easy.

A few notes about this:
1. I tested this on a Nano but it should work just the same on an Uno or Mega.

2. I set it to blink pin 13 as I was too lazy to hook up a LED.

3. I made this to store the previous-valid-character-entered, and to ONLY switch blink states when a different valid character than the last valid character is entered...

4. This filters out any characters that are not the two you want to use (zero and one) because...

5. Normally a PC serial program will append a cr+lf character (ASCII 10) onto the end of everything it sends, even a single character (that was only one byte long).

6. Notice that it has a conditional line that says { while (Serial.available() }. The reason for this is that if you did not do that and you only read one character, then you are leaving the last character sent, in the serial-in buffer, which is ASCII (10) ,,,,,, and then the next time you tried to read the first character, you'd just get ASCII (10). If you just read to the last character in the serial-in buffer, then all you will ever see is the last ASCII (10) character. ...So when you are reading chars from the serial buffer, you should always read ALL of them that are present, and you write a way to catch the characters you are looking for and to throw away any of the characters that you don't want.

7. If it gets a character that is not a 0 or 1, then this shows you what was rejected--it gives you the ASCII code, because some characters (like the cr+lf character) are non-printing. If you just use Serial.print() to show them, you still cannot see them. ....And you will notice that even if you give it a zero or a one, it still will reject the ASCII (10) character that was on the end of the 0/1....

8. Finally--the reason that I did not use the delay() command is because of this: for any time that the delay() command is running, the Arduino cannot catch sent serial messages. So I used a millis() time check instead, to space out the LED blinking on and off. And that way the serial messages will work any time they happen to arrive.
 
Last edited:
Top