LED can't turn off after using Serial input (RL_OFF, GL_OFF and BL_OFF)

void serialBlinkingLED(){
  if(input_state == 0){
    if(prompt_printed == false){
      Serial.println("Enter Delay in seconds: ");
      prompt_printed = true;
    }
    if(Serial.available()){ 
      input_delay = Serial.parseInt();
      input_done = true;
    }
    if(input_done){
      Serial.print("You entered a delay of: ");
      Serial.print(input_delay);
      Serial.println(" seconds");
      prompt_printed = false;
      input_done = false;
      input_state++;
    }
  }
  if(input_state == 1){
    if(prompt_printed == false){
      Serial.println("Enter LED number (RED[7], GREEN[6] or BLUE[5]): ");
      prompt_printed = true;
    }
    if(Serial.available()){ 
      input_LED = Serial.parseInt();
      input_done = true;
    }
    if(input_done){
      Serial.print("You entered LED on pin: ");
      Serial.println(input_LED);
      prompt_printed = false;
      input_done = false;
      input_state = 0;
    }
  }
  switch(input_LED){
      case RED_LED_PIN:
        RL_ON();
        delay(input_delay*1000);
        RL_OFF();
        break;
      case GREEN_LED_PIN:  
        GL_ON();
        delay(input_delay*1000);
        GL_OFF();
        break;
      case BLUE_LED_PIN:        
        BL_ON(); 
        delay(input_delay*1000);
        BL_OFF();
        break;
      default:
        break;
    } 
}

Print the incoming serial data to make sure that it is what you think it is.

What is the source of the serial data? Does the source send line endings?

Are you sure that the problem is in the snippet that you posted?

Hello. Thank you for the response! I am kind of new to working with arduino. I do have my incoming serial data printed and it seems to be correct. Here is my entire code:

// C++ code
//
#define RED_LED_PIN 7
#define GREEN_LED_PIN 6
#define BLUE_LED_PIN 5
#define DATA_RATE 9600

int default_delay = 300;
int long_delay = 1000;

int input_LED;
int input_delay;
int input_state = 0;
boolean input_done; 
boolean prompt_printed;

void setup()
{
  //init LEDs and test
  initSerial();
  initLEDs();
}

void loop()
{
  
  serialBlinkingLED();
}

void initSerial(){
  // Serial Initialization
  Serial.begin(DATA_RATE);
  Serial.println("---------Serial is init.---------");
}

void initLEDs() {
  // LED Initialization
  
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);
  
  // turn all LEDs ON
  RL_ON();
  GL_ON();
  BL_ON();
  delay(long_delay);
  // turn all LEDs OFF after 1 second
  RL_OFF();
  GL_OFF();
  BL_OFF();
  delay(long_delay);
  Serial.println("--------All LEDs are init.-------");
}

// LEDs ON/OFF Functions
void RL_ON(){
  digitalWrite(RED_LED_PIN, HIGH);
}
void GL_ON(){
  digitalWrite(GREEN_LED_PIN, HIGH);
}
void BL_ON(){
  digitalWrite(BLUE_LED_PIN, HIGH);
}
void RL_OFF(){
  digitalWrite(RED_LED_PIN, LOW);
}
void GL_OFF(){
  digitalWrite(GREEN_LED_PIN, LOW);
}
void BL_OFF(){
  digitalWrite(BLUE_LED_PIN, LOW);
}


// LEDs Blinking in Serial Input Intervals and Order
void serialBlinkingLED(){
  if(input_state == 0){
    if(prompt_printed == false){
      Serial.println("Enter Delay in seconds: ");
      prompt_printed = true;
    }
    if(Serial.available()){ 
      input_delay = Serial.parseInt();
      input_done = true;
    }
    if(input_done){
      Serial.print("You entered a delay of: ");
      Serial.print(input_delay);
      Serial.println(" seconds");
      prompt_printed = false;
      input_done = false;
      input_state++;
    }
  }
  if(input_state == 1){
    if(prompt_printed == false){
      Serial.println("Enter LED number (RED[7], GREEN[6] or BLUE[5]): ");
      prompt_printed = true;
    }
    if(Serial.available()){ 
      input_LED = Serial.parseInt();
      input_done = true;
    }
    if(input_done){
      Serial.print("You entered LED on pin: ");
      Serial.println(input_LED);
      prompt_printed = false;
      input_done = false;
      input_state = 0;
    }
  }
  switch(input_LED){
    case RED_LED_PIN:
      RL_ON();
      delay(input_delay*1000);
      RL_OFF();
      break;
    case GREEN_LED_PIN:  
      GL_ON();
      delay(input_delay*1000);
      GL_OFF();
      break;
    case BLUE_LED_PIN:        
      BL_ON(); 
      delay(input_delay*1000);
      BL_OFF();
      break;
    default:
      break;
  }   
}

Serial prints are the best debugging tool that you have. Sprinkle serial prints at strategic locations to follow the code execution and variable values. Like right after the switch statements to see that the variables are what you think.

switch(input_LED)
{
    Serial.print("value of input_LED = ");
    Serial.println(input_LED);
    case RED_LED_PIN:

Yes, that was my first move as well. But still can't get it to turn off. Everything is working flawlessly, I get all the prompts, the chosen LED lights up...however it stays on and won't turn off.
I just tried with the exact example you gave me. The LED lights up but no message appears. The function just starts over again.
UPDATE: Works when inside a case in the switch condition(value of input_LED = 7). Seems right.

Serial Monitor:
---------Serial is init.---------
--------All LEDs are init.-------
Enter Delay in seconds:
You entered a delay of: 4 seconds
Enter LED number (RED[7], GREEN[6] or BLUE[5]):
You entered LED on pin: 7
Enter Delay in seconds:

Hi
I think it needs a delay after turning off the LED.
Test the modified code.

// C++ code
//
#define RED_LED_PIN 7
#define GREEN_LED_PIN 6
#define BLUE_LED_PIN 5
#define DATA_RATE 9600

int default_delay = 300;
int long_delay = 1000;

int input_LED;
int input_delay;
int input_state = 0;
boolean input_done;
boolean prompt_printed;

void setup()
{
  //init LEDs and test
  initSerial();
  initLEDs();
}

void loop()
{

  serialBlinkingLED();
}

void initSerial() {
  // Serial Initialization
  Serial.begin(DATA_RATE);
  Serial.println("---------Serial is init.---------");
}

void initLEDs() {
  // LED Initialization

  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);

  // turn all LEDs ON
  RL_ON();
  GL_ON();
  BL_ON();
  delay(long_delay);
  // turn all LEDs OFF after 1 second
  RL_OFF();
  GL_OFF();
  BL_OFF();
  delay(long_delay);
  Serial.println("--------All LEDs are init.-------");
}

// LEDs ON/OFF Functions
void RL_ON() {
  digitalWrite(RED_LED_PIN, HIGH);
}
void GL_ON() {
  digitalWrite(GREEN_LED_PIN, HIGH);
}
void BL_ON() {
  digitalWrite(BLUE_LED_PIN, HIGH);
}
void RL_OFF() {
  digitalWrite(RED_LED_PIN, LOW);
}
void GL_OFF() {
  digitalWrite(GREEN_LED_PIN, LOW);
}
void BL_OFF() {
  digitalWrite(BLUE_LED_PIN, LOW);
}


// LEDs Blinking in Serial Input Intervals and Order
void serialBlinkingLED() {
  if (input_state == 0) 
  {
    if (prompt_printed == false) 
    {
      Serial.println("Enter Delay in seconds: ");
      prompt_printed = true;
    }
    if (Serial.available()) {
      input_delay = Serial.parseInt();
      input_done = true;
    }
    if (input_done) {
      Serial.print("You entered a delay of: ");
      Serial.print(input_delay);
      Serial.println(" seconds");
      prompt_printed = false;
      input_done = false;
      input_state++;
    }
  }
  if (input_state == 1) 
  {
    if (prompt_printed == false) {
      Serial.println("Enter LED number (RED[7], GREEN[6] or BLUE[5]): ");
      prompt_printed = true;
    }
    if (Serial.available()) {
      input_LED = Serial.parseInt();
      input_done = true;
    }
    if (input_done) {
      Serial.print("You entered LED on pin: ");
      Serial.println(input_LED);
      prompt_printed = false;
      input_done = false;
      input_state = 0;
    }
  }
  switch (input_LED) {
    case RED_LED_PIN:
      RL_ON();
      delay(input_delay * 1000);
      RL_OFF();
       delay(input_delay * 1000);
      break;
    case GREEN_LED_PIN:
      GL_ON();
      delay(input_delay * 1000);
      GL_OFF();
       delay(input_delay * 1000);
      break;
    case BLUE_LED_PIN:
      BL_ON();
      delay(input_delay * 1000);
      BL_OFF();
       delay(input_delay * 1000);
      break;
    default:
      break;
  }
}
1 Like

Worked! I have been wondering why it isn't working the last couple of hours now. Thank you so very much. Can't quite get it why that missing 2nd delay would keep it from turning off, but at least it works now. Thanks again!

Hi
the way the code was written, the turn off was so fast that you didn't notice.
The delay allowed to visualize the turn off.

1 Like

Hi, it turns off without the 2nd delay also (as @ruilviana already mentioned). But because input_LED variable is not changed after each case, it turns on again immediately (so fast you can't see the off state). If you just only insert a second delay at the end of each case, the last controlled led will turn on even without any input. Or is this what you'd like to achieve?

If no, you could have a STANDBY state, where none of the LEDs are controlled.

  switch (input_LED) {
    case STANDBY:
      //wait for input
      break;
    case RED_LED_PIN:
      RL_ON();
      delay(input_delay * 1000);
      RL_OFF();
      break;
    case GREEN_LED_PIN:
      GL_ON();
      delay(input_delay * 1000);
      GL_OFF();
      break;
    case BLUE_LED_PIN:
      BL_ON();
      delay(input_delay * 1000);
      BL_OFF();
      break;
    default:
      break;
  }
  input_LED = STANDBY;

You should also check out Blink Without Delay.

1 Like

Hello. My assignment is just to create a program that can take a chosen delay and LED through serial input. I was thinking about making the LED light only once when values are given, but I guess blinking is also ok.
UPDATE: After playing around it works even beter with STANDBY. Thank you for the help as well!

Yeah, because that second delay could be veeery long if you are ready to enter the next input. :slight_smile: You're welcome.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.