From eba13c618175da68df5185a5321bb015e4ce4210 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sun, 15 Feb 2026 19:05:19 +0100 Subject: [PATCH] Improved state change mechanism --- esp32_MachineNotify.ino | 90 +++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/esp32_MachineNotify.ino b/esp32_MachineNotify.ino index d2c303e..5c566d7 100644 --- a/esp32_MachineNotify.ino +++ b/esp32_MachineNotify.ino @@ -56,10 +56,9 @@ BH1750 lightMeter; // Thresholds const float LIGHT_ACTIVATION_THRESHOLD = 50.0; -const float LIGHT_DEACTIVATION_THRESHOLD = 20.0; -const unsigned long VIBRATION_STATE_CHANGE_INTERVAL = 10000; // 1000 = 1 second +const unsigned long WINDOW_DURATION = 10000; // 10 seconds +const int REQUIRED_CONSECUTIVE_WINDOWS = 6; const unsigned long VIBRATION_ACTIVE_THRESHOLD = 100000; -const int VIBRATION_WINDOW_SIZE = 6; // X * VIBRATION_STATE_CHANGE_INTERVAL seconds window const unsigned long WARMUP_DURATION = 30000; // 20 seconds warmup // Device state @@ -67,9 +66,7 @@ bool isVibrationActive = false; bool isLightActive = false; // Time tracking for sensor states -unsigned long lastVibrationCheckTime = 0; -unsigned long lightHighStartTime = 0; -unsigned long lightLowStartTime = 0; +unsigned long lastWindowStartTime = 0; // OLED display data #ifdef ENABLE_DISPLAY @@ -91,10 +88,12 @@ QueueHandle_t notificationQueue; volatile bool isNetworkActive = false; #ifdef ENABLE_SENSORS -unsigned long vibrationHistory[VIBRATION_WINDOW_SIZE]; -int vibrationHistoryIdx = 0; -unsigned long vibrationWindowTotal = 0; unsigned long vibrationTotalLow = 0; +int vibConsecutiveOn = 0; +int vibConsecutiveOff = 0; +int lightConsecutiveOn = 0; +int lightConsecutiveOff = 0; +float maxLightInWindow = 0.0; volatile unsigned long lastChangeTime = 0; volatile unsigned long lowTimeAccumulator = 0; volatile unsigned long highTimeAccumulator = 0; @@ -186,9 +185,6 @@ void setup() { lastChangeTime = micros(); attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), onChange, CHANGE); - // Initialize history buffer - for(int i=0; i maxLightInWindow) { + maxLightInWindow = currentLightLevel; + } #else float currentLightLevel = 0.0; #endif @@ -257,11 +256,12 @@ void loop() { bool previousVibrationState = isVibrationActive; bool previousLightState = isLightActive; - // Vibration state change logic - #ifdef ENABLE_SENSORS - if (currentTime - lastVibrationCheckTime >= VIBRATION_STATE_CHANGE_INTERVAL) { - lastVibrationCheckTime = currentTime; + // Window Logic + if (currentTime - lastWindowStartTime >= WINDOW_DURATION) { + lastWindowStartTime = currentTime; + // 1. Process Vibration + #ifdef ENABLE_SENSORS noInterrupts(); unsigned long now = micros(); unsigned long duration = now - lastChangeTime; @@ -278,40 +278,42 @@ void loop() { highTimeAccumulator = 0; interrupts(); - vibrationWindowTotal -= vibrationHistory[vibrationHistoryIdx]; - vibrationHistory[vibrationHistoryIdx] = vibrationTotalLow; - vibrationWindowTotal += vibrationTotalLow; - vibrationHistoryIdx = (vibrationHistoryIdx + 1) % VIBRATION_WINDOW_SIZE; + bool vibWindowOn = (vibrationTotalLow > VIBRATION_ACTIVE_THRESHOLD); - if (vibrationWindowTotal > VIBRATION_ACTIVE_THRESHOLD && currentTime > WARMUP_DURATION) { - isVibrationActive = true; + if (vibWindowOn) { + vibConsecutiveOn++; + vibConsecutiveOff = 0; } else { + vibConsecutiveOff++; + vibConsecutiveOn = 0; + } + + if (vibConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) { + isVibrationActive = true; + } else if (vibConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) { isVibrationActive = false; } - } - #endif + #endif - // Light state change logic - if (currentLightLevel >= LIGHT_ACTIVATION_THRESHOLD && !isLightActive) { - if (lightHighStartTime == 0) { - lightHighStartTime = currentTime; + // 2. Process Light + bool lightWindowOn = (maxLightInWindow > LIGHT_ACTIVATION_THRESHOLD); + + if (lightWindowOn) { + lightConsecutiveOn++; + lightConsecutiveOff = 0; + } else { + lightConsecutiveOff++; + lightConsecutiveOn = 0; } - if (currentTime - lightHighStartTime >= VIBRATION_STATE_CHANGE_INTERVAL && currentTime > WARMUP_DURATION) { + + if (lightConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) { isLightActive = true; - } - lightLowStartTime = 0; - } else if (currentLightLevel < LIGHT_DEACTIVATION_THRESHOLD && isLightActive) { - if (lightLowStartTime == 0) { - lightLowStartTime = currentTime; - } - if (currentTime - lightLowStartTime >= VIBRATION_STATE_CHANGE_INTERVAL) { + } else if (lightConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) { isLightActive = false; } - lightHighStartTime = 0; - } else if(currentLightLevel >= LIGHT_ACTIVATION_THRESHOLD) { - lightLowStartTime = 0; - } else { - lightHighStartTime = 0; + + // Reset Light Accumulator + maxLightInWindow = 0.0; } // Device 1 (Vibration) Notifications @@ -382,10 +384,10 @@ void loop() { #ifdef ENABLE_DISPLAY // Update display data - displayData[0] = String(DEVICE1_NAME) + ": " + String(vibrationWindowTotal); - displayData[1] = "Vibra: " + String(isVibrationActive ? "ON" : "OFF"); + displayData[0] = String(DEVICE1_NAME) + ": " + (vibrationTotalLow > VIBRATION_ACTIVE_THRESHOLD ? "YES" : "NO"); + displayData[1] = "Vibra: " + String(isVibrationActive ? "OFF? " + String(vibConsecutiveOff) : "ON? " + String(vibConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS); displayData[2] = String(DEVICE2_NAME) + ": " + String(currentLightLevel, 0); - displayData[3] = "Light: " + String(isLightActive ? "ON" : "OFF"); + displayData[3] = "Light: " + String(isLightActive ? "OFF? " + String(lightConsecutiveOff) : "ON? " + String(lightConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS); displayDataLines = 4; // Update display