Bianchi Rider
Published © GPL3+

Garage Door Opener With Blynk

Open, close and monitor a garage door opener with a smart phone using a Particle Photon and the Blynk application.

IntermediateShowcase (no instructions)10 hours1,545
Garage Door Opener With Blynk

Things used in this project

Hardware components

Photon
Particle Photon
×1
Relay (generic)
I used a 4 channel relay, a 3 channel will work
×1
Magnetic Switch
×2
DHT11 Temperature & Humidity Sensor
DHT11 Temperature & Humidity Sensor
×1
Resistor 10k ohm
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
Blynk

Story

Read more

Schematics

Particle Photon Fritzing

Code

Magic Garage Door Code

C/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

Bianchi Rider

Bianchi Rider

0 projects • 1 follower
Contact

Comments

Add projectSign up / Login