Arduino Garage Door opener that integrates into OpenHAB/MQTT

details

Description:

The following outlines how to build an Arduino Garage Door Opener that integrates into OpenHAB/MQTT. This is designed to work with an Arduino Uno Rev3 with Ethershield board .

OpenHAB and Mosquitto:

 

The Arduino code has been written specifically to work with Open HAB(open source home automation software) and an MQTT broker such as Mosquitto (a messaging subscribe/publish type protocol that is lightweight and great for communication between devices) Don’t let the names or acronyms scare you, they are really quite simple to use once you get to know how they work. I utilise OpenHAB on a NTC C.H.I.P  however many people use a Raspberry Pi or similar. This tutorial assumes you have implemented OpenHAB .

To install Mosquitto, following this link then select the type of device you are using and follow the instructions. Because C.H.I.P runs Debian (Jessie), you can follow the Raspberry Pi instructions if you are using C.H.I.P. for your Home Automation device (also note, its best to reconfigure CHIP to boot from the CLI. There are instructions for this here)

Once you have OpenHAB and Mosquitto running, you need to prepare the Arduino IDE for the code below. First, you need to add the PubSubClient library. In the Arduino IDE, from the menu’s go to Sketch, Include Library, Manage LibrariesIn the filter search box, type PubSubClient then highlight the search result and click to Install (at time of writing, the latest version is 2.6.0) You will also need the Ethernet library which covers extensions for the Ethernet shield.

The Garage Door opener does 2 things. First, it provides a button in OpenHAB to activate the door to open or close. Secondly it provides feedback to OpenHAB on the status of the door (either open, closed or partially open)

Hardware:

• Arduino uno R3

• Ethernet Shield

• 5 V relay

• 1K resistor

• Transistor(2N2222)

•Diodes

• Reed Swictes

The resistor, transistor and diode help create the circuit to the relay, which is triggered by a button in OpenHAB to open/close the door. The reed switches provide feedback to OpenHAB as to the garage doors status. These parts can be sourced cheaply from any electronics shop. Using these components is also the recommended way to configure the Arduino with a relay as per the Arduino site (note: the LED on the breadboard below is simply for test purposes, the red/black wires will usually go to the garage door opener)

180

With the garage door in an ‘open’ state as shown below, clicking the ‘Close’ button will trigger OpenHAB to send an MQTT message to the Arduino, the Arduino will then open the relay for 1 second, causing the door to close. The (door open) reed switch will become open which the Arduino will pick up and send a new door status back to OpenHAB which will then display the updated status ‘Partially Open’ until the door fully closes, at which stage the (door closed) reed switch will close, this will be detected by the Arduino which will then send a new message to the MQTT broker and status will then update to ‘Closed’ .

182

 

// Define Libraries
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>;

// Define Sub's and Pub's
const char* OPENHABSUBDOORSWITCH = "openhab/garage/doorswitch";
const char* OPENHABPUBDOORSTATUS = "openhab/garage/doorstatus";
const char* OPENHABPUBHUMIDITY = "openhab/garage/humidity";
const char* OPENHABPUBTEMPERATURE = "openhab/garage/temperature";

// Define Arduino PIN's
#define PINRELAY 7    // Relay module - trigger door here
#define PINLED 13     // Onboard LED - Activation Indicator
#define PINOPEN 5     // Door Open PIN - Reed switch for door open
#define PINCLOSED 6   // Door Closed PIN - Reed switch for door shut
#define PINDHT 2      // DHT22 PIN - Humidity and Temperature readings

// Declare DHT22 sensor for 16Mhz Arduino
DHT dht(PINDHT, DHT22); 

// DHT22 Variables
float fHumidity;
float fTemperature;

// Door states
enum doorStates {
  DOOROPEN = 0,
  DOORCLOSED = 1,
  DOORPARTIAL = 2,
};

// Initial door state (assume neither closed nor open when starting)
doorStates doorState = DOORPARTIAL;

// MQTT Broker
IPAddress MQTT_SERVER(192, 168, 222, 254);

// The IP address of the Arduino
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Remove remarks and alter if you want a fixed IP for the Arduino
// IPAddress ip(192, 168, 222, 100);

// Delay timer
unsigned long durationToCheck = 0;

// Define message buffer and publish string
char message_buff[10];
String pubString;

// Ethernet Initialisation
EthernetClient ethClient;


// Callback to Arduino from MQTT (inbound message arrives for a subscription - in this case the door on/off switch)
void callback(char* topic, byte* payload, unsigned int length) 
{

  // MQTT Inbound messaging 
  int iChar = 0;
  for(iChar=0; iChar<length; iChar++) {
    message_buff[iChar] = payload[iChar];
  }
  message_buff[iChar] = '\0';

  // Convert buffer to string
  String msgString = String(message_buff);
  Serial.println("Inbound: " + String(topic) +":"+ msgString);
  
  // Only open if not already open, only close if not already closed
  if ( (msgString == "ACTIVATE" && doorState != DOOROPEN) || (msgString == "DEACTIVATE" && doorState != DOORCLOSED) ) 
  {

    Serial.println("Activating Relay");
    digitalWrite(PINRELAY, HIGH);
    digitalWrite(PINLED, LOW);
    delay(1000); 
    digitalWrite(PINRELAY, LOW);
    digitalWrite(PINLED, HIGH);

  }
}

// Define Publish / Subscribe client (must be defined after callback function above)
PubSubClient mqttClient(MQTT_SERVER, 1883, callback, ethClient);


void setup() {

  // LED off, visual indicator when triggered
  pinMode(PINLED, OUTPUT);
  digitalWrite(PINLED, LOW);

  // Reed switch pins are inputs, activate internal pullup resistor by writing high
  pinMode(PINCLOSED, INPUT);
  digitalWrite(PINCLOSED, HIGH);
  pinMode(PINOPEN, INPUT);
  digitalWrite(PINOPEN, HIGH);

  // Start Network (replace with 'Ethernet.begin(mac, ip);' for fixed IP)
  while (Ethernet.begin(mac) == 0) {
    Serial.println("Could not obtain DHCP lease");
    delay(5000);
  }

  // Let network have a chance to start up
  delay(1500);

  // Start Serial
  Serial.begin(9600);

  // DHT Sensor
  dht.begin();

  // Display IP for debugging purposes
  printIPAddress();

}

void loop() {

  // If not MQTT connected, try connecting
  if (!mqttClient.connected())  {

    // Connect to MQTT broker on the openhab server, retry constantly
    while (mqttClient.connect("garagedoor") != 1) {
      Serial.println("Error connecting to MQTT (State:" + String(mqttClient.state()) + ")");
      delay(1000);
    }
    
    // Subscribe to the activate switch on OpenHAB
    mqttClient.subscribe(OPENHABSUBDOORSWITCH);

  }
  
  // Wait a little bit between status checks...
  if (millis() > (durationToCheck + 5000)) {

    // Where are we right now
    durationToCheck = millis();

    // Publish Door Status
    if (digitalRead(PINCLOSED) == LOW ) {
      doorState = DOOROPEN;
    }
    else if (digitalRead(PINOPEN) == LOW ) {
      doorState = DOORCLOSED;
    }
    else {
      doorState = DOORPARTIAL;
    }

    // Send message
    PublishMQTTMessage(OPENHABPUBDOORSTATUS, String(doorState));

    // Read and send humidity
    fHumidity = dht.readHumidity();
    PublishMQTTMessage(OPENHABPUBHUMIDITY, String(fHumidity));
  
    // Read and send temperature
    fTemperature = dht.readTemperature();
    PublishMQTTMessage(OPENHABPUBTEMPERATURE, String(fTemperature));
  
  }
  
  // Do it all over again
  mqttClient.loop();
  
}


// Print IP for debugging, can be removed if needed
void printIPAddress()
{
  Serial.print("My IP address: ");
  
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }

  Serial.println();
}


// Publish MQTT data to MQTT broker
void PublishMQTTMessage(const char* sMQTTSubscription, String sMQTTData)
{

  // Define and send message about door state
  sMQTTData.toCharArray(message_buff, sMQTTData.length()+1);
  mqttClient.publish(sMQTTSubscription, message_buff); 

  // Debug info
  Serial.println("Outbound: " + String(sMQTTSubscription) +":"+ message_buff);
 
}

 

 

More information:

http://www.chimera.co.nz/electronics/garage-door.ino

 

Description:

The following outlines how to build an Arduino Garage Door Opener that integrates into OpenHAB/MQTT. This is designed to work with an Arduino Uno Rev3 with Ethershield board .

OpenHAB and Mosquitto:

 

The Arduino code has been written specifically to work with Open HAB(open source home automation software) and an MQTT broker such as Mosquitto (a messaging subscribe/publish type protocol that is lightweight and great for communication between devices) Don’t let the names or acronyms scare you, they are really quite simple to use once you get to know how they work. I utilise OpenHAB on a NTC C.H.I.P  however many people use a Raspberry Pi or similar. This tutorial assumes you have implemented OpenHAB .

To install Mosquitto, following this link then select the type of device you are using and follow the instructions. Because C.H.I.P runs Debian (Jessie), you can follow the Raspberry Pi instructions if you are using C.H.I.P. for your Home Automation device (also note, its best to reconfigure CHIP to boot from the CLI. There are instructions for this here)

Once you have OpenHAB and Mosquitto running, you need to prepare the Arduino IDE for the code below. First, you need to add the PubSubClient library. In the Arduino IDE, from the menu’s go to Sketch, Include Library, Manage LibrariesIn the filter search box, type PubSubClient then highlight the search result and click to Install (at time of writing, the latest version is 2.6.0) You will also need the Ethernet library which covers extensions for the Ethernet shield.

The Garage Door opener does 2 things. First, it provides a button in OpenHAB to activate the door to open or close. Secondly it provides feedback to OpenHAB on the status of the door (either open, closed or partially open)

Hardware:

• Arduino uno R3

• Ethernet Shield

• 5 V relay

• 1K resistor

• Transistor(2N2222)

•Diodes

• Reed Swictes

The resistor, transistor and diode help create the circuit to the relay, which is triggered by a button in OpenHAB to open/close the door. The reed switches provide feedback to OpenHAB as to the garage doors status. These parts can be sourced cheaply from any electronics shop. Using these components is also the recommended way to configure the Arduino with a relay as per the Arduino site (note: the LED on the breadboard below is simply for test purposes, the red/black wires will usually go to the garage door opener)

180

With the garage door in an ‘open’ state as shown below, clicking the ‘Close’ button will trigger OpenHAB to send an MQTT message to the Arduino, the Arduino will then open the relay for 1 second, causing the door to close. The (door open) reed switch will become open which the Arduino will pick up and send a new door status back to OpenHAB which will then display the updated status ‘Partially Open’ until the door fully closes, at which stage the (door closed) reed switch will close, this will be detected by the Arduino which will then send a new message to the MQTT broker and status will then update to ‘Closed’ .

182

 

// Define Libraries
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>;

// Define Sub's and Pub's
const char* OPENHABSUBDOORSWITCH = "openhab/garage/doorswitch";
const char* OPENHABPUBDOORSTATUS = "openhab/garage/doorstatus";
const char* OPENHABPUBHUMIDITY = "openhab/garage/humidity";
const char* OPENHABPUBTEMPERATURE = "openhab/garage/temperature";

// Define Arduino PIN's
#define PINRELAY 7    // Relay module - trigger door here
#define PINLED 13     // Onboard LED - Activation Indicator
#define PINOPEN 5     // Door Open PIN - Reed switch for door open
#define PINCLOSED 6   // Door Closed PIN - Reed switch for door shut
#define PINDHT 2      // DHT22 PIN - Humidity and Temperature readings

// Declare DHT22 sensor for 16Mhz Arduino
DHT dht(PINDHT, DHT22); 

// DHT22 Variables
float fHumidity;
float fTemperature;

// Door states
enum doorStates {
  DOOROPEN = 0,
  DOORCLOSED = 1,
  DOORPARTIAL = 2,
};

// Initial door state (assume neither closed nor open when starting)
doorStates doorState = DOORPARTIAL;

// MQTT Broker
IPAddress MQTT_SERVER(192, 168, 222, 254);

// The IP address of the Arduino
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Remove remarks and alter if you want a fixed IP for the Arduino
// IPAddress ip(192, 168, 222, 100);

// Delay timer
unsigned long durationToCheck = 0;

// Define message buffer and publish string
char message_buff[10];
String pubString;

// Ethernet Initialisation
EthernetClient ethClient;


// Callback to Arduino from MQTT (inbound message arrives for a subscription - in this case the door on/off switch)
void callback(char* topic, byte* payload, unsigned int length) 
{

  // MQTT Inbound messaging 
  int iChar = 0;
  for(iChar=0; iChar<length; iChar++) {
    message_buff[iChar] = payload[iChar];
  }
  message_buff[iChar] = '\0';

  // Convert buffer to string
  String msgString = String(message_buff);
  Serial.println("Inbound: " + String(topic) +":"+ msgString);
  
  // Only open if not already open, only close if not already closed
  if ( (msgString == "ACTIVATE" && doorState != DOOROPEN) || (msgString == "DEACTIVATE" && doorState != DOORCLOSED) ) 
  {

    Serial.println("Activating Relay");
    digitalWrite(PINRELAY, HIGH);
    digitalWrite(PINLED, LOW);
    delay(1000); 
    digitalWrite(PINRELAY, LOW);
    digitalWrite(PINLED, HIGH);

  }
}

// Define Publish / Subscribe client (must be defined after callback function above)
PubSubClient mqttClient(MQTT_SERVER, 1883, callback, ethClient);


void setup() {

  // LED off, visual indicator when triggered
  pinMode(PINLED, OUTPUT);
  digitalWrite(PINLED, LOW);

  // Reed switch pins are inputs, activate internal pullup resistor by writing high
  pinMode(PINCLOSED, INPUT);
  digitalWrite(PINCLOSED, HIGH);
  pinMode(PINOPEN, INPUT);
  digitalWrite(PINOPEN, HIGH);

  // Start Network (replace with 'Ethernet.begin(mac, ip);' for fixed IP)
  while (Ethernet.begin(mac) == 0) {
    Serial.println("Could not obtain DHCP lease");
    delay(5000);
  }

  // Let network have a chance to start up
  delay(1500);

  // Start Serial
  Serial.begin(9600);

  // DHT Sensor
  dht.begin();

  // Display IP for debugging purposes
  printIPAddress();

}

void loop() {

  // If not MQTT connected, try connecting
  if (!mqttClient.connected())  {

    // Connect to MQTT broker on the openhab server, retry constantly
    while (mqttClient.connect("garagedoor") != 1) {
      Serial.println("Error connecting to MQTT (State:" + String(mqttClient.state()) + ")");
      delay(1000);
    }
    
    // Subscribe to the activate switch on OpenHAB
    mqttClient.subscribe(OPENHABSUBDOORSWITCH);

  }
  
  // Wait a little bit between status checks...
  if (millis() > (durationToCheck + 5000)) {

    // Where are we right now
    durationToCheck = millis();

    // Publish Door Status
    if (digitalRead(PINCLOSED) == LOW ) {
      doorState = DOOROPEN;
    }
    else if (digitalRead(PINOPEN) == LOW ) {
      doorState = DOORCLOSED;
    }
    else {
      doorState = DOORPARTIAL;
    }

    // Send message
    PublishMQTTMessage(OPENHABPUBDOORSTATUS, String(doorState));

    // Read and send humidity
    fHumidity = dht.readHumidity();
    PublishMQTTMessage(OPENHABPUBHUMIDITY, String(fHumidity));
  
    // Read and send temperature
    fTemperature = dht.readTemperature();
    PublishMQTTMessage(OPENHABPUBTEMPERATURE, String(fTemperature));
  
  }
  
  // Do it all over again
  mqttClient.loop();
  
}


// Print IP for debugging, can be removed if needed
void printIPAddress()
{
  Serial.print("My IP address: ");
  
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }

  Serial.println();
}


// Publish MQTT data to MQTT broker
void PublishMQTTMessage(const char* sMQTTSubscription, String sMQTTData)
{

  // Define and send message about door state
  sMQTTData.toCharArray(message_buff, sMQTTData.length()+1);
  mqttClient.publish(sMQTTSubscription, message_buff); 

  // Debug info
  Serial.println("Outbound: " + String(sMQTTSubscription) +":"+ message_buff);
 
}

 

 

More information:

http://www.chimera.co.nz/electronics/garage-door.ino

 

COMMENTS

Please Login to comment
  Subscribe  
Notify of