From 99234105ccb61839264301b8182ec387c88ba803 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Thu, 12 Feb 2026 18:47:30 +0100 Subject: [PATCH] Initial commit --- esp32_MachineNotify.ino | 222 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 esp32_MachineNotify.ino diff --git a/esp32_MachineNotify.ino b/esp32_MachineNotify.ino new file mode 100644 index 0000000..4f59abe --- /dev/null +++ b/esp32_MachineNotify.ino @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include + +// WiFi credentials +const char* WIFI_SSID = "YOUR_WIFI_SSID"; +const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"; + +// ntfy.sh topic +const char* NTFY_TOPIC = "YOUR_NTFY_TOPIC"; + +// Pin definitions +const int VIBRATION_PIN = 4; + +// OLED display settings +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) +#define SCREEN_ADDRESS 0x3C +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +// Light sensor +BH1750 lightMeter; + +// Thresholds +const float LIGHT_ACTIVATION_THRESHOLD = 200.0; +const float LIGHT_DEACTIVATION_THRESHOLD = 10.0; +const unsigned long VIBRATION_STATE_CHANGE_INTERVAL = 5000; // 5 seconds + +// Device state +bool isVibrationActive = false; +bool isLightActive = false; +bool isDeviceActive = false; + +// Time tracking for sensor states +unsigned long vibrationLowStartTime = 0; +unsigned long vibrationHighStartTime = 0; +unsigned long lightHighStartTime = 0; +unsigned long lightLowStartTime = 0; + +// OLED display data +String displayData[4]; +int currentDisplayLine = 0; +unsigned long lastDisplayScrollTime = 0; +const unsigned long DISPLAY_SCROLL_INTERVAL = 2000; // 2 seconds + +void setup() { + Serial.begin(115200); + + // Initialize vibration sensor pin + pinMode(VIBRATION_PIN, INPUT); + + // Initialize I2C bus + Wire.begin(); + + // Initialize light sensor + if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) { + Serial.println(F("Could not find a valid BH1750 sensor, check wiring!")); + while (1) { } + } + + // Initialize OLED display + if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { + Serial.println(F("SSD1306 allocation failed")); + for (;;); + } + display.clearDisplay(); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0, 0); + display.println(F("Initializing...")); + display.display(); + + // Connect to WiFi + Serial.print("Connecting to "); + Serial.println(WIFI_SSID); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + display.clearDisplay(); + display.setCursor(0,0); + display.println("WiFi Connected"); + display.display(); + delay(1000); + + lastVibrationChangeTime = millis(); + lastLightChangeTime = millis(); +} + +void sendNotification(String message); +void updateDisplay(); + +void loop() { + unsigned long currentTime = millis(); + + // Sensor readings + bool currentVibrationState = (digitalRead(VIBRATION_PIN) == LOW); + float currentLightLevel = lightMeter.readLightLevel(); + + // Vibration state change logic + if (currentVibrationState && !isVibrationActive) { // Vibration is active (LOW) + if (vibrationLowStartTime == 0) { + vibrationLowStartTime = currentTime; + } + if (currentTime - vibrationLowStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + isVibrationActive = true; + } + vibrationHighStartTime = 0; // Reset high timer + } else if (!currentVibrationState && isVibrationActive) { // Vibration is inactive (HIGH) + if (vibrationHighStartTime == 0) { + vibrationHighStartTime = currentTime; + } + if (currentTime - vibrationHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + isVibrationActive = false; + } + vibrationLowStartTime = 0; // Reset low timer + } else if (currentVibrationState) { + vibrationHighStartTime = 0; + } else { + vibrationLowStartTime = 0; + } + + // Light state change logic + if (currentLightLevel >= LIGHT_ACTIVATION_THRESHOLD && !isLightActive) { + if (lightHighStartTime == 0) { + lightHighStartTime = currentTime; + } + if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + isLightActive = true; + } + lightLowStartTime = 0; + } else if (currentLightLevel < LIGHT_DEACTIVATION_THRESHOLD && isLightActive) { + if (lightLowStartTime == 0) { + lightLowStartTime = currentTime; + } + if (currentTime - lightLowStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + isLightActive = false; + } + lightHighStartTime = 0; + } else if(currentLightLevel >= LIGHT_ACTIVATION_THRESHOLD) { + lightLowStartTime = 0; + } else { + lightHighStartTime = 0; + } + + + // Overall device state + bool previousDeviceState = isDeviceActive; + isDeviceActive = isVibrationActive || isLightActive; + + if (isDeviceActive != previousDeviceState) { + if (isDeviceActive) { + sendNotification("Washing machine cycle started."); + } else { + sendNotification("Washing machine cycle finished."); + } + } + + // Update display data + displayData[0] = "Vibration: " + String(isVibrationActive ? "ON" : "OFF"); + displayData[1] = "Light: " + String(currentLightLevel) + " lx"; + displayData[2] = "Light Active: " + String(isLightActive ? "ON" : "OFF"); + displayData[3] = "Device: " + String(isDeviceActive ? "ACTIVE" : "INACTIVE"); + + // Update display + updateDisplay(); +} + +void sendNotification(String message) { + if (WiFi.status() == WL_CONNECTED) { + HTTPClient http; + String url = "http://ntfy.sh/" + String(NTFY_TOPIC); + http.begin(url); + http.addHeader("Content-Type", "text/plain"); + + int httpResponseCode = http.POST(message); + + if (httpResponseCode > 0) { + Serial.print("HTTP Response code: "); + Serial.println(httpResponseCode); + } else { + Serial.print("Error on sending POST: "); + Serial.println(httpResponseCode); + } + + http.end(); + } else { + Serial.println("WiFi Disconnected. Cannot send notification."); + } +} + +void updateDisplay() { + unsigned long currentTime = millis(); + + // Scroll logic + if (currentTime - lastDisplayScrollTime > DISPLAY_SCROLL_INTERVAL) { + lastDisplayScrollTime = currentTime; + currentDisplayLine = (currentDisplayLine + 1) % 4; + } + + display.clearDisplay(); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0, 0); + + for (int i = 0; i < 4; i++) { + int lineIndex = (currentDisplayLine + i) % 4; + display.println(displayData[lineIndex]); + } + + display.display(); +}