Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *********
- THIS SCRIPT UPDATE PREVENTS THE RESUBMISSION DIALOG BOX FROM APPEARING IN THE WEB SERVER
- Door opener
- https://forum.arduino.cc/t/garage-door-opener-with-esp8266-web-server/1154364/18
- 11_17_2024 ADDED CODE TO UPDATE WEBSERVER IF OTHER DEVICE OPENS THE GARAGE DOOR, LIKE THE REMOTE OR THEDOOR PUSH BUTTON
- *********
- MY ACTUAL GARAGE DOOR OPENER HAS THE TWO REED SWITCHES CONNECTED TO THE "NC" TERMINALS AND YHE COMMON TO GROUND, THE TOP REED SWITCH WILL HAVE WEB SERVER AS The Garage Door is Closing, Please Wait...
- THE BOTTOM REED SWITCH WILL HAVE WEB SERVER AS The Garage Door is Opening, Please Wait...
- 11_18_2024 I edited void checkForExternalChanges() so that when the garage door is opening via any external device "remote" the web server will report just like if the web server was used to open or close the
- garage door message The Garage Door is Opening, Please Wait... or The Garage Door is Closing, Please Wait...
- DECLARATIONS
- Written by and edited by, John James Guarnieri, 09_05_2023
- Credits noiasca Arduino Forum
- Latest Working Script, John's Garage Door Opener, using the NORMALLY OPEN, "NO" Terminal on the relay
- Also in this setup, you are switching the "HOT side" of the load, so the "HOT" wire goes into the "NO" terminal, and the ground wire goes into "COMMON" terminal of the relay.
- REMEMBER!, if the signal wire is "LOW", zero v, the relay is "ON", and the 'NO" terminal is "CLOSED" and has power, If the signal wire is "HIGH", 3.3v the relay is "OFF", and the "NC" terminal has power.
- We are using the "NO" terminal on the relay in this script to power the load
- THE CONFUSING PART OF THE 5V RELAY! "SIGNAL WIRE HIGH", Relay OFF, "NORMALL OPEN" terminal is "OFF", the green LED indicator is "OFF"
- "SIGNAL WIRE HIGH", Relay OFF, "NORMALLY CLOSED" terminal is "ON", green LED indicator is "OFF"
- The 5v relay explained: When the relay signal pin is "LOW" the relay is "ON", and the green LED on the relay, is "ON" and the pole, or armature in the relay, is pulled to the "normally open" "NO" terminal
- when the signal wire is "HIGH" the relay is "OFF" and the pole or armature is back to the normally closed terminal "NC" and the green LED is "OFF", and power is sent to the load, if your load is connected
- to the "NC" terminal.
- */
- // Constants and Pins
- const int positionSwitchTop = 14; // Pin connected to Top reed switch when the top reed switch goes LOW the web server message is The Garage Door is Closing, Please Wait...
- const int positionSwitchBottom = 4; // Pin connected to Bottom reed switch when the bottom reed switch goes low the web message is The Garage Door is Opening, Please Wait...
- const int LED_Reed_Switch_Indicator = 16; // Built-in LED pin
- // INT
- int Bottom_Reed_Switch_Proximity = digitalRead(positionSwitchBottom); // Read bottom reed switch
- int Top_Reed_Switch_Proximity = digitalRead(positionSwitchTop); // Read top reed switch
- // BOOL
- bool The_Garage_Door_Is_Open = false;
- bool The_Garage_Door_Is_Closed = false;
- // Library includes for Wi-Fi and Web Server
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
- // Assign output variables to GPIO pins, using "const" ensures pin numbers remain fixed throughout the program, "uint8_t" is always 8 bits,
- const uint8_t output5 = 5; // Output pin for door
- // Timing variables
- unsigned long lastTimeDoorWasActivated = 0; // millis() tracking
- const unsigned long doorDelay = 12000; // 12 seconds for door movement
- // Enum for FSM
- enum class State { OPENED, CLOSING, CLOSED, OPENING };
- State state5 = State::CLOSED; // Start state
- // Wi-Fi settings
- const char* ssid = "xxxxxx";
- const char* password = "xxxxxxxx";
- // Static IP settings
- //IPAddress local_IP(xxx.xxx.xxx.xxx); //IP USED FOR TESTING
- IPAddress local_IP(xxx.xxx.xxx.xxx); //Actual Garage Door Opener IP
- IPAddress gateway(xxx.xxx.xxx.xxx;
- IPAddress subnet(255, 255, 255, 0);
- IPAddress primaryDNS(208, 67, 222, 222);
- IPAddress secondaryDNS(208, 67, 220, 220);
- // Web server on port 80
- ESP8266WebServer server(80);
- // Function to open the door
- void doorOpen() {
- lastTimeDoorWasActivated = millis();
- digitalWrite(output5, LOW); // Activate relay
- state5 = State::OPENING;
- Serial.println(F("state5 OPENING"));
- }
- // Function to close the door
- void doorClose() {
- lastTimeDoorWasActivated = millis();
- digitalWrite(output5, LOW); // Activate relay
- state5 = State::CLOSING;
- Serial.println(F("state5 CLOSING"));
- }
- void runFSM() {
- Serial.print(F("Current State: "));
- Serial.println((state5 == State::OPENED) ? "OPENED" :
- (state5 == State::CLOSED) ? "CLOSED" :
- (state5 == State::OPENING) ? "OPENING" : "CLOSING");
- switch (state5) {
- case State::OPENED:
- The_Garage_Door_Is_Open = true;
- The_Garage_Door_Is_Closed = false;
- Serial.println(F("State: OPENED"));
- break;
- case State::CLOSING:
- if (millis() - lastTimeDoorWasActivated > doorDelay) {
- digitalWrite(output5, HIGH); // Deactivate relay
- state5 = State::CLOSED; // Transition to CLOSED
- Serial.println(F("State transition: CLOSING to CLOSED"));
- }
- break;
- case State::CLOSED:
- The_Garage_Door_Is_Open = false;
- The_Garage_Door_Is_Closed = true;
- Serial.println(F("State: CLOSED"));
- break;
- case State::OPENING:
- if (millis() - lastTimeDoorWasActivated > doorDelay) {
- digitalWrite(output5, HIGH); // Deactivate relay
- state5 = State::OPENED; // Transition to OPENED
- Serial.println(F("State transition: OPENING to OPENED"));
- }
- break;
- }
- }
- // Web server setup and connection
- void setup() {
- Serial.begin(115200);
- pinMode(output5, OUTPUT);
- pinMode(LED_Reed_Switch_Indicator, OUTPUT);
- pinMode(positionSwitchTop, INPUT_PULLUP);
- pinMode(positionSwitchBottom, INPUT_PULLUP);
- WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println("");
- Serial.println("WiFi connected.");
- Serial.println("IP address: ");
- Serial.println(WiFi.localIP());
- server.on("/", HTTP_GET, handleRoot);
- server.on("/toggle", HTTP_POST, toggleDoor); // AJAX toggle for door
- server.on("/doorstatus", HTTP_GET, handleDoorStatus); // AJAX status check
- server.begin();
- Serial.println("Server started");
- }
- void handleRoot() {
- String html = "<html>\
- <head>\
- <title>John's Garage Door Controller</title>\
- <style>\
- body { text-align: center; font-family: Arial; }\
- h1 { font-size: 80px; } /* Larger title text */\
- .button { width: 600px; height: 150px; font-size: 50px; color: white; } /* More rectangular button */\
- .red { background-color: red; }\
- .green { background-color: green; }\
- </style>\
- <script>\
- function toggleDoor() {\
- var xhr = new XMLHttpRequest();\
- xhr.open('POST', '/toggle', true);\
- xhr.send();\
- setTimeout(getDoorStatus, 500); /* Ensure status updates after toggle */\
- }\
- function getDoorStatus() {\
- var xhr = new XMLHttpRequest();\
- xhr.onreadystatechange = function() {\
- if (xhr.readyState == 4 && xhr.status == 200) {\
- var status = xhr.responseText;\
- var button = document.getElementById('doorStatus');\
- console.log('Door status:', status); /* Log for debugging */\
- if (status === 'OPEN') {\
- button.innerHTML = 'The Garage Door is Open';\
- button.className = 'button green';\
- } else if (status === 'CLOSED') {\
- button.innerHTML = 'The Garage Door is Closed';\
- button.className = 'button red';\
- } else if (status === 'OPENING') {\
- button.innerHTML = 'The Garage Door is Opening, Please Wait...';\
- button.className = 'button green'; /* Show green while opening */\
- } else if (status === 'CLOSING') {\
- button.innerHTML = 'The Garage Door is Closing, Please Wait...';\
- button.className = 'button red'; /* Show red while closing */\
- }\
- }\
- };\
- xhr.open('GET', '/doorstatus', true);\
- xhr.send();\
- }\
- setInterval(getDoorStatus, 300); /* Check status every 300ms */\
- </script>\
- </head>\
- <body>\
- <h1>John's Garage Door Controller</h1>\
- <button class=\"button red\" id=\"doorStatus\" onclick=\"toggleDoor()\">The Garage Door is Closed</button>\
- </body>\
- </html>";
- server.send(200, "text/html", html);
- }
- // AJAX function to provide door status
- void handleDoorStatus() {
- String doorStatus = (state5 == State::OPENED) ? "OPEN" :
- (state5 == State::CLOSED) ? "CLOSED" :
- (state5 == State::OPENING) ? "OPENING" : "CLOSING";
- Serial.print(F("handleDoorStatus reports: "));
- Serial.println(doorStatus);
- server.send(200, "text/plain", doorStatus); // Send status to web server
- }
- //THIS FUNCTION CHECKS FOR ANY EXTERNAL DEVICE THAT MAY BE OPENING OR CLOSING THE GARAGE DOOR AND UPDATES THE WEB SERVER ACCORDINGLY
- void checkForExternalChanges() {
- static int lastBottomSwitchState = HIGH; // Assuming switches are normally HIGH
- static int lastTopSwitchState = HIGH;
- int currentBottomSwitchState = digitalRead(positionSwitchBottom);
- int currentTopSwitchState = digitalRead(positionSwitchTop);
- // Detect changes on the bottom reed switch (door closing)
- if (currentBottomSwitchState != lastBottomSwitchState) {
- lastBottomSwitchState = currentBottomSwitchState;
- if (currentBottomSwitchState == LOW) {
- //if (state5 != State::CLOSING) {
- //state5 = State::CLOSING;
- //My Edit 11_18_2024 WORKING
- if (state5 != State::CLOSING) {
- state5 = State::OPENING;
- lastTimeDoorWasActivated = millis(); // Start the 12-second timer
- Serial.println(F("External event: Door is Closing"));
- }
- }
- }
- // Detect changes on the top reed switch (door opening)
- if (currentTopSwitchState != lastTopSwitchState) {
- lastTopSwitchState = currentTopSwitchState;
- if (currentTopSwitchState == LOW) {
- // if (state5 != State::OPENING) {
- // state5 = State::OPENING;
- //My Edit 11_18_2024 WORKING
- if (state5 != State::OPENING) {
- state5 = State::CLOSING;
- lastTimeDoorWasActivated = millis(); // Start the 12-second timer
- Serial.println(F("External event: Door is Opening"));
- }
- }
- }
- }
- // Function to toggle the door's open/close state
- void toggleDoor() {
- if (state5 == State::CLOSED || state5 == State::CLOSING) {
- doorOpen();
- } else if (state5 == State::OPENED || state5 == State::OPENING) {
- doorClose();
- }
- server.send(200, "text/plain", "Toggled");
- }
- // Reed switch status function (optional, based on initial code)
- void reedSwitchStatus() {
- if (digitalRead(positionSwitchBottom) == LOW) {
- Serial.println("Bottom Switch closed");
- } else if (state5 == State::OPENING) {
- digitalWrite(LED_BUILTIN, LOW);
- } else if (state5 == State::OPENED) {
- digitalWrite(output5, HIGH);
- Serial.println("Bottom_Reed_Switch_Proximity opened");
- }
- if (digitalRead(positionSwitchTop) == LOW) {
- Serial.println("Top Switch closed");
- } else if (state5 == State::CLOSING) {
- digitalWrite(LED_BUILTIN, LOW);
- } else if (state5 == State::CLOSED) {
- digitalWrite(output5, HIGH);
- Serial.println("Top_Reed_Switch_Proximity opened");
- }
- }
- void loop() {
- server.handleClient();
- reedSwitchStatus();
- checkForExternalChanges(); // New function to detect remote control use external device
- runFSM();
- }
Advertisement
Add Comment
Please, Sign In to add comment