diff --git a/esp32_MachineNotify.ino b/esp32_MachineNotify.ino index 532cd0b..1f3c182 100644 --- a/esp32_MachineNotify.ino +++ b/esp32_MachineNotify.ino @@ -3,8 +3,8 @@ // Feature Configuration - Comment out to disable #define ENABLE_SENSORS #define ENABLE_DISPLAY -#define ENABLE_WIFI -#define ENABLE_NOTIFICATIONS +//#define ENABLE_WIFI +//#define ENABLE_NOTIFICATIONS #ifdef ENABLE_WIFI #include @@ -47,9 +47,11 @@ BH1750 lightMeter; #endif // Thresholds -const float LIGHT_ACTIVATION_THRESHOLD = 200.0; -const float LIGHT_DEACTIVATION_THRESHOLD = 10.0; +const float LIGHT_ACTIVATION_THRESHOLD = 100.0; +const float LIGHT_DEACTIVATION_THRESHOLD = 20.0; const unsigned long VIBRATION_STATE_CHANGE_INTERVAL = 5000; // 5 seconds +const unsigned long VIBRATION_ACTIVE_THRESHOLD = 10000; +const int VIBRATION_WINDOW_SIZE = 4; // X * 5s seconds window // Device state bool isVibrationActive = false; @@ -57,18 +59,17 @@ bool isLightActive = false; bool isDeviceActive = false; // Time tracking for sensor states -unsigned long vibrationLowStartTime = 0; -unsigned long vibrationHighStartTime = 0; +unsigned long lastVibrationCheckTime = 0; unsigned long lightHighStartTime = 0; unsigned long lightLowStartTime = 0; // OLED display data #ifdef ENABLE_DISPLAY -String displayData[4]; +String displayData[5]; int currentDisplayLine = 0; unsigned long lastDisplayScrollTime = 0; const unsigned long DISPLAY_SCROLL_INTERVAL = 2000; // 1000 = 1 second -const int displayTextLines = 5; +const int displayTextLines = 4; int displayDataLines = displayTextLines; #endif @@ -77,6 +78,30 @@ String queuedNotification = ""; String queuedTitle = ""; String queuedPriority = ""; +#ifdef ENABLE_SENSORS +unsigned long vibrationHistory[VIBRATION_WINDOW_SIZE]; +int vibrationHistoryIdx = 0; +unsigned long vibrationWindowTotal = 0; +unsigned long vibrationTotalLow = 0; +volatile unsigned long lastChangeTime = 0; +volatile unsigned long lowTimeAccumulator = 0; +volatile unsigned long highTimeAccumulator = 0; + +void IRAM_ATTR onChange() { + unsigned long now = micros(); + unsigned long duration = now - lastChangeTime; + lastChangeTime = now; + + if (digitalRead(VIBRATION_PIN) == HIGH) { + // Changed to HIGH, so previous state was LOW + lowTimeAccumulator += duration; + } else { + // Changed to LOW, so previous state was HIGH + highTimeAccumulator += duration; + } +} +#endif + void setup() { Serial.begin(9600); Serial.println("Setup started."); @@ -88,6 +113,11 @@ void setup() { #ifdef ENABLE_SENSORS // Initialize vibration sensor pin pinMode(VIBRATION_PIN, INPUT); + lastChangeTime = micros(); + attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), onChange, CHANGE); + + // Initialize history buffer + for(int i=0; i= VIBRATION_STATE_CHANGE_INTERVAL) { + lastVibrationCheckTime = currentTime; + + noInterrupts(); + unsigned long now = micros(); + unsigned long duration = now - lastChangeTime; + lastChangeTime = now; + + if (digitalRead(VIBRATION_PIN) == LOW) { + lowTimeAccumulator += duration; + } else { + highTimeAccumulator += duration; } - if (currentTime - vibrationLowStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + + vibrationTotalLow = lowTimeAccumulator; + lowTimeAccumulator = 0; + highTimeAccumulator = 0; + interrupts(); + + vibrationWindowTotal -= vibrationHistory[vibrationHistoryIdx]; + vibrationHistory[vibrationHistoryIdx] = vibrationTotalLow; + vibrationWindowTotal += vibrationTotalLow; + vibrationHistoryIdx = (vibrationHistoryIdx + 1) % VIBRATION_WINDOW_SIZE; + + if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD) { 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) { + } else { isVibrationActive = false; } - vibrationLowStartTime = 0; // Reset low timer - } else if (currentVibrationState) { - vibrationHighStartTime = 0; - } else { - vibrationLowStartTime = 0; } + #endif // Light state change logic if (currentLightLevel >= LIGHT_ACTIVATION_THRESHOLD && !isLightActive) { @@ -244,10 +283,10 @@ void loop() { #ifdef ENABLE_DISPLAY // 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"); + displayData[0] = "Vibra: " + String(vibrationWindowTotal); + displayData[1] = " : " + String(isVibrationActive ? "ON" : "OFF"); + displayData[2] = "Light: " + String(currentLightLevel) + " lx"; + displayData[3] = " : " + String(isLightActive ? "ON" : "OFF"); displayDataLines = 4; // Update display