turn led off after 5 seconds!!

Hi guys!I can’t find the way to turn the led after the delay of 5 seconds!Could someone help me with the code?I tried to turn it off automatically by using millis but i find difficulties.So when i push the button i want the led to turn on and after 5 sec ti turn off automatically!i found the sketch and i want to make automaton for electric shouters!
I included inside to the code the :

unsigned long off_time; //what a added
off_time = millis() + 5000;
(millis()>=off_time)

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3);
 

// Variables used for incoming data
const byte maxDataLength = 20;
char receivedChars[21] ;
boolean newData = false;

// Constants for hardware
const byte LED1_PIN = 4;
const byte SWITCH1_PIN = 5;

// general variables
unsigned long off_time;  //what a added

boolean LED1_State = false;
boolean switch1_State = false;
boolean oldswitch1_State = false;

void setup()  
{
    // Set the button switch pin for input
    pinMode(SWITCH1_PIN, INPUT); 

    // Set the red LED pin for output and make it LOW
    pinMode(LED1_PIN, OUTPUT); 
    digitalWrite(LED1_PIN,LOW);
     
    // open serial communication for debugging
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println(__FILE__);
    Serial.print("Uploaded: ");   Serial.println(__DATE__);
    Serial.println(" ");
     
    //  open software serial connection to the Bluetooth module.
    BTserial.begin(9600); 
    Serial.println("AltSoftSerial started at 9600"); 
          
    newData = false;

} // void setup()
 
 
void loop()  
{
       checkSwitch();
       recvWithStartEndMarkers();                // check to see if we have received any new commands
       if (newData)  {   processCommand();  }    // if we have a new command do something about it
}



/*
****************************************
* Function checkSwitch()
* checks the status of a button switch and turns an LED on or off depending on the switch status
* 
* passed:
*  
* global: 
*      switch1_State
*      LED1_State
*      oldswitch1_State
*
* Returns:
*          
* Sets:
*      switch1_State
*      LED1_State
*      oldswitch1_State
*/
void checkSwitch()
{
     // Simple toggle switch function with very simple debouce.
     boolean state1 = digitalRead(SWITCH1_PIN); delay(1);
     boolean state2 = digitalRead(SWITCH1_PIN); delay(1);
     boolean state3 = digitalRead(SWITCH1_PIN); delay(1);

     if ((state1 == state2) && (state1==state3))   
     { 
          switch1_State = state1;  
          if ( (switch1_State == HIGH) && (oldswitch1_State == LOW) )
          {
               
               LED1_State = ! LED1_State; 
              
              off_time = millis() + 5000;
              
                
               if( ( LED1_State==HIGH)  && (millis()>=off_time) )  
               {  
                    
                    
                    digitalWrite(LED1_PIN,HIGH);
                    BTserial.print("<L,1,1>" );  
                      
                    Serial.println("Sent - <L,1,1>");    
               }
                                           
               else 
              
                                   
               {  
                   BTserial.print("<L,1,0>");   
                   digitalWrite(LED1_PIN,LOW);   
                   Serial.println("Sent - <L,1,0>");    
               }    
          }          
          oldswitch1_State = switch1_State;
      }
}






/*
****************************************
* Function processCommand
* parses data commands contained in receivedChars[]
* receivedChars[] has not been checked for errors
* 
* passed:
*  
* global: 
*       receivedChars[]
*       newData
*
* Returns:
*          
* Sets:
*       receivedChars[]
*       newData
*/
void processCommand()
{

     Serial.print("receivedChars = ");  
     Serial.println(receivedChars);

    if (strcmp ("L10",receivedChars) == 0) 
    {
        digitalWrite(LED1_PIN,LOW);
        LED1_State = LOW; 
        Serial.println("LED1 LOW");  
    }
    
    else if (strcmp ("L11",receivedChars) == 0)
    {
        digitalWrite(LED1_PIN,HIGH);
        LED1_State = HIGH; 
        Serial.println("LED1 HIGH");  
    }




   
    receivedChars[0] = '\0';
    newData = false;
   
}


// function recvWithStartEndMarkers by Robin2 of the Arduino forums
// See  http://forum.arduino.cc/index.php?topic=288234.0
/*
****************************************
* Function recvWithStartEndMarkers
* reads serial data and returns the content between a start marker and an end marker.
* 
* passed:
*  
* global: 
*       receivedChars[]
*       newData
*
* Returns:
*          
* Sets:
*       newData
*       receivedChars
*
*/
void recvWithStartEndMarkers()
{
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '<';
     char endMarker = '>';
     char rc;
 
     if (BTserial.available() > 0) 
     {
          rc = BTserial.read();
          if (recvInProgress == true) 
          {
               if (rc != endMarker) 
               {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx > maxDataLength) { ndx = maxDataLength; }
               }
               else 
               {
                     receivedChars[ndx] = '\0'; // terminate the string
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
               }
          }
          else if (rc == startMarker) { recvInProgress = true; }
     }
}

TWO_WAY_LED_CONTROL_1_LED.ino (5.68 KB)

What happens when you run the program ?

      if ( ( LED1_State == HIGH)  && (millis() >= off_time) )
      {
        digitalWrite(LED1_PIN, HIGH);
        BTserial.print("<L,1,1>" );
        Serial.println("Sent - <L,1,1>");
      }

This block of code is within the test for a new button press. Move it into loop() so that is executed each time through loop() not only when the button becomes pressed

Hello buddy!!When i push the button(without the millis,that i included) the led turns on and when i push it again it turns off!Now with the millis when i push the button,nothing happen(it does not turn on).I am beginner,so i a am not good with code.Where exactly to put the knew code? Thanks!!

How is this post different then https://forum.arduino.cc/index.php?topic=479594.msg3275043#msg3275043

The same code is!The first one that i posted has 3 buttons and 3 led!Then i included a code with a push button and one led!This code is not mine ,but it does what i want to do.I want to control the electric shouters with both push button and the app from the app inventor.It is necessary when i push the button,the shouters will work for 5 seconds(untill to go up or down) and then to turn it off automatically.I read that the function of millis can help for this job!

If anyone could help i would appreciate i!My occupation is electrician,so i am good with electrics but not with codes!I like arduino and i try to learn as much things as i can!!

@Odi

Man, don’t use your occupation as an excuse to not be able to code. I’m an electrician too but after some time of tinkering with Arduino, I was able to code significantly with the help of this forum contributors.

#include <Bounce2.h>
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3);
Bounce Switch1_debounce = Bounce();

#define baud_rate 9600

const byte maxDataLength = 20;
char receivedChars[26] ;
boolean newData = false;

const byte LED1_PIN = 4;
const byte SWITCH1_PIN = 5;

const unsigned long off_time = 5UL * 1000UL;
unsigned long timePrevious = 0;
boolean LED1_State = false;
boolean LED1_State_Previous = false;
void setup() {
  init_Serial();
  init_BT();
  init_Input();
  init_Output();
}

void loop() {
  checkSwitch();
  recvWithStartEndMarkers();
  if (newData)  {
    processCommand();
  }
  update_led();
}

void init_Serial() {
  Serial.begin(baud_rate);
  Serial.print("Sketch:   ");   Serial.println(__FILE__);
  Serial.print("Uploaded: ");   Serial.println(__DATE__);
  Serial.println("");
}

void init_BT() {
  BTserial.begin(baud_rate);
  Serial.println("AltSoftSerial started at 9600");
}

void init_Input() {
  pinMode(SWITCH1_PIN, INPUT);
  digitalWrite (SWITCH1_PIN, HIGH);
  Switch1_debounce.attach (SWITCH1_PIN);
  Switch1_debounce.interval (5);
}

void init_Output()
{
  pinMode(LED1_PIN, OUTPUT);
  digitalWrite(LED1_PIN, LOW);
}

void checkSwitch() {
  Switch1_debounce.update();
  if ( Switch1_debounce.fell() ) {
    LED1_State = !LED1_State;
    timePrevious = millis();
  }
}

void recvWithStartEndMarkers()
{
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  if (BTserial.available() > 0) {
    rc = BTserial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx > maxDataLength) {
          ndx = maxDataLength;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }
    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void processCommand() {
  Serial.print("receivedChars = ");
  Serial.println(receivedChars);
  if (strcmp ("L10", receivedChars) == 0) {
    digitalWrite(LED1_PIN, LOW);
    LED1_State = LOW;
    Serial.println("LED1 LOW");
  }
  else if (strcmp ("L11", receivedChars) == 0) {
    digitalWrite(LED1_PIN, HIGH);
    LED1_State = HIGH;
    Serial.println("LED1 HIGH");
  }
  receivedChars[0] = '\0';
  newData = false;
}

void update_led() {
  if ( LED1_State) {
    if ( millis() - timePrevious >= off_time )
    {
      LED1_State = false;
      BTserial.print("<L,1,1>");
      Serial.println("Sent - <L,1,1>");
    }
  }
  if ( !LED1_State && LED1_State_Previous) {
    BTserial.print("<L,1,0>");
    Serial.println("Sent - <L,1,0>");
  }
  digitalWrite(LED1_PIN, LED1_State);
  LED1_State_Previous = LED1_State;
}

With this, I also used bounce2 library which you can download using the link below
Bounce2

You are wright buddy,and i appreciate your help!Thanks.I will test it.

The sketch that you made it works perfectly when i push the natural push button,but when i push the button from the app,the led just blinks.Is like something prevent it for staying on.Also it seems that the feedback does not go to the app!Thanks for your effort!!

a fun and simple way to do this would be to use the MsTimer2 library along with a callback function. The library is included in the IDE but you may have to add it.

A “callback” is a fancy name for a function (what you define and pass as an argument) that will be triggered by some event some time later. MsTimer2 uses (surprise!) Timer 2 which also controls PWM on a couple pins, so this isn’t for every case.

here is an example you can try:

#include <MsTimer2.h>

const byte buttonPin = 5;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{
  if(buttonFivePressed())
  {
   flashLedThirteen();
  }
}

bool buttonFivePressed(void)
{
  static unsigned long lastMillis = 0;
  static byte lastPress = HIGH;
  byte currentPress = digitalRead(buttonPin);
  if(currentPress != lastPress)
  {
    if(millis() - lastMillis < 200) return false;
    lastPress = currentPress;
    if(currentPress == LOW)
    {
      Serial.println(" button press detected!");
      lastMillis = millis();
      return true;
    }
  }
  return false;
}

void flashLedThirteen()
{
  digitalWrite(13, HIGH);
  Serial.println("LED ON");
  // sets a new timer callback function
  MsTimer2::set(5000, [] {  // the square brackets define the start of the anonymous callback function which is executed after 5000 milliseconds in this example
    digitalWrite(13, LOW);
    Serial.println("Timer expired...");
    Serial.println("LED OFF");
    MsTimer2::stop();
  }); // the curly brace defines the end of the anonymous callback function
  MsTimer2::start();
}

This library is not often seen here on the forum, so this was a nice opportunity for people to see how cool it is!!

You know, I only focus on getting the Arduino to be reactive when it comes to hardware input. The things are that I didn’t know your intention when it comes to using the app as you haven’t stated it previously.

Here’s an updated version based on your request. If you think the code satisfied you need for the given topic, please edit your first post title to include [SOLVE] and give karma to those who helped.

#include <Bounce2.h>
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3);
Bounce Switch1_debounce = Bounce();

#define baud_rate 9600

const byte maxDataLength = 20;
char receivedChars[26] ;
boolean newData = false;

const byte LED1_PIN = 4;
const byte SWITCH1_PIN = 5;

const unsigned long off_time = 5UL * 1000UL;
unsigned long timePrevious = 0;
boolean LED1_State = false;
boolean LED1_State_Previous = false;

void setup() {
  init_Serial();
  init_BT();
  init_Input();
  init_Output();
}

void loop() {
  checkSwitch();
  recvWithStartEndMarkers();
  if (newData)  {
    processCommand();
  }
  update_led();
}

void init_Serial() {
  Serial.begin(baud_rate);
  Serial.print("Sketch:   ");   Serial.println(__FILE__);
  Serial.print("Uploaded: ");   Serial.println(__DATE__);
  Serial.println("");
}

void init_BT() {
  BTserial.begin(baud_rate);
  Serial.println("AltSoftSerial started at 9600");
}

void init_Input() {
  pinMode(SWITCH1_PIN, INPUT);
  digitalWrite (SWITCH1_PIN, HIGH);
  Switch1_debounce.attach (SWITCH1_PIN);
  Switch1_debounce.interval (5);
}

void init_Output()
{
  pinMode(LED1_PIN, OUTPUT);
  digitalWrite(LED1_PIN, LOW);
}

void checkSwitch() {
  Switch1_debounce.update();
  if ( Switch1_debounce.fell() ) {
    LED1_State = !LED1_State;
    timePrevious = millis();
  }
}

void recvWithStartEndMarkers()
{
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  if (BTserial.available() > 0) {
    rc = BTserial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx > maxDataLength) {
          ndx = maxDataLength;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }
    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void processCommand() {
  Serial.print("receivedChars = ");
  Serial.println(receivedChars);
  if (strcmp ("L10", receivedChars) == 0) {
    LED1_State = LOW;
    Serial.println("LED1 LOW");
  }
  else if (strcmp ("L11", receivedChars) == 0) {
    LED1_State = HIGH;
    Serial.println("LED1 HIGH");
    timePrevious = millis();
  }
  receivedChars[0] = '\0';
  newData = false;
}

void update_led() {
  if ( LED1_State) {
    if ( millis() - timePrevious >= off_time )
    {
      LED1_State = false;
      BTserial.print("<L,1,1>");
      Serial.println("Sent - <L,1,1>");
    }
  }
  if ( !LED1_State && LED1_State_Previous) {
    BTserial.print("<L,1,0>");
    Serial.println("Sent - <L,1,0>");
  }
  digitalWrite(LED1_PIN, LED1_State);
  LED1_State_Previous = LED1_State;
}

Put a green LED on 3. Put a red LED on 4; Put buttons on 5,6,7 (I just add a jumper and touch the end to ground)

Touching 5 to ground lights green for 5 seconds. Touching 6 to ground lights red for 5 seconds. Touching 7 to ground lights red for 1 second.

class LedPoiker {
    const byte pin;
    boolean poiked;
    uint32_t poikStartMs;
    uint32_t poikTimeMs;

  public:
    LedPoiker(byte pin) : pin(pin) {}
    void setup() {
      pinMode(pin, OUTPUT);
    }
    void loop() {
      if (poiked && millis() - poikStartMs >= poikTimeMs) {
        digitalWrite(pin, LOW);
        poiked = false;
      }
    }
    void poik(uint32_t poikTimeMs) {
      digitalWrite(pin, HIGH);
      this->poikTimeMs = poikTimeMs;
      poikStartMs = millis();
      poiked = true;
    }
};


LedPoiker green(3), red(4);

void setup() {
  green.setup();
  red.setup();

  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
}


void loop() {
  green.loop();
  red.loop();

  if (digitalRead(5) == LOW) green.poik(5000);
  if (digitalRead(6) == LOW) red.poik(5000);
  if (digitalRead(7) == LOW) red.poik(1000);
}

Hello and thanks for your help guys! Ashraf you are wright i didn’t refer it in the beginning(my mistake)!I uploaded it to the arduino it works fine ether from the natural push button or from the push buttons from the app!
there is only one thing that seems to have problem.As you can see to the video that i uploaded,when i push the natural push button(on) it seems that the app does not take the feedback(also not color change) and when i push the button from the app in order to turn it off without waiting the time it does not turn it off.So when i push again the button of app then it turns off!This happen only when i turn on the led form the phisical button and then
when i push the button from the app in order to turn it off!

It is evident that you are very good with arduino coding.I would like a last favour buddy!How can i put your sketch into the code that i added and it has 3 leds and 3 push buttons!the delay will be only for 1 push button and led!The other 2 push button and led will act without delay because i will connect lights!
I thought that i could incorporate your code inside to the code with the other push buttons and led but i find difficulties.I rely on you buddy!!!

here is the video and how it works:

Also i included the code with 3 push button and led(I will understand if you don’t want to do it,you really helped me a lot and thank you)!All this happen because i want to put a delay only in one of the 3 button and led!The first button will be for electric shouters and the other 2 for lights!

TWO_WAY_LED_CONTROL_3_LEDS.ino (8.52 KB)