Handling delays within a loop

Hi, very much a novice but learning. I'm using a DHT22 sensor to monitor the internal greenhouse temperature, for controlling the opening and closing of the door. The sensor needs a 2sec sampling window which is built into my program code as standard practice. My problem is when the door opens and closes the 2 sec delay interferes with the door stop limit switches. What is the best way of taking out the delay command from the loop while the door opens and closes. Any ideas would be appreciated with help examples of code please. Kind regards Jevray

Hello Jevray,
If you want specific advice about your code you need to post your code, we are not telepathic!

General guidance and
How to use this forum

If you want general advice on non-blocking code read:
Using millis for timing
Demonstration for several things at the same time

Thank you.

The code below is how I read my DHT11 ala blink without delay. It's the code from the DHT11 example, stuck in a function, and called via a millis()-based timer.

(Note it's DHT11 not 22, but the idea's exactly what you want....)

// based on....
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
// ... but tidier

#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4

unsigned long lastDHT;
int dhtReadInterval = 10000;

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}//setup

void loop()
{
  if (millis() - lastDHT >= (unsigned long) dhtReadInterval) //check if time has elapsed
  {
    lastDHT = millis();  //save for next time
    doDHTstuff();
  }
}//loop

void doDHTstuff()
{
  int chk;
  Serial.print("DHT11, \t");
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk) {
    case DHTLIB_OK:
      Serial.print("OK,\t");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.print("Checksum error,\t");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.print("Time out error,\t");
      break;
    default:
      Serial.print("Unknown error,\t");
      break;
  }
  // DISPLAT DATA
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t");
  Serial.println(DHT.temperature, 1);
}//dht stuff

In addition to what the others have said, is it possible to know when the door is moving and suspend readings from the DHT22 while it is in progress?

...R

Robin2:
In addition to what the others have said, is it possible to know when the door is moving and suspend readings from the DHT22 while it is in progress?

...R

This exactly what I need to do. As the temperature increases beyond a set point the door opens as it activates the limit switch to shut off the door motor any active delay creates a problem with stopping the motor, same situation for when it closes.

Here is my code:-

// software GH_030420_master.INO
// Program written by M. Deeley 03/04/20
// Greenhouse control system using fan ventilation.
// electronic door motor control
// Arduino nano
#define DHTPIN 4 // pin 4 sensor is connected to
#include <DHT.h>
#define DHTTYPE DHT22 // DHT 22 (AM2302)

// motor (1) door control motor = in1,in2,enA

int outPin = 13; // external door hold open led
int in1 = 9; // door control input
int in2 = 10; // " " "
int enApin = 11; // " " "
int vent = 8; // window vent fan
int fan = 12; // humidity fan
int buttonLpin = 6; // left side door switch
int buttonRpin = 5; // right hand door switch
int val = 0;
int ledPin = 7; // door hold open indicator led

// *******************MANUAL DOOR LOCK OPEN *****************
const uint32_t debounceTime = 10; // switches debounce time
const uint8_t switchPin = 2; // switched to ground to activate
const bool switchOn = false; // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState = switchOff;
bool toggleState = false;
volatile int buttonState = 0;
// ======================== user max/min temperature settings
int maxTemp2 = 29; // max set at 29 for door
int minTemp2 = 25; // min set at 25 " "
int maxTemp = 22; // max set at 18 for vent
int minTemp = 20; // min set at 15 for vent
int maxHum = 60; // humidity setting max
int minHum = 55; // humidity setting min
DHT dht(DHTPIN, DHTTYPE);

void setup() {
pinMode (ledPin, OUTPUT); // door locked open signal
pinMode (vent, OUTPUT); // ventfan
pinMode (enApin, OUTPUT); // motor conrol module enable
pinMode (in1, OUTPUT); // motor control
pinMode (in2, OUTPUT); // motor control
pinMode (fan, OUTPUT); // humidity fan
pinMode (buttonLpin, INPUT_PULLUP); // left door switch
pinMode (buttonRpin, INPUT_PULLUP); // right door switch
pinMode (switchPin, INPUT_PULLUP); // toggle switch internal + external
Serial.begin(9600);
dht.begin();
}
//==========================================================================
void loop() {
delay(2000); // Wait a few seconds between measurements.
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// *********************** Door manual_open/close *******
{ buttonState = digitalRead (switchPin);
if (buttonState == LOW ) {
digitalWrite(ledPin, HIGH); // internal led(warning door held open
digitalWrite(outPin, HIGH); // external led ( warning door held open
digitalWrite(vent, LOW); // turn vent fan off
digitalWrite(enApin, HIGH); // door motor control logic
val = digitalRead(buttonLpin); // read the Left door limit switch
digitalWrite(enApin, val); // door motor module control pin 9
delay( debounceTime );
digitalWrite(in1, LOW); // door motor >>>> OPEN pin 12
digitalWrite(in2, HIGH); // " " " " pin 11
}
else {
digitalWrite(ledPin, LOW); //cancel hold open door switch command
digitalWrite(outPin, LOW);
// ================================= VENT CHECK =======================
if (t > maxTemp) {
digitalWrite(vent, HIGH);
} else if (t < minTemp) { // if(h < minHum || t < minTemp) {
digitalWrite(vent, LOW);
// ======================== DOOR CONTROL LOGIC... OPENING FOR HIGH TEMPERATURE (Temp2)
}
if (t > maxTemp2) {
val = digitalRead(buttonLpin); // read the input pin
digitalWrite(enApin, val); // was in1 for grounded limit sw or 2 if using pull up
delay( debounceTime );
digitalWrite(in1, LOW); // door motor >>>> OPEN pin 12
digitalWrite(in2, HIGH); // " " " " pin 11

// ======================= DOOR CONTROL LOGIC / for temp2 = LOW TEMPERATURE DOOR CLOSING
} else if (t < minTemp2) {
val = digitalRead(buttonRpin); // read the input pin
digitalWrite(enApin, val); // sets the output to in1 (if pull up)(in2 for input grounded via sw)
delay( debounceTime );
digitalWrite(in1, HIGH); // door motor >>>> CLOSE pin 12
digitalWrite(in2, LOW); // " " " " pin 11

} //=================== checking humidity sensors to control fan if high fan on
if (h > maxHum) {
digitalWrite(fan, HIGH);
} else if (h < minHum) {
digitalWrite(fan, LOW);
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
}
}
}

See reply #1 for how to use this forum.
Specifically, how about posting your code in code tags?

delay(2000);                   // Wait a few seconds between measurements.

See reply #1, fix that, follow the instructions in the various tutorials and post your code properly as well.

When someone is given advice and clearly doesn't bother to follow it then it puts people off helping any more.

Jevray:
As the temperature increases beyond a set point the door opens as it activates the limit switch to shut off the door motor any active delay creates a problem with stopping the motor, same situation for when it closes.

if your Arduino is causing the door to open then it should be straightforward to stop checking the temperature until the door has finished moving.

Plus what is in Reply #7

...R

Thank you for your reply. Sorry I thought I had used the code brackets! May I just mention here that I posed a question regarding delays within a loop, and gave a brief description regarding the DHT22 delay period between measurements, and is there a method how the delay period could be eliminated from the main program loop. I expected an answer that may be on the lines of, Try this way, or have you tried, etc.
I was not encouraged by your rather abrupt answer! At seventy-four years of age I don't have the benefit of good health. It takes me over an hour just to write a few lines. Also, when I post a reply here i have to post a reply within five minutes or my post is suspended?

In answer to your question, here is my code correctly presented. Kind Regards

// software GH_030420_master.INO
// Program written by M. Deeley   03/04/20
// Greenhouse control system using fan ventilation.
// electronic door motor control
// Arduino nano
#define DHTPIN 4         // pin 4 sensor is connected to
#include <DHT.h>
#define DHTTYPE DHT22   // DHT 22  (AM2302)

// motor (1) door control motor = in1,in2,enA

int outPin = 13;          // external door hold open led
int in1 = 9;              // door control input
int in2 = 10;             //  "     "       "
int enApin = 11;          //  "     "       "
int vent = 8;             // window vent fan
int fan = 12;             // humidity fan
int buttonLpin = 6;       // left side door switch
int buttonRpin = 5;       // right hand door switch
int val = 0;
int ledPin = 7;           // door hold open indicator led

// *******************MANUAL DOOR LOCK OPEN *****************
const uint32_t debounceTime = 10;  // switches debounce time
const uint8_t switchPin     = 2;   //  switched to ground to activate
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState   = switchOff;
bool newState    = switchOff;
bool toggleState = false;
volatile int buttonState = 0;
// ======================== user max/min temperature settings
int maxTemp2 = 29;     // max set at 29  for door
int minTemp2 = 25;     // min set at 25   "    "
int maxTemp = 22;      // max set at 18  for vent
int minTemp = 20;      // min set at 15  for vent 
int maxHum  = 60;      // humidity setting max
int minHum  = 55;      // humidity setting min
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode (ledPin, OUTPUT);  // door locked open signal
  pinMode (vent, OUTPUT);   // ventfan
  pinMode (enApin, OUTPUT);  // motor conrol module enable
  pinMode (in1, OUTPUT);     // motor control
  pinMode (in2, OUTPUT);     // motor control
  pinMode (fan, OUTPUT);     // humidity fan
  pinMode (buttonLpin, INPUT_PULLUP);     // left door switch
  pinMode (buttonRpin, INPUT_PULLUP);     // right door switch
  pinMode (switchPin, INPUT_PULLUP);      // toggle switch internal + external 
  Serial.begin(9600);
  dht.begin();
}
//==========================================================================
void loop() {
  delay(2000);                   // Wait a few seconds between measurements.
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // *********************** Door manual_open/close *******
  { buttonState = digitalRead (switchPin);
    if (buttonState == LOW ) {
      digitalWrite(ledPin, HIGH);       //  internal led(warning door held open
      digitalWrite(outPin, HIGH);       //  external led ( warning door held open 
      digitalWrite(vent, LOW);          // turn vent fan off
      digitalWrite(enApin, HIGH);       //  door motor control logic
      val = digitalRead(buttonLpin);    // read the Left door limit switch
      digitalWrite(enApin, val);        // door motor module control pin 9
      delay( debounceTime );
      digitalWrite(in1, LOW);        // door  motor  >>>> OPEN pin 12
      digitalWrite(in2, HIGH);       //  "      "     "     "  pin 11
    }
    else {
      digitalWrite(ledPin, LOW);     //cancel hold open door switch command
      digitalWrite(outPin, LOW);
      // ================================= VENT CHECK =======================
      if (t > maxTemp) {
        digitalWrite(vent, HIGH);
      } else if (t < minTemp) {       // if(h < minHum || t < minTemp) {
        digitalWrite(vent, LOW);
      // ======================== DOOR CONTROL LOGIC... OPENING FOR HIGH TEMPERATURE (Temp2)
      }
      if (t > maxTemp2) {
        val = digitalRead(buttonLpin);     // read the input pin
        digitalWrite(enApin, val);         // was in1 for grounded limit sw or 2 if using pull up
        delay( debounceTime );
        digitalWrite(in1, LOW);        // door  motor  >>>> OPEN   pin 12
        digitalWrite(in2, HIGH);        //  "      "     "     "  pin 11

        // ======================= DOOR CONTROL LOGIC / for temp2 = LOW TEMPERATURE DOOR CLOSING
      } else if (t < minTemp2) {
        val = digitalRead(buttonRpin);   // read the input pin
        digitalWrite(enApin, val);      // sets the output to in1 (if pull up)(in2 for input grounded via sw)
        delay( debounceTime );
        digitalWrite(in1, HIGH);       // door  motor  >>>> CLOSE  pin 12
        digitalWrite(in2, LOW);       //  "      "     "     "  pin 11

      }   //=================== checking humidity sensors to control fan if high fan on
      if (h > maxHum) {
        digitalWrite(fan, HIGH);
      } else if (h < minHum) {
        digitalWrite(fan, LOW);
      }
      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.println(" *C ");
    }
  }
}

Do you realize delay() stops code execution for the delay amount of time ?


Can you explain what this BWD code segment does ?
if(timerEnableFlag == true && millis() - startTime >= interval)
{
// do some stuff
}

larryd:
Do you realize delay() stops code execution for the delay amount of time ?


Can you explain what this BWD code segment does ?
if(timerEnableFlag == true && millis() - startTime >= interval)
{
// do some stuff
}

The delay of 2 sec period is for the DHT22 sensor temperature reads. My question is how can I avoid this delay within the main control loop of my existing code.Regards Jevray

Trying to help you but first, will you explain what is happening in the code segment below ?

if(timerEnableFlag == true && millis() - startTime >= interval)
{
// do some stuff
}

larryd:
Trying to help you but first, will you explain what is happening in the code segment below ?

if(timerEnableFlag == true && millis() - startTime >= interval)
{
// do some stuff
}

AS I see it, if timer is set, and delay period - start time, is greater or equal to interval (period) then do whatever?

Jevray:
I posed a question regarding delays within a loop, and gave a brief description regarding the DHT22 delay period between measurements,

That is not how you presented the problem in your Original Post. You said "The sensor needs a 2sec sampling window" which I took to mean that when you ask the sensor for a value it waits (internally) for 2 seconds before responding.

That is a very different issue from a decision made by you to cause measurements to be taken at 2-second intervals. If you want to take measurements at intervals without using the delay() function you can do it like this

if (millis() - lastMeasurementTime >= 2000) {
   lastMeasurementTime = millis();
   // code to take a measurement
}

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

I was not encouraged by your rather abrupt answer!

Well, I'm sorry if you found my answer abrupt but when advice is given and obviously ignored it is frustrating.

Anyway, you have had some good advice from others while I've been watching telly, I have nothing useful to add at this point. Good luck with your project.

PerryBebbington:
Well, I'm sorry if you found my answer abrupt but when advice is given and obviously ignored it is frustrating.

Anyway, you have had some good advice from others while I've been watching telly, I have nothing useful to add at this point. Good luck with your project.

Thank you I have not ignored your advice, I'm grateful for any advice that is helpful, for reasons I've explained I have difficulties in responding. Kind Regards Jevray

This will not work but you can see from the code how things can be changed.

Try things out and report back with what needs changing.

//Version 1.00

// software GH_030420_master.INO
// Program written by M. Deeley   03/04/20
// Greenhouse control system using fan ventilation.
// electronic door motor control
// Arduino nano

#define DHTPIN 4          //pin 4 sensor is connected to

#include <DHT.h>

#define DHTTYPE DHT22    //DHT 22  (AM2302)

//****************************************************************************
const byte switchPin     = 2;     //  switched to ground to activate

//motor (1) door control motor = in1,in2,enA
const byte buttonRpin    = 5;       // right hand door switch
const byte buttonLpin    = 6;       // left side door switch
const byte ledPin        = 7;       // door hold open indicator led
int vent                 = 8;       // window vent fan
const byte in1           = 9;       // door control input
const byte in2           = 10;      //
const byte enApin        = 11;      //
const byte fan           = 12;      // humidity fan
const byte outPin        = 13;      // external door hold open led

int val = 0;

byte lastButtonState;
byte buttonState = 0;

bool motorFlag           = false;
bool processFlag         = false;

// ======================== user max/min temperature settings
int maxTemp2             = 29;     //max set at 29  for door
int minTemp2             = 25;     //min set at 25   "    "
int maxTemp              = 22;     //max set at 18  for vent
int minTemp              = 20;     //min set at 15  for vent
int maxHum               = 60;     //humidity setting max
int minHum               = 55;     //humidity setting min

unsigned long switchMillis;
unsigned long dhtMillis;
unsigned long currentMillis;
unsigned long startMillis;


DHT dht(DHTPIN, DHTTYPE);
float t;
float h;


//==========================================================================
void setup()
{
  pinMode (ledPin, OUTPUT);               // door locked open signal
  pinMode (vent, OUTPUT);                 // ventfan
  pinMode (enApin, OUTPUT);               // motor conrol module enable
  pinMode (in1, OUTPUT);                  // motor control
  pinMode (in2, OUTPUT);                  // motor control
  pinMode (fan, OUTPUT);                  // humidity fan
  pinMode (buttonLpin, INPUT_PULLUP);     // left door switch
  pinMode (buttonRpin, INPUT_PULLUP);     // right door switch
  pinMode (switchPin, INPUT_PULLUP);      // toggle switch internal + external
  Serial.begin(9600);
  dht.begin();
}
//==========================================================================
void loop()
{
  currentMillis = millis();

  //**************************
  checkSwitches();

  //**************************
  readDHT();

  if (processFlag == true)
  {
    processDHT();
  }

  //**************************
  if (motorFlag == true)
  {
    val = digitalRead(buttonLpin);    // read the Left door limit switch

    digitalWrite(enApin, val);        // door motor module control pin 9
    //delay( debounceTime );
    digitalWrite(in1, LOW);           // door  motor  >>>> OPEN pin 12
    digitalWrite(in2, HIGH);          //  "      "     "     "  pin 11

    motorFlag = false;
  }

} //END of loop()

//==========================================================================
void checkSwitches()
{
  //check every 50ms
  if (currentMillis - switchMillis < 50)
  {
    //it is not time yet
    return;
  }

  //restart the TIMER
  switchMillis = currentMillis;

  //*************************                    s w i t c h P i n
  buttonState = digitalRead (switchPin);

  //did the switch change state ?
  if ( lastButtonState == buttonState)
  {
    return;
  }

  //update to the this state
  lastButtonState = buttonState;

  // *********************** Door manual_open/close *******
  if (buttonState == LOW )
  {
    digitalWrite(ledPin, HIGH);       // internal led(warning door held open)
    digitalWrite(outPin, HIGH);       // external led ( warning door held open)
    digitalWrite(vent, LOW);          // turn vent fan off
    digitalWrite(enApin, HIGH);       // door motor control logic

    motorFlag = true;
  }

  else
  {
    digitalWrite(ledPin, LOW);       //cancel hold open door switch command
    digitalWrite(outPin, LOW);

    motorFlag = false;
  }

} //END of checkSwitches()

//==========================================================================
void readDHT()
{
  //time to read the DHT every 2000ms
  if (currentMillis - startMillis < 2000)
  {
    //it is not time yet
    return;
  }

  //restart the TIMER
  startMillis = currentMillis;

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  h = dht.readHumidity();

  // Read temperature as Celsius
  t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t))
  {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //we are ready to act on new reading
  processFlag = true;

} //END of readDHT()


//==========================================================================
void processDHT()
{
  processFlag = false;

  //*************************
  //VENT CHECK
  if (t > maxTemp)
  {
    digitalWrite(vent, HIGH);
  }

  else if (t < minTemp)           
  {
    digitalWrite(vent, LOW);
  }

  //*************************
  if (t > maxTemp2)
  {
    val = digitalRead(buttonLpin);     //read the input pin
    digitalWrite(enApin, val);         //was in1 for grounded limit sw or 2 if using pull up
    //delay( debounceTime );
    digitalWrite(in1, LOW);            //door  motor  >>>> OPEN   pin 12
    digitalWrite(in2, HIGH);           // "      "     "     "  pin 11
  }

  //*************************
  else if (t < minTemp2)
  {
    val = digitalRead(buttonRpin);     //read the input pin
    digitalWrite(enApin, val);         //sets the output to in1 (if pull up)(in2 for input grounded via sw)
    //delay( debounceTime );
    digitalWrite(in1, HIGH);           //door  motor  >>>> CLOSE  pin 12
    digitalWrite(in2, LOW);            // "      "     "     "  pin 11
  }

  //*************************
  //checking humidity sensors to control fan if high fan on
  if (h > maxHum)
  {
    digitalWrite(fan, HIGH);
  }

  else if (h < minHum)
  {
    digitalWrite(fan, LOW);
  }
  
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" *C ");

} //END of readDHT()

EDIT
Changed to:
//time to read the DHT every 2000ms
if (currentMillis - startMillis < 2000)

Edit
See attached .ino file for version 2.00

sketch_apr15b.ino (6.53 KB)

Jevray:
and gave a brief description regarding the DHT22 delay period between measurements, and is there a method how the delay period could be eliminated from the main program loop. I expected an answer that may be on the lines of, Try this way, or have you tried, etc.

In #2 I gave you an actual sketch to do that (ok, for a different dht sensor, but still...) and larryd was encouraging you to think along those lines in #10 and #12, as was Robin2 in #14.

Also, when I post a reply here i have to post a reply within five minutes or my post is suspended?

No, you have that backwards: you have to wait at least 5 minutes between your posts.

Robin2:
That is not how you presented the problem in your Original Post. You said "The sensor needs a 2sec sampling window" which I took to mean that when you ask the sensor for a value it waits (internally) for 2 seconds before responding.

That is a very different issue from a decision made by you to cause measurements to be taken at 2-second intervals. If you want to take measurements at intervals without using the delay() function you can do it like this

if (millis() - lastMeasurementTime >= 2000) {

lastMeasurementTime = millis();
  // code to take a measurement
}




Have a look at [Using millis() for timing. A beginners guide](http://forum.arduino.cc/index.php?topic=503368.0) if you need more explanation.


...R

Thank you for your help, I will go through your recommendations, and thanks to others who have posted. Hopefully I can overcome this problem soon. Thanks again to all and be safe. Kind Regards Jevray