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

Нужна помощь ESP-01. Отображения значения переменной на Web странице

Сергей_Ф

Moderator
Команда форума
@bavspb у кнопки есть дребезг при срабатывании контактов. При перекидывания замыкающего контакта он ударяется о неподвижный и отскакивает несколько раз. Как молоток от наковальни. Почитайте то что написано чуть выше. С дребезгом надо бороться, как - решать вам. Одно предложение тут уже было озвучено.
 

Сергей_Ф

Moderator
Команда форума
@nikolz зачем везде ставить? Я так не делаю и не предлагал. Исхожу из рекомендаций Как использовать ключевое слово volatile на языке C | avr | programming
Тут явно рекомендуют глобальную переменную, изменяемую в процедуре прерывания, так объявлять. Не вижу причин так не делать. Если не об явить то работать будет, может быть. А может и нет. Не люблю неопределенность.
[off]П.с.а за чем вы свои посты удаляете? Трудно потом слдедить за дискуссией.[/off]
 

CodeNameHawk

Moderator
Команда форума
оператор X++; X загрузится из памяти и значение поместится в X
а в регистре X
В этот момент происходит прерывание, оно снова берет Х из памяти, увеличивает ее и записывает в память, после выхода с прерывания, регистр восстанавливается но в нем хранится старое значение переменной.
 

Сергей_Ф

Moderator
Команда форума
@CodeNameHawk в принципе есть атомарный операнд инкремента переменной в памяти, так что вероятность такого события очень мала. А вот то что мы прочитаем в основной программе и откуда прочитаем - это загадка без volatile. Есть несколько вариантов: 1)все работает как задумалось
2)компилятор оптимизировал код и поскольку в основной программе переменная не меняется загнал ее в константу
3)компилятор загрузил переменную в регистр и не обращается к больше к памяти
Мне видится так.
@CodeNameHawk ещё раз перечитал, сорри. Не правильно понял в первый раз. Вы правы. Можно считать ещё один вариант.
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
Если совсем на пальцах, то
1)Прерывание по отпусканию кнопки это RISING, а не FALLING, как у вас
2) объявить Result в начале программы как volatile
3) добавить внутрь прерывания небольшую задержку delay(DELAY), где DELAY подобрать экспериментально от 2 до 20. Это простейший, но не оптимальный способ борьбы с дребезгом.
4) заменить кнопку на геркон.
 
Последнее редактирование:

CodeNameHawk

Moderator
Команда форума
Мне чаще всего попадался пункт
2)компилятор оптимизировал код и поскольку в основной программе переменная не меняется загнал ее в константу
1)Прерывание по отпусканию кнопки это RISING, а не FALLING, как у вас
Реакция "должна" быть на нажатие кнопки, так что FALLING здесь подходит.
Провода кнопки делайте минимальной длины(если рядом много помех не помешает экранированный провод ), прямо на вход проца поставьте подтягивающий резистор на 1 ком к +5В и конденсатор на 0.1 мкф на минус.
 

Сергей_Ф

Moderator
Команда форума
Вопрос: как вывести на HTML страницу значение переменной, которая будет накапливать количество срабатывания геркона?
Реакция "должна" быть на нажатие кнопки,
можно поспорить ;)
По мне так срабатывание геркона - это его замыкание и размыкание. Полный цикл.
 

Сергей_Ф

Moderator
Команда форума
т е дребезг автоматом фильтруется.
Спасибо за подсказку попробую использовать такой фильтр.
Конкретно в этой задаче неважно запрещать прерывания или нет, такой дребезг как вы описали отфильтруется в любом случае, либо прерывание повторно не сработает, либо сработает, но запишет так, что никто не прочтёт, имхо.
А ТС вы дали пример, там запрещения прерываний в начале и разрешения в конце нет. И, скорее всего, оно и не требуется, прерывание не сработает внутри прерывания, даже если поставить задержку delay(20); как я предложил. Будет неявный запрет, имхо.
 

CodeNameHawk

Moderator
Команда форума
По мне так срабатывание геркона - это его замыкание и размыкание. Полный цикл.
Хорошо будет работать в сигнализации.
Или подсчет входящих в помещение людей с одновременным включением света в помещении.
Явно зависит от задачи.
 

CodeNameHawk

Moderator
Команда форума
вообще-то в колбеке я всегда в начале запрещаю прерывание а в конце разрешаю. А ВЫ?
Я стараюсь выставить флаг, обработка в основном цикле.

В случае указанном вами это даже хорошо
так как означает что был дребезг и переменная изменится лишь на 1
т е дребезг автоматом фильтруется.
Не нравиться мне такая идея.
 

rst

Member
3) добавить внутрь прерывания небольшую задержку delay(DELAY), где DELAY подобрать экспериментально от 2 до 20.
Жесть какая! Как можно в ISR добавлять задержки??? :eek:
Задержку можно использовать для борьбы с дребезгом. Но никак не зависанием на N мсек в ISR. Для борьбы с дребезгом, длительность задержки должна быть заведомо > максимального времени дребезга контактов. Для кнопок, нажимаемых пальцем времена дребезга обычно лежат в диапазоне от нескольких мсек до сотни мсек. Конечно дребезг при отжатии обычно немного меньше чем при нажатии, но всё равно - зависнуть в ISR даже на несколько мсек??? Это кривейшее решение, которое только можно придумать.
Нормально задержка от дребезга по нажатию делается:
1) В прерывании нажатия или отжатия запрещаем это самое прерывание, и взводим таймер на прерывание через время > максимальной длительности дребезга;
2) В прерывании таймера запрещаем это самое прерывание, и заново разрешаем прерывание от нажатия или отжатия (в зависимости от того, какое состояние кнопки сейчас).
Таким образом регистрируются события и нажатия и отжатия (с паузой подавления дребезга после каждого), но уведомление фоновому процессу идёт только о нужных событиях.
Всё. И никаких зависонов внутри ISR.
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
Жесть какая! Как можно в ISR добавлять задержки???
я же пометил что это простейший не оптимальный вариант. Так делать в прерывании нельзя, но сначала разговор шёл о цикле. Там можно.
Нормально задержка от дребезга делается:
1) В прерывании нажатия или отжатия запрещаем это самое прерывание, и взводим таймер на прерывание через время > максимальной длительности дребезга;
2) В прерывании таймера запрещаем это самое прерывание, и заново разрешаем прерывание от нажатия или отжатия.
вряд ли ТС понял, что вы написали, имхо.
 

CodeNameHawk

Moderator
Команда форума
содержательно.
В колбеке, не запрещая прерывания, устанавливаете переменную флаг в true.(типа knopka_nazata=true;)
(дребезг контактов кнопки сбросить ее не может)
В main проверяете if (knopka_nazata==true) выполняете "полезное действие".
Если время выполнения "полезного действия" меньше чем 300 мс добавляете задержку.
Сбрасываете флаг в false.
 

rst

Member
В колбеке, не запрещая прерывания, устанавливаете переменную флаг в true.(типа knopka_nazata=true;)
(дребезг контактов кнопки сбросить ее не может)
А в чём тут защита от дребезга?
Дребезг нажатия сбросить её не сможет, но дребезг отжатия установить - сможет. Итого: knopka_nazata=true будет при нажатиях, а иногда и при отжатиях. :eek:
См: https://esp8266.ru/forum/threads/es...mennoj-na-web-stranice.3774/page-3#post-55719
 
Последнее редактирование:

bavspb

New member
А в чём тут защита от дребезга?
Дребезг нажатия сбросить её не сможет, но дребезг отжатия установить - сможет. Итого: knopka_nazata=true будет при нажатиях, а иногда и при отжатиях. :eek:
См: https://esp8266.ru/forum/threads/es...mennoj-na-web-stranice.3774/page-3#post-55719

Спасибо за пояснение про "дребезг".

В итоге сделал задержку на 0,5 секунды и все стабильно работает

void handleInterrupt() {

static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();

if (interrupt_time - last_interrupt_time > 500)
{
Result++;
}
last_interrupt_time = interrupt_time;
}
 
Сверху Снизу