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 turn on and off every 2000ms. Then, when '0' is send via serial monitor, the LED need to be turn off until next '1' is send , so that the Led ON PIN 3 can be turn on and off every for 2000ms again. But it doesn't work for my code, can anyone tell me what is wrong in my code. Below is my 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 3 as output pin
}
void loop()
{
   if(Serial.available()>0 )      // Send data only when you receive data:
   {
      data = Serial.read();        //Read the incoming data send via serial monitor & store into data
    Serial.print(data);          //Print Value inside data in Serial monitor
     Serial.print("\n");        
     

            while(data == '1')          //Do looping so that when '1' send via serial monitor, the LED can blink
            {
                digitalWrite(3, HIGH);   
                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
         
}
}

When you get into either of those while(){}'s you'll never get out because you're not checking serial input any more.

because i want to make the LED blink for itself when '1' is read and turn off LED only when '0' is read. So i need a loop

Lemon_Foam:
So i need a loop

Yes, but the way you did it, using while(), once it has read the serial and gotten a 0 or 1 and gone into either of the while()'s, that serial read is never checked again becasue it's outside the while() so it stays in the while() forever. If it's inside the while (data==1) {}, it can never ever become 0 again since the serial read is never going to happen again.

But here's a hint if you need a loop: loop() is already a loop.

You need to look at BlinkWithOutDelay and use that approach, so if the blinking is turned on, you can still read the serial in a non-blocking way and then turn it off.

wilfredmedlin:
When you get into either of those while(){}'s you'll never get out because you're not checking serial input any more.

What is sir mean by 'not checking serial input any more'? That mean i need to check the serial input in my loop? I have change my code as follow, but it still doesn't work, because the LED can't blink anymore after i send '1' via serial monitor, below is my 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);
               

                  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 == '0')         //  Checks whether value of data is equal to 0
      {
         digitalWrite(3, LOW);    //If value is 0 then LED turns OFF


               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");        
                  }



      }
         
         
}
}

You new code actually works for me. (Except that now, once it's blinking after an initial '1', any input to the serial will take out of the while, not just a '0'.

But it's not what I suggested, which was to use the technique of BlinkWithOutDelay.

Sir,i have try to integrate the 'Blink without delay' technique into my original serial.read () coding, but it still doesn't work. Below is my latest code:

char data = 0;            //Variable for storing received data
const int ledPin =  3;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

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

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
 

   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");        
      if(data == '1')              // Checks whether value of data is equal to 1
        
           {

             unsigned long currentMillis = millis();


  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) 
    {
      ledState = HIGH;
      
    } 
                    
    else 
    {
      ledState = LOW;
   
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}


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

   }
}

I don't have time to look at that code now, but I did write a solution yesterday. If you want it I will post it.

wilfredmedlin:
I don't have time to look at that code now, but I did write a solution yesterday. If you want it I will post it.

Ya sir, can i get that solution, because i still cannot get my code work after this few days of try.

Ok but I don't have time to explain it, and you may not learn too much from this exercise.

//http://forum.arduino.cc/index.php?topic=526411
//    no guarantee what so ever...
//    there will probably be better ways to do this but it works
//                                          YMMV

byte thePin = 13;
bool blinkMode = false;
unsigned long currentMillis;
unsigned long previousMillis = 0;
int interval = 2000;
bool ledState;

char data = 0;            //Variable for storing received data
void setup()
{
  Serial.begin(9600);   //Sets the baud for serial data transmission
  pinMode(thePin, OUTPUT);  //Sets digital pin 3 as output pin
}//setup


void loop()
{
  currentMillis = millis();
  if (Serial.available() > 0 )   // Send data only when you receive data:
  {
    data = Serial.read();        //Read the incoming data send via serial monitor & store into data
    Serial.print(data);          //Print Value inside data in Serial monitor
    Serial.print("\n");
  }//serial available

  if (data == '1')
  {
    if (!blinkMode)
    {
      Serial.println("going blinky");
      blinkMode = true;
    }//if (!blinkMode)
  }//if (data == '1')

  if (data == '0')
  {
    if (blinkMode)
    {
      Serial.println("going off");
      blinkMode = false;
      digitalWrite(thePin, LOW);    //If value is 0 then LED turns OFF
    }//if (blinkMode)
  }//if (data == '0')

  if (blinkMode)
  {
    if (currentMillis - previousMillis > interval)
    {
      Serial.println("blink....");
      ledState = !ledState;
      digitalWrite(thePin, ledState);
      previousMillis = currentMillis;
    }//time check
  }//if (blinkMode)

}//loop