├── README.md ├── GarageDoorOpenerV2.ino └── GarageDoorOpener.ino /README.md: -------------------------------------------------------------------------------- 1 | # MQTT_ESP8266_Garage_Door 2 | Sample code shows how to use an MSP8266 for a MQTT connected garage door opener. 3 | The ESP8277 publishes door status (opened or closed) and listens for commands to open or close the door. There also is a loop to read a thermistor and send back tmeperature. 4 | 5 | Youtube video for the garage door opener here https://youtu.be/X4qXy2JFg_w 6 | My Blog with more projects http://ElectronHacks.com 7 | Youtube MQTT Playlist https://www.youtube.com/playlist?list=PLkIA6OiRuCWa-H9IqUinyZlpg3te4qTuU 8 | 9 | The first sketch works with the Arduino IDE version 1.6.5 and older, after this there was a bug in the ide that they don't plan to fix. A prblem where the function prototype is created before it's referred to in the client object instantiation. Information here: http://forum.arduino.cc/index.php?topic=370284.0 10 | 11 | The V2 code works well with Arduino IDE1.6.13. 12 | -------------------------------------------------------------------------------- /GarageDoorOpenerV2.ino: -------------------------------------------------------------------------------- 1 | /* 2 | //######################################################################## 3 | //# ESP8266 MQTT Garage Door Opener with Temperature # 4 | //# Code refactored 12/27/2016 to work with the new Arduinio IDE 1.6.13 # 5 | //# Blog post, videos, and code can be found at www.electronhacks.com # 6 | //######################################################################## 7 | */ 8 | 9 | 10 | #include 11 | #include 12 | 13 | //Variables 14 | //Update these with values suitable for your network. 15 | const char* ssid = "shp"; 16 | const char* password = "fef105ec00"; 17 | const char* mqtt_server = "10.100.100.181"; 18 | const char* mqtt_topic = "GarageDoor/"; 19 | const char* mqtt_user = "guest"; 20 | const char* mqtt_password = "12345"; 21 | 22 | char vInp13 = 0; 23 | String rx; 24 | int rxLength = 0; 25 | //Analog input variables 26 | int vA0 = 0; 27 | int iA0 = 0; 28 | int Counter = 0; 29 | 30 | WiFiClient espClient; 31 | PubSubClient client(espClient); 32 | long lastMsg = 0; 33 | char msg[50]; 34 | int value = 0; 35 | 36 | void setup() { 37 | pinMode(5, OUTPUT); 38 | pinMode(13, INPUT_PULLUP); 39 | 40 | //pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output 41 | Serial.begin(115200); 42 | setup_wifi(); 43 | client.setServer(mqtt_server, 1883); 44 | client.setCallback(callback); 45 | } 46 | 47 | void setup_wifi() { 48 | 49 | delay(10); 50 | // We start by connecting to a WiFi network 51 | Serial.println(); 52 | Serial.print("Connecting to "); 53 | Serial.println(ssid); 54 | 55 | WiFi.begin(ssid, password); 56 | 57 | while (WiFi.status() != WL_CONNECTED) { 58 | delay(500); 59 | Serial.print("."); 60 | } 61 | 62 | Serial.println(""); 63 | Serial.println("WiFi connected"); 64 | Serial.println("IP address: "); 65 | Serial.println(WiFi.localIP()); 66 | } 67 | 68 | void callback(char* topic, byte* payload, unsigned int length) {\ 69 | Serial.print("RX: "); 70 | //Convert and clean up the MQTT payload messsage into a String 71 | rx = String((char *)payload); //Payload is a Byte Array, convert to char to load it into the "String" object 72 | rxLength = rx.length(); //Figure out how long the resulting String object is 73 | for (int i = length; i <= rxLength; i++) //Loop through setting extra characters to null as garbage may be there 74 | { 75 | rx.setCharAt(i, ' '); 76 | } 77 | rx.trim(); //Use the Trim function to finish cleaning up the string 78 | Serial.print(rx); //Print the recieved message to serial 79 | Serial.println(); 80 | 81 | //Evaulate the recieved message to do stuff 82 | if ((rx == "OpenGarageDoor") && (vInp13 == HIGH)) 83 | {digitalWrite(5, 1);} //Turn the output on / open the door 84 | delay(1000); //Wait a second 85 | digitalWrite(5, 0); //Turn the output back off 86 | delay(1000); //Let Voltage settle before resuming. 87 | 88 | if ((rx == "CloseGarageDoor") && (vInp13 == LOW)) 89 | {digitalWrite(5, 1);} //Turn the output on / close the door 90 | delay(1000); //Wait a second 91 | digitalWrite(5, 0); //Turn the output back off 92 | delay(1000); //Let Voltage settle before resuming. 93 | 94 | /*Serial.print("Message arrived ["); 95 | Serial.print(topic); 96 | Serial.print("] "); 97 | for (int i = 0; i < length; i++) { 98 | Serial.print((char)payload[i]); 99 | } 100 | Serial.println(); 101 | 102 | // Switch on the LED if an 1 was received as first character 103 | if ((char)payload[0] == '1') { 104 | digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level 105 | // but actually the LED is on; this is because 106 | // it is acive low on the ESP-01) 107 | } else { 108 | digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH 109 | }*/ 110 | 111 | } 112 | 113 | void reconnect() { 114 | // Loop until we're reconnected 115 | while (!client.connected()) { 116 | Serial.print("Attempting MQTT connection..."); 117 | // Attempt to connect 118 | if (client.connect(mqtt_topic,mqtt_user,mqtt_password)) { 119 | Serial.println("connected"); 120 | // Once connected, publish an announcement... 121 | client.publish(mqtt_topic, "hello world"); 122 | // ... and resubscribe 123 | client.subscribe(mqtt_topic); 124 | } else { 125 | Serial.print("failed, rc="); 126 | Serial.print(client.state()); 127 | Serial.println(" try again in 5 seconds"); 128 | // Wait 5 seconds before retrying 129 | delay(5000); 130 | } 131 | } 132 | } 133 | void loop() { 134 | 135 | if (!client.connected()) { 136 | reconnect(); 137 | } 138 | 139 | ///// Evaluate input 13 and send a message if the value changes 140 | if (digitalRead(13) != vInp13) 141 | { 142 | vInp13 = digitalRead(13); 143 | if (vInp13 == LOW) 144 | { 145 | client.publish(mqtt_topic, "DoorOpened"); 146 | Serial.println("TX: DoorOpened"); 147 | } 148 | else 149 | { 150 | client.publish(mqtt_topic, "DoorClosed"); 151 | Serial.println("TX: DoorClosed"); 152 | } 153 | } 154 | //Evaluate ADC 155 | /* iA0 = analogRead(A0); // Read the analog value 156 | if (Counter >= 150) // Counter reduces how often we update to help prevent broker spam 157 | { 158 | Counter = 0; 159 | //if (1==1) //For testing and scaling, 160 | if (((iA0 * 1.02) < vA0) or ((iA0 * 0.98) > vA0)) //(Deadband)Only Update if the raw value is +- 10% 161 | { 162 | vA0 = iA0; //Set the variables equal to eachother for next time comparison 163 | iA0 = ((iA0/9.76)+12); //Scale and offset the value to Degrees F https://www.youtube.com/watch?v=ub20R9WnH-g 164 | String str = (String)iA0; //PubSubClient requires data to be a char* (char array) so we have to convert the int 165 | int str_len = str.length() +1; //Length + null terminator 166 | char char_array[str_len]; //Prepare the character array (buffer) 167 | str.toCharArray(char_array, str_len); // Copy it over 168 | client.publish(mqtt_topic, char_array); // Publish to MQTT 169 | Serial.print("TX: RAW: "); // Print to Seral window 170 | Serial.print(vA0); 171 | Serial.print(" Scaled: "); // Print to Seral window 172 | Serial.println(iA0); 173 | } 174 | } 175 | else 176 | { 177 | Counter++; 178 | } */ 179 | 180 | 181 | client.loop(); 182 | 183 | //long now = millis(); 184 | //if (now - lastMsg > 2000) { 185 | // lastMsg = now; 186 | // ++value; 187 | // snprintf (msg, 75, "hello world #%ld", value); 188 | // Serial.print("Publish message: "); 189 | // Serial.println(msg); 190 | // client.publish(mqtt_topic, msg); 191 | //} 192 | delay(10); 193 | } 194 | -------------------------------------------------------------------------------- /GarageDoorOpener.ino: -------------------------------------------------------------------------------- 1 | //######################################################################## 2 | //# ESP8266 MQTT Garage Door Opener with Temperature # 3 | //# Blog post, videos, and code can be found at www.electronhacks.com # 4 | //######################################################################## 5 | 6 | 7 | //##### Declarations and Variables ##### 8 | #include 9 | #include 10 | char vInp13 = 0; 11 | int vA0 = 0; 12 | int iA0 = 0; 13 | int Counter = 0; 14 | String rx; 15 | int rxLength = 0; 16 | float tempaverage = 0; 17 | float temparray[9]; 18 | int arraycounter = 0; 19 | bool startup = 1; 20 | 21 | //Configuration, enter your own values here 22 | char ssid[] = "Your Wifi SSID"; // your network name also called SSID 23 | char password[] = "Your Wifi Password"; // your network password 24 | char server[] = "192.168.1.165"; // MQTT Server IP or machine name 25 | char topic[] = "GarageDoor/"; // MQTT Topic 26 | char mQTTID[] = "ESP8266GarageDoor"; // MQTT ID. Make this unique for each device connecting to the MQTT Broker or they will disconnect eachother! 27 | char mQTTUser[] = "MQTTuser"; // MQTT UserName (See below for modification if you don't use user and password) 28 | char mQTTPassword[] = "MQTTPass"; // MQTT Password (See below for modification if you don't use user and password) 29 | 30 | WiFiClient wifiClient; 31 | PubSubClient client(server, 1883, callback, wifiClient); 32 | 33 | 34 | //##### Void Setup, runs once on startup ##### 35 | void setup() 36 | { 37 | pinMode(5, OUTPUT); 38 | pinMode(13, INPUT_PULLUP); 39 | 40 | Serial.begin(115200); 41 | Serial.print("Attempting to connect to Network named: "); 42 | Serial.println(ssid); 43 | WiFi.begin(ssid, password); 44 | while ( WiFi.status() != WL_CONNECTED) 45 | { 46 | Serial.print("."); // print dots while we wait to connect 47 | delay(300); 48 | } 49 | 50 | Serial.println("\nYou're connected to the network"); 51 | Serial.println("Waiting for an ip address"); 52 | while (WiFi.localIP() == INADDR_NONE) 53 | { 54 | Serial.print("."); // print dots while we wait for an ip addresss 55 | delay(300); 56 | } 57 | Serial.println("\nIP Address obtained"); 58 | } 59 | 60 | 61 | 62 | 63 | //##### Main Program ##### 64 | void loop() 65 | { 66 | //Reconnect if we are not subscribed to the LaunchPad/In topic 67 | if (!client.connected()) { 68 | Serial.println("Disconnected. Reconnecting...."); 69 | delay(30000); //Wait 30 seconds between connection attempts 70 | if(!client.connect(mQTTID, mQTTUser, mQTTPassword)) { //Use this line if you have a User or Password for the MQTT Broker 71 | //if(!client.connect(mQTTID)) { //Use this line if you don't have a User or Password for the MQTT Broker 72 | Serial.println("Connection failed"); 73 | } else { 74 | Serial.println("Connection success"); 75 | if(client.subscribe(topic)) { 76 | Serial.println("Subscription successfull"); 77 | } 78 | } 79 | } 80 | 81 | ///// Evaluate input 13 and send a message if the value changes 82 | if (digitalRead(13) != vInp13) 83 | { 84 | vInp13 = digitalRead(13); 85 | if (vInp13 == LOW) 86 | { 87 | client.publish(topic, "DoorOpened"); 88 | Serial.println("TX: DoorOpened"); 89 | } 90 | else 91 | { 92 | client.publish(topic, "DoorClosed"); 93 | Serial.println("TX: DoorClosed"); 94 | } 95 | } 96 | 97 | //#############Evaluate the analog input############### 98 | if (Counter >= 20) // Counter reduces how often we update to help prevent broker spam 99 | { 100 | Counter = 0; 101 | if (startup == 1){ // Load all 10 slots in the array if this is startup so we don't get wonky readings 102 | iA0 = analogRead(A0); // Read the analog value 103 | iA0 = ((iA0/5.2)-53); //Scale and offset the value to Degrees F 104 | for (int i = 0; i < 10; i++){ 105 | temparray[i] = iA0; 106 | } 107 | startup = 0; 108 | } 109 | 110 | iA0 = analogRead(A0); // Read the analog value 111 | iA0 = ((iA0/9.76)+16); //Scale and offset the value to Degrees F 112 | if (arraycounter >= 9) { //If the counter reaches 9 set it back to 0 113 | arraycounter = 0;} 114 | else{ 115 | arraycounter ++;} //Otherwise increment the array counter 116 | temparray[arraycounter] = iA0; //Load one slot in the array, this loops through the slots on each execution 117 | 118 | if (((iA0 * 1.02) < vA0) or ((iA0 * 0.98) > vA0)) //(Deadband)Only Update if the raw value is +- whatever % you choose 119 | { 120 | vA0 = iA0; //Set the saved temp equal to the current temp for next time comparison 121 | tempaverage = ((temparray[0] + temparray[1] + temparray[2] + temparray[3] + temparray[4] + temparray[5]+ temparray[6]+ temparray[7]+ temparray[8]+ temparray[9])/10); 122 | String str = (String)tempaverage; //PubSubClient requires data to be a char* (char array) so we have to convert the int 123 | int str_len = str.length() +1; //Length + null terminator 124 | char char_array[str_len]; //Prepare the character array (buffer) 125 | str.toCharArray(char_array, str_len); // Copy it over 126 | client.publish(GarageTemp, char_array); // Publish to MQTT 127 | Serial.println("TX: Temperature: " + String(tempaverage) + " RAW:" + String(analogRead(A0))); // Print to Seral window 128 | //iA0 = ((iA0/9.76)+16); 129 | } 130 | } 131 | else 132 | { 133 | Counter++; 134 | } 135 | 136 | client.loop(); // Check if any subscribed messages were received 137 | delay(10); 138 | } 139 | 140 | 141 | 142 | //##### Subroutines ##### 143 | ///// VOID CALLBACK - prints to the serial monitor if we recieve a MQTT message ///// 144 | void callback(char* topic, byte* payload, unsigned int length) 145 | { 146 | Serial.print("RX: "); 147 | //Convert and clean up the MQTT payload messsage into a String 148 | rx = String((char *)payload); //Payload is a Byte Array, convert to char to load it into the "String" object 149 | rxLength = rx.length(); //Figure out how long the resulting String object is 150 | for (int i = length; i <= rxLength; i++) //Loop through setting extra characters to null as garbage may be there 151 | { 152 | rx.setCharAt(i, ' '); 153 | } 154 | rx.trim(); //Use the Trim function to finish cleaning up the string 155 | Serial.print(rx); //Print the recieved message to serial 156 | Serial.println(); 157 | 158 | //Evaulate the recieved message to do stuff 159 | if ((rx == "OpenGarageDoor") && (vInp13 == HIGH)){digitalWrite(5, 1);} //Turn the output on / open the door 160 | delay(1000); //Wait a second 161 | digitalWrite(5, 0); //Turn the output back off 162 | delay(1000); //Let Voltage settle before resuming. 163 | 164 | if ((rx == "CloseGarageDoor") && (vInp13 == LOW)){digitalWrite(5, 1);} //Turn the output on / close the door 165 | delay(1000); //Wait a second 166 | digitalWrite(5, 0); //Turn the output back off 167 | delay(1000); //Let Voltage settle before resuming. 168 | 169 | } 170 | 171 | 172 | 173 | --------------------------------------------------------------------------------