Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Garage Lights script written by John James Guarnieri 09_16_2024
- “NC” Normally Closed
- “NO” Normally Open
- Hello Everyone,
- I would like to share my script to help others with a real-world garage light controller using a web server with an ESP8266, to have your smartphone turn on and off your garage lights.
- I have 120v LED lights hanging in my garage and I set up a wall-mounted 3-way switch with a relay and an ESP8266. I can turn the garage lights on or off with my Android phone via the web server and they can be turned on/off manually by the 3-way switch
- The problem was if my phone stated the garage lights were off and someone used the 3-way switch and turned the garage lights on, how do I update my phone to state that the garage lights are on?
- Well, I tested an automotive 12v bulb, which draws over 2a on a high beam, a bench power supply source voltage, 12v a 3v relay that handles 12v, and a 3.3v optocoupler that handles 12v.
- I will eventually use a 120v optocoupler
- Now the 3-way switch doesn’t have an on/off position like a regular wall light switch, it has two traveler wires, red and black, the red traveler wire is connected to the relay “NC” terminal, and the black traveler wire is connected to the “NO” terminal
- I am using a Leviton 120v E5603-SW Decora Edge 15 Amp 3-Way Rocker Switch for my testing on 12v
- When the switch is oriented correctly, “the top “UP” position of the switch would be where the text on the switch is NOT upside down.
- THE CONFUSION STARTS HERE!
- SWITCH “DOWN” “NC” HAS ZERO V, “NO” HAS 12V,
- SWITCH “UP” “NC” HAS 12V, “NO” HAS ZERO V
- When the switch is “DOWN” the “NO” traveler wire going to the relay “NO” terminal has 12v power.
- When the switch is “UP” the “NC” traveler wire going to the relay “NC” terminal has 12v power.
- What you have to understand is when the switch is “DOWN” the relay is “OFF” and the “NC” terminal on the relay is “CLOSED” but the “NC” terminal has ZERO V so the light is “OFF” the “NO” terminal of the relay has 12v and is “OPEN”
- What you have to understand is when the the switch is “UP” and the relay is “OFF” the “NC” terminal on the relay is “CLOSED” and the “NC” terminal has 12 V so the light is “ON”, the “NO” terminal of the relay has ZERO v and is “OPEN”
- How do I determine if my 3-way switch is up or down?
- You use a single-channel optocoupler. When the switch is “UP” channel 1 will read a “HIGH” voltage of 2.72v, when the switch is “DOWN” channel 1 will read a “LOW” voltage, close to ZERO v
- How do I hook up my optocoupler?
- You run a jumper wire from the “NO” terminal of the relay to the + Positive of the channel 1 input, then you run a ground from the 12v source ground to the – Negative of channel 1 input.
- The output of the optocoupler channel 1 connects to GPIO 12 of the ESP8266
- When GPIO 12 is “LOW” ZERO V you know the switch is “DOWN”, when GPIO 12 is “HIGH” you know the switch is “UP”
- WHEN THE RELAY IS ON!
- REMEMBER: SWITCH “DOWN” “NC” HAS ZERO V, “NO” HAS 12V,
- When the relay is “ON” and the switch is “DOWN” the light is “ON”, “NO” has 12v and is “CLOSED”, “NC” has ZERO V and is “OPEN”
- REMEMBER: SWITCH “UP” “NC” HAS 12V, “NO” HAS ZERO V
- When the relay is “ON” and the switch is “UP” the light is “OFF”, “NO” has ZERO V and is “CLOSED”, “NC” has 12v and is “OPEN”
- For the 120v Garage lights, I will switch out the 12v optocoupler for a 120v optocoupler
- Garage_Lights_My_Working_Corrected_Logic MAIN TAB
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h> // Include for the web server
- // Declare global variables and constants
- #define SWITCH_PIN 12 // Pin connected to the optocoupler "determines if 3-way switch is up or down"
- #define RELAY_PIN 5 // Pin connected to the relay control
- // Network credentials and static IP configuration
- const char* ssid = "XXXXXXXXXX";
- const char* password = "XXXXXXXXXX";
- IPAddress local_IP(xxx, xxx, xxx, xxx);
- IPAddress gateway(xxx, xxx, xxx, x);
- IPAddress subnet(255, 255, 255, 0);
- IPAddress primaryDNS(8, 8, 8, 8);
- IPAddress secondaryDNS(8, 8, 4, 4);
- ESP8266WebServer server(80); // Declare the web server object
- // Timing variables for millis() based delay replacement
- unsigned long previousMillisState = 0;
- unsigned long stateMachineDelay = 100; // Delay for state machine transitions
- unsigned long previousMillisWiFi = 0; // Track previous millis for Wi-Fi
- unsigned long previousMillisWiFiDelay = 500; // Delay for Wi-Fi connection status messages
- bool wifiConnected = false; // Track Wi-Fi connection state
- void setup() {
- pinMode(SWITCH_PIN, INPUT);
- pinMode(RELAY_PIN, OUTPUT);
- Serial.begin(115200);
- // Configure static IP
- if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
- Serial.println("STA Failed to configure");
- }
- // Start WiFi connection attempt
- WiFi.begin(ssid, password);
- // Setup web server routes
- setupWebServer();
- }
- void loop() {
- // Handle Wi-Fi connection management
- manageWiFiConnection();
- // Continue only if Wi-Fi is connected
- if (wifiConnected) {
- server.handleClient(); // Handle incoming client requests
- }
- unsigned long currentMillis = millis();
- // Check if it's time to transition the state machine
- if (currentMillis - previousMillisState >= stateMachineDelay) {
- previousMillisState = currentMillis;
- // State machine to handle various checks
- runStateMachine();
- }
- }
- // RelayControl.ino TAB
- int switchState = LOW; // Variable to store switch state "LOW" means the switch is "DOWN", "HIGH" means the switch is "UP"
- int relayState = LOW; // Relay starts OFF
- int lightStatus = LOW; // Light starts OFF
- enum States {
- CHECK_SWITCH,
- CHECK_RELAY,
- CHECK_LIGHT_STATUS,
- CHECK_WEB_UPDATE
- };
- States currentState = CHECK_SWITCH;
- void runStateMachine() {
- // State machine to handle various checks
- switch (currentState) {
- case CHECK_SWITCH:
- checkSwitch();
- currentState = CHECK_RELAY; // Move to the next state
- break;
- case CHECK_RELAY:
- checkRelay();
- currentState = CHECK_LIGHT_STATUS; // Move to the next state
- break;
- case CHECK_LIGHT_STATUS:
- checkLightStatus();
- currentState = CHECK_WEB_UPDATE; // Move to the next state
- break;
- case CHECK_WEB_UPDATE:
- checkWebUpdate();
- currentState = CHECK_SWITCH; // Return to the first state to repeat the cycle
- break;
- default:
- currentState = CHECK_SWITCH; // Default to the first state if something goes wrong
- break;
- }
- }
- void checkSwitch() {
- int currentSwitchState = digitalRead(SWITCH_PIN); // Read current switch state
- if (currentSwitchState != switchState) {
- switchState = currentSwitchState; // Update switch state
- Serial.print("Switch state: ");
- Serial.println(switchState == LOW ? "DOWN" : "UP");
- }
- }
- void checkRelay() {
- relayState = digitalRead(RELAY_PIN); // Read relay state
- Serial.print("Relay state: ");
- Serial.println(relayState == LOW ? "OFF" : "ON");
- }
- void checkLightStatus() {
- // If switch is UP and relay is OFF, turn the light ON
- if (switchState == LOW && relayState == LOW) {
- lightStatus = LOW; // Light OFF
- Serial.println("Light status: OFF");
- }
- // If switch is DOWN, turn the light ON
- else if (switchState == HIGH && relayState == LOW) {
- lightStatus = HIGH; // Light ON
- Serial.println("Light status: ON");
- }
- else if (switchState == LOW && relayState == HIGH) {
- lightStatus = HIGH; // Light ON
- Serial.println("Light status: OFF");
- }// WebServerHandler.ino
- void setupWebServer() {
- server.on("/", HTTP_GET, []() {
- handleRoot(); // Update and render the web page
- });
- server.on("/toggle", HTTP_POST, []() {
- relayState = !relayState; // Toggle the relay state
- digitalWrite(RELAY_PIN, relayState); // Update the relay
- handleRoot(); // Re-render the page
- });
- server.on("/lightstatus", handleLightStatus);
- server.begin();
- Serial.println("Server started");
- }
- void handleRoot() {
- String buttonText;
- String buttonColor;
- if (lightStatus == LOW) {
- buttonText = "The Garage Lights Are OFF";
- buttonColor = "red";
- } else {
- buttonText = "The Garage Lights Are ON";
- buttonColor = "green";
- }
- String html = "<html>\
- <head>\
- <title>John's LED Garage Lights Controller</title>\
- <style>\
- body { text-align: center; font-family: Arial; }\
- .button { width: 275px; height: 75px; font-size: 30px; color: white; }\
- .red { background-color: red; }\
- .green { background-color: green; }\
- </style>\
- <script>\
- function getLightStatus() {\
- var xhr = new XMLHttpRequest();\
- xhr.onreadystatechange = function() {\
- if (xhr.readyState == 4 && xhr.status == 200) {\
- var lightState = xhr.responseText;\
- var button = document.getElementById('lightStatus');\
- if (lightState == 'ON') {\
- button.innerHTML = 'The Garage Lights Are ON';\
- button.className = 'button green';\
- } else {\
- button.innerHTML = 'The Garage Lights Are OFF';\
- button.className = 'button red';\
- }\
- }\
- };\
- xhr.open('GET', '/lightstatus', true);\
- xhr.send();\
- }\
- setInterval(getLightStatus, 500); // Refresh every 500ms for quicker updates\
- </script>\
- </head>\
- <body>\
- <h1>John's LED Garage Lights Controller</h1>\
- <form action=\"/toggle\" method=\"POST\">\
- <button class=\"button " + buttonColor + "\" id=\"lightStatus\" type=\"submit\">" + buttonText + "</button>\
- </form>\
- </body>\
- </html>";
- server.send(200, "text/html", html);
- }
- void handleLightStatus() {
- if (lightStatus == LOW) {
- server.send(200, "text/plain", "OFF");
- } else {
- server.send(200, "text/plain", "ON");
- }
- }
- else if (switchState == HIGH && relayState == HIGH) {
- lightStatus = LOW; // Light ON
- Serial.println("Light status: OFF");
- }
- }
- void checkWebUpdate() {
- if (lightStatus == HIGH) {
- Serial.println("Web update: Light ON");
- } else {
- Serial.println("Web update: Light OFF");
- }
- }
- // WebServerHandler.ino TAB
- void setupWebServer() {
- server.on("/", HTTP_GET, []() {
- handleRoot(); // Update and render the web page
- });
- server.on("/toggle", HTTP_POST, []() {
- relayState = !relayState; // Toggle the relay state
- digitalWrite(RELAY_PIN, relayState); // Update the relay
- handleRoot(); // Re-render the page
- });
- server.on("/lightstatus", handleLightStatus);
- server.begin();
- Serial.println("Server started");
- }
- void handleRoot() {
- String buttonText;
- String buttonColor;
- if (lightStatus == LOW) {
- buttonText = "The Garage Lights Are OFF";
- buttonColor = "red";
- } else {
- buttonText = "The Garage Lights Are ON";
- buttonColor = "green";
- }
- String html = "<html>\
- <head>\
- <title>John's LED Garage Lights Controller</title>\
- <style>\
- body { text-align: center; font-family: Arial; }\
- .button { width: 275px; height: 75px; font-size: 30px; color: white; }\
- .red { background-color: red; }\
- .green { background-color: green; }\
- </style>\
- <script>\
- function getLightStatus() {\
- var xhr = new XMLHttpRequest();\
- xhr.onreadystatechange = function() {\
- if (xhr.readyState == 4 && xhr.status == 200) {\
- var lightState = xhr.responseText;\
- var button = document.getElementById('lightStatus');\
- if (lightState == 'ON') {\
- button.innerHTML = 'The Garage Lights Are ON';\
- button.className = 'button green';\
- } else {\
- button.innerHTML = 'The Garage Lights Are OFF';\
- button.className = 'button red';\
- }\
- }\
- };\
- xhr.open('GET', '/lightstatus', true);\
- xhr.send();\
- }\
- setInterval(getLightStatus, 500); // Refresh every 500ms for quicker updates\
- </script>\
- </head>\
- <body>\
- <h1>John's LED Garage Lights Controller</h1>\
- <form action=\"/toggle\" method=\"POST\">\
- <button class=\"button " + buttonColor + "\" id=\"lightStatus\" type=\"submit\">" + buttonText + "</button>\
- </form>\
- </body>\
- </html>";
- server.send(200, "text/html", html);
- }
- void handleLightStatus() {
- if (lightStatus == LOW) {
- server.send(200, "text/plain", "OFF");
- } else {
- server.send(200, "text/plain", "ON");
- }
- }
- // WebServerHandler.ino
- void setupWebServer() {
- server.on("/", HTTP_GET, []() {
- handleRoot(); // Update and render the web page
- });
- server.on("/toggle", HTTP_POST, []() {
- relayState = !relayState; // Toggle the relay state
- digitalWrite(RELAY_PIN, relayState); // Update the relay
- handleRoot(); // Re-render the page
- });
- server.on("/lightstatus", handleLightStatus);
- server.begin();
- Serial.println("Server started");
- }
- void handleRoot() {
- String buttonText;
- String buttonColor;
- if (lightStatus == LOW) {
- buttonText = "The Garage Lights Are OFF";
- buttonColor = "red";
- } else {
- buttonText = "The Garage Lights Are ON";
- buttonColor = "green";
- }
- String html = "<html>\
- <head>\
- <title>John's LED Garage Lights Controller</title>\
- <style>\
- body { text-align: center; font-family: Arial; }\
- .button { width: 275px; height: 75px; font-size: 30px; color: white; }\
- .red { background-color: red; }\
- .green { background-color: green; }\
- </style>\
- <script>\
- function getLightStatus() {\
- var xhr = new XMLHttpRequest();\
- xhr.onreadystatechange = function() {\
- if (xhr.readyState == 4 && xhr.status == 200) {\
- var lightState = xhr.responseText;\
- var button = document.getElementById('lightStatus');\
- if (lightState == 'ON') {\
- button.innerHTML = 'The Garage Lights Are ON';\
- button.className = 'button green';\
- } else {\
- button.innerHTML = 'The Garage Lights Are OFF';\
- button.className = 'button red';\
- }\
- }\
- };\
- xhr.open('GET', '/lightstatus', true);\
- xhr.send();\
- }\
- setInterval(getLightStatus, 500); // Refresh every 500ms for quicker updates\
- </script>\// WiFiManager.ino
- void manageWiFiConnection() {
- unsigned long currentMillis = millis(); // Declare currentMillis locally
- // If not connected, try to connect
- if (!wifiConnected) {
- if (WiFi.status() != WL_CONNECTED) {
- // Print connection status every 500ms
- if (currentMillis - previousMillisWiFi >= previousMillisWiFiDelay) {
- previousMillisWiFi = currentMillis;
- Serial.println("Connecting to Wi-Fi...");
- }
- } else {
- // Successfully connected
- wifiConnected = true;
- Serial.println("Connected to Wi-Fi");
- Serial.print("IP Address: ");
- Serial.println(WiFi.localIP());
- }
- }
- }
- </head>\
- <body>\
- <h1>John's LED Garage Lights Controller</h1>\
- <form action=\"/toggle\" method=\"POST\">\
- <button class=\"button " + buttonColor + "\" id=\"lightStatus\" type=\"submit\">" + buttonText + "</button>\
- </form>\
- </body>\
- </html>";
- server.send(200, "text/html", html);
- }
- void handleLightStatus() {
- if (lightStatus == LOW) {
- server.send(200, "text/plain", "OFF");
- } else {
- server.send(200, "text/plain", "ON");
- }
- }
- // WiFiManager.ino TAB
- void manageWiFiConnection() {
- unsigned long currentMillis = millis(); // Declare currentMillis locally
- // If not connected, try to connect
- if (!wifiConnected) {
- if (WiFi.status() != WL_CONNECTED) {
- // Print connection status every 500ms
- if (currentMillis - previousMillisWiFi >= previousMillisWiFiDelay) {
- previousMillisWiFi = currentMillis;
- Serial.println("Connecting to Wi-Fi...");
- }
- } else {
- // Successfully connected
- wifiConnected = true;
- Serial.println("Connected to Wi-Fi");
- Serial.print("IP Address: ");
- Serial.println(WiFi.localIP());
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment