Прекращаем флуд в теме! Кому "релюхи" сюда не заглядывают и не оставляют свое "бесценное мнение"! Делайте на чем угодно, но данная тема вполне понятно называется.
Спасибо от RK9AMX
Спасибо от RK9AMX
Часть кода с терминалом тоже интересна. Если сочтете возможным, то с удовольствием посмотрел бы и её)
По коду. Когда назначаете номера выводов, то лучше их прописывать через константы или дефайны. Вы же не переназначаете работу портов в процессе выполнения алгоритма. Поэтому лучше сделать так:
В результате данные запишутся во флеш (её не жалко ), а не будут болтаться в RAM.Код:const int buttonInt = 0; const int Button = 2;
Объявление переменной (константы) int для назначения работы портов избыточно (2 байта). Достаточно uint8_t - 1 байт (0-255).
В результате можно записать так:
Дребезг контактов тактовых кнопок в зависимости от их конструктивных особенностей и износа может быть разным. Обычно 10-20мс, но может достигать 40мс и более. Это желательно учесть.Код:const uint8_t buttonInt = 0;
Вот у вас реализован отчет интервала времени в обработчике прерывания через millis(), а в основном цикле вы используете delay. Delay останавливает выполнение алгоритма. Поэтому временные задержки лучше выполнять через счетчики. В ардуино они уже реализованы - millis() и micros(). if-ами в основном цикле проверяйте наступило событие или нет. Не забывайте при этом обновлять переменную со значением счетчика начала отсчета времени.
Кстати, в обработчике прерывания непонятно для чего идет проверка if (millis() >= 10) {...}. Оно будет всегда верно, за исключением интервала времени 10мс после подачи питания и при переполнении счетчика после 4294967295мс. Так и задумано?
Из кода непонятно как реализовано управление. Схему бы ещё посмотреть. Хотя бы от руки нарисованную. Так будет более предметный разговор.
Полностью согласен с замечаниями насчёт портов. Этот код писался как проба работ с прерываниями, ну и так и остался. С дребезгом контактов в прерывании тут всё хитро. Как известно в прерывании ни Delay ни millis() и micros() не работают и не изменяют своих значений, а меняют свои значения в основной программе. Как видно в программе прерывание вызывается при изменении состояния входного сигнала. Если есть дребезг - я даже боюсь подумать в какое состояние мы попадём, потому что прерывание будет вызываться как по фронту так и по срезу входного сигнала. Так вот эта конструкция как бы фиксирует время вызова прерывания, и даёт его завершить без проблем. Счётчик тикает только в основном цикле. И опять же если дребезг то в прерывании никаких действий не будет. Вот такая вот идея.
Управление - схему я не рисовал, она и так понятна. Выходы с модуля на ULN2003 ну и на реле, или если использовать готовые модули реле - можно напрямую на них. Там по входу стоят оптроны. Скоро будут отдельные микросхемы 328Р, попробую всё это с внутренним тактовым генератором.
Спасибо от RK9AMX
Очень интересное решение. Тем не менее, даже если функция millis() не меняет своего значения во время прерывания, условие будет выполняться как я и описал. Есть такое подозрение. Я в описании прерывания не нашел, что происходит со значением счетчика millis(). Значение счетчика millis() сбрасывается в ноль после прерывания или счет продолжается со значения до прерывания?
Просто во время прерывания не тикает. Поэтому не надо в прерывании ничего долгого делать, можно зафиксировать изменение состояния кнопки и значение millis (не забыть обьявить переменные как volatile), а в основном цикле через 50мс от этого момента считаем, что кнопка нажата или отпущена, если будет дребезг - millis в прерывании поменяется и 50мс не натикают.
Спасибо от RK9AMX
Да, в прерывании не тикает, а в основном цикле продолжает, а там ещё и delay внутри которых тоже не тикает. Так что однозначно время на дребезг пройдет.
Спасибо от RK9AMX
Ага. Понятно. Тогда моё предположение, что условие в обработчике прерывания всегда будет верное подтвердилось.
R2DHG, примерно так?
Код:int buttonInt = 0; //... volatile uint32_t debouce_time; //... void setup () { //... attachInterrupt(buttonInt, swap, CHANGE); } // Обработчик прерывания void swap() { debounce_time = millis(); } void loop () { if (millis() - debounce_time > 50) { // считаем, что кнопка нажата. } //... }
Чтоб развеять сомнения можно в разных точках сохранить состояния а потом посмотреть их через Serial.print
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)