Replace delay with millis in loop

Hello,
my na me is Niko and i am from Greece.
I am an electronic engineer around automations.
Since some years ago there were simple ways of
achieving automated projects with no programming at all.
Using cmos ic's you could do almost everything.
Now more complicated projects are coming up.
So the need of microprossesors is vital.
I am not such of programming because i never learned.
I have made a project which controls climate condition
on a travel Bus only by searching and reading around this forum.
It has an LM35 which reads temperature and a pot which controls
set temperature.
As you may understand in this sketch there are many parts which
have to be on or off and with many delays because of high currents
switching all these outputs.
everything works fine except the delay of writing on lcd the set temp
when i turn the knob, and is from all delays.
I started reading about millis() but honestly i did not figure it out
how to replace all these delays.
If there is any suggestion please tell me...
Thanks in advance
Niko

p.s. sorry for my long writing

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int tempPin = 5;
int potPin = A0;
int lowTemp = 10;
int highTemp = 34;

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("IONIAN TRANSPORT");
  lcd.setCursor(0, 1);
  lcd.print("    ZAZ-1101   ");
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  

  delay(5000);
}
void loop() {
  int tempReading = analogRead(tempPin);
  float tempVolts = (tempReading * 500) / 1024.0;
  float temp = tempVolts;
  int potValue = analogRead(potPin);
  potValue = map(potValue, 0, 1023, lowTemp, highTemp);


  lcd.clear();
  lcd.print("Set:     Temp:");
  lcd.setCursor(5, 0);
  lcd.print(potValue);
  lcd.setCursor(14, 0);
  lcd.print(tempVolts, 0);
  
  //lcd.setCursor(0, 0);
  
  digitalWrite(8, HIGH);


  if (temp > potValue + 3) {
    digitalWrite(A1, LOW);
    digitalWrite(6, LOW);
    delay(500);
    digitalWrite(9, HIGH);
    delay(500);
    digitalWrite(10, HIGH);
  } else {
    delay(500);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(A2, LOW);
    delay(500);



  }
  if (temp > potValue + 5) {
    delay(500);
    digitalWrite(A2, HIGH);
  }
  else {
    digitalWrite(A2, LOW);
  }

  if (temp < potValue - 3) {
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(A2, LOW);
    delay(1500);
    digitalWrite(A1, HIGH);
    delay(500);
    digitalWrite(6, HIGH);
  }
  else {
    delay(500);
    digitalWrite(A1, LOW);
    digitalWrite(6, LOW);
  }
  if (temp < potValue - 5) {

    digitalWrite(7, HIGH);
  }
  else {

    digitalWrite(7, LOW);
  }


}

there was an extra delay after digitalWrite(8, HIGH); it was wrong
i deleted.

Have you looked at and played with the BlinkWithoutDelay example?

Hello Mark,
yes it took me a long around all
methods
as i said i dont know any about programming
but i can understand logic things easily..
as i read around every post has to do about
if time reaches ..do this or that..
i am not sure how this works...
i tried a lot of coding but no luck...

thanks for reply

the variable names in Blink without delay always confused me so I renamed them to make it easier to understand.

unsigned long starTime =0; // Use unsigned long when dealing with millis()
unsigned long interval = 1000 // 1000 millis = 1 second
void setup() {
 
}

void loop() {
 // do something you want to time then
 startime = millis();// start the timing code
 // do other stuff


unsigned long currenTime = millis();         
if (currenTime -starTime <= interval){   // if time is up
   // do stuff here
   starTime = 0; // reset the timing 
  }
}

You might want to look at using SwitchCase ( it is a type of state machine) it could make it easier to handle the timing code. Since your delays are all the same length and don't overlap it is possible to put the timing code into a function and call that function when needed.

Hutkikz, I have been looking are your code for a while, but I can't see that it will work. I spot 3 errors.

Nikoskir, to use millis() you have to rewrite the code.
The loop() should run without delay, and millis() is used to check if it is about time that something needs to be done.
If you have a certain sequence with delays, that sequence has to be split into seperate parts and the right part should be executed at the right time.
If you understand the BlinkWithoutDelay, have a look at this : Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Note to self: don't write and post code while drinking.
My apologies. :zipper_mouth_face:

I was just playing so im not sure if this will work but it should (untested but it does compile).

seems odd that you have a 1500 ms delay in there and one of you outputs doesn't have a 500ms delay when its turned off. The code takes account of the 1500ms delay but I added a 500ms delay when turning the output off. Simple fix if you have to have the delay

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int tempPin = 5;
int potPin = A0;
int lowTemp = 10;
int highTemp = 34;
byte heaterlag = 0;
unsigned long prevmillis = 0;
unsigned long prevmillis1 = 0;
unsigned long interval = 500;
byte prevheater = 0;
byte outputs[] = {9, 13, A1, 7, 10, 6,};

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("IONIAN TRANSPORT");
  lcd.setCursor(0, 1);
  lcd.print("    ZAZ-1101   ");
  pinMode(1, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(A1, OUTPUT);

  delay(5000);
}
void loop() {
  int tempReading = analogRead(tempPin);
  float tempVolts = (tempReading * 500) / 1024.0;
  float temp = tempVolts;
  int potValue = analogRead(potPin);
  potValue = map(potValue, 0, 1023, lowTemp, highTemp);
  unsigned long currentmillis = millis();

  lcd.clear();
  lcd.print("Set:     C");
  lcd.setCursor(6, 0);
  lcd.print(potValue);

  lcd.setCursor(0, 1);
  lcd.print("Temp:    C");
  lcd.setCursor(6, 1);
  lcd.print(tempVolts, 0);
  digitalWrite(8, HIGH);

  byte heater = 7;
  interval = 500;

  if (temp > potValue + 3) {
    heater = 0;
    interval = 500;
  }
  if (temp > potValue + 5) {
    heater = 1;
    interval = 500;
  }
  if (temp < potValue - 3) {
    heater = 2;
    interval = 1500;
  }
  if (temp < potValue - 5) {
    heater = 3;
    interval = 500;
  }

  if (heater != prevheater) {
    if ((currentmillis - prevmillis >= interval) && (heaterlag == 0)) {
      //outputs[] = {9, 13, A1, 7, 10, 6,};
      for (byte x = 0; x < 7; x = x + 1) {
        if (heater = x) {
          digitalWrite(outputs[x], HIGH);
        }
        else {
          digitalWrite(outputs[x], LOW);
        }
        if (heater == 0) {
          heaterlag = 1;
          prevmillis1 = currentmillis;
        }

        if (heater == 2) {
          heaterlag = 2;
          prevmillis1 = currentmillis;
        }

      }
      prevmillis = currentmillis;
    }
    prevheater = heater;
  }


  if (heaterlag != 0) {
    if (currentmillis - prevmillis1 >= 500) {
      switch (heaterlag) {
        case 0:
          break;
        case 1:
          digitalWrite(10, HIGH);
          heaterlag = 0;
          break;
        case 2:
          digitalWrite(6, HIGH);
          heaterlag = 0;
          break;
      }
      heaterlag = 0;
    }
  }
}

ops that's wrong

prevheater = heater;

should be one bracket up just after

prevmillis = currentmillis;

if not it will block itself and miss the state change.........I think

Example:

int myReading;

//**********************************************************************
void setup()
{
  Serial.begin(115200);  
  pinMode(12, OUTPUT);

} //  >>>>>>>>>>>>>> E N D  o f  s e t u p ( ) <<<<<<<<<<<<<<<<<

//**********************************************************************
void loop()
{
  myReading = analogRead(A0);
  Serial.println(myReading);
  
  if(myReading >= 700)
  {
    delay(500);  //1st delay
    digitalWrite(12, HIGH);
    delay(1000); //2nd delay
    digitalWrite(12, LOW);
    delay(2000); //3rd delay
    digitalWrite(12, HIGH);
    delay(3000); //4th delay
    digitalWrite(12, LOW);
  }

} //  >>>>>>>>>>>>>> E N D  o f  l o o p ( ) <<<<<<<<<<<<<<<<<
unsigned long myMillis;
unsigned long led13Millis;
unsigned long myDelay;
int  myReading;
byte mState = 0;

//**********************************************************************
void setup()
{
  Serial.begin(115200);  
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);

} //  >>>>>>>>>>>>>> E N D  o f  s e t u p ( ) <<<<<<<<<<<<<<<<<

//**********************************************************************
void loop()
{

  //***************************
  //some code to see if the sketch is blocking
  if(millis() - led13Millis >= 500)
  {
    digitalWrite(13, !digitalRead(13));
    led13Millis = led13Millis + 500;
  }
  //***************************

  myReading = analogRead(A0);
  Serial.println(myReading);

  if(mState == 0)
  {
    if(myReading >= 700)
    {
      mState = 1;
      myMillis = 500UL;
    }
  }


  //***************************
  switch (mState)
  {
    //**********
  case 0:
    {
    }
    break;

    //**********
  case 1:
    {
      if(millis() - myMillis >= myDelay) //1st delay
      {
        digitalWrite(12, HIGH);   
        mState = 2;
        myMillis = millis();
        myDelay = 1000UL;    
      }
    }
    break;

    //**********
  case 2:
    {
      if(millis() - myMillis >= myDelay) //2nd delay
      {
        digitalWrite(12, LOW);
        mState = 3;
        myMillis = millis();
        myDelay = 2000UL;    
      }      
    }
    break;

    //**********
  case 3:
    {
      if(millis() - myMillis >= myDelay) //3rd delay
      {
        digitalWrite(12, HIGH);
        mState = 4;
        myMillis = millis();
        myDelay = 3000UL;   
      }
    }

    break;

    //**********
  case 4:
    {
      if(millis() - myMillis >= myDelay) //4th delay
      {
        digitalWrite(12, LOW);
        mState = 0;
      }
    }
    break;    

    //**********
  default: 
    // default code goes here
    break;

  } // END of switch (mSate)

  // other non blocking stuff here


} //  >>>>>>>>>>>>>> E N D  o f  l o o p ( ) <<<<<<<<<<<<<<<<<

Hello all,
thanks for the replies.
Let me clarify some things first.
In a bus there a lot of ventilation systems
roof and bottom..radiators for cool and heat
stuck as sandwich..etc.
The delays are needed because of big current flaws
and also the quick exchange from heat to cold.
Dont miss a big rule here.
the driver who is going to use this system for me is a STUPID one.
So the system needs to be protected.
Also when desired temp is close to actual,the
ventilators are slowing down for there is no reason to quick
cool the bus.
Please give me time to study all your answers and i will
post the results..
Thank you all.