• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь ESP8266 прерывания

whiteud

New member
Цель: сделать счетчик воды (горячей и холодной)
Что имеется: два разных счетчика, цепляюсь к нему тестером "на замывание" и получаю следующее, при достижении следующего деления цепь в счетчике замыкается, примерно на половину движения минимального деления, затем цепь на примерно эту же часть деления размыкается. Т.е. по сути нажатие кнопки и ее удержание, затем кнопку отпускают - считаем это за 1 единицу.
Мой код реализации:

Код:
#include <Wire.h>

int button_cold = 5;
int counter_cold = 0;
int laststate = LOW;

void cold_water_interrupt()
{
if ((digitalRead(button_cold)==HIGH) and (laststate==LOW))
     {
       counter_cold++;
       Serial.print("Cold water: ");
       Serial.println(counter_cold);
       laststate=HIGH;
     }
    if ((digitalRead(button_cold)==LOW) and (laststate==HIGH))
      laststate=LOW;
}

void setup()
{
  Serial.begin(115200);
  Serial.println("");
  pinMode(button_cold, INPUT);
  attachInterrupt(button_cold,cold_water_interrupt,CHANGE);
}

void loop()
{

}
Почему решил использовать прерывания: кроме подсчета воды там будет настройка через веб значений, их выгрузка по MQTT, будут датчики протечки воды, и возможно исполнительная система перекрывания воды. Так вот, чтобы посторонний исполняемый код не вмешивался в подсчет (чтобы он был точным) решил использовать прерывания, в противном случае в loop можно пропустить кубометр другой.

Суть кода: на GPIO5 вешаем кнопку (делаю на макетке), далее мы эту кнопку инициализируем и вешаем на прерывание с режимом CHANGE функцию cold_water_interrupt (по идее должно было работать на RISING, но не полетело). Далее запускаем и видим, что при нажатии цифра постоянно растет, чего по идее быть не должно т.к. метод CHANGE подразумевает смену с LOW->HIGH или наоборот. Посему было добавлено два условия, 1. если кнопка нажата, а до этого ее положение было не нажато (laststate) то счетчик холодной воды (counter_cold) увеличиваем. Условие 2 если стейт был HIGH и кнопка не нажата - то меняем стейт на LOW.

В чем беда: проблему это решило, но не совсем, иногда проскакивают подряд 3-4 нажатия. И я вот не могу понять, может у меня кнопка хреновая? Или что-то барахлит, или код мой херовый?

По железу - NodeMCU + резистор в 1КОм на пин VIN и к кнопке, через GPIO5
 
Последнее редактирование:

fandy

Member
Думаю, что дребезг контактов никто не отменял.
Запоминайте время перехода с HIGH на LOW, при переходе с LOW на HIGH проверяйте. Если прошло меньше, например 10 мсек (сами посмотрите как быстро у Вас счетчик может замыкаться), то состояние все-равно меняем на HIGH, но счетчик не увеличиваем. То есть считаем, только если HIGH наступил после достаточно длительного LOW.
При этом алгоритме надо не забыть, что время переполняется раз в месяц с копейками. Так что это тоже надо анализировать, иначе можете обсчитаться на импульс.
Ну и обычно вместо чистого режима INPUT у входа включают подтягивающий резистор.
 

whiteud

New member
Спасибо, о таких тонкостях я не знал :) когда без прерываний делал проверка в Loop прокатывала )
 
Сверху Снизу