Delay for Garage Door Closing

I fixed my issue with my door sensor but I ran into another problem with a particle.Function that actually shuts my door with a relay. (Garage Door Detector Problem). I send a “close” command and the door closes via a relay. But the return value I want to see does line up with what actually happens. When I type in “close” the door will close but my delay of 10 sec doesn’t seem to work. I keep getting a return of 999999. The door takes about 6 sec. to close. Any idea’s.

int GDopener(String command){
    if (command == "close"){
        digitalWrite (button , HIGH);
        delay (500);
        digitalWrite (button, LOW);
        delay (10000);
        if (digitalRead(doordetector)==0) {
        return 1111;
        Particle.publish ("doorclose","successfull", 60, PRIVATE);
        }
        else {
        return 999999;
        Particle.publish ("doorclose","fail", 60, PRIVATE);
        }
    }
    else {
        return 1919191;
    }
}

This is the whole code if that helps.

int doordetector = A2;
int button = D4;
int doorvalue;
int hour;
int out = A5;
bool dooropened = false;
bool after9 = false;


void setup() {
Time.zone(-4);
pinMode(out, OUTPUT);
pinMode (doordetector, INPUT);
pinMode (button, OUTPUT);
Particle.variable ("GarageDoor", doorvalue);
Particle.variable ("hours" , hour);
Particle.function ("GDopener",GDopener);
}
void loop() {
doorvalue=digitalRead(doordetector);
hour=Time.hour();
if (doorvalue==1 && dooropened != true) {
        dooropened = true ;
        Particle.publish("Garage_Door","Opened" , 60 , PRIVATE);
        delay (1000);
        }
    else if (doorvalue == 0) {
    dooropened = false;
    }


if ((doorvalue ==1 && hour >= 17  && after9 != true) || (doorvalue ==1 && hour <=3  && after9 != true)) {
    after9 = true ;
    Particle.publish ("GarageDoor","After_9PM", 60, PRIVATE);
    delay (1000);
    }
    else {
    }
}
int GDopener(String command){
    if (command == "close"){
        digitalWrite (button , HIGH);
        delay (500);
        digitalWrite (button, LOW);
        delay (10000);
        if (digitalRead(doordetector)==0) {
        return 1111;
        Particle.publish ("doorclose","successfull", 60, PRIVATE);
        }
        else {
        return 999999;
        Particle.publish ("doorclose","fail", 60, PRIVATE);
        }
    }
    else {
        return 1919191;
    }
}
    

So if I understand your code correctly, when you receive the command you output the signal. You then wait 10 secs to wait for it to close (should only take 6). If it's not closed according to the reading you return 999999 otherwise 1111.

1 Issue you might have is your if statement.

digitalRead() returns HIGH or LOW

but your if statement:

if (digitalRead(doordetector)==0)

So try this:

if (digitalRead(doordetector)==LOW)

(I'm not sure if LOW==0 which could be the case for convenience but trying won't hurt :slight_smile: )

Yes that's true, so it doesn't matter.

@jzalar
Particle.function() should not keep the code flow trapped for that long. The better approach would be to just trigger the HIGH and "wind up" a one-shot timer which does the setting LOW and checks the reached status.

BTW, these Particle.publish() instructions after the return statements are futile.
Also, do you have pull resistors in place?
If you don't use INPUT_PULLUP/INPUT_PULLDOWN in your code, you should at least put a comment about using extern pull-resistors in the code and maybe mention it in your post too.
You also don't state how you've wired the sensor, so for us it's actually imposible to know, whether this is the correct behaviour and just your assumption that a LOW reading would mean "closed" might be wrong.
It may be just as well the opposite.

2 Likes

You should consider using two reed switches … one to sense door open, the other to sense door closed. If you use an analog pin, you can read both reed switches with two wires … just put a resistor in series with one of the the reed switches (same value as your pull resistor), and it will return a mid-range value when it closes.

Two sensors provide a much better idea of what state the door is in. Most doors can be “open”, “closed”, “opening”, “closing”, and “stopped”. From a coding perspective, there is one additional door state, and that is “unknown”, The meaning of a button press changes depending on what state the door is in:

  • Closed door + button press = Opening door
  • Opening door + button press = Stopped door
  • Stopped door + button press = Closing door
  • Closing door + button press = Opening door
  • Open door + button press = Closing door
  • Unknown + button press = Unknown … until a sensor sets the door state.

Being able to reverse or stop a moving door is a safety issue, and the delays in your code prevents you from doing anything while the door is moving.

To get rid of the delay()s, you could define a few global variables … like:

const  int RELAY_ACTIVE_TIME = 500;
uint32_t relayExpiration = 0;
bool buttonPressed = false;

Your “GDopener” function could merely set a flag …

    buttonPressed = true;

And loop() could look something like:

loop() {
	if ((relayExpiration > 0) && (millis() > relayExpiration)) {
		... turn relay off
		relayExpiration = 0;
	}
	if (buttonPressed) {
		... turn relay on
		relayExpiration = millis() + RELAY_ACTIVE_TIME;
                buttonPressed = false;
        }
}

With this type of logic, loop() never stops, and you can perform all of the door state transitions mentioned above.

1 Like

I do have a resister hooked up to the sensor and ground. Between A2 and Ground. To be honest, I am not sure how to tell if it is a pull down or not. It is a 10k ohm resister. (my picture will not upload I think). As for the safety issue from Bear, I have not disable the floor sensors so I think i am good there. I do have another door sensor I could add, but I was trying to keep it incase the other one fails.

I commented out the particle.publish commands in the Function and it seems to be working how I want. In case anyone is interested, I have an “After_9PM” working. I need to add a 30 min. loop so it keeps reminding me when it is open. Code Below.

int doordetector = A2;
int button = D4;
int doorvalue;
int hour;
int out = A5;
bool dooropened = false;
bool after9 = false;


void setup() {
Time.zone(-4);
pinMode(out, OUTPUT);
pinMode (doordetector, INPUT);
pinMode (button, OUTPUT);
Particle.variable ("GarageDoor", doorvalue);
Particle.variable ("hours" , hour);
Particle.function ("GDopener",GDopener);
}
void loop() {
doorvalue=digitalRead(doordetector);
hour=Time.hour();
if (doorvalue==1 && dooropened != true) {
        dooropened = true ;
        Particle.publish("Garage_Door","Opened" , 60 , PRIVATE);
        delay (1000);
        }
    else if (doorvalue == 0) {
    dooropened = false;
    }


if ((doorvalue ==1 && hour >= 17  && after9 != true) || (doorvalue ==1 && hour <=3  && after9 != true)) {
    after9 = true ;
    Particle.publish ("GarageDoor","After_9PM", 60, PRIVATE);
    delay (1000);
    }
    else {
    }
}
int GDopener(String command){
    if (command == "close"){
        digitalWrite (button , HIGH);
        delay (500);
        digitalWrite (button, LOW);
        delay (10000);
        if (digitalRead(doordetector)==LOW) {
        return 1111;
        //Particle.publish ("doorclose","successfull", 60, PRIVATE);
        }
        else {
        return 999999;
        //Particle.publish ("doorclose","fail", 60, PRIVATE);
        }
    }
    else {
        return 1919191;
    }
}


Ok, I was wrong. it takes at least 13 sec. to close the door. I added in Door Open and Open Close functions will checks to see if it is the opposite of what I want to do. The code is below. If anyone has an example on how to send IFTTT notifications ever 30 min that would be awesome.

int doordetector = A2;
int button = D4;
int doorvalue;
int hour;
int out = A5;
bool dooropened = false;
bool after9 = false;


void setup() {
Time.zone(-4);
pinMode(out, OUTPUT);
pinMode (doordetector, INPUT);
pinMode (button, OUTPUT);
Particle.variable ("GarageDoor", doorvalue);
Particle.variable ("hours" , hour);
Particle.function ("CLOSEopener",CLOSEopener);
Particle.function ("OPENGarage", OPENGarage);
}
void loop() {
doorvalue=digitalRead(doordetector);
hour=Time.hour();
if (doorvalue==1 && dooropened != true) {
        dooropened = true ;
        Particle.publish("Garage_Door","Opened" , 60 , PRIVATE);
        delay (1000);
        }
    else if (doorvalue == 0) {
    dooropened = false;
    }


if ((doorvalue ==1 && hour >= 17  && after9 != true) || (doorvalue ==1 && hour <=3  && after9 != true)) {
    after9 = true ;
    Particle.publish ("GarageDoor","After_9PM", 60, PRIVATE);
    delay (1000);
    }
    else {
    }
}
int CLOSEopener(String command){
    if (command == "close" && (digitalRead(doordetector)==HIGH) ){
        digitalWrite (button , HIGH);
        delay (500);
        digitalWrite (button, LOW);
        delay (16000);
        if (digitalRead(doordetector)==LOW) {
        return 1111;
        //Particle.publish ("doorclose","successfull", 60, PRIVATE);
        }
        else {
        return 999999;
        //Particle.publish ("doorclose","fail", 60, PRIVATE);
        }
    }
    else {
        return 1919191;
    }
}
int OPENGarage(String command){
    if (command == "open" && (digitalRead(doordetector)==LOW)){
        digitalWrite (button , HIGH);
        delay (500);
        digitalWrite (button, LOW);
        delay (16000);
        if (digitalRead(doordetector)==HIGH) {
        return 1111;
        //Particle.publish ("doorclose","successfull", 60, PRIVATE);
        }
        else {
        return 999999;
        //Particle.publish ("doorclose","fail", 60, PRIVATE);
        }
    }
    else {
        return 1919191;
    }
}

If it pulls to GND it's a pull-down, if it pulls to the HIGH level (e.g. 3.3V) it's a pull-up.