Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- 🧠 Quick GPIO reference for ESP8266 NodeMCU / Wemos D1 Mini:
- D0 = 16
- D1 = 5 RELAY_PIN 5 turns the relay on HIGH when sensors get activated
- D2 = 4 LASER_PIN 4 laser beam across the garage door and the man door
- D3 = 0
- D4 = 2
- D5 = 14 PIR_PIN 14 detects body heat
- D6 = 12 SWITCH_PIN 12 3-way switch
- D7 = 13 REED_PIN 13 detects when the garage door is opened,so the garage lights will turn on for 4.5 minutes
- D8 = 15
- */
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
- // === Pin Definitions ===
- #define RELAY_PIN 5
- #define SWITCH_PIN 12
- #define REED_PIN 13
- #define PIR_PIN 14
- #define LASER_PIN 4 // Laser sensor pin (NPN NO, HIGH = triggered)
- // === WiFi Config ===
- const char* ssid = "xxxxxxxxxx";
- const char* password = "xxxxxxxx";
- IPAddress local_IP(xx,xx,xx,xx);
- IPAddress gateway(xx,xx,xx,xx);
- IPAddress subnet(255, 255, 255, 0);
- IPAddress primaryDNS(8, 8, 8, 8);
- IPAddress secondaryDNS(8, 8, 4, 4);
- ESP8266WebServer server(80);
- // === Timing and States ===
- unsigned long previousMillisState = 0;
- unsigned long stateMachineDelay = 100;
- unsigned long reedActivatedTime = 0;
- unsigned long pirActivatedTime = 0;
- unsigned long laserActivatedTime = 0;
- unsigned long lightOnTime = 0;
- unsigned long startupDelay = 5000; // ms
- unsigned long bootTime;
- const unsigned long lightTimeout = 15000;
- const unsigned long pirLightTimeout = 15000;
- const unsigned long laserLightTimeout = 15000;
- const unsigned long reedResetTimeout = 15000;
- const unsigned long pirResetTimeout = 15000;
- const unsigned long laserResetTimeout = 15000;
- bool wifiConnected = false;
- bool reedTriggered = false;
- bool pirTriggered = false;
- bool laserTriggered = false;
- bool ignoreReedSwitch = true; // ⛔ Disable REED initially to prevent Garage lights from comming on at script startup
- bool ignorePIR = true; // ⛔ Disable PIR initially to prevent Garage lights from comming on at script startup
- bool ignoreLaser = false;
- bool lightOn = false;
- bool sensorsEnabled = true;
- int switchState = LOW;
- int relayState = LOW;
- int lightStatus = LOW;
- enum States {
- CHECK_SWITCH,
- CHECK_RELAY,
- CHECK_LIGHT_STATUS,
- CHECK_REED_SENSOR,
- CHECK_PIR_SENSOR,
- CHECK_WEB_UPDATE
- };
- States currentState = CHECK_SWITCH;
- void setup() {
- Serial.begin(115200);
- relayState = LOW;
- lightOn = false;
- pinMode(SWITCH_PIN, INPUT);
- pinMode(RELAY_PIN, OUTPUT);
- pinMode(REED_PIN, INPUT_PULLUP);
- pinMode(PIR_PIN, INPUT);
- pinMode(LASER_PIN, INPUT);
- digitalWrite(RELAY_PIN, LOW); // Turn relay off on startup
- Serial.println("🐛 DEBUG: Relay explicitly set LOW at startup");
- if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
- Serial.println("STA Failed to configure");
- }
- WiFi.begin(ssid, password);
- setupWebServer();
- }
- void loop() {
- manageWiFiConnection();
- if (wifiConnected) server.handleClient();
- if (millis() - previousMillisState >= stateMachineDelay) {
- previousMillisState = millis();
- runStateMachine();
- }
- }
- void runStateMachine() {
- switch (currentState) {
- case CHECK_SWITCH:
- checkSwitch(); currentState = CHECK_RELAY; break;
- case CHECK_RELAY:
- checkRelay(); currentState = CHECK_LIGHT_STATUS; break;
- case CHECK_LIGHT_STATUS:
- checkLightStatus(); currentState = CHECK_REED_SENSOR; break;
- case CHECK_REED_SENSOR:
- if (sensorsEnabled && millis() - bootTime > startupDelay) checkReedSensor();
- currentState = CHECK_PIR_SENSOR;
- break;
- case CHECK_PIR_SENSOR:
- if (sensorsEnabled && millis() - bootTime > startupDelay) {
- checkPIRSensor();
- checkLaserSensor(); // Laser remains enabled
- }
- currentState = CHECK_WEB_UPDATE;
- break;
- case CHECK_WEB_UPDATE:
- checkWebUpdate(); currentState = CHECK_SWITCH; break;
- default:
- currentState = CHECK_SWITCH; break;
- }
- }
- // === Input/Output Logic ===
- void checkSwitch() {
- int currentSwitchState = digitalRead(SWITCH_PIN);
- if (currentSwitchState != switchState) {
- switchState = currentSwitchState;
- Serial.print("Switch state: ");
- Serial.println(switchState == LOW ? "DOWN" : "UP");
- if (switchState == HIGH) turnOnLightManually();
- else turnOffLight();
- }
- }
- void checkRelay() {
- relayState = digitalRead(RELAY_PIN);
- Serial.print("Relay state: ");
- Serial.println(relayState == LOW ? "OFF" : "ON");
- if (relayState == HIGH) Serial.println("🐛 DEBUG: Relay is HIGH in checkRelay()");
- }
- void checkLightStatus() {
- lightStatus = (switchState == LOW && relayState == LOW) ? LOW : HIGH;
- Serial.print("Light status: ");
- Serial.println(lightStatus == HIGH ? "ON" : "OFF");
- }
- void checkReedSensor() {
- int reedState = digitalRead(REED_PIN);
- Serial.print("🐛 DEBUG: Reed state = ");
- Serial.println(reedState == LOW ? "CLOSED (triggered)" : "OPEN (normal)");
- if (reedState == LOW && !reedTriggered && !ignoreReedSwitch) {
- reedTriggered = true;
- lightOnTime = reedActivatedTime = millis();
- turnOnLightFromSensor();
- Serial.println("Reed switch triggered: Relay ON, Light ON");
- }
- if (lightOn && millis() - lightOnTime >= lightTimeout) {
- turnOffLight();
- Serial.println("Light timeout reached (Reed): Relay OFF, Light OFF");
- }
- if (reedTriggered && millis() - reedActivatedTime >= reedResetTimeout) {
- reedTriggered = false;
- ignoreReedSwitch = true;
- Serial.println("Reed reset timeout reached");
- }
- if (reedState == HIGH) ignoreReedSwitch = false;
- }
- void checkPIRSensor() {
- int pirState = digitalRead(PIR_PIN);
- Serial.print("🐛 DEBUG: PIR state = ");
- Serial.println(pirState == HIGH ? "HIGH (triggered)" : "LOW");
- if (pirState == HIGH && !pirTriggered && !ignorePIR) {
- pirTriggered = true;
- pirActivatedTime = lightOnTime = millis();
- turnOnLightFromSensor();
- Serial.println("PIR triggered: Relay ON, Light ON");
- }
- if (lightOn && millis() - lightOnTime >= pirLightTimeout) {
- turnOffLight();
- Serial.println("PIR light timeout reached: Relay OFF, Light OFF");
- }
- if (pirTriggered && millis() - pirActivatedTime >= pirResetTimeout) {
- pirTriggered = false;
- ignorePIR = true;
- Serial.println("PIR reset timeout reached");
- }
- if (pirState == LOW) ignorePIR = false;
- }
- void checkLaserSensor() {
- int laserState = digitalRead(LASER_PIN);
- if (laserState == LOW && !laserTriggered && !ignoreLaser) {
- laserTriggered = true;
- laserActivatedTime = lightOnTime = millis();
- turnOnLightFromSensor();
- Serial.println("Laser beam broken: Relay ON, Light ON");
- }
- if (lightOn && millis() - lightOnTime >= laserLightTimeout) {
- turnOffLight();
- Serial.println("Laser light timeout reached: Relay OFF, Light OFF");
- }
- if (laserTriggered && millis() - laserActivatedTime >= laserResetTimeout) {
- laserTriggered = false;
- ignoreLaser = true;
- Serial.println("Laser reset timeout reached");
- }
- if (laserState == HIGH) ignoreLaser = false;
- }
- void checkWebUpdate() {
- Serial.print("Web update: Light ");
- Serial.println(lightStatus == HIGH ? "ON" : "OFF");
- }
- // === Control Functions ===
- void turnOnLightManually() {
- if (digitalRead(SWITCH_PIN) == HIGH) {
- relayState = LOW;
- digitalWrite(RELAY_PIN, relayState);
- lightOn = true;
- sensorsEnabled = false;
- Serial.println("Switch UP: Relay OFF, Light ON, Sensors disabled.");
- }
- }
- void turnOffLight() {
- if (digitalRead(SWITCH_PIN) == LOW) {
- relayState = LOW;
- digitalWrite(RELAY_PIN, relayState);
- lightOn = false;
- sensorsEnabled = true;
- Serial.println("Switch DOWN: Relay OFF, Light OFF, Sensors enabled.");
- }
- }
- void turnOnLightFromSensor() {
- relayState = HIGH;
- digitalWrite(RELAY_PIN, relayState);
- Serial.println("🐛 DEBUG: Relay set HIGH in turnOnLightFromSensor()");
- lightOn = true;
- sensorsEnabled = true;
- }
- // === Web Server ===
- void setupWebServer() {
- server.on("/", HTTP_GET, []() { handleRoot(); });
- server.on("/toggle", HTTP_GET, []() {
- relayState = !relayState;
- digitalWrite(RELAY_PIN, relayState);
- if (relayState == HIGH) {
- Serial.println("🐛 DEBUG: Relay toggled to HIGH via web");
- turnOnLightManually();
- } else {
- turnOffLight();
- }
- handleRoot();
- });
- server.on("/lightstatus", HTTP_GET, []() {
- server.send(200, "text/plain", lightStatus == HIGH ? "ON" : "OFF");
- });
- server.begin();
- Serial.println("Server started");
- }
- void handleRoot() {
- String buttonText = (lightStatus == HIGH) ? "The Garage Lights Are ON" : "The Garage Lights Are OFF";
- String buttonColor = (lightStatus == HIGH) ? "green" : "red";
- String html =
- "<html><head><style>"
- "body { text-align: center; font-family: Arial; }"
- "h1 { font-size: 60px; }"
- ".button { width: 600px; height: 250px; font-size: 75px; color: white; }"
- ".red { background-color: red; }"
- ".green { background-color: green; }"
- "</style><script>"
- "function toggleLight() { fetch('/toggle').then(() => getLightStatus()); }"
- "function getLightStatus() {"
- " fetch('/lightstatus').then(r => r.text()).then(state => {"
- " const btn = document.getElementById('lightStatus');"
- " btn.innerHTML = (state == 'ON') ? 'The Garage Lights Are ON' : 'The Garage Lights Are OFF';"
- " btn.className = 'button ' + ((state == 'ON') ? 'green' : 'red');"
- " });"
- "}"
- "setInterval(getLightStatus, 500);"
- "</script></head><body onload=\"getLightStatus();\">"
- "<h1>John's LED Garage Lights Controller</h1>"
- "<button onclick=\"toggleLight();\" class=\"button " + buttonColor + "\" id=\"lightStatus\">" + buttonText + "</button>"
- "</body></html>";
- server.send(200, "text/html", html);
- }
- // === Wi-Fi Manager ===
- void manageWiFiConnection() {
- if (!wifiConnected && WiFi.status() == WL_CONNECTED) {
- wifiConnected = true;
- bootTime = millis(); // Set bootTime when connected
- Serial.println("Connected to Wi-Fi");
- Serial.print("IP Address: ");
- Serial.println(WiFi.localIP());
- }
- }
- ScriptExplanation.ino
- /*
- I added a lazer Taiss/1 Pair photoelectric Switch 0-20M Through-Beam Reflection Optical Photoelectric Beam Sensor NPN NO to this script that is hooked up to an optocoupler
- 12V Optocoupler Isolation Board Optoelectronic Isolator EL817 PC817 Card Rail Bracket Input 3-5 V Optocoupler Isolation Module 1 Channel Opto PNP NPN Signal Converter
- You hook up the optocoupler by giving 12v power to the two brown wires and the two blue wires goto ground the black wire is the signal wire. So on the two terminal input side of the optocoupler the + top terminal gets 12v source power
- the lower terminal negative gets the signal wire from the lazer. On the 3 terminal output side the top + terminal gets 3.3v from the ESP8266 and the lower negative terminal gets a ground from the ESP8266
- the middle terminal the ouput terminal connects to the GPIO pin 4
- When the lazer beam is broken a high 3.3v signal is sent to GPIO pin 4 and the relay goes high which turns on the 120v garage lights 🙂
- */
Advertisement
Add Comment
Please, Sign In to add comment