• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 прокатывала )
 
Сверху Снизу