Need replacement for delay() in a loop (millis() ? )

The delay() slow down or looks like freeze everything until the timer is done, what is not really what i need. Most code samples with millis() didnt work because the timer started after booting right away. should be after : if (val2 < 12.40) { = true the timer starts
and the timer should be set to 0 again after the time is finished.and check the voltage again if its higher or lower again

if (val2 < 12.40) {
    delay(100000);
  } else if (val2 < 12.40) {
    digitalWrite(13, HIGH);  // K1 = OFF = Lipo wird abgeschaltet
    lcd1.setCursor(0, 3);
    lcd1.print("K1=");
    lcd1.setCursor(3, 3);
    lcd1.write(byte(1));  // UNHAPPY
  }

Can you explain your problem, please?

my display stops changing values until the delay time is done

Don't use delay, or anything that resembles it. Then the loop function can respond very quickly, to do whatever is needed when something changes.

See this excellent tutorial: https://www.baldengineer.com/blink-without-delay-explained.html

1 Like

you have twice the same test... so if it's not true the first time, it won't be true in the else... :man_shrugging:

1 Like

The second if is never true while the first if is true.

J-M-L was a little faster.

1 Like

the reason is a voltage drop by higher load of the inverter. after a few seconds the voltage goes back

i tryed this sample code already. but it didnt work for my reason. Start of the timer should be after voltage is below 12.40. Not in the main loop

Then you made a mistake. Post that code, and explain what you expected to happen, and what happened instead.

Not sure what you mean but that does not make the if-else more appropriate the way you coded it...

Maybe you can correct my code :slightly_smiling_face:
If the voltage drops below 12.40 the timer must start.
and when the time is finished i must check the voltage again. because of the voltage drop the voltage goes higher than 12.40. and if the voltage is permanent below 12.40 K3 is activ

Maybe you can show us your code.

#include <WiFi.h>
WiFiClient client;
#include <Wire.h>
//------------------------------------------
#include <SDL_Arduino_INA3221.h>
SDL_Arduino_INA3221 ina3221;
//-----------------------------------------
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd1(0x27, 20, 4);
//LiquidCrystal_I2C lcd(0x25, 20, 4);
//------------------------------------------------------------------

//------------------------------------------------------------------
const char* ssid = "722027";
const char* password = "240833348";
const char* host = "tolentino-solarpanel.000webhostapp.com"; 
const char* url = "/index.php";
//-----------------------------------------------------------------------
// INA3221
float busvoltage1 = 0;
float val2 = 0;  // LEADACID

float busvoltage2 = 0;
float val5 = 0;  // LIPO
//-------------------------------------------------------------------------
int vin1 = 0;  //Procent % Lead Acid Battery //int
int vin2 = 0;  //Procent % Lipo Battery // int
//------------------------------------------------------------------------
// the three channels of the INA3221
#define LEADACID_BATTERY_CHANNEL 1  // Leadacid Battery
#define LIPO_BATTERY_CHANNEL 2      // Lipo4 Battery
//------------------------------------------
#define ONBOARD_LED 2
//------------------------------
const int buttonPin23 = 23;  //       Manually Lipo4 zu  Lead Acid aktivieren K1
const int buttonPin18 = 18;  //       not used
int RelayControl33 = 33;     //       LED RED - Buzzer
const int buttonPin19 = 19;  //       Manual Arduino RESET
const int buttonPin16 = 16;  //       not used
const int buttonPin12 = 12;  //       not used
int RelayControl13 = 13;     // K1    Lipo4 to Leadacid ON/OFF
int RelayControl27 = 27;     // K2    not used
int RelayControl25 = 25;     // K3    Fridge ON/OFF 230V normal Power
int RelayControl26 = 26;     // K4    Fridge ON/OFF Inverter
//--------------------------------------------------------------------------------------------
//                                    Reset Function Arduino by AH by 998
void (*resetFunc)(void) = 0;  //      declare reset fuction at address 0
//---------------------------------------------------------------------------------------------
//                                            SMILY
byte a[8] = {  //SMILE
  B00000,
  B00000,
  B01010,
  B00000,
  B10001,
  B01110,
  B00000,
  B00000
};

byte b[8] = {  //unhappy
  B00000,
  B01010,
  B00000,
  B00000,
  B01110,
  B10001,
  B00000,
  B00000
};
byte c[8] = {  // !
  B00000,
  B00100,
  B00100,
  B00100,
  B00100,
  B00100,
  B00000,
  B00100
};

//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
// Functions



//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//---------------------------------------------------------------------------------------------
void connectWiFi() {
  WiFi.begin(ssid, password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    counter++;
    if (counter >= 20) {
      lcd1.setCursor(0, 2);
      lcd1.print("                ");
      lcd1.setCursor(0, 2);
      lcd1.print("Wifi Restart");
      delay(10000);
      ESP.restart();
      counter = 0;
    }
  }
}
//------------------------------------------------------------------------------------------------

//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF


//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void setup() {

  Serial.begin(9600);
  Wire.begin();
  connectWiFi();
  //-------------------------------------------------
  lcd1.init();
  lcd1.init();  // Start lcd1 Display(Top one)
  lcd1.backlight();
  //-----------------------------------
  lcd1.createChar(0, a);  // SMILY
  lcd1.createChar(1, b);  // UNHAPPY
  lcd1.createChar(2, c);  // !!!!!!!
  delay(500);             //100
  //------------------------------------
  ina3221.begin();
  //------------------------------------
  
  //------------------------------------
  // Set Relays status in lcd after reboot
  lcd1.setCursor(0, 3);
  lcd1.print("K1=");
  //-------------------------------------
  lcd1.setCursor(5, 3);
  lcd1.print("K2=");
  lcd1.setCursor(8, 3);
  lcd1.write(byte(0));  // SMILE
  //------------------------------------
  lcd1.setCursor(10, 3);
  lcd1.print("K3=");
  lcd1.setCursor(13, 3);
  lcd1.print("G");  // INVERTER OFF
  //------------------------------------
  lcd1.setCursor(15, 3);
  lcd1.print("K4=");
  lcd1.setCursor(18, 3);
  lcd1.print("X");  // GRID OFF
  //-----------------------------------

  pinMode(ONBOARD_LED, OUTPUT);  //ESP32 LED"
  //-----------------------------------------------------------------------------------------
  //      Switches
  pinMode(buttonPin12, INPUT_PULLUP);  //   not used
  pinMode(buttonPin16, INPUT_PULLUP);  //   not used
  pinMode(buttonPin23, INPUT_PULLUP);  //   Manually Lipo4 zu Lead acid aktivieren
  pinMode(buttonPin18, INPUT_PULLUP);  //   not used
  pinMode(buttonPin19, INPUT_PULLUP);  //   Manual Arduino RESET
  //------------------------------------------------------------------------------------------
  //      Smily K1 to K4 as output definiert
  pinMode(26, OUTPUT);  // K4 Fridge ON/OFF Inverter
  pinMode(25, OUTPUT);  // K3 Fridge ON/OFF 230V normal Power
  pinMode(27, OUTPUT);  // K2 not used
  pinMode(13, OUTPUT);  // K1 Lipo4 to Leadacid ON/OFF
  pinMode(32, OUTPUT);  // Alarm LED to pin 32
  //----------------------------------------------
  //By start all relays OFF
  digitalWrite(26, HIGH);  // K4(LED off) by start Arduino - NOT USED
  digitalWrite(25, HIGH);  // K3(LED on) by start Arduino - Fridge ON/OFF INVERTER (I)                    ?????????????????????
  digitalWrite(27, HIGH);  // K2(LED off) by start Arduino - K2 Inverter on/OFF ATS2
  digitalWrite(13, HIGH);  // K1(LED off) by start Arduino - K1 Lipo4 to Leadacid ON/OFF
  //------------------------------------------------------------------------------------------
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void loop() {
  //-------------------------------------------------------------------------------------------
  if (WiFi.status() != WL_CONNECTED) {
    lcd1.setCursor(0, 2);
    lcd1.print("                ");
    lcd1.setCursor(0, 2);
    lcd1.print("WiFi lost......");
    connectWiFi();
  }
  if (WiFi.status() == WL_CONNECTED) {
    lcd1.setCursor(0, 2);
    lcd1.print("                ");
    lcd1.setCursor(0, 2);
    lcd1.print(WiFi.localIP());
  }
  //-------------------------------------------------------------------------------------------
  delay(500);
  digitalWrite(ONBOARD_LED, HIGH);
  delay(500);
  digitalWrite(ONBOARD_LED, LOW);
  //-----------------------------------------------------------------------------------------
  // INA3221
  busvoltage1 = ina3221.getBusVoltage_V(LEADACID_BATTERY_CHANNEL);
  val2 = busvoltage1;

  busvoltage2 = ina3221.getBusVoltage_V(LIPO_BATTERY_CHANNEL);
  val5 = busvoltage2;
  //----------------------------------------------------------------------------------------
  //   TELEMETRY DATA LOGGER

  float lead_acid = val2;
  float lipo4 = val5;

  char lead_acid_text[30];
  char lipo4_text[30];
  char solar1_text[30];
  char solar2_text[30];

  dtostrf(lead_acid, 10, 10, lead_acid_text);
  dtostrf(lipo4, 10, 10, lipo4_text);

  char text[125];
  snprintf(text, 125, "%s,%s", lead_acid_text, lipo4_text);
  Serial.println(text);
  //---------------------------------------------------------
  //  Leadacid Battery %
  vin1 = 100 * (val2 - 11.50) / (12.70 - 11.50);
  if (val2 > 12.70) {
    vin1 = 100;
  }
  //-----------------------------------------------------------------------
  // Lipo4 - Battery %

  if (val5 >= 14.6) {
    vin2 = 100;
  } else if (val5 >= 13.6) {
    vin2 = 99;
  } else if (val5 >= 13.4) {
    vin2 = 90;
  } else if (val5 >= 13.3) {
    vin2 = 70;
  } else if (val5 >= 13.2) {
    vin2 = 50;
  } else if (val5 >= 13.1) {
    vin2 = 40;
  } else if (val5 >= 13.0) {
    vin2 = 30;
  } else if (val5 >= 12.9) {
    vin2 = 20;
  } else if (val5 >= 12.8) {
    vin2 = 17;
  } else if (val5 >= 12.5) {
    vin2 = 14;
  } else if (val5 >= 12.0) {
    vin2 = 9;
  } else if (val5 >= 10.0) {
    vin2 = 0;
  }
  //------------------------------------------------------------------------------------------

  lcd1.setCursor(0, 1);
  lcd1.print("Lipo4  :");
  lcd1.setCursor(8, 1);  // Lipo4 Volt
  lcd1.print(val5);
  lcd1.setCursor(16, 1);
  lcd1.print(vin2);
  lcd1.print("% ");

  //--------------------------------------------------
  //         Lead Acid Battery Voltage + Charge status
  lcd1.setCursor(0, 0);
  lcd1.print("Battery:");
  lcd1.print(val2);
  lcd1.setCursor(16, 0);
  lcd1.print(vin1);
  lcd1.print("%");
  //--------------------------------------------------------------------------------------------
  //        Manual Arduino RESET
  if (digitalRead(buttonPin19) == LOW) {  //
    resetFunc();                          //call reset
  }
  //-------------------------------------------------------------------------------------------
  // Fridge (INVERTER) On K3 (LED ON) Relay 1 NO
  if (val2 > 12.80 && val2 < 14.60) {
    digitalWrite(25, HIGH);  // Fridge ON INVERTER (K3 = ON) (ATS Fridge)
    lcd1.setCursor(10, 3);
    lcd1.print("K3=");
    lcd1.setCursor(13, 3);
    lcd1.print("I");                          // Inverter ON
  } 
  if (val2 > 12.50 && val2 < 12.80) {  // NUR ANZEIGE !!
    lcd1.setCursor(10, 3);
    lcd1.print("K3=");
    lcd1.setCursor(13, 3);
    lcd1.print("I");  // Inverter ON
  }
  if (val2 > 0.00 && val2 < 12.50) {
    delay(100000);
  } else if (val2 > 0.00 && val2 < 12.50) {  //9% (becauseof voltage drop.Its still 14%)
    digitalWrite(25, LOW);            // Fridge ON GRID (K3 = OFF) (ATS)
    lcd1.setCursor(10, 3);
    lcd1.print("K3=");
    lcd1.setCursor(13, 3);
    lcd1.print("G");  // INVERTER OFF
  }

  //---------------------------------------------------------------------------------------------------------------------------------------------------------
  //            K2 Actually Cut off Inverter to activate ADS to switch to Grid
  if (val2 > 12.80 && val2 < 14.60) {
    digitalWrite(27, HIGH);  //  K2 = OFF - Inverter ON
    lcd1.setCursor(5, 3);
    lcd1.print("K2=");
    lcd1.setCursor(8, 3);
    lcd1.write(byte(0));  // SMILE
  }
  if (val2 < 11.80) {
    delay(100000);
  } else if (val2 < 11.80) {
    digitalWrite(27, LOW);  //  K2 = ON - Inverter OFF
    lcd1.setCursor(5, 3);
    lcd1.print("K2=");
    lcd1.setCursor(8, 3);
    lcd1.write(byte(0));  // SMILE
  }
  //---------------------------------------------------------------------------------------------------------------------------------------------------------
  //      K1 ON Lipo4 Battery (LED ON)
  if (val2 > 12.70 && val2 < 14.60) {
    digitalWrite(13, LOW);  // K1 = ON = Lipo wird eingeschaltet
    lcd1.setCursor(0, 3);
    lcd1.print("K1=");
    lcd1.setCursor(3, 3);
    lcd1.write(byte(0));                      // HAPPY
  } 
  if (val2 > 12.40 && val2 < 12.70) {  // NUR ANZEIGE !!
    lcd1.setCursor(0, 3);
    lcd1.print("K1=");
    lcd1.setCursor(3, 3);
    lcd1.write(byte(0));  // HAPPY
  }
  if (val2 < 12.40) {
    delay(100000);
  } else if (val2 < 12.40) {
    digitalWrite(13, HIGH);  // K1 = OFF = Lipo wird abgeschaltet
    lcd1.setCursor(0, 3);
    lcd1.print("K1=");
    lcd1.setCursor(3, 3);
    lcd1.write(byte(1));  // UNHAPPY
  }
  //---------------------------------------------------------------------------------------------------------------------------------------------------------
}  // Program END

If not the lcd print, than what needs to be delayed?
That something should start when your timer is due. You should start the timer at the point where the delay is now.
So, in loop:

if (voltage<12.4){
    Start timer;
}
if (timer overdue) {
     if (voltage<12.4) {
         activate k3;
         while (true) {
             ; // wait forever
         }
     }
     Reset timer; //?
}

You have a pretty unhandy/confusing/unnecessary complicated way of naming variables...

Thats my new version. But seems only 1 time working after restart. Seems the timer has to be reset somehow

if (val2 > 0.00 && val2 < 12.50) {
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      if (val2 > 0.00 && val2 < 12.50) {  //9% (becauseof voltage drop.Its still 14%)
        digitalWrite(25, LOW);            // Fridge ON GRID (K3 = OFF) (ATS)
        lcd1.setCursor(10, 3);
        lcd1.print("K3=");
        lcd1.setCursor(13, 3);
        lcd1.print("G");  // INVERTER OFF
      }
    }
  }

What event should trigger the reset?
In the while forever loop you can add

if (sometrigger) {
    break;
}

You have to understand one basic thing about non-blocking timing based on function millis()

All timing is done based on calculating a time-difference

instead of resetting a timer you simply store the momentary actual value of milliseconds in a variable
TimeStampAtStart

and then calculate actual millis() minus TimeStampAtStart
millis() - TimeStampAtStart

Which will give the time in milliseconds that have passed by since "TimeStampAtStart" happened

example-numbers
actual milliseconds 10002: you execute TimeStampAtStart = millis();
so variable TimeStampAtStart holds value 10002
actual milliseconds 10003: millis() - TimeStampAtStart = 1
actual milliseconds 10004: millis() - TimeStampAtStart = 2
actual milliseconds 10005: millis() - TimeStampAtStart = 3
actual milliseconds 10006: millis() - TimeStampAtStart = 4
....
......
actual milliseconds 22402: millis() - TimeStampAtStart = 12400 milliseconds = 12,4 seconds

best regards Stefan

This posting has two substantial flaws

  1. it is just a code-snippet intead of the complete sketch
  2. you did not post a normal worded description of the wanted functionality

You might have misconceptions about how the code works
These eventual misconception stays hidden without the normal worded description of what functional behaviour you want to have

best regards Stefan

1 Like

And again, if the first if is true, the second if is also true, so no need to check...

1 Like

There is a short voltage drop on the battery voltage if for example a load with 30 ampere starts