Hello, my husband is in the early stages of dementia and lately he has been sometimes forgetting to close the fridge door all the way. I am working on an alarm that will tell me if the door has been left open but not to have the alarm go off every time we open the fridge door. I would like the alarm to go off only after the door has been open for 30 seconds then continue to go off so I can go and close the door. I am not very experienced with code so I was using a simple delay in the void loop but that is not working the way I need it to. I would really appreciate some guidance in how to approach the problem.
//Fridge Door Alarm using Hall Effect Sensor
const int halleffectPin = 2; // the hall effect sensor pin
const int redledPin = 13; // the red LED pin
const int greenledPin = 12; // the green LED pin
const int buzzer = 5; // // the buzzer pin
int halleffectState = 0; // variable for reading the hall sensor status
void setup() {
pinMode(redledPin, OUTPUT); // initialize the LED pins and hall effect pin
pinMode(greenledPin, OUTPUT);
pinMode(halleffectPin, INPUT_PULLUP);
}
void loop(){
halleffectState = digitalRead(halleffectPin); // read the state of the hall effect sensor
if (halleffectState == HIGH) {
// the door is left open
digitalWrite(greenledPin, LOW); // turn green LED off
digitalWrite(redledPin, HIGH); // turn red LED on
delay(30000); // for 30 seconds
tone(buzzer, 1000); // generate 1KHz alarm tone
delay(1000); // for 1 second
noTone(buzzer); // stop sound
delay(1000); // for 1 second
}
else {
// door is closed
noTone(buzzer); // Stop sound
digitalWrite(redledPin, LOW); // turn red LED off
digitalWrite(greenledPin, HIGH); // turn green LED on
}
}
You can't really use delay in this instance as this blocks the code... so even if you close the door the delay continues.
You need to use a different technique. This is demonstrated in the "Blink Without Delay" example in the IDE. Instead of using delay, instead you keep track of the time (using a function called millis()) that certain things happen (like the door first being opened)... and then check the current time to determine what you need to do. This all happens within loop.
Also be aware that you are pulling the Hall effect pin HIGH with...
pinMode(halleffectPin, INPUT_PULLUP);
You would normally do this if the sensor is active LOW... so you probably want to be checking for LOW not HIGH.
You need to be able to tell when the door was first opened, to start your timer. The easiest way to do that is continually check the sensor on each loop and compare its value to the loop before. When it changes from HIGH -> LOW that's the point you start your timer from.
Also, to start with I'd recommended just turning ON/OFF the LEDs and the buzzer ON. Don't try and have the buzzer turn ON/OFF every second. That's another timing consideration and adds a bit of complication, but get the basic program working first before you try that bit.
Thank you both for the assistance, I really appreciate it. I am studying the Blink Without Delay example but it would be more helpful for a newbie like me if it was more about turning on an LED with delay and didn't have all the blinking code to make it more complicated.
//Fridge Door Alarm using Hall Effect Sensor
//********************************************^************************************************
#define PUSHED LOW
#define RELEASED HIGH
#define CLOSED LOW
#define OPEN HIGH
#define ENABLED true
#define DISABLED false
#define LEDon HIGH
#define LEDoff LOW
//********************************************^************************************************
const byte halleffectPin = 2; //the hall effect sensor pin
const byte buzzer = 5; //the buzzer pin
const byte heartbeatLED = 11;
const byte greenledPin = 12; //the green LED pin
const byte redledPin = 13; //the red LED pin
boolean halleffectTimerFlag = DISABLED;
boolean buzzerFlag = DISABLED;
boolean buzzerState = DISABLED;
byte lastHalleffectState;
//timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;
unsigned long halleffectMillis;
unsigned long buzzerMillis;
const unsigned long alarmInterval = 30000ul; //30 seconds
const unsigned long buzzerInterval = 1000ul; //1 seconds
// s e t u p ( )
//********************************************^************************************************
void setup()
{
pinMode(redledPin, OUTPUT);
digitalWrite(redledPin, LEDoff);
pinMode(greenledPin, OUTPUT);
digitalWrite(greenledPin, LEDon);
pinMode(heartbeatLED, OUTPUT);
pinMode(buzzer, OUTPUT);
noTone(buzzer);
pinMode(halleffectPin, INPUT_PULLUP);
}
// l o o p ( )
//********************************************^************************************************
void loop()
{
//********************************* h e a r t b e a t T I M E R
//is it time to toggle the heartbeatLED ?
if (millis() - heartbeatMillis >= 500ul)
{
//restart this TIMER
heartbeatMillis = millis();
//toggle the heartbeatLED
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//********************************* c h e c k s w i t c h T I M E R
//is it time to check the switches ?
if (millis() - switchMillis >= 50ul)
{
//restart this TIMER
switchMillis = millis();
checkSwitches();
}
//********************************* h a l l e f f e c t T I M E R
//if this TIMER is enabled, has it expired ?
if (halleffectTimerFlag == ENABLED && millis() - halleffectMillis >= alarmInterval)
{
//disable this TIMER
halleffectTimerFlag = DISABLED;
//enable the buzzer TIMER
buzzerFlag = ENABLED;
//start the TIMER
buzzerMillis = millis();
//turning on the buzzer
buzzerState = ENABLED;
tone(buzzer, 1000);
}
//********************************* b u z z e r T I M E R
//if this TIMER is enabled, has it expired ?
if (buzzerFlag == ENABLED && millis() - buzzerMillis >= buzzerInterval)
{
//restart this TIMER
buzzerMillis = millis();
buzzerState = !buzzerState;
if (buzzerState == ENABLED)
{
tone(buzzer, 1000);
}
else
{
noTone(buzzer);
}
}
} //END of loop()
// c h e c k S w i t c h e s ( )
//********************************************^************************************************
//this function runs every 50ms; this effectively debounces your inputs
void checkSwitches()
{
byte currentState;
//************************************************ b u t t o n 1 P i n
currentState = digitalRead(halleffectPin);
//has this switch changed state ?
if (lastHalleffectState != currentState)
{
//update to the new switch state
lastHalleffectState = currentState;
//*************************
//has this door opened ?
if (currentState == OPEN)
{
//the door is open
digitalWrite(redledPin, LEDon);
digitalWrite(greenledPin, LEDoff);
//disable this TIMER
buzzerFlag = DISABLED;
//enabled this TIMER
halleffectTimerFlag = ENABLED;
//start the TIMER
halleffectMillis = millis();
}
//door is closed
else
{
//disable this TIMER
halleffectTimerFlag = DISABLED;
//disable this TIMER
buzzerFlag = DISABLED;
noTone(buzzer);
digitalWrite(redledPin, LEDoff);
digitalWrite(greenledPin, LEDon);
}
} //END of this switch
//*********************************
// Future switches go here
//*********************************
} //END of checkSwitches()
Hi Larry, I read elsewhere on the forum that it is best when asking questions on this forum to state clearly what I need my code to do and what I am trying to achieve with my project. I hope it did not come across as trying to get sympathy, that was not my intent.
Here's another version. This doesn't toggle the buzzer yet... but hopefully you get the idea and can see how you would achieve that.
//Fridge Door Alarm using Hall Effect Sensor
const int halleffectPin = 2; // the hall effect sensor pin
const int redledPin = 13; // the red LED pin
const int greenledPin = 12; // the green LED pin
const int buzzer = 5; // the buzzer pin
int halleffectState = 0; // variable for reading the hall sensor status
int previousState = 0; // value on previsou loop.
unsigned long openTime = 0; // Time when door first opened.
void setup()
{
pinMode(redledPin, OUTPUT);
pinMode(greenledPin, OUTPUT);
pinMode(halleffectPin, INPUT_PULLUP);
}
void loop()
{
halleffectState = digitalRead(halleffectPin); // read the state of the hall effect sensor
if (halleffectState == LOW) // Door open
{
if (previousState == HIGH) // Door has just been opened
{
openTime = millis(); // Keep track on when the door was opened.
}
if (millis() - openTime > 20000) // Has the door has been open too long?
{
digitalWrite(greenledPin, LOW); // turn green LED off
digitalWrite(redledPin, HIGH); // turn red LED on
tone(buzzer, 1000); // generate 1KHz alarm tone
}
}
else // Door closed
{
noTone(buzzer); // Stop sound
digitalWrite(redledPin, LOW); // turn red LED off
digitalWrite(greenledPin, HIGH); // turn green LED on
}
previousState = halleffectState; // Update the previous state for checking next loop.
}
Thank you red_car, that is so clear and easy to understand. I feel confident now that I can experiment with it to get it to do exactly what I need. This is so much more helpful for me as a newbie to millis than the BlinkWIthoutDelay example, thank you again for taking the time to write it out for me. Cheers!
I think that I might use a sound module to say "the fridge door is open" repeatedly rather than the buzzer. There are other things that beep in a similar fashion around our home and having the spoken words as the alarm might be easier to for him to recognize that it is the fridge that needs to be responded to. I have used mp3 player modules in previous projects so I don't require help with that, I just thought I'd mention the idea in case it helps someone else with a similar project.
Hello arduinokov
And now you have a wide range of solutions for your project.
//Fridge Door Alarm using Hall Effect Sensor
const int halleffectPin = 2; // the hall effect sensor pin
const int redledPin = 13; // the red LED pin
const int greenledPin = 12; // the green LED pin
const int buzzer = 5; // // the buzzer pin
int halleffectState = 0; // variable for reading the hall sensor status
int halleffectStateOld = 0; // variable for reading the hall sensor status old
unsigned long timeStamp; // time stamp for door open event
const unsigned long time4alert {30000}; // time to go before alert
bool timerRun;
int alertState; // 0 = no alert, 1 = alert
enum Alerts {NoAlert, Alert};
void setup() {
Serial.begin(9600);
pinMode(redledPin, OUTPUT); // initialize the LED pins and hall effect pin
pinMode(greenledPin, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(halleffectPin, INPUT_PULLUP);
}
void loop() {
halleffectState = !digitalRead(halleffectPin); // read the state of the hall effect sensor
if (halleffectStateOld != halleffectState) // any changes ?
{ //if yes
halleffectStateOld = halleffectState; //save new state
if (!halleffectState) // door open?
{ // is open
timeStamp = millis(); // start timer
timerRun = true;
Serial.println(F("door open"));
} else { // is closed
alertState = NoAlert;
timerRun = false; // stop timer
Serial.println(F("door closed"));
}
}
if (millis() - timeStamp >= time4alert && timerRun) timerRun = false, alertState = Alert; // out of time
digitalWrite(greenledPin, !alertState);
digitalWrite(redledPin, alertState);
digitalWrite(buzzer, alertState);
}
Have a nice day and enjoy programming in C++ and learning.
Errors and omissions excepted.
Дайте миру шанс!
I have been using the alarm on the fridge now for a week and it is working well. The only issue is that the alarm buzzer, while loud enough to get my husband's attention, is a bit overwhelming. So now I am trying to make it beep at first, say once every 30 seconds for a few minutes to give him a chance to respond to it before going for the full tone. I have not been able to get the tone to beep though.
//Fridge Door Alarm using Hall Effect Sensor
const int halleffectPin = 2; // the hall effect sensor pin
const int redledPin = 13; // the red LED pin
const int greenledPin = 12; // the green LED pin
const int buzzer = 5; // the buzzer pin
int halleffectState = 0; // variable for reading the hall sensor status
int previousState = 0; // value on previous loop.
unsigned long openTime = 0; // time when door first opened.
void setup()
{
pinMode(redledPin, OUTPUT);
pinMode(greenledPin, OUTPUT);
pinMode(halleffectPin, INPUT_PULLUP);
}
void loop()
{
halleffectState = digitalRead(halleffectPin); // read the state of the hall effect sensor
if (halleffectState == HIGH) // door open
{
if (previousState == HIGH) // door opened and ok
digitalWrite(greenledPin, HIGH); // turn green LED on
{
if (previousState == LOW) // door has just been opened
{
openTime = millis(); // keep track on when the door was opened.
}
if (millis() - openTime > 30000) // the door is open
{
digitalWrite(greenledPin, LOW); // turn green LED off
digitalWrite(redledPin, HIGH); // blink red LED
delay(500);
digitalWrite(redledPin, LOW);
delay(500);
}
if (millis() - openTime > 150000) // has the door has been open too long?
{
tone(buzzer, 1000); // generate 1KHz alarm tone
delay(30000);
}
}
}
else // door closed
{
noTone(buzzer); // stop sound
digitalWrite(redledPin, LOW); // turn red LED off
digitalWrite(greenledPin, LOW); // turn green LED off
}
previousState = halleffectState; // update the previous state for checking next loop
}