Check Same Condition Twice to trigger event

hi. I have a fridge alarm concept that I'm trying to build. basically the arduino sends me a warning SMS if the fridge temperature goes above 0 degC and stays above 0 degC for more than 20 Min. easy enough to do with a "delay", but the problem is while arduino is on delay for 20 Min it can do nothing else (like continuing to update the LCD display with the temperature.) I've been trying to figure out over the last 3 days how to use "Timer library", if statements and switch case statements, but I still cant figure it out. I'm not asking for someone to write my code for me (would be nice:) but just point me in the right direction. I'm trying to get the arduino to read the temperature sensor, and when it gets to 0 deg C to trigger a timer of 20 Min. when 20 Min has elapsed i would like my arduino to re-check the temperature and if the temperature is still 0 deg C or above, to trigger an event like send me a warning SMS that my fridge is out of temperature range. do all this while continuing to display the current temperature on my LCD. Some good advice would be really appreciated, thanks in advance.

Here we go again Cue chorus 3 2 1

"Look at the BlinkWithoutDelay example in the IDE"

I'm trying to get the arduino to read the temperature sensor, and when it gets to 0 deg C to trigger a timer of 20 Min. when 20 Min has elapsed i would like my arduino to re-check the temperature and if the temperature is still 0 deg C or above, to trigger an event like send me a warning SMS that my fridge is out of temperature range.

Do you start counting time again if the temp falls below zero in the 20 minute period?

I’m guessing my question gets asked a lot in this forum. :blush:
No, if the temperature falls below 0, then I don’t count time anymore, because then, assumingly, the fridge has come out of its defrost cycle and is working normally, and there is no need to send an alarm anymore.

One way to implement that would be to read the temperature and compare it to your threshold. If it's safely below the threshold, note the current time. If it's above the threshold, subtract the last time you noted it was below the threshold from the current time to find how long it's been above the threshold. When that duration exceeds your limit, send the alarm. It should take you about half a dozen lines of code to implement.

jasonvanwyk: ... but the problem is while arduino is on delay for 20 Min it can do nothing else ...

Funnily enough I have a page about that:

http://www.gammon.com.au/blink

Thank you all very much, and for bearing with me and this topic once again
:slight_smile:

Coding issues aside, I think your logic is flawed, if you're only going to check the temp 20 minutes later. It might be that the temp goes below 0 a mere second or two into the timer, but you're not looking. Then it might stay below 0 for the next 19+ minutes, and rise above 0 just before your timer expires. So you see 2x over-zero readings, 20 min apart, and raise a false alarm because in reality it was ok for 99% of the 20 mins and has only just this second gone above again.

Maybe you could look at the temperature every (say) 5 seconds for 20 minutes....

ah, Yes, i do believe is see your point. Thank you… back to the drawing board :slight_smile:
when i get it working I’ll post my code here for more comment/review. but right now back to my day job :frowning:

PeterH's algorithm solves your false alarm problem.

ok, so my day job has kept me from testing out my new code. So I'm just going to post it here untested (until i get a chance to test it) for more review. NOTE: i haven't addressed the false alarm yet, but i just want to see first if i have a grip on the timing issue.

void loop() { if (degreesC > 0); timer = millis(); //start timer

if (millis() - timer >= (10000UL * 60 * 20)){ //after 20 Min tempCheck = degreesC; //check temperature } if (tempCheck >= 0){ //send SMS code here? }

So many things wrong...

void loop()
{
 if (degreesC > 0);
 timer = millis(); //start timer

if (millis() - timer >= (10000UL * 60 * 20)){ //after 20 Min
 tempCheck = degreesC; //check temperature
}
if (tempCheck >= 0){
  //send SMS code here?
  }

Where is degreesC set?

An IF that goes nowhere followed by timer being updated to now.

if (degreesC > 0);
 timer = millis(); //start timer

Don't just look at the BlinkWithoutDelay sketch. Work with it. Play with it. Figure out what they got wrong and why it works anyway and when/how the gotcha happens, ie Know It.

ok i’m learning 8)
that previous piece of code is completely flawed.
here’s my new code - it works…partly.
for the sake of saving time and money, i’ve substituted the 20 min time frame for 5 sec and the “send SMS” part of the code for just “Serial.print” (just to test and see if the code works)

const int temperaturePin = 0;
unsigned long threshHold = 5000;
unsigned long alarmTime;
unsigned long timer;

void setup()
{
Serial.begin(9600);

}
void loop()
{
float voltage, degreesC;
voltage = getVoltage(temperaturePin);
degreesC = (voltage - 0.5) * 100.0;

Serial.print("deg C: ");
Serial.println(degreesC);

delay(1000);

if (degreesC <= 22){
timer = millis();
}
else (degreesC > 22);{
alarmTime = millis() - timer;
}

if (alarmTime >= threshHold){

Serial.println(“hot”);
}
}
float getVoltage(int pin)
{
return (analogRead(pin) * 0.004882814);
}

This isn't doing what you expect:

else (degreesC > 22);

else doesn't take a condition and you've compounded the error with that semicolon that ensures that the block following it is always executed. What you need there instead is:

else

Somebody still doesn't know how BWD works. Not. At. All.

OK, so I’m still learning- a heck of a lot!
this is my new and improved code, Thanks PeterH for your help on the algorithm.

float temp;
int tempPin = 0;
unsigned long currentTime;
int overTime;

void setup()
{
Serial.begin(9600);
}

void loop()
{
temperature();// read the temperature by calling the temperature function
Serial.println (temp);//print the temperature to the serial monitor
if (temp < 30){ //read the temperature and compare it to the threshhold.
currentTime = millis(); // if the temperature id below the threshold, note the current time.
}
if (temp >= 30){ //read the temperature
overTime = millis()-currentTime; //if the temperature is above the threshold
}
if (overTime > 10000){ //if overtime is greater than 10 sec
Serial.print("hot! ");
Serial.println(temp);
overTime = millis()-currentTime; //reset overtime
}

delay(1000); //only print to serial monitor every 1 sec

}
void temperature(){ //temperature function
temp = analogRead(tempPin);
temp = temp * 0.48828125;
}

Is there any reason that temperature() does not have a verb in the name? Is there any reason that temperature() is diddling with a global variable, instead of returning a value?

Isthereanygoodreasonwhyyourcodeisalljammedtogether?

As long as temperature is >= 30, currentTime is not updated which the label is misleading anyway but figure out what that does.but oh, wait, BWD is far simpler and apparently that is too much.

Make enough gut-feel hunch-based changes and in time your code might do what you think it should. When you get tired of that, start working out the logic.

ok, so I’ve un-bunched my code (if that’s what I think I’ve done).
I’ve added a verb to make my “processTemperature” function more descriptive.
I obviously have no idea about global variables - i thought my function was returning a value, don’t know how to fix it, so i obviously still have no idea.
still trying to graps BWD - despite my best efforts, i obviously still have no idea.
this is my call for help and plead for patience :blush:

the code seems to work, but most probably not doing what i assume it should be doing

float temp;
int tempPin = 0;
float currentTime;
float overTime;

void setup()
{
Serial.begin(9600);
}

void loop()
{
processTemperature();// read the temperature by calling the temperature function

Serial.println (temp);//print the temperature to the serial monitor

if (temp < 28){ //read the temperature and compare it to the threshhold.
currentTime = millis(); // if the temperature id below the threshold, note the current time.
}

if (temp >= 28){ //read the temperature
overTime = millis()-currentTime; //if the temperature is above the threshold, note how much time it is over the threshhold
}

if (overTime > 5000){
Serial.print("hot! ");
Serial.println(temp);
currentTime = millis(); // reset current time
overTime = millis()-currentTime; //reset overtime
}

delay(1000);

}
void processTemperature(){
temp = analogRead(tempPin);
temp = temp * 0.48828125;
}

Here we go again Cue chorus 3 2 1

"Look at the BlinkWithoutDelay example in the IDE"

Hi, I vote the "delay" command should be omitted from the arduino command set. All it does is stops sketches from running. Tom...... :)