Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //BEGIN SERVER TAB 1 UPDATE using "fetchAPI/JavaScript" 08_18_2023
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //DECLARATIONS
- //Written by and edited by, John James Guarnieri, 09_05_2023
- //MODIFIED FROM MY GARAGE DOOR OPENER SCRIPT USED A 12V MOTOR INSTEAD OF A GARAGE DOOR
- //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.
- //CONST INT
- const int positionSwitchTop = 14; // Pin connected to Top reed switch
- const int positionSwitchBottom = 4; // Pin connected to Bottom reed switch
- //
- const int LED_Reed_Switch_Indicator = 16; // Built in LED pin turns on when door is in motion, else it is off
- //when using the D1 Min Pro module
- #define LED_BUILTINN D4
- //INT
- int Bottom_Reed_Switch_Proximity = digitalRead(positionSwitchBottom); // Read the state of the bottom reed switch
- int Top_Reed_Switch_Proximity = digitalRead(positionSwitchTop); // Read the state of the top reed switch
- //BOOL
- bool The_Garage_Door_Is_Open = false;
- bool The_Garage_Door_Is_Closed = false;
- //LIBRARY
- // Load Wi-Fi library
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
- // Assign output variables to GPIO pins
- const uint8_t output5 = 5; // a output pin for door5
- //UNSIGNED LONG
- unsigned long lastTimeDoorWasActivated = 0; // times for millis()
- const unsigned long doorDelay = 12000; // 12 seconds approximate time for garage door to fully open or close
- //ENUM FSM
- // how long does it take to open/close the door - set to 12 seconds
- enum class State { OPENED,
- CLOSING,
- CLOSED,
- OPENING }; // due to naming conflicts you will need a scoped enumeration (enum class)
- // 0 1 2 3 // the compiler will assign numbers to the enumeration items
- State state5 = State::CLOSED; // state5 a variable to store the current state for output5 running State Closed first
- #if true // true for stspringer
- // Replace with your network credentials
- const char* ssid = "XXX, XXX, XXX,XXX";
- const char* password = "XXX, XXX, XXX,XXX";
- //My Add/ DEFINE STATIC IP 10.0.69.22 WORKING! https://www.youtube.com/watch?v=B9jJI7p2Gw4
- //STATIC IP ADDRESS
- //IPAddress local_IP(XXX, XXX, XXX, 22);//22 is the actual wireless ESP8266 in the garage digitalWrite(relayPin, //relayOnState);
- IPAddress local_IP(XXX, XXX, XXX, 19); // 19 for testing
- IPAddress gateway(XXX,XXX,XXX, XX);
- IPAddress subnet(255, 255, 255, 0);
- IPAddress primaryDNS(208, 67, 222, 222);
- IPAddress secondaryDNS(208, 67, 220, 220);
- #endif
- // Set web server port number to 80
- ESP8266WebServer server(80);
- // open door
- void doorOpen()
- {
- lastTimeDoorWasActivated = millis();
- digitalWrite(output5, LOW); //the relay signal wire is LOW, zerov the "NO" terminal is now "closed", working, sending power to the load the green LED indicator is "ON"
- state5 = State::OPENING;
- Serial.println(F("state5 OPENING"));
- }
- // forced close
- void doorClose()
- {
- lastTimeDoorWasActivated = millis();
- digitalWrite(output5, LOW); //the relay signal wire is LOW, zerov the "NO" terminal is now "closed", working, sending power to the load the green LED indicator is "ON"
- state5 = State::CLOSING; //running State Closed first
- Serial.println(F("state5 CLOSING"));
- }
- void runFSM()
- {
- //Check state5 here
- //if (digitalRead(positionSwitchBottom) == LOW && state5 != State::CLOSED) state5 = State::CLOSED;//My Edit if the door is CLOSED but state5 is OPENED set stae5 to CLOSED
- //if (digitalRead(positionSwitchTop) == LOW && state5 != State::OPENED) state5 = State::OPENED;//My Edit if the door is OPENED but state5 is CLOSED set stae5 to OPENED
- //My Add/EDIT check BOTTOM Reed Switch here
- if (digitalRead(positionSwitchBottom) == LOW && state5 != State::CLOSED) //bottom reed switch closing the circuit "ON", "LOW", initally when the BOTTOM reed switch is closed if the state on the web page is NOT CLOSED then make it CLOSED
- {
- state5 = State::CLOSED; //My Edit if the door is CLOSED but state5 is OPENED set state5 to CLOSED
- if (The_Garage_Door_Is_Closed) //YES THE GARAGE DOOR IS CLOSED
- {
- state5 = State::OPENING; //the garage door is CLOSED so OPEN it, call OPENING
- }
- else //THE GARAGE DOOR IS OPENED
- {
- state5 = State::CLOSED; //the garage door is OPENED so close it, call CLOSED
- }
- } else if (digitalRead(positionSwitchBottom) == LOW && state5 == State::OPENED) // the garage door is in the physical CLOSED position, but state5 is showing OPENED on the web page, so set state5 to CLOSED
- {
- state5 = State::CLOSED;
- }
- //check TOP Reed Switch here
- if (digitalRead(positionSwitchTop) == LOW && state5 != State::OPENED) //TOP reed switch closing the circuit "ON", "LOW", initally when the TOP reed switch is CLOSED if the state on the web page is NOT OPENED then make it OPENED
- {
- state5 = State::OPENED; //My Edit if the door is OPENED but state5 is CLOSED, set state5 to OPENED
- if (The_Garage_Door_Is_Open) //YES THE GARAGE DOOR IS OPENE
- {
- state5 = State::CLOSING; //the garage door is OPENED so CLOSE IT, call CLOSING
- }
- else //THE GARAGE DOOR IS CLOSED
- {
- state5 = State::OPENED; //the garage door CLOSED so OPEN it, CALL OPENED
- }
- } else if (digitalRead(positionSwitchTop) == LOW && state5 == State::CLOSED) // the garage door is in the physical OPENED position, but state5 is showing CLOSED on the web page, so set state5 to OPENED
- {
- state5 = State::OPENED;
- }
- switch (state5) // state5 a variable to store the current state for output5
- {
- case State::OPENED:
- // here you could read a hardware button
- The_Garage_Door_Is_Open = true;
- The_Garage_Door_Is_Closed = false;
- break;
- case State::CLOSING:
- if (millis() - lastTimeDoorWasActivated > doorDelay) //wait 12 seconds
- {
- //This triggers the 5v relay to turn "OFF" after 12 seconds.
- digitalWrite(output5, HIGH); //the relay signal wire is "HIGH" 3.3v, & "OFF" "NO" "Normally Open is "Open", zero volts" "NC" has 12v from power supply
- Serial.println(F("state5 CLOSED"));
- state5 = State::CLOSED; // state5 a variable to store the current state for output5
- }
- break;
- case State::CLOSED:
- // here you could read a hardware button
- The_Garage_Door_Is_Open = false;
- The_Garage_Door_Is_Closed = true;
- break;
- case State::OPENING:
- if (millis() - lastTimeDoorWasActivated > doorDelay) //wait 12 seconds
- {
- //This triggers the 5v relay to turn "OFF" after 12 seconds.
- digitalWrite(output5, HIGH); //the relay signal wire is "HIGH" 3.3v, & "OFF" "NO" "Normally Open is "Open", zero volts" "NC" has 12v from power supply
- Serial.println(F("state5 OPENED"));
- state5 = State::OPENED; // state5 a variable to store the current state for output5
- }
- break;
- } //switch state
- } //runFSM
- //SETUP
- void setup()
- {
- Serial.begin(115200);
- // Initialize the output variables as outputs
- //OUTPUT
- pinMode(output5, OUTPUT);
- pinMode(LED_BUILTINN, OUTPUT);
- //INPUT
- pinMode(positionSwitchTop, INPUT_PULLUP);
- pinMode(positionSwitchBottom, INPUT_PULLUP);
- digitalWrite(LED_BUILTINN, HIGH); //The LED_BUILTINN D4 on D1 Min Pro is off
- // Connect to Wi-Fi network with SSID and password
- Serial.print(F("Connecting to "));
- Serial.println(ssid);
- //My Add/ Define Static IP Setings working!
- if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS))
- {
- Serial.println(F("STA Failed to configure"));
- }
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED)
- {
- delay(500);
- Serial.print(".");
- }
- Serial.println("");
- Serial.println(F("WiFi connected."));
- // Print local IP address and start web server
- Serial.println(F("IP address: "));
- Serial.println(WiFi.localIP());
- serverSetup(); //in TAB 2 server
- }
- void reedSwitchStatus()
- {
- ////////////////////////////////////////////////////////////////////////////////////////
- //BEGIN Bottom_Reed_Switch_Proximity
- ///////////////////////////////////////////////////////////////////////////////////////
- // If the pin reads low, the switch is closed.
- if (Bottom_Reed_Switch_Proximity = LOW) //Bottom_Reed_Switch_Proximity "reed Switch" is Closed IMPORTANT WATCH OUT FOR == ERROR HERE SHOULD BE =
- {
- Serial.println("Bottom Switch closed");
- }
- else //Bottom_Reed_Switch_Proximity "reed Switch" is Open, turn on the blue built in LED 16 when the garage door is in motion
- {
- if (state5 == State::OPENING) {
- digitalWrite(LED_BUILTINN, LOW); //The LED_BUILTINN D4 on D1 Min Pro is on
- } else if (state5 == State::OPENED) {
- digitalWrite(output5, HIGH); //this insures we turn the relay signal wire "off" after an opening or closing of the garage door
- digitalWrite(positionSwitchBottom, HIGH); //reed switch open
- digitalWrite(LED_BUILTINN, HIGH); //The LED_BUILTINN D4 on D1 Min Pro is off
- Serial.println("Bottom_Reed_Switch_Proximity opened");
- }
- } //if Bottom
- ////////////////////////////////////////////////////////////////////////////////////////
- //BEGIN Top_Reed_Switch_Proximity
- ///////////////////////////////////////////////////////////////////////////////////////
- // If the pin reads low, the switch is closed.
- if (Top_Reed_Switch_Proximity = LOW) //Top_Reed_Switch_Proximity "reed Switch" is Closed IMPORTANT WATCH OUT FOR == ERROR HERE SHOULD BE =
- {
- Serial.println("Top Switch closed");
- }
- else // Top_Reed_Switch_Proximity "reed Switch" is Open, turn on the blue built in LED 16 when the garage door is in motion
- {
- if (state5 == State::CLOSING)
- {
- digitalWrite(LED_BUILTINN, LOW); //The LED_BUILTINN D4 on D1 Min Pro is on
- } else if (state5 == State::CLOSED) {
- digitalWrite(output5, HIGH); //this insures we turn the relay signal wire off after an opening or closing of the garage door
- digitalWrite(positionSwitchTop, HIGH); //reed switch open
- digitalWrite(LED_BUILTINN, HIGH); //The LED_BUILTINN D4 on D1 Min Pro is off
- Serial.println("Top_Reed_Switch_Proximity opened");
- }
- } //if Top
- } //reedSwitch
- void loop()
- {
- server.handleClient(); // call the webserver
- reedSwitchStatus();
- runFSM();
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //END SERVER TAB 1 UPDATE using "fetchAPI/JavaScript" 08_18_2023
- ////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //BEGIN SERVER TAB 2 UPDATE using "fetchAPI/JavaScript" 08_18_2023
- ////////////////////////////////////////////////////////////////////////////////////////////////
- /*
- Webserver Parts
- Update page with FetchAPI & JavaScript
- button sends request to a dedicated resource to process commands
- */
- // we need the button text in the page and in the JSON, hence a global structure to avoid duplicated code.
- struct Stateinfo {
- const char caption[42]; // text/caption for the button
- const char style[10]; // the CSS class (button, button2)
- };
- // the order must fit to the order of the states in the enumeration
- Stateinfo stateinfo[4] {
- {"The Motor is OFF", "button"}, // green - button2
- {"Please wait...12 seconds Motor is working", "button2"}, // red - button
- {"The Motor is OFF", "button"}, // red - button
- {"Please wait...12 seconds Motor is working", "button2"} // green - button2
- };
- // call this function in setup()
- void serverSetup() {
- server.on("/", handlePage); // the home page
- server.on("/j.js", handleJs); // javscript based on fetch API to update the page
- server.on("/json", handleJson); // send data in JSON format
- server.on("/cmd", handleCmd); // process commands
- server.begin();
- }
- // the main handle for the page
- void handlePage() {
- //Serial.println(F(" D8 handle page"));
- String message;
- message.reserve(1000);
- // Display the HTML web page
- message += F("<!DOCTYPE html>\n"
- "<html lang=\"en\">\n" // define the language of the content
- "<head>\n"
- "<title>John's Motor Controller</title>\n" // mostly displayed on the title bar of the browser tab
- "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" // set the viewport for mobile devices
- "<link rel=\"icon\" href=\"data:,\">\n" // avoid loading of favicon.ico
- "<script src='j.js'></script>\n" // include the JavaScript
- "<style>\n" // inline style (or include a CSS)
- "html {font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"
- "button, input[type=submit], .button {border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 20px; margin: 2px; cursor: pointer;}\n"
- ".button {background-color: #195B6A;}\n" //green
- //".button {background-color: #FF0000;}\n" //red
- //".button2 {background-color: #195B6A;}\n" //green
- ".button2 {background-color: #FF0000;}\n" //red
- "</style>\n"
- "</head>\n"
- "<body>\n"
- "<h1>John's Motor Controller</h1>\n");
- // Display current state of output5
- message += F("<p>GPIO 5 - State<span id=\"output5\">");
- message += digitalRead(output5);
- message += F("</span></p>\n");
- // Display a form with one command button (=submit)
- Serial.println(stateinfo[(int)state5].caption);
- message += F("<form action=\"/cmd\" method=\"POST\"><button id=\"button5\" name=\"button5\" class=\"");
- message += stateinfo[(int)state5].style; // access the index based on the integer value of state5
- message += F("\">");
- message += stateinfo[(int)state5].caption;
- message += F("</button></form>\n");
- // just for debugging - you will see 0, 1, 2, 3 as numeric representation of state5
- message += F("<p>global state5=<span id=\"state5\">"); message += (int)state5; message += F("</span></p>\n");
- message += F("<p>FetchAPI</p>\n");
- message += F("</body>\n");
- message += F("</html>");
- server.send(200, "text/html", message);
- //Serial.print(F("handle page message length=")); Serial.println(message.length());
- }
- // process incomming commands LOGIC HERE button5 pressed if state5 == State :: OPENED doorClose()
- void handleCmd() {
- if (server.hasArg("button5")) {
- if (state5 == State::OPENED) doorClose();
- else if (state5 == State::CLOSED) doorOpen();
- else Serial.println(F("D81 pressed cmd button in a state where no action is defined"));
- }
- handlePage(); // as HTML output we return the start page to the browser
- }
- // Output: send data to browser as JSON
- // after amodification always check if JSON is still valid. Just call the JSON (json) in your webbrowser and check.
- void handleJson() {
- String message = "";
- message.reserve(1000);
- message = F(" {\"ss\":"); // Start of JSON and the first object "ss": with the actual runtime in seconds
- message += millis() / 1000;
- message += F(",\"output5\":"); message += digitalRead(output5);
- message += F(",\"state5\":"); message += (int)state5;
- message += F(",\"style5\":\""); message += stateinfo[(int)state5].style; message += F("\""); // access the index based on the integer value of state5. Its text therefore the content must be enclosed in "
- message += F(",\"caption5\":\""); message += stateinfo[(int)state5].caption; message += F("\"");
- message += (F("}")); // End of JSON
- server.send(200, "application/json", message); // set MIME type https://www.ietf.org/rfc/rfc4627.txt
- //Serial.print(F("handleJson message length=")); Serial.println(message.length());
- }
- // Output: a fetch API / JavaScript
- // a function in the JavaScript uses the fetchAPI to request a JSON file from the webserver.
- // The JavaScript process the JSON file and updates the values on the page
- void handleJs() {
- String message;
- message.reserve(1000);
- message += F("const url ='json';\n"
- "function renew(){\n"
- " document.getElementById('state5').style.color = 'blue';\n" // if the timer starts the request, this field gets blue
- " fetch(url)\n" // Call the fetch function passing the url of the API as a parameter
- " .then(response => {return response.json();})\n"
- " .then(jo => {\n"
- " for (var i in jo)\n"
- " {\n"
- " if (document.getElementById(i)) document.getElementById(i).innerHTML = jo[i];\n" // as long as the JSON name fits to the HTML id, the value will be replaced
- " }\n"
- // add other fields here (e.g. the delivered JSON name doesn't fit to the html id
- " document.getElementById('button5').innerHTML = jo['caption5'];\n"
- " document.getElementById('button5').className = jo['style5'];\n"
- " document.getElementById('state5').style.color = '';\n" // if everything was ok, the field will get the default color again
- " })\n"
- " .catch(function() {\n" // this is where you run code if the server returns any errors
- " document.getElementById('state5').style.color = 'red';\n" // indicator that something went wrong
- " });\n"
- "}\n"
- "document.addEventListener('DOMContentLoaded', renew, setInterval(renew, 1000));\n"); // call JSON every n milliseconds
- server.send(200, "text/javascript", message);
- //Serial.print(F("handleJs message length=")); Serial.println(message.length());
- }
- //
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //END SERVER TAB 2 UPDATE 08_18_2023
- ////////////////////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment