I try to modify the Webserver with password example to be used for garage door opener. I want to use an ESP-01 for this purpose. Pin 0 will be used as a trigger and Pin 2 as the status indicator. I think I know how to do the trigger part and I can read Pin 2 and change its status with no problem. The issue is, once I the Pin 2’s status is changed, I don’t know how to let the server send a web page without click a button on the client.
I think this is similar to the question regarding the garage door opener that was asked before but the setup there seems too complex to me. Maybe Rui or someone else can give me some hint?
Thanks in advance.
Hi, use Ajax to update web page
- circuits4you.com/2018/02/04/esp8266-ajax-update-part-of-web-page-without-refreshing/
- https://randomnerdtutorials.com/esp8266-dht11dht22-temperature-and-humidity-web-server-with-arduino-ide/
from the code
////////////////////////////////////////////////////////////////////////////////////// <button type="button" onclick="sendData(1)">LED ON</button> is calls function sendData(led) { // here led = 1 var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("LEDState").innerHTML = this.responseText; } }; xhttp.open("GET", "setLED?LEDstate="+led, true); //sen xhttp.send(); //which sends /setLED?LEDstate=1 to server //////////////////////////////////////////////////////////////////////////////// Server part /////////////////////////////////////////////////////////////////////////////// server.on("/setLED", handleLED ); //deals with /setLED?LEDstate=1 its calls void handleLED() { String ledState = "OFF"; String t_state = server.arg("LEDstate"); //Refer xhttp.open("GET", "setLED?LEDstate="+led, true); Serial.println(t_state); if(t_state == "1") { digitalWrite(Pin2,LOW); //LED ON ledState = "ON"; //Feedback parameter } else { digitalWrite(Pin2,HIGH); //LED OFF ledState = "OFF"; //Feedback parameter } server.send(200, "text/plane", ledState); //Send web page //updates web page } ///////////////////////////////////////////////////////////////////////////////////////////////////// //webpage //////////////////////////////////////////////////////////////////////////////////////////////////// LED State is : <span id="LEDState">NA</span>
Hope it helps
Thanks DK. I will looking into this when have time. It is quite a departure from the original setup in Part 1, Unit 4 of the book “Home Automation Using ESP8266” though. I wish there is a simpler solution with the same setup.
Hi. I have that book too …
https://gist.github.com/RuiSantosdotme/1e1f0f415a8da5fc901257296a9a0b68
from that code
sub PIN2 for your gpio number
///////////////////////////////////////////////////////////////////////////////////////////////////////////// //Gobal Variable String PIN2_state = "Off"; else if(header.indexOf("GET /Pin2 HTTP/1.1") >= 0) { Serial.println(" else if(header.indexOf("GET /Pin2on HTTP/1.1") >= 0) { Serial.println("Pin2 On"); PIN2_state = "On"; //displayed in webpage digitalWrite(PIN2, HIGH); } else if(header.indexOf("GET /PIN2offf HTTP/1.1") >= 0){ Serial.println("PIN2Off"); PIN2_state = "Off"; // dislayed in webpage digitalWrite(PIN2, LOW); }
webpage part:
client.println("<h2>PIN2 - Current State: " + PIN2_state);
Hi, DK:
Thank you for your reply. I have changed gpio5 and gpio4 to gpio0 and gpio2 with no problem. My problem is that I want change gpio 2 as an input pin instead of output. It is connected to a reed switch. When the switch status changes form open to close or from close to open, I want its status is shown on the screen. To achieve that, I changed gpio 2 from OUTPUT to INPUT. In the sketch, I added the statements reading its status and detecting the state transition. The state of gpio 2 will display in the browser page correctly if I click on any button so the screen will reflash. However, after the state change I cannot figure out a way for ESP8266 to trigger the webpage reflash without pushing any button on the screen. I don’t think you code does that either.
Hi
you need Ajax to refresh value without reloading all webpage
example
https://randomnerdtutorials.com/esp8266-dht11dht22-temperature-and-humidity-web-server-with-arduino-ide/
DK: Thanks. As I want reuse parts of the original code, e.g., password protection and gpio0 buttons, do you think add Ajax will affect any of them?
Hi, copy all your code you have omit password and I can change your code to include Ajax
Hi, DK:
Great! The the code with password and other credentials deleted is attached below. What I want to happen is when the variable “transition” happens, i.e., to be 1, the browser would show the gpio2 state without click any button.
I really appreciate your help.
/********* Rui Santos Complete project details at http://randomnerdtutorials.com *********/ // Including the ESP8266 WiFi library #include <ESP8266WiFi.h> // Replace with your network details const char* ssid = ""; const char* password = ""; // Web Server on port 8888 WiFiServer server(8888); // variables String header; String gpio0_state = "Off"; String gpio2_state = "Off"; String gpio2_state_save = "Off"; int gpio0_pin = 0; int gpio2_pin = 2; char transition = 0; // only runs once void setup() { // Initializing serial port for debugging purposes Serial.begin(115200); delay(10); // preparing GPIOs pinMode(gpio0_pin, OUTPUT); digitalWrite(gpio0_pin, LOW); pinMode(gpio2_pin, INPUT); // digitalWrite(gpio2_pin, LOW); // Connecting to WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); // Starting the web server server.begin(); Serial.println("Web server running. Waiting for the ESP IP..."); delay(10000); // Printing the ESP IP address Serial.println(WiFi.localIP()); } // runs over and over again void loop() { // Listenning for new clients if(digitalRead(gpio2_pin)==LOW) { //header.indexOf("GET /gpio2on HTTP/1.1") >= 0){ // Serial.println("GPIO 2 Off"); gpio2_state = "Off"; // digitalWrite(gpio2_pin, HIGH); } else { //header.indexOf("GET /gpio2off HTTP/1.1") >= 0){ // Serial.println("GPIO 2 On"); gpio2_state = "On"; // digitalWrite(gpio2_pin, LOW); } if (gpio2_state!=gpio2_state_save) { transition = 1; gpio2_state_save=gpio2_state; Serial.println("GPIO 2 state change"); } WiFiClient client = server.available(); if (client) { Serial.println("New client"); // boolean to locate when the http request ends boolean blank_line = true; while (client.connected()) { if (client.available()) { char c = client.read(); header += c; if (c == '\n' && blank_line) { // ||(transition)) // checking if header is valid // dXNlcjpwYXNz = 'user:pass' (user:pass) base64 encode Serial.print(header); // Finding the right credential string if(header.indexOf("") >= 0) { //successful login client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // turns the GPIOs on and off if(header.indexOf("GET / HTTP/1.1") >= 0) { Serial.println("Main Web Page"); } else if(header.indexOf("GET /gpio0on HTTP/1.1") >= 0){ Serial.println("GPIO 0 On"); gpio0_state = "On"; digitalWrite(gpio0_pin, HIGH); } else if(header.indexOf("GET /gpio0off HTTP/1.1") >= 0){ Serial.println("GPIO 0 Off"); gpio0_state = "Off"; digitalWrite(gpio0_pin, LOW); } // your web page client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">"); client.println("</head><div class=\"container\">"); client.println("<h1>Web Server</h1>"); client.println("<h2>GPIO 0 - Current State: " + gpio0_state); client.println("<div class=\"row\">"); client.println("<div class=\"col-md-2\"><a href=\"/gpio0on\" class=\"btn btn-block btn-lg btn-success\" role=\"button\">ON</a></div>"); client.println("<div class=\"col-md-2\"><a href=\"/gpio0off\" class=\"btn btn-block btn-lg btn-danger\" role=\"button\">OFF</a></div>"); client.println("</div>"); client.println("<h2>GPIO 2 - Current State: " + gpio2_state); client.println("<div class=\"row\">"); // client.println("<div class=\"col-md-2\"><a href=\"/gpio2on\" class=\"btn btn-block btn-lg btn-success\" role=\"button\">ON</a></div>"); // client.println("<div class=\"col-md-2\"><a href=\"/gpio2off\" class=\"btn btn-block btn-lg btn-danger\" role=\"button\">OFF</a></div>"); client.println("</div></div></html>"); transition = 0; } // wrong user or passm, so http request fails... else { client.println("HTTP/1.1 401 Unauthorized"); client.println("WWW-Authenticate: Basic realm=\"Secure\""); client.println("Content-Type: text/html"); client.println(); client.println("<html>Authentication failed</html>"); } header = ""; break; } if (c == '\n') { // when starts reading a new line blank_line = true; } else if (c != '\r') { // when finds a character on the current line blank_line = false; } } } // closing the client connection delay(1); client.stop(); Serial.println("Client disconnected."); } }
Hi, I have code for Ajax server
- gpio0_pin turn on the motor or relay
- gpio2_pin is a Sensor(transition) to detect when door is fully closed or open, it is comments out, if you wish to
use it with a sensor remove comments
Real World …This is code will open the door, but it will not closed it, you need a H-Brigde Controller
to select direction of the motor and control the speed
teachmemicro.com/use-l298n-motor-driver/
copy the code whole into IDE and Upload
////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> int gpio0_pin = 0; //turn motor int gpio2_pin = 2; //Senesor when door is fully closed or open const char MAIN_page[] PROGMEM = R"=====( <!DOCTYPE html> <html> <body> <center> <br> <br> <div id="demo"> <button type="button" style="background-color:black;color:white;width:150px; height:40px;" onclick="sendData(1)">opening</button> <button type="button" style="background-color:black;color:white;width:150px; height:40px;" onclick="sendData(0)">closing</button><BR><BR> </div> <div> <b>Garage Door</b> is : <font color=red><span id="DoorState"></font></span> </div> </center> <script> function sendData(doorstatus) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("DoorState").innerHTML = this.responseText; } }; xhttp.open("GET", "set?Doorstate="+doorstatus, true); xhttp.send(); } </script> </body> </html> )====="; //SSID and Password of your WiFi router const char* ssid = "SSID"; const char* password = "password"; String State; //Variable to check the state int SensorState; ESP8266WebServer server(80); //Server on port 80 void handleRoot() { String s = MAIN_page; //Read HTML contents server.send(200, "text/html", s); //Send web page } void handleDoor() { State = "Closed"; String t_state = server.arg("Doorstate"); Serial.println(t_state); if(t_state == "1") //door is opening { digitalWrite(gpio0_pin,HIGH); //turn on motor State = "Openning ..."; //Feedback parameter server.send(200, "text/plane", State); //Send web page } else { //door is closing digitalWrite(gpio0_pin,LOW); State = "Closed"; //Feedback parameter server.send(200, "text/plane", State); //Send web page } } void setup(void) { // preparing GPIOs need only 1 pin pinMode(gpio0_pin, OUTPUT); //trigger door open or close pinMode(gpio2_pin, INPUT); //Sensor digitalWrite(gpio0_pin, LOW); //set default off digitalWrite(gpio2_pin, LOW); //set default no Sensor contact Serial.begin(115200); WiFi.begin(ssid, password); //Connect to your WiFi router Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //If connection successful show IP address in serial monitor Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); //IP address assigned to your ESP server.on("/", handleRoot); //Which routine to handle at root location. This is display page server.on("/set", handleDoor); server.begin(); //Start server Serial.println("HTTP server started"); } void loop(void) { // Checks if the Sensor state has change SensorState = digitalRead(gpio2_pin); //has door fully open or closed // if(SensorState == HIGH) // { // ddigitalWrite(gpio0_pin,LOW); //turn off motor // State = "Open .."; //Feedback parameter // server.send(200, "text/plane", State); //Send web page // } server.handleClient(); //Handle client requests } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I am not sure this works the way I want. The door open/close button and the sensor status display to be independent and sensor state should be displayed when it changes. In addition, there’s no password protection for this website. I will looking into to see what I can do.
Well, thank you for your help anyway.
Hi,
gpio0_pin start openning the door and changes Doorstate to "openning ..."
gpio2_pin senses the door fully open ie hitting the ground and stops the motor +
changes Doorstate to "open ..."
// Checks if the Sensor state has change SensorState = digitalRead(gpio2_pin); //has door fully open or closed // if(SensorState == HIGH) // { // ddigitalWrite(gpio0_pin,LOW); //turn off motor // State = "Open .."; //Feedback parameter // server.send(200, "text/plane", State); //Send web page // }
just remove the comments
You still need a H-Brigde controller to open and close the door
I did write up fully becos ot this ...
play around with handleDoor() to do something else
code with username and password
var confirmPassword = "fun";
var confirmuser = "me";
just enter username me
and password fun
Regards
derek
////////////////////////////////////////////////////////////////////
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
int gpio0_pin = 0; //turn motor
int gpio2_pin = 2; //Senesor when door is fully closed or open
const char MAIN_page[] PROGMEM = R”=====(
<!DOCTYPE html>
<html>
<head>
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
<style>
#myDIV {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
</style>
</head>
<body>
<center>
<br>
<br>
<div id=”myDIV”>
<form >
<label for=”pswd”>username: </label>
<input type=”oser” id=”user”><br>
<label for=”pswd”>password: </label>
<input type=”password” id=”pswd”><br>
<input type=”button” value=”Submit” onclick=”checkPswd();” />
</form>
</div>
<script type=”text/javascript”>
function checkPswd()
{
//
var confirmPassword = “fun”; // you can change
var confirmuser = “me”; // you can change
var password = document.getElementById(“pswd”).value;
var user = document.getElementById(“user”).value;
if (password == confirmPassword && user == confirmuser)
{
var x = document.getElementById(“myDIV”);
if (x.style.display === “block”)
{
x.style.display = “none”;
} else
{
x.style.display = “block”;
var newhtml = “<button type=button style=background-color:black;color:white;width:150px; height:40px; onclick=sendData(1)>opening</button><button type=button style=background-color:black;color:white;width:150px; height:40px; onclick=sendData(0)>closing</button><BR><BR><b>Garage Door</b> is : <font color=red><span id=DoorState></font></span>”;
document.getElementById(“myDIV”).innerHTML = newhtml;
}
}
else
{
alert(“do not match.”);
}
}
</script>
<script>
function sendData(doorstatus) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(“DoorState”).innerHTML =
this.responseText;
}
};
xhttp.open(“GET”, “set?Doorstate=”+doorstatus, true);
xhttp.send();
}
</script>
</body>
</html>
)=====”;
//SSID and Password of your WiFi router
const char* ssid = “SSID”;
const char* password = “lpasword”;
String State;
//Variable to check the state
int SensorState;
ESP8266WebServer server(80); //Server on port 80
void handleRoot()
{
String s = MAIN_page; //Read HTML contents
server.send(200, “text/html”, s); //Send web page
}
void handleDoor()
{
State = “Closed”;
String t_state = server.arg(“Doorstate”);
Serial.println(t_state);
if(t_state == “1”) //door is opening
{
digitalWrite(gpio0_pin,HIGH); //turn on motor
State = “Openning …”; //Feedback parameter
server.send(200, “text/plane”, State); //Send web page
}
else
{ //door is closing
digitalWrite(gpio0_pin,LOW);
State = “Closed”; //Feedback parameter
server.send(200, “text/plane”, State); //Send web page
}
}
void setup(void)
{
// preparing GPIOs need only 1 pin
pinMode(gpio0_pin, OUTPUT); //trigger door open or close
pinMode(gpio2_pin, INPUT); //Sensor
digitalWrite(gpio0_pin, LOW); //set default off
digitalWrite(gpio2_pin, LOW); //set default no Sensor contact
Serial.begin(115200);
WiFi.begin(ssid, password); //Connect to your WiFi router
Serial.println(“”);
// Wait for connection
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(“.”);
}
//If connection successful show IP address in serial monitor
Serial.println(“”);
Serial.print(“Connected to “);
Serial.println(ssid);
Serial.print(“IP address: “);
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
server.on(“/”, handleRoot); //Which routine to handle at root location. This is display page
server.on(“/set”, handleDoor);
server.begin(); //Start server
Serial.println(“HTTP server started”);
}
void loop(void)
{
// Checks if the Sensor state has change
SensorState = digitalRead(gpio2_pin); //has door fully open or closed
// if(SensorState == HIGH)
// {
// ddigitalWrite(gpio0_pin,LOW); //turn off motor
// State = “Open ..”; //Feedback parameter
// server.send(200, “text/plane”, State); //Send web page
// }
server.handleClient(); //Handle client requests
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Hi DK:
Thank you for your effort. However, when I tried, if I enter the wrong password, it will reject. If I enter the right password, nothing happens. No new webpage will display.
Moreover, the garage door opener behavior is different from what you described. (At least for those in the US.)
There is only one open/close door. Once pushed it will send a pulse for a short time. The door will close or open depending on the current state. The pin 2 is only for indicate the door states and independent of the open/close operation.
The garage door opener code give here works fine. The only issue is once logged in, the port on ip address is always open for anyone else’s access unless you disconnect. I try find a way to prevent anyone’s access without entering the username and password. I don’t know if you code can do that because I cannot test it.
Hi
hey no worries
var newhtml = “<button type=button style=background-color:black;color:white;width:150px; height:40px; onclick=sendData(1)>opening</button><button type=button style=background-color:black;color:white;width:150px; height:40px; onclick=sendData(0)>closing</button><BR><BR><b>Garage Door</b> is : <font color=red><span id=DoorState></font></span>”;
should in 1 long line for the code to work