Led without delay different timing

Hey guys,

i have little dilema now with timing LED without delay properly. I want do something like
if (value1>value2){let's turning on and off led (1 sec turn on, 3 sec turn off)} but when value2 become higher than value1 just turn off led.

I tried several things but when values change when LED is ON it stay ON and when is OFF it stay OFF. And i can't figure out something what turn OFF that led, when it stayed stucked ON.

I tried something like if((value2>value1)&&(LED==HIGH)){digitalwrite(pin,LOW);} but it seems not working. Maybe i just used it in bad part of code.

So i will be very pleased if you can provide me some solution.

Thank you very much

So i will be very pleased if you can provide me some solution.

I will be quite pleased if you post a complete program that illustrates the problem

The demo Several Things at a Time illustrates the use of millis() to manage timing. It may help with understanding the technique. It blinks a few LEDs

...R

(deleted)

Thank you guys, i exactly used several things at a time code. Here is code. I tried use that if inside updateLed_A_State() but i can’t figure that out. Thanks for your help and sorry that i didn’t posted whole code.

#include <DHT.h>

#define DHTPIN1 22 
#define DHTPIN2 23    

#define DHTTYPE DHT11

DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);

const int led_A_Pin = 39;
const int led_B_Pin = 38;
const int led_C_Pin = 37;
const int led_D_Pin = 36;
const int led_E_Pin = 40;

const int led_A_Interval = 2500;
         int led_B_Interval = 4500;
const int led_C_Interval = 3000;
const int led_D_Interval = 2000;
const int led_E_Interval = 1000;
const int blinkDuration = 5000; 

int pozad_vlh=60 ;

float vlh_vzd,tep_vzd,vlh_zem;

byte led_A_State = LOW;           //   LOW = off
byte led_B_State = LOW;
byte led_C_State = LOW;
byte led_D_State = LOW;
byte led_E_State = LOW;


unsigned long currentMillis = 0;
unsigned long previousLed_A_Millis = 0;
unsigned long previousLed_B_Millis = 0;
unsigned long previousLed_C_Millis = 0;
unsigned long previousLed_D_Millis = 0;
unsigned long previousLed_E_Millis = 0;

void setup()
{
  Serial.begin(115200);
  
    pinMode(led_A_Pin, OUTPUT);
    pinMode(led_B_Pin, OUTPUT);
    pinMode(led_C_Pin, OUTPUT);
    pinMode(led_D_Pin, OUTPUT);
    pinMode(led_E_Pin, OUTPUT);   

    dht1.begin();
    dht2.begin();
 
  
 
}

void loop() {

currentMillis = millis();  
switchLeds();



  vlh_vzd = dht1.readHumidity();
  tep_vzd = dht1.readTemperature();
  vlh_zem = dht2.readHumidity(); 
  Serial.println(vlh_zem);
                    
                         if (pozad_vlh >= vlh_zem)
                            {
                                updateLed_A_State();  
                              if((vlh_zem > pozad_vlh)&&(led_A_State == HIGH)){digitalWrite(39, LOW);}
                            }
                        // if(vlh_zem > pozad_vlh){digitalWrite(39, LOW);}
                      else {digitalWrite(39, LOW);}



}







void switchLeds() {
      // this is the code that actually switches the LEDs on and off

 
  digitalWrite(led_A_Pin, led_A_State);
  digitalWrite(led_B_Pin, led_B_State);
  digitalWrite(led_C_Pin, led_C_State);
  digitalWrite(led_D_Pin, led_D_State);
  digitalWrite(led_E_Pin, led_E_State);
}





void updateLed_A_State() {

  if (led_A_State == LOW) {
    if (currentMillis - previousLed_A_Millis >= led_A_Interval) {
       led_A_State = HIGH;
       previousLed_A_Millis += led_A_Interval;
      
    }
  }

  else {
    if (currentMillis - previousLed_A_Millis >= blinkDuration) {
       led_A_State = LOW;
       previousLed_A_Millis += blinkDuration;
       
    } 
  }    
}

To summarise your first post :

if value1 is greater than value2 blink the LED
if value2 is greater than value1 then turn on the LED

If that is what you want then set a boolean to true when value1 is greater than value2 and false when it is not

Blink the LED only when the boolean is true

Thank you again, i think i writed it bad. I meant if value2 is greater than value1 then turn OFF the LED. But i think solution will be similar.

I tried

if (pozad_vlh > vlh_zem){pumpa_bool=true;}
                             else {pumpa_bool=false;}
                         if(pumpa_bool == true){updateLed_A_State(); }
                             else {digitalWrite(38, LOW);}

and it still doing same thing.

I want to do: when LED is ON and in that moment values change(vlh_zem become higher than pozad_vlh), it must turn OFF led in the moment or just finish that counting inside function and jump out from function updateLed_A_State(). Because when values change when function updateLed_A_State() is running, it stay stucked ON or OFF depends on last state LED had.

I want to do: when LED is ON and in that moment values change(vlh_zem become higher than pozad_vlh), it must turn OFF led in the moment or just finish that counting inside function and jump out from function updateLed_A_State(). Because when values change when function updateLed_A_State() is running, it stay stucked ON or OFF depends on last state LED had.

Did you see my advice about using a boolean to flag the state of the system ?

Yes i saw, but i think i don't understand how you meant it. I did it like i writed in my last comment. But i think u meant use boolean inside function updateLed_A_State()?

This is the sort of thing that I had in mind

start of loop()
  currentTime = millis()
  if (value1 > value2)
  {
    blinking = true
    startTime = millis()
  }
  else
  {
    blinking = false
    turn off the LED
  }

  if (blinking)
  {
    if (currentTime - startTime  >= period
    {
      change the state of the LED
      startTime = millis()
    }
  }
end of loop()

NOTE : this is not real code but should give you some ideas. Before you ask, the LED would be on and off for the same time but that is easy to fix. Get this simple version working first.

I did it like this:

currentTime = millis();
  if (pozad_vlh > vlh_zem)
  {
    blinking = true;
    startTime = millis();

  }
  else
  {
    blinking = false;
   led_A_State = LOW;
  }

  if (blinking == true)
  { 
    
     if (currentTime - previousLed_A_Millis >= period)
    {
      if (led_A_State == LOW) {
      led_A_State = HIGH;
    } else {
      led_A_State = LOW;
    }
      previousLed_A_Millis = currentTime;
    }
  }

It's working like you said. Now i need do it in different times On,OFF like i wanted. I tried something like this :

currentTime = millis();
  if (pozad_vlh > vlh_zem)
  {
    blinking = true;
    startTime = millis();

  }
  else
  {
    blinking = false;
   led_A_State = LOW;
  }

  if (blinking == true)
  { 
    
    
    
    if (led_B_State == LOW) {
    if (currentTime - previousLed_A_Millis >= led_A_Interval) {
       led_A_State = HIGH;
       previousLed_A_Millis = currentTime;
    }
  }
  else {
    if (currentTime - previousLed_A_Millis >= blinkDuration) {
       led_A_State = LOW;
      previousLed_A_Millis = currentTime;
    }
  }
 }

but it only lights on and dont blink like it should.

Let's deal with the different on/off periods

Have a look at this example

const byte ledPin =  13;
unsigned long previousMillis = 0;
const byte states[] = {HIGH, LOW};
const unsigned long intervals[] = {200, 200, 200, 800};
const byte NO_OF_INTERVALS = sizeof(intervals) / sizeof(intervals[0]);
byte state;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervals[state % NO_OF_INTERVALS])
  {
    previousMillis = currentMillis;
    digitalWrite(ledPin, states[state++ % 2]);
  }
}

Try the example on its own first

Thank you very very much Bob. You helped me much. If i find some problem with timing like this i will write here.

Hello again,
i have found some issue inside code. I put variable instead number in const unsigned long intervals[] = {200, 200, 200, 800}; i offcourse change all constants to normal variables so it should change . I change one off numbers by variable which i changing with buttons. Click button1 add to this variable +1000 click button2 -1000. So i think it will change time how long is led OFF. But it still blink same frequency. Do you know why? I dont know if is needed a whole code with buttons. But only changing variabe +=1000 or -=1000 and that variable is inside like this unsigned long intervals1[] = {led_B_Interval, 1000};

Please post the code that you tried

#include <DHT.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include "DHT.h"
#include <DS3231.h>

#define DHTPIN1 22 
#define DHTPIN2 23    
#define DHTTYPE DHT11

DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
LiquidCrystal lcd(8,9,4,5,6,7); 

float vlh_vzd,tep_vzd,vlh_zem;

const int led_B_Pin = 38;
int led_B_Interval = 4000;
int keypad_pin = A0;
int keypad_value = 0;
int frek_hnoj;

char btn_push; 
byte mainMenuPage = 1;
byte mainMenuPageOld = 1;
byte mainMenuTotal = 4;
byte led_B_State = LOW;
boolean blinking1;

unsigned long intervals1[] = {led_B_Interval, 1000};
byte states1[] = {HIGH, LOW};
byte NO_OF_INTERVALS1 = sizeof(intervals1) / sizeof(intervals1[0]);
byte state1;


unsigned long currentMillis = 0;
const long interval2 = 500;
unsigned long previousMillis2 = 0;
unsigned long currentTime1 = 0;
unsigned long previousLed_B_Millis = 0;


void setup() {
  
    pinMode(led_B_Pin, OUTPUT);

    lcd.begin(16,2);  
    dht1.begin();
    dht2.begin();
    MainMenuBtn();
    ReadKeypad();
WaitBtnRelease();
}

void loop() {
  currentMillis = millis(); 

  MainMenuBtn();
  
  vlh_vzd = dht1.readHumidity();
  tep_vzd = dht1.readTemperature();
  vlh_zem = dht2.readHumidity(); 

updateLed_B_State();
switch (mainMenuPage) {
  
                        case 1:
                                  MenuB();      
                                  break;
                        case 2:
                                  //MenuA();
                                  break;
                        case 3:
                                  //MenuC(); 
                                  break;
       
                        case 4:
                                  //MenuD();
                                  break;
          
       
                                        }
}
void MenuB() {
 if (ReadKeypad()== 'S'){mainMenuPage +=1;}
      if (ReadKeypad()== 'R')
      {led_B_Interval += 1000 ;}
      else if (ReadKeypad()== 'L')
      {led_B_Interval -= 1000 ;}
      
    if (currentMillis - previousMillis2 >= interval2) {
        previousMillis2 = currentMillis;
       lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("FH:");                        
      frek_hnoj = led_B_Interval/1000;
      lcd.setCursor(4,0);      
      lcd.print(frek_hnoj);
      lcd.print(" h");
     
      }
}


void MainMenuBtn()
{
    WaitBtnRelease();
    if(btn_push == 'S')
    {
        mainMenuPage++;
        if(mainMenuPage > mainMenuTotal)
          mainMenuPage = 1;
    }
   
    if(mainMenuPage == 5) 
    {        
        mainMenuPage=1;
    }
}



char ReadKeypad()
{
  /* Keypad button analog Value
  no button pressed 1023
  select  741
  left    503
  down    326
  up      142
  right   0
  */
  keypad_value = analogRead(keypad_pin);
 
  if(keypad_value < 100)
    return 'R';
  else if(keypad_value < 200)
    return 'U';
  else if(keypad_value < 400)
    return 'D';
  else if(keypad_value < 600)
    return 'L';
  else if(keypad_value < 800)
    return 'S';
  else
    return 'N';
 
}
 
void WaitBtnRelease()
{
    while( analogRead(keypad_pin) < 800){}
} 
void updateLed_B_State() {
currentTime1 = millis();

  if (led_B_Interval > 0)
  {
    blinking1 = true;
  }
  else if(led_B_Interval == 0){blinking1 = false; digitalWrite(led_B_Pin, LOW);}
  else
  {
    blinking1 = false;
    digitalWrite(led_B_Pin, LOW);
  }

  if (blinking1 == true)
  { 
    
     if (currentTime1 - previousLed_B_Millis >= intervals1[state1 % NO_OF_INTERVALS1])
  {
    previousLed_B_Millis = currentTime1;
    digitalWrite(led_B_Pin, states1[state1++ % 2]);
  }         
    }   
}
int led_B_Interval = 4000;

Set the initial value of the interval. By the way, this should really be a long not an int

unsigned long intervals1[] = {led_B_Interval, 1000};

Populate the array with values

OK so far

 if (ReadKeypad() == 'R')
  {
    led_B_Interval += 1000 ;
  }
  else if (ReadKeypad() == 'L')
  {
    led_B_Interval -= 1000 ;
  }

Change the value of the variable holding the period value

   if (currentTime1 - previousLed_B_Millis >= intervals1[state1 % NO_OF_INTERVALS1])

Check whether the current interval has ended.

But you are checking the value in the array and after changing led_B_Interval above you did not put it into the array so the value there will not have changed.

Just because you declared the value in the array using a variable does not mean that changing the value of the variable will change the value in the array. You have to do that yourself.

Thank you, i just thought i can do it like i did. It's working now. I just changed led_B_Interval for intervals1[0].

Problem solved, now just make it whole smoothly because when i press button not everytime it recognize it. Sometimes i must press 3 or 4 times and sometimes only one time. I think it's caused of timing without delay. And when led is ON and i hold button it stay ON when i am holding it. Holding button is causing something like delay(). When i hold button nothing else is happening.

Thanks for tips

Please post your code as it is now