В чём вижу проблему: счетчики воды бывают 3-х классов. Обычно класс В - он обязан крутиться от 30л/час. класс А - от 60л/час. Класс С почти нет - 15л/час. Поэтому протечку сложно будет детектировать.
Алгоритм:
Запоминаем через сколько циклов пришёл новый импульс.
Если число циклов отличается от предыдущего числа на +- Х шт (гистерезис), то увеличиваем Y на единицу. Иначе Y=0.
Если Y превысил порог - тревога.
Пример:
Пусть тревога - 50 литров за 30мин.
Счетчик на 10л/имп.
Значит вода должна литься с одинаковой скоростью каждые
50л/30мин = 10л/3мин
Т.е. 1 импульс через каждые 180сек или 180*4 = 720 итераций пробуждения.
Те протечка - это если 5 раз подряд пришёл импульс через интервал не больше 720 итераций.
И эти интервалы близки.
Идея реализовать детектирование равномерного расхода воды в течении некоторого времени. Пример реализации: https://www.saures.ru/resheniya/kvartira/kontrol-protechek/
В чём вижу проблему: счетчики воды бывают 3-х классов. Обычно класс В - он обязан крутиться от 30л/час. класс А - от 60л/час. Класс С почти нет - 15л/час. Поэтому протечку сложно будет детектировать.
Алгоритм:
Пример: Пусть тревога - 50 литров за 30мин. Счетчик на 10л/имп. Значит вода должна литься с одинаковой скоростью каждые 50л/30мин = 10л/3мин Т.е. 1 импульс через каждые 180сек или 180*4 = 720 итераций пробуждения.
Те протечка - это если 5 раз подряд пришёл импульс через интервал не больше 720 итераций. И эти интервалы близки.
Примерный ход разработки:
define LEAK_WDT_LIMIT_DEFAULT 720
define LEAK_COUNT_DEFAULT 5
uint16_t wdt_prev; uint16_t leak_wdt_limit0 = LEAK_WDT_LIMIT_DEFAULT; uint16_t leak_wdt_limit1 = LEAK_WDT_LIMIT_DEFAULT; uint16_t leak_count0 = 0; uint16_t leak_count1 = 0;
.... bool is_leak(uint16_t &limit, uint16_t &count) { if (wdt_prev > 0) {
uint16_t diff = wdt_count - wdt_prev; if (wdt_count < wdt_prev) //перешли через wakeup_period { diff = wakeup_period - wdt_prev + wdt_count; }
if (abs(limit - diff) < LEAK_WDT_HISTERESIS) { count++; if (count >= LEAK_COUNT_DEFAULT) { return true; } } } else { count = 0; } } else { wdt_prev = wdt_count; } return false; }
.... if (counter0.is_impuls()) {
if (is_leak(leak_wdt_limit0, leak_count0)) { info.state.states0 = LEAK; wdt_count = wakeup_period; //пробуждаемся } }