Example sketches for the new Arduino IDE for ESP8266

Moderator: igrr

User avatar
By swilson
#15448 Been working on this Wifi Garage Door Opener and finally got password protection on the webpage. Just thought I would post the sketch I am using. This will load a webserver with status of the door and a button to activate the door. It refreshes the page automatically every 10 seconds to update the status. In order to activate the door you have to put in a valid 4 digit code. The door is sensed at a closed state via a magnetic door switch. GPIO5 is connected to the high level input trigger of a 5V relay and is pulled HIGH for 1 second when the button is pressed on the page.

The ESP-12 is soldered to a smd adapter with onboard LDO from Electrodragon. I am powering the relay and esp via a 5V 1A power brick.

This example works but I may work on stream lining it a bit. Possibly add more features.

Code: Select all/* IoT Garage Door Opener
/ This is a sketch for the ESP8266, ESP-12 in my case, using the Arduino IDE for ESP8266.  This sketch will allow you to see the current
/ state of the garage door using a magnetic switch on the garage door, one side connected to pin 4 of the ESP-12 and the other side
/ connected to ground.  Doing this pulls pin 4 LOW when the Garage Door is closed completely.  The webpage updates every 10 seconds
/ in order to update the status of the door.  It is possible to add another magnetic switch to show when the door is fully open by
/ tieing it to another pin the same way.  You would have to change the code for the new pin.
/ Activating the button for the door requires a 4 digit pass code.
/
/ To open the door I am using a High level triggered single 5V relay.  I am pulling pin 5 LOW in setup then high for 1 second to 
/ trigger the door.  ESP os on a smd adapter frpm Electrodragon. I am powering the ESP and the relay using a 5V 1A power adapter.
*/
#include <ESP8266WiFi.h>

int openClosePin = 5;
int statusPin = 4;

String doorClosed = "<form action='/GDOOR=ACTIVATE'><input type='submit' VALUE='Open the Door' style='height:50px; width:225px'></form>";
String doorOpen = "<form action='/GDOOR=ACTIVATE'><input type='submit' VALUE='Close the Door' style='height:50px; width:225px'></form>";
String passCode = "<form METHOD=get action=''><input type=password name='code' size='4' maxlength='4'><input type=submit name='Submit' value='Code'></form>";

WiFiServer server(8100);

//*-- IoT Information
const char* SSID = "network_name";
const char* PASS = "network_pass";
char codeOK='0';//start Code is blank....

void setup() {
    Serial.begin(115200);
    pinMode(openClosePin, OUTPUT);
    pinMode(statusPin, INPUT);
    digitalWrite(openClosePin, LOW);
    delay(50);
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(SSID);
    
    WiFi.begin(SSID, PASS);
    
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    delay(1000);
    
    //Start the server
    server.begin();
    Serial.println("Server started");
    
    //Print the IP Address
    Serial.print("Use this URL to connect: ");
    Serial.print("http://");
    Serial.print(WiFi.localIP());
    Serial.println("/");
    delay(1000);
}

void loop() {
  
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
   
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
   
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
  
  // Set the code
  if (request.indexOf("/?code=xxxx&Submit=Code")>0) {
    codeOK='1';
    Serial.print("codeOK=");
    Serial.println(codeOK);
  }
  // Match the request
  if (codeOK == '1') {
    if (request.indexOf("/GDOOR=ACTIVATE") != -1) {
      digitalWrite(openClosePin, HIGH);
      Serial.println("Relay is On");
      delay(1000);
      digitalWrite(openClosePin, LOW);
      Serial.println("Relay is Off");
      codeOK='0';
    }   
  }

  // Return the response
  client.println("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
  //client.println("Content-Type: text/html");
  //client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n<title>IoT Garage Door</title>");
  //client.println("<html>");
  //client.println("<head>");
  //client.println("<title>IoT Garage Door</title>");
  client.println("<meta name='viewport' content='width=device-width', initial-scale='1'>");
  client.println("<meta http-equiv='refresh' content='9; URL=http://xxx.xxx.xxx.xxx:8100'>\r\n</head>");
  //client.println("</head>");
  client.println("<body>\r\n<center>\r\n<h1>IoT Garage Door Opener</h1>\r\n<hr>\r\n<br><form name='counter'>Refreshing page in: <input type='text' size='1' name='d2'>seconds</form><br>\r\nGarage Door is now: ");
  //client.println("<center>");
  //client.println("<h1>IoT Garage Door Opener</h1>");
  //client.println("<hr>");
  //client.print("<br>");
  //client.print("Garage Door is now: ");
  
  int closed;
  int doorState = digitalRead(statusPin);
  if (doorState == LOW) {
    client.print("<span style='background-color:#00FF00; font-size:18pt'>Closed</span>\r\n<br>");
    Serial.println("Closed");
    closed = 1;  
    } 
    else {
    client.print("<span style='background-color:#FF0000; font-size:18pt'>Open</span>\r\n<br>");
    Serial.println("Open");
    closed = 0;
  }
  client.println("<script>\r\n<!--\r\n'//'\r\nvar milisec=0\r\nvar seconds=11\r\ndocument.counter.d2.value='15'\r\nfunction display(){\r\nif (milisec<=0){\r\nmilisec=9\r\nseconds-=1\r\n}\r\nif (seconds<=-1){\r\nmilisec=0\r\nseconds+=1\r\n}\r\nelse\r\nmilisec-=1\r\ndocument.counter.d2.value=seconds\r\nsetTimeout('display()',100)\r\n}\r\ndisplay()\r\n-->\r\n</script>\r\n<br><br>");
  client.println(passCode);
  client.println("<br>");
  if (closed == 1) { 
  client.println(doorClosed + "</center>\r\n</html>");
  } else
  {
  client.println(doorOpen + "</center>\r\n</html>");
  }
  //client.println("</center>\r\n</html>");
  //client.println("</html>");
 
  delay(1);
  Serial.println("Client disconnected");
  Serial.println("");

}



gardooropen.jpg
You do not have the required permissions to view the files attached to this post.
Last edited by swilson on Fri May 01, 2015 9:40 pm, edited 1 time in total.
User avatar
By swilson
#16240 Got a new version of this project with a little different approach. Using AJAX to update only the status of the door every second and not the whole page. Only thing that reloads the page is when you submit the pass code. Still may be a few bugs to work out and I am not sure if the watchdog works correctly all the time. I have seen certain times if you get just wdt reset it won't restart and requires power cycling. Anyway here is the updated code.

Code: Select all/* IoT Garage Door Opener
/ This is a sketch for the ESP8266, ESP-12 in my case, using the Arduino IDE for ESP8266.  This sketch will allow you to see the current
/ state of the garage door using a magnetic switch on the garage door, one side connected to pin 4 of the ESP-12 and the other side
/ connected to ground.  Doing this pulls pin 4 LOW when the Garage Door is closed completely.  The webpage updates (doesn't reload) via AJAX every 1 second
/ in order to update the status of the door.  It is possible to add another magnetic switch to show when the door is fully open by
/ tieing it to another pin the same way.  You would have to add the code for the new pin.
/ Activating the button for the door requires a 4 digit pass code.  If you put in the code and then close the browser or app you are using
/ and then log back on you will have to re-enter the code again.  That is done in case you enter the code and close the browser and someone else logs on.
/ They would be able to activate the door since the ESP would still think that codeOK=1.  Each client connect sets codeOK=0 right off the bat.
/
/ To open the door I am using a High level triggered single 5V relay.  I am pulling pin 5 LOW in setup then high for 1 second to
/ trigger the door.  ESP is on a smd adapter with onboard LDO (5v to 3.3V voltage regultor) from Electrodragon. I am powering the ESP and the relay using a 5V 1A power adapter.
/
/ I am using watchdog to detect any crashes and hopefully restart the software.  I am not completely sure the watchdog works yet.
/ I hope they mplement watchdog interrupt capability in the near future.
*/
#include <ESP8266WiFi.h>
extern "C" {
  #include "user_interface.h"
}

int openClosePin = 5;
int statusPin = 4;

String HTTP_req;
String code;

WiFiServer server(8100);

//*-- IoT Information
const char* SSID = "xxxxxx";
const char* PASS = "xxxxxxxxx";
const char* pass_sent = "xxxx";
char codeOK='0';//start Code is blank....

void setup() {
    ESP.wdtDisable();
    Serial.begin(115200);
    pinMode(openClosePin, OUTPUT);
    pinMode(statusPin, INPUT);
    digitalWrite(openClosePin, LOW);
    delay(50);
    Serial.print(F("Connecting to "));
    Serial.println(F(SSID));
    wifi_set_opmode(WIFI_STA);
    WiFi.begin(SSID, PASS);
   
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(F("."));
    }
    Serial.println(F(""));
    Serial.println(F("WiFi connected"));
    delay(1000);
    ESP.wdtEnable(WDTO_4S);
    //Start the server
    server.begin();
    Serial.println(F("Server started"));
   
    //Print the IP Address
    Serial.print(F("Use this URL to connect: "));
    Serial.print(F("http://"));
    Serial.print(F(WiFi.localIP()));
    Serial.println(F("/"));
    delay(1000);
}

void loop() {
  delay(0);
  // Check if a client has connected
  WiFiClient client = server.available();
 
  // Return the response
  if (client) {  // got client?
    boolean currentLineIsBlank = true;
    codeOK='0';
    while (client.connected()) {
      if (client.available()) {   // client data available to read
        char c = client.read(); // read 1 byte (character) from client
        HTTP_req += c;  // save the HTTP request 1 char at a time
        // last line of client request is blank and ends with \n
        // respond to client only after last line received
        if (c == '\n' && currentLineIsBlank) {
          client.println(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: keep-alive"));
          client.println();
          if (HTTP_req.indexOf("ajax_switch") > -1) {
            // read switch state and send appropriate paragraph text
            GetSwitchState(client);
            delay(0);
          }
          else {  // HTTP request for web page
            // send web page - contains JavaScript with AJAX calls
            client.print(F("<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<title>IoT Garage Door</title>\r\n<meta name='viewport' content='width=device-width', initial-scale='1'>"));
            client.print(F("<script>\r\nfunction GetSwitchState() {\r\nnocache = \"&nocache=\" + Math.random() * 1000000;\r\nvar request = new XMLHttpRequest();\r\nrequest.onreadystatechange = function() {\r\nif (this.readyState == 4) {\r\nif (this.status == 200) {\r\nif (this.responseText != null) {\r\ndocument.getElementById(\"switch_txt\").innerHTML = this.responseText;\r\n}}}}\r\nrequest.open(\"GET\", \"ajax_switch\" + nocache, true);\r\nrequest.send(null);\r\nsetTimeout('GetSwitchState()', 1000);\r\n}\r\n</script>\n"));
            client.print(F("<script>\r\nfunction DoorActivate() {\r\nvar request = new XMLHttpRequest();\r\nrequest.open(\"GET\", \"door_activate\" + nocache, true);\r\nrequest.send(null);\r\n}\r\n</script>\n"));
            client.print(F("</head>\r\n<body onload=\"GetSwitchState()\">\r\n<center><h1>IoT Garage Door</h1><hr>\r\n<div id=\"switch_txt\">\r\n</div>\r\n<br>\n"));
            client.print(F("Input password to control Garage Door.\r\n<br><br><form name=\"passcode\" onSubmit=\"GetCode()\"><input type=\"password\" name=\"password\" size='8' maxlength='4'>&nbsp;<input type=submit name=\"Submit\" value=\"Submit\" onClick=\"GetCode()\" style='height:22px; width:80px'></form><br><br>\n"));
            if (HTTP_req.indexOf(pass_sent) > 0) {
              GetCode();
            }
            if (codeOK == '0') {
              client.print(F("<button type=\"button\" disabled style='height:50px; width:225px'>Activate the Door</button><br><br>\n"));
            }
            if (codeOK == '1') {
            client.print(F("<button type=\"button\" onclick=\"DoorActivate()\" style='height:50px; width:225px'>Activate the Door</button><br><br>\n"));
            }
            client.println(F(system_get_free_heap_size()));
            if (HTTP_req.indexOf("door_activate") > -1) {
            // read switch state and send appropriate paragraph text
            DoorActivate();
            }
            //}
            client.println(F("</body>\r\n</html>"));
            delay(0);
          } 
 
          // display received HTTP request on serial port
          Serial.println(F(HTTP_req));
          HTTP_req = "";            // finished with request, empty string
          break;
        }
        // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                  }
                  else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                  }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
        delay(0);
    } // end if (client)
}

// send the state of the switch to the web browser
void GetSwitchState(WiFiClient cl) {
    if (digitalRead(4)) {
      cl.println(F("<p>Garage Door is currently: <span style='background-color:#FF0000; font-size:18pt'>Open</span></p>"));
    }
    else {
      cl.println(F("<p>Garage Door is currently: <span style='background-color:#00FF00; font-size:18pt'>Closed</span></p>"));
    }
  }
 
  void GetCode() {
      codeOK='1';
  }
 
  void DoorActivate() {
    digitalWrite(openClosePin, HIGH);
    delay(1000);
    digitalWrite(openClosePin, LOW);
    codeOK='0';
  }


iotgdoor.jpg
You do not have the required permissions to view the files attached to this post.
Last edited by swilson on Sat May 02, 2015 10:06 pm, edited 1 time in total.