IRQ while processing Delay.

While delay takes place, is an IRQ buffered? that is, once it exits out of ‘delay(1000)’ for example , if at 555ms in, would if an interrupt triggered, get placed in a queue?

if not, I may need to drop Delay and switch to milli,and or leave in a small delay 50ms or so (i’m taking temperature measurements and I really don’t want to have a relay oscillating that quickly if I accidentally introduced a bug, so the delay is purely protection) (only needed a delay to so i can debug it via serial) …

Because it’s happy to wait 1.25 seconds per reading from the dallas sensor, i’m happy, the relay’s happy, speed is not important at all, I think 1 second is a little quick lol

#include <OneWire.h>
#include <stdlib.h>
#include <DallasTemperature.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//#include <Wire.h>
//#include <Adafruit_BMP085.h>
#define RelayPin 2
#define Rled 3
#define Gled 5
#define Bled 6

boolean Relay = false;
boolean RelayM = false;

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal_I2C lcd(0x27,16,2);
DallasTemperature sensors(&oneWire);


void setup(void)
{
  // start serial port
  pinMode(Rled,OUTPUT);
  pinMode(Gled,OUTPUT);
  pinMode(Bled,OUTPUT);
  pinMode(RelayPin,OUTPUT);  
  pinMode(8,INPUT);
  analogWrite(Rled,0);
  analogWrite(Gled,0);
  analogWrite(Bled,0);  

 for (int i=1; i<10; i++)   //3 pin RGB test
 { 
  analogWrite(Rled,225);
  delay(20);     
  analogWrite(Rled,0);  
  delay(20);     
  analogWrite(Gled,225);
  delay(20);     
  analogWrite(Gled,0);  
  delay(20);     
  analogWrite(Bled,225);
  delay(20);     
  analogWrite(Bled,0);  
  delay(20);       
 }
   
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  // Print a message to the LCD.
/*  for (int n=1; n<55;) 
   {
    n++;
    lcd.backlight();
    delay(100);
    lcd.noBacklight();  
    delay(100);  
   }*/   

  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

// if (!bmp.begin())
 //   Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  // Start up the library
  sensors.begin();
}



void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Dallas -  Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");

  lcd.setCursor(0,0);
  lcd.print("The Temperature:");  
  
  
  float T;
  char TStr[5];

// T= 21;
 // Serial.println(T);

  T = sensors.getTempCByIndex(0);  

  if (T<10)  //this is for a quick visual status 
   {
     //relay on, heater on.
     Serial.println("freezing cold");     
     analogWrite(Rled,0);
     analogWrite(Gled,0);     
     analogWrite(Bled,220);     
   }

   if ((T>=10) &(T<19))
    {
      Serial.println("cold");     
     analogWrite(Rled,0);
     analogWrite(Bled,225);
     analogWrite(Gled,225);
    }

   if ((T>=19) & (T<26))
    {
     Serial.println("warm");     
     analogWrite(Rled,0);
     analogWrite(Gled,225);
     analogWrite(Bled,0);     
    }
    
   if ((T>=26) & (T<40))
    {
      Serial.println("hot");     
     analogWrite(Rled,225);
     analogWrite(Gled,0);
     analogWrite(Bled,0);     
     }
     
     
  //pin 8 connects to a button to override and turn on the heater
  //ideally, I want to trigger this quicker, so a delay may have to go
   if (digitalRead(8)==HIGH) 
   {
      RelayM=!RelayM;
      digitalWrite(RelayPin,RelayM);
   }

   
   if (RelayM==true)  //button press detected (although holding down is required depends on luck)
    {
        if (T>=22.00)  //max temp to reach with override button
       {
         RelayM=false;
         digitalWrite(RelayPin,RelayM);      
        } //heater off
    }
    

  if (T>=20.00 & RelayM==false) //if override is off do normal operation
    {
      Relay=false; //turn off relay
      digitalWrite(RelayPin,Relay);      
    } //heater off
   else
  if (T<=18.00)
   {
     Relay=true;  //turn on relay as it's cold
     digitalWrite(RelayPin,Relay);
   }
  

    
  dtostrf(T,5, 3, &TStr[0]);
  TStr[5]=0;
  lcd.setCursor(0,1);
  Serial.println(TStr);
  lcd.print(TStr);
  lcd.println(" Degrees C ");  
  delay(1250);
  lcd.clear();  //i2c library LCD

//was hooked up to a Barometer/Temp sensor, not needed.

/*   Serial.println("");  
   Serial.println("Barometer / Temp info");
   Serial.println("");       
   Serial.print("Temperature = ");
   Serial.print(bmp.readTemperature());
   Serial.println(" *C");
   
   Serial.print("Pressure = ");
   float pr;
   pr = (bmp.readPressure()/100)+ 9.5;
   Serial.print(pr);
   Serial.println(" hPa");
   
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");


  delay(1250);

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Real altitude = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" meters");

*/
    
}

So any suggestions? drop the delay? or not worth the bother (i don’t mind holding down the button lol)

Drop the delay. Go on, you know you want to, you know you you ought to. Do the right thing.

I assume that your question about interrupts during delay() was because you are thinking of triggering an interrupt with the switch. No need. millis() is the way to go. I would also suggest that you break out some of the stuff in loop() into their own functions with meaningful names. Easier to read and maintain.

i would consider this a small project i tend to do that when i hit around 500 lines old habits die hard coding with object pascal for 15 years got me lazy lol

my multi threaded server has nice named objects and thread... ohhh if only we could spawn a thread! .. can a due suppor a thread? (i have one in my draw lol)

To answer your question, the interrupt actually interrupts the delay and executes the interrupt service routine. If you were to attach an interrupt to pin8, instead of polling it, you could toggle RelayM and the actual relay in the interrupt service routine, and the delay wouldn't even know what hit it. Similar to spawning a very short-lived thread.

You would have to debounce it, but it isn't hard.

Just a nit pick...

  if (T>=20.00 & RelayM==false) //if override is off do normal operation

C uses double && for logical and. Single & is bitwise and, and I think in this case has tighter precedence than the >= and the ==.

Your other if statements have parentheses, which means they'll probably be OK, but you really should change them as well.

oh i see!

An interrupt does interrupt a delay now does it?.... oh i have to try this :slight_smile: Thanks :slight_smile:

  if ((T>=20.00) && (RelayM==false)) //if override is off do normal operation
    {
      Relay=false; //turn off relay
      digitalWrite(RelayPin,Relay);      
    } //heater off
   else
  if (T<=18.00)
   {
     Relay=true;  //turn on relay as it's cold
     digitalWrite(RelayPin,Relay);
   }

I would not have this problem with Pascal (just sayin…)

Time to go try an interrupt, see what happens.

My software bounce of “delay” inside the interrupt, did not “delay” at all, so unless there’s another software way, I’d have to add a hardware denounce circuit (for another time maybe).

meanwhile, this without any use of milli does the job just fine, as it now relies on only differences in temperature from last reading, in short, when you press the button, there’s only a tiny amount of
lag, and holding it down gives a nice 125ms off / on time, that will protect the relay just fine.

#include <OneWire.h>
#include <stdlib.h>
#include <DallasTemperature.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//#include <Wire.h>
//#include <Adafruit_BMP085.h>
#define RelayPin 7
#define Rled 3
#define Gled 5
#define Bled 6

float OldTemp;
boolean Relay = false;
boolean RelayM = false;

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
LiquidCrystal_I2C lcd(0x27,16,2);
DallasTemperature sensors(&oneWire);


void setup(void)
{
  // start serial port
  pinMode(Rled,OUTPUT);
  pinMode(Gled,OUTPUT);
  pinMode(Bled,OUTPUT);
  pinMode(RelayPin,OUTPUT);  
  pinMode(8,INPUT);
  analogWrite(Rled,0);
  analogWrite(Gled,0);
  analogWrite(Bled,0);  

 for (int i=1; i<10; i++)   //3 pin RGB test
 { 
  analogWrite(Rled,225);
  delay(20);     
  analogWrite(Rled,0);  
  delay(20);     
  analogWrite(Gled,225);
  delay(20);     
  analogWrite(Gled,0);  
  delay(20);     
  analogWrite(Bled,225);
  delay(20);     
  analogWrite(Bled,0);  
  delay(20);       
 }
   
  lcd.init();                      // initialize the lcd 
  lcd.backlight();
  // Print a message to the LCD.
/*  for (int n=1; n<55;) 
   {
    n++;
    lcd.backlight();
    delay(100);
    lcd.noBacklight();  
    delay(100);  
   }*/
 // attachInterrupt(0,TriggerIRQ,RISING);
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

// if (!bmp.begin())
 //   Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  // Start up the library
  sensors.begin();
}



void loop(void)
{ 
  sensors.requestTemperatures(); // Send the command to get temperatures
  float T;
  char TStr[5];

// T= 21;
 // Serial.println(T);

  T = sensors.getTempCByIndex(0);  

  if (T<10)  //this is for a quick visual status 
   {
     //relay on, heater on.
 //    Serial.println("freezing cold");     
     analogWrite(Rled,0);
     analogWrite(Gled,0);     
     analogWrite(Bled,220);     
   }

   if ((T>=10) &(T<19))
    {
//      Serial.println("cold");     
     analogWrite(Rled,0);
     analogWrite(Bled,225);
     analogWrite(Gled,225);
    }

   if ((T>=19) & (T<26))
    {
 //    Serial.println("warm");     
     analogWrite(Rled,0);
     analogWrite(Gled,225);
     analogWrite(Bled,0);     
    }
    
   if ((T>=26) & (T<40))
    {
 //     Serial.println("hot");     
     analogWrite(Rled,225);
     analogWrite(Gled,0);
     analogWrite(Bled,0);     
     }

    if (RelayM==true)  //button press detected (although holding down is required depends on luck)
    {
        if (T>=22.00)  //max temp to reach with override button
       {
         RelayM=false;
         digitalWrite(RelayPin,RelayM);      
        } //heater off
    } 
     
     
  //pin 8 connects to a button to override and turn on the heater
  //ideally, I want to trigger this quicker, so a delay may have to go

   if (digitalRead(2)==HIGH) 
   {
      RelayM=!RelayM;
      digitalWrite(RelayPin,RelayM);
      delay(100);
   }
   
    

  if ((T>=20.00) && (RelayM==false)) //if override is off do normal operation
    {
      Relay=false; //turn off relay
      digitalWrite(RelayPin,Relay);      
    } //heater off
   else
  if (T<=18.00)
    {
      Relay=true;  //turn on relay as it's cold
      digitalWrite(RelayPin,Relay);
    }
    
//    Serial.println(T);
//    Serial.println(OldTemp);    
  if (OldTemp!=T) 
   {     
     dtostrf(T,5, 3, &TStr[0]);
     TStr[5]=0;   
     lcd.clear();  //i2c library LCD              
     lcd.setCursor(0,0);
     lcd.print("The Temperature:");  
     lcd.setCursor(1,1);
     lcd.print(TStr);
     lcd.println(" Degrees C");  
     delay(55);      
   }   
     OldTemp = T;      
     
   
}

Meanwhile, denouncing a button from an interrupt?

In order to implement a hardware interrupt, try something like this:

volatile long int LastInterruptTimeStamp = 0;
volatile boolean RelayM = false;      // Must be volatile because we mess with it in an interrupt service routine

void InterruptServiceRoutine()
{
  long int CurrentTime = millis();
  
  if (CurrentTime - LastInterruptTimeStamp > 100)     //  Debounce
  {
    RelayM=!RelayM;
    digitalWrite(RelayPin,RelayM);
  }
  LastInterruptTimeStamp = CurrentTime;
}

void setup()
{
// Add this line
  attachInterrupt(0, InterruptServiceRoutine, RISING);    // Int0 must be digital pin 2 on the Uno
}

loop()
{
...
// Comment out these lines:
//   if (digitalRead(2)==HIGH) 
//   {
//      RelayM=!RelayM;
//      digitalWrite(RelayPin,RelayM);
//      delay(100);
//   }
...
}
void InterruptServiceRoutine()
{
  long int CurrentTime = millis();
  
  if (CurrentTime - LastInterruptTimeStamp > 100)     //  Debounce
  {
    RelayM=!RelayM;
    digitalWrite(RelayPin,RelayM);
  }
  LastInterruptTimeStamp = CurrentTime;
}

perfect :slight_smile: never occurred to me... Thanks!