223 lines
6.1 KiB
C++
223 lines
6.1 KiB
C++
#include <WiFi.h>
|
|
#include <HTTPClient.h>
|
|
#include <Wire.h>
|
|
#include <BH1750.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
|
|
// 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();
|
|
}
|