Magnetic door sensor state

Hello. I’ve posted a question related to this subject before but now I have another one. So I’d like to use 2 magnetic sensors to check the state of a garage door. I’d also like to see if the garage door is opening/closing. Here is the code:

void setup()
{
  // Debug console
  Serial.begin(9600);
  pinMode(D1,INPUT_PULLUP);
   pinMode(D2,INPUT_PULLUP);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(100L,stagiu);
}

void stare(){
  if(digitalRead(D1)==LOW){
    door=0;
  }
  else if(digitalRead(D1)==HIGH){
    door=1;
  }
}

void stagiu(){
  void stare();
  if(digitalRead(D1)==LOW && digitalRead(D2)==HIGH && door==0){    
      Blynk.virtualWrite(V0,"OPEN");
  }
   void stare();
   if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door==0){    
      Blynk.virtualWrite(V0,"CLOSING");
  }
  void stare();
     if(digitalRead(D1)==HIGH && digitalRead(D2)==LOW && door==0){    
      Blynk.virtualWrite(V0,"CLOSED");
  }
  void stare();
     if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door==1){    
      Blynk.virtualWrite(V0,"OPENING");
}
}

void loop()
{
  Blynk.run();
  timer.run();
}

So the widget displays if the door is either open,closed or closing, but no way I can get it to show ‘opening’. The way I see it,I should do something to constantly check if the ‘door’ variable is 1 or 0. How would I do that? I tried adding the ‘stare’ function in front of every ‘if’ in the ‘stagiu’ function, but it doens’t seem to work. Thank you

Later Edit:

I’ve managed to do it by addin another variable and a timer that checks the ‘stare’ function every few milliseconds. Here’s the code if anyone is interested:

void stare(){
  if(digitalRead(D1)==LOW){
    door=0;
  }
  else if(digitalRead(D1)==HIGH){
    door=1;
  }
}

void stagiu(){
  if(digitalRead(D1)==LOW && digitalRead(D2)==HIGH && door==0){    
      Blynk.virtualWrite(V0,"OPEN");
         Serial.print(door);
         door2=0;
  }
   if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door2==0){    
      Blynk.virtualWrite(V0,"CLOSING");
               Serial.print(door);
  }
     if(digitalRead(D1)==HIGH && digitalRead(D2)==LOW && door==1){    
      Blynk.virtualWrite(V0,"CLOSED");
               Serial.print(door);
               door2=1;
  }
     if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door2==1){    
      Blynk.virtualWrite(V0,"OPENING");
               Serial.print(door);
}
}

Now, for the next part. I’d like the widget to display something such as “stuck” or “stalled” after some time has passed and both door sensors are set to HIGH. What would be the best way?

To be more specific, if door has been on the ‘opening’ or ‘closing’ state for a specified amount of time, the message should change from’opening/closing’ to ‘stalled’

Okay, looking at your code I’ve made the following assumptions…

  1. Your reed switches are normally closed, so read HIGH unless the magnet is next to them
  2. The switch attached to D1 is at the top of the door (open)
  3. The switch attached to D2 is at the bottom of the door (closed)

If this is the case then we can assume:

a) If D1 is LOW the door must be open (no need to do any other checks, both switches can’t be LOW at the same time)

b) If D2 is LOW the door must be closed

c) If D1 is HIGH && D2 is HIGH then the door must be either opening or closing. The direction of travel is unknown unless we use a flag to hold the last status of the door (open or closed). If the door was previously open, and D1 and D2 are HIGH then it must be closing. If the door was previously closed, and D1 and D2 are HIGH then it must be opening.

d) We’ll use the “door” flag to hold the last door status, with 1 for closed and 0 for open

The code should look like this…


void stagiu()
{
  if(digitalRead(D1)==LOW
  {  
      Blynk.virtualWrite(V0,"OPEN");
      door=0 // The door is open, so update the flag
  }
  if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door == 0)
  {    
      Blynk.virtualWrite(V0,"CLOSING");
  }
  if(digitalRead(D2)==LOW
  {    
    Blynk.virtualWrite(V0,"CLOSED");
    door=1 // The door is closed, so update the flag
  }
  if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door == 1)
  {    
    Blynk.virtualWrite(V0,"OPENING");
  }
}

Pete.

1 Like

Hello @PeteKnight . As you can see I did something simillar in the post above. I tried the exact code you posted some time before but for some reason it wouldn’t go back to OPEN or CLOSED, maybe I’ve had some connection problems or who knows.

Now, for the next part. I’d like the widget to display something such as “stuck” or “stalled” after some time has passed and both door sensors are set to HIGH. What would be the best way?
To be more specific, if door has been on the ‘opening’ or ‘closing’ state for a specified amount of time, the message should change from’opening/closing’ to ‘stalled’

Would you also have a solution for this one? I’m assuming I need to use a timer, but I really don’t know what to begin with, I don’t fully understand how the simpleTimer works. Thank you for your help

Just thinking about this a bit more, we should probably have a return at the end of each if statement so that processing the other options is bypassed.

You could use a timer, but you’re actually running a timer that calls this function every 100ms so you could use that and count how many times it’s been called, like this…

void stagiu()
{
  if(digitalRead(D1)==LOW
  {  
    Blynk.virtualWrite(V0,"OPEN");
    door=0 // The door is open, so update the flag
    movetime = 0;
    return;
  }

  if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door == 0)
  {    
    if(movetime>200) // Equivalent of around 20 seconds
    {
      Blynk.virtualWrite(V0,"STALLED"); 
    }   
    else
    {
      Blynk.virtualWrite(V0,"CLOSING");
      movetime ++;
    }
    return;
  }

  if(digitalRead(D2)==LOW
  {    
    Blynk.virtualWrite(V0,"CLOSED");
    door=1 // The door is closed, so update the flag
    movetime = 0;
    return;
  }

  if(digitalRead(D1)==HIGH && digitalRead(D2)==HIGH && door == 1)
  {    
     if(movetime>200) // Equivalent of around 20 seconds
     {
       Blynk.virtualWrite(V0,"STALLED"); 
     }   
    else
    {
      Blynk.virtualWrite(V0,"OPENING");
      movetime ++;
    }
    return;  
  }
}


You'd need to add the global variable (integer) called movetime.

I've not tried to compile this code!

Pete.

It works if I use 2 flags, as I did in one of my replys above. Thank you! I have also added a notification widget in the same ‘if’ with the ‘stalled’ message, but when it stalls I get a notification once every 2 seconds or so

You need another flag to show that the notification has been sent already.

Pete.

1 Like