Things used in this project

Hardware components:
Photon new
Particle Photon
×1
Relay (generic)
I used a 4 channel relay, a 3 channel will work
×1
Magnetic Switch
×2
386 00
DHT11 Temperature & Humidity Sensor
×1
Mfr 25frf52 10k sml
Resistor 10k ohm
×1
MQ2 Gas Sensor
×1
YuRobot Breadboard Power Supply
Need this if using the MQ2 gas sensor
×1
Software apps and online services:
Blynk logo avatars
Blynk

Schematics

Particle Photon Fritzing
particle_photon_garage_door_2z7DU6mYlO.fzz

Code

Magic Garage Door CodeC/C++
Any input for improvement and simplification of the code will be appreciated.
/*
This works well with a Sears Craftsman Model 139 Garage Door Opener. However
if using it with a safety reverse you will need to restart the opener and Photon to 
resume operating IF the safety reverse is activated.
Blynk Virtual Pins
V0   Relay channel 3
V3   Door location (0,50,100)
V5   Door status (Closed,Halfway,Open)
V6   Humidity
V7   Temperature
V8   Wifi signal
V9   Gas sensor (MQ-2)
V10  Terminal Widget
Photon Pins
D0   Relay channel 2
D1   Relay channel 3
D3   Side switch
D5   Temp/humid sensor
D6   Relay channel 1 (plus button on Blynk)
D7   Center switch
A0   Gas sensor
*/
#include <blynk.h>
#include <Adafruit_DHT.h>
#define BLYNK_PRINT Serial
#define DHTPIN 5  
#define DHTTYPE DHT11
#define RelayCH1 D6  // Relay channel 1
#define RelayCH2 D0  // Relay channel 2
#define RelayCH3 D1  // Relay channel 3 (lock)
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
char auth[] = "Insert your Blynk token here";
BlynkTimer timer;
unsigned long lastSync = millis();  // For time synchronization from the Particle Cloud
float f;  // Temperature
int h;  // Humidity
int signal;  // Wifi strength (dB)
int DoorLocation;  // Door location for history graph
double TimerStuck;  // Counter for door stuck in between
double NotifyCounter;  // Counter to prevent excess notifications for door open at night
double CountOpen;  // Counter to prevent overwrite
double CountClose;  // Counter to prevent overwrite
DHT dht(DHTPIN, DHTTYPE);
const int SideSwitch = D3;  // Side (south) switch
const int CenterSwitch = D7;  // Center (north) switch V4
const int GasPin = A0; //Gas sensor
String DoorStatus;
WidgetTerminal terminal(V10);  // Blynk Terminal

void setup() {
delay(5000);  // Allow board to settle.... so they say
Blynk.begin(auth);
digitalWrite(RelayCH1,LOW);
digitalWrite(RelayCH2,LOW);
digitalWrite(RelayCH3,LOW);
timer.setInterval(1000, sendStatus);  // Send data to Blynk once a second
timer.setInterval(60000, sendAtm);  // Send data to Blynk once a minute
dht.begin();  // DHT11
pinMode(SideSwitch, INPUT_PULLDOWN);  // Door Switches
pinMode(CenterSwitch, INPUT_PULLDOWN);  // Door Switches
pinMode(RelayCH1, OUTPUT);  // Relay 1
pinMode(RelayCH2, OUTPUT);  // Relay 2
pinMode(RelayCH3, OUTPUT);  // Relay 3. For lock out to prevent accidental opening
NotifyCounter = 0;  // Initialize value
Particle.syncTime();  // Request time synchronization from the Particle Cloud (UTC)
Time.zone(-4);  // Set to correct time zone
}
//  End of setup
//
//  Get terminal data if Photon rebooted
//
BLYNK_CONNECTED() {
    Blynk.syncVirtual(V10);
}
//
//  Send data to Blynk
//

void sendAtm()  // Once every minute
{
  signal = abs(WiFi.RSSI());  // Wifi -1 db strong, -127 db weak. Make positive for easy charting
  analogRead(GasPin);  // A0 V9
  h = dht.getHumidity();  // V6
  f = dht.getTempFarenheit();  // V7
  Blynk.virtualWrite(V6,h);  // Humidity (%)
  Blynk.virtualWrite(V7,f);  // Temperature (F)
  Blynk.virtualWrite(V8,signal);  // Wifi strength (dB)
  Blynk.virtualWrite(V9,GasPin);  // Gas
  Blynk.syncVirtual(V10);  // Sync terminal. Tends to not update if app is running on phone 
  terminal.flush();  // Maybe this will keep the terminal screen updated
//
// Sync time once a day
//
if (millis() - lastSync > ONE_DAY_MILLIS) {
    terminal.println(Time.format(Time.now(), "%m.%d.%y %I:%M:%S %p Current Time"));
    Particle.syncTime();  // Request time synchronization from the Particle Cloud
    lastSync = millis();
    Time.zone(-4);  // Set correct time zone
    terminal.println(Time.format(Time.now(), "%m.%d.%y %I:%M:%S %p Updated Time"));
    terminal.flush();
}
}
void sendStatus()  // Once every second
{
  Blynk.virtualWrite(V3,DoorLocation);
  Blynk.virtualWrite(V5,DoorStatus);
  if (DoorStatus == "Halfway"){
      Blynk.virtualWrite(V0, 0);  // Change display
      digitalWrite(RelayCH3,LOW);  // Need to keep manual door switch on wall operable
      digitalWrite(RelayCH1, LOW);  // Be sure to reset relay
  }
} 
BLYNK_WRITE(V0)  // To open door if V0 button is pressed or reinitiate lock 
{
  int lockvalue = param.asInt();
  if(lockvalue==1){
      digitalWrite(RelayCH3,HIGH);
  }
  if(lockvalue==0){
      digitalWrite(RelayCH3,LOW);
  }
}

void loop() {
Blynk.run();
timer.run();
//
// Check door for closed status
//
if (digitalRead(SideSwitch) == LOW and digitalRead(CenterSwitch) == HIGH ){
    DoorStatus = "Door Closed";  // V5
    TimerStuck = millis();
    DoorLocation = 0;
    NotifyCounter = 0;
    digitalWrite(RelayCH2,LOW);  //  Need to keep door switch on wall operable
    if (CountClose < 1) { 
        terminal.println(Time.format(Time.now(), "%m.%d %I:%M %p Closed"));
        terminal.flush();
        CountClose = 1;  // Prevent overwrite of time closed while closed
        CountOpen = 0;  // Allow overwrite of time opened
    }
}    
//
// Check door for open status
//
if (digitalRead(SideSwitch) == HIGH and digitalRead(CenterSwitch) == LOW){
    DoorStatus = "Door Open";  // V5
    TimerStuck = millis();
    DoorLocation = 100;
    digitalWrite(RelayCH2,LOW);  //  Need this to keep the manual door switch on wall operable
    if (CountOpen < 1) {
        terminal.println(Time.format(Time.now(), "%m.%d %I:%M %p Open"));
        terminal.flush();
        CountOpen = 1;
        CountClose = 0;
    }
}   
//
// Report current status during movement
//
if (digitalRead(SideSwitch)== LOW and digitalRead(CenterSwitch)==LOW and (millis()-TimerStuck)<= 600000){
    DoorStatus = "Halfway";
    DoorLocation = 50;
    digitalWrite(RelayCH3,LOW);  //  Need to keep manual door switch on wall operable
    digitalWrite(RelayCH2,HIGH); //  Need to keep manual door switch on wall operable
}   
//
// Notify once and report if door is halfway open for more than 10 minutes
//
if (digitalRead(SideSwitch)== LOW and digitalRead(CenterSwitch)==LOW and NotifyCounter < 1 and (millis()-TimerStuck) > 600000){
    DoorStatus = "Door stuck- big trouble";
    DoorLocation = 50;
    NotifyCounter = 2;
    Blynk.notify("Door stuck- big trouble");
    terminal.println(Time.format(Time.now(), "%m.%d %I:%M %p Door stuck- big trouble"));
    terminal.flush();
}
//
// Notify once and report if door open past 10PM and before 7AM
// 
if (digitalRead(SideSwitch) == HIGH and digitalRead(CenterSwitch) == LOW and NotifyCounter < 1 and (Time.hour()>= 22 || Time.hour()<7)) {
    DoorStatus = "CLOSE DOOR";  // V5
    NotifyCounter = 2; //
    Blynk.notify("It's late ! Close the garage door !");
    terminal.println(Time.format(Time.now(), "%m.%d %I:%M %p It's late ! Close the garage door !"));
    terminal.flush();
}   

}
// End of loop

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

ConnectTheDots with Particle Azure IoT Hub Integration
Intermediate
  • 563
  • 7

Protip

This project will allow you to connect your Particle device into an Azure IoT Hub for viewing data in real-time through an ASP.NET web app!

Other Clocks
Intermediate
  • 186
  • 3

Work in progress

A combination of 3 different clocks in one frame.

Christmas Gift Box
Intermediate
  • 3,602
  • 595

Full instructions

Christmas Gift Box plays music and sends an email when it is opened.

Weather Aware Sprinkler Controller
Intermediate
  • 1,301
  • 16

Full instructions

6 station Photon controller uses the Weather Underground API to prevent watering when windy, rainy, or too cold.

Simple Environmental Monitoring
Intermediate
  • 1,558
  • 13

Full instructions

Particle Photon circuit allowing the display of environmental conditions (light, temperature, humidity, pressure) using the Blynk app.

THDweeter
Intermediate
  • 249
  • 2

Protip

Yet another temperature-humidity sensor publishing to dweeter, with WiFi auto-disconnect and a push button to read daily max and min values.

Add projectSign up / Login