A small wait without "delay"

Hi,

I am really new to this, but have cobbled together a project that simply sounds an alarm and flashes lights if the fridge door is left open.

My switch is a magnet switch, and so far this all works very well, except the alarm goes off immediately the door is opened.

I have played with delay(), but it just seems to cause more problems than it solves.

Can anyone give me pointers on how I can tweak this code so that when the switch is opened, a 120 seconds countdown begins, only then sounding the alarm. However, if the door is closed and the switch closed, the alarm cancels and returns to monitoring?

Any help would be hugely appreciated,

Mike

// constants won't change. Used here to set a pin number :
const int greenledPin =  3;      // the number of the LED pin
const int redledPin =  4;        // the number of the LED pin
const int magSwitch =  5;        // the number of the Magnetic Switch
const int alarmBuzzer =  6;        // the number of the Buzzer

// Variables will change :
int ledState = LOW;             // ledState used to set the LED
int magswitchState = 0;            // variable for reading the mag switch status

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change :
const long interval = 750;           // green interval at which to blink (milliseconds)

void setup() {
  // set INPUTS OUTPUTS
  pinMode(greenledPin, OUTPUT);
  pinMode(redledPin, OUTPUT);  
  pinMode(magSwitch, INPUT); 
  pinMode(alarmBuzzer, OUTPUT);    
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

// read the state of the mag switch value:
magswitchState = digitalRead(magSwitch);
  
if (magswitchState == LOW) {

   digitalWrite(redledPin, LOW); 
   digitalWrite(alarmBuzzer, LOW);     

    // GREEN LED
      if (currentMillis - previousMillis >= interval) {
              // save the last time you blinked the LED
              previousMillis = currentMillis;

              // if the LED is off turn it on and vice-versa:
              if (ledState == LOW) {
                ledState = HIGH;
              } else {
                ledState = LOW;
              }

              // set the LED with the ledState of the variable:
              digitalWrite(greenledPin, ledState);
      }

}  else {

   digitalWrite(greenledPin, LOW);
   digitalWrite(redledPin, HIGH);
   digitalWrite(alarmBuzzer, HIGH);
   delay(100); 
   digitalWrite(alarmBuzzer, LOW);
   delay(100);       
}

}

The blink without delay Arduino example shows you how to time events without using delay(). That way you can keep sampling the switch until a timeout occurs.

It looks like you have the basic idea, but are making some mistake in organization. I would suggest using a state machine (also one of the Arduino examples).

Tutorial here: https://www.baldengineer.com/blink-without-delay-explained.html

2 Likes

Thank you, I'll go and read.

M.

looks like you got the door closing ok..
just need at least one more previous millis counter and an if wrap around the bottom else..
really, i would add 2 more counter and lose the delay(100), blink the buzzer like you blink the led up above..
need a door interval there's 1000 millis in a second, so you need like 120,000.

1 Like

Start your switch timeout (record millis()) when the switch becomes opened.

The Arduino Files>Examples>0.2.Digital>StateChangeDetection example shows you how.

1 Like

Thank you. It's late here now, I shall look into this tomorrow.

You could write a sketch that just sounds an alarm after 2 minutes. Then power the entire unit via the door switch. That way, the unit is off and no power is wasted until it comes back on.

1 Like

Too clever by half! A 555 timer would do the job, too.

1 Like

For really really long delays there is a way to use a CD4060 oscillator/counter.

I didn't mean to be flip. It's just that I couldn't manage, "just use millis()" for the 999,999th time.

1 Like

Not sure I understand, but shall look into it. Thank you! :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.