В следующих трех уроках научимся обрабатывать сигналы на дискретных входах микроконтроллера для определения их достоверного состояния. Попросту говоря, будем бороться с дребезгом механических контактов и повышать помехозащищенность входов. В последующих двух уроках мы разработаем класс обработки сигналов и оформим его библиотекой.
А в этом уроке разберемся с проблемами чтения состояния входных сигналов и алгоритмами для их решения.
Предыдущий урок Список уроков Следующий урок
Значительную часть информации извне микроконтроллер получает со своих дискретных входов. Я имею в виду чисто дискретные входы. Не аналоговые входы, не интерфейсные устройства, а просто логические входы, на которых сигнал может иметь высокий или низкий уровень.
В реальных схемах к дискретным входам микроконтроллера могут быть подключены самые разные устройства. И проблемы с ними могут быть самыми разнообразными. В уроке я рассматриваю вопросы искажения формы сигнала на входах микроконтроллера и способы определения их достоверного состояния.
Эта тема достаточно подробно затронута в Уроках Ардуино. Я повторно, в более компактной форме, расскажу о проблемах и алгоритмах для их решения. Кто совсем не знаком с этим вопросом, лучше прочитать Уроки Ардуино 6, 7, 8. Тем более, что урок 7 посвящен классам, а в следующем уроке мы также будем разрабатывать класс.
Типовые проблемы определения микроконтроллером состояния входных дискретных сигналов.
Как правило, реальные сигналы на входах микроконтроллера имеют не ту форму, на которую мы рассчитываем. Речь идет не об идеальности фронтов, или незначительных колебаниях амплитуды. Я имею в виду принципиальные искажения сигналов, не позволяющие определить их состояние простым чтением входа.
Ко входам микроконтроллера могут быть подключены самые разные компоненты, устройства.
Механические контакты.
Это кнопки, переключатели, концевики, контакты реле и т.п.
Главная проблема – дребезг контактов. Контакты – это механические предметы.
При коммутации они отскакивают друг от друга. Поверхности у них неровные, часто покрыты грязью, окислами и т.п. Естественно при касании контактов происходит хаотичная коммутация электрической цепи. Это приводит к переходному процессу, называемому противным словом дребезг. Диаграмма сигнала коммутации механического контакта выглядит примерно так.
У такого сигнала невозможно выделить фронт переключения простым чтением входа. Например, невозможно определить, сколько нажатий кнопки было сделано.
Аналоговые компараторы.
Выходы аналоговых компараторов это тоже дискретные сигналы. Компараторы преобразовывают аналоговые сигналы, например датчиков, в логические уровни. Таким образом, микроконтроллер может получать информацию об аналоговых величинах.
Но компараторы обладают способностью выделять разность входных напряжений на уровне до нескольких мкВ. И если сравниваемые величины близки, то они ловят все возможные помехи. Это приводит к тому, что при изменении аналогового сигнала вблизи порога компаратора, на его выходе присутствует сигнал достаточно высокой частоты и полной амплитуды.
Простое чтение входа не выделит достоверно момент коммутации.
Датчики с дискретными выходами.
Я имею в виду оптические датчики положения, датчики Холла и т.п.
Эти датчики не имеют контактов, но у них тоже может быть дребезг. Любой датчик – это пороговый элемент и вблизи порога возможны непредсказуемые переключения.
Но с ними есть еще проблема. Это вибрации механических частей, положение которых они определяют. Представьте себе барабан, который вращается шаговым двигателем и должен остановиться по оптическому датчику. В момент остановки двигателя возникнут механические колебания, связанные с дискретностью положения ротора двигателя, явлением механического резонанса и т.п. Датчик честно отследит эти колебания. Но для нас они такие же паразитные, как и дребезг контактов.
Внешние дискретные сигналы.
На входы микроконтроллера могут приходить сигналы идеальной формы от другого интеллектуального устройства. Но если это устройство физически расположено на значительном расстоянии, то на линии связи наверняка будут воздействовать наводки, электромагнитные помехи. В сигналах вполне могут появиться паразитные короткие импульсы, которые приведут к недостоверному результату при простом чтении состояния входов.
Это касается и всех предыдущих устройств , например кнопки, подключенной к микроконтроллеру длинными проводами.
Длинная несогласованная линия.
Речь идет о передаче сигнала по длинной линии, волновое сопротивление которой не согласовано с передатчиком и приемником. В этом случае при коммутациях возникают значительные искажения сигнала, которые приводят к тем же последствиям, которые я перечислял выше.
Инерционность чтения состояния.
Иногда бывает алгоритмическая необходимость ввести инерционность в чтение состояния сигнала. Пример, рожденный моей фантазией – нажатие кнопки трясущейся рукой. Нам надо устранить тремор рук.
Вряд ли я перечислил все варианты. Жизнь их все время добавляет. Но я рассчитываю, убедить вас в том, что практически все входные дискретные сигналы необходимо обрабатывать программно. Внешние точно. Как исключение, я бы согласился без обработки считывать сигналы между компонентами одной платы.
В микроконтроллерах STM32 эта проблема усугубляется тем, что уровень входных сигналов всего 3,3 В. Фатальный результат принесет помеха с меньшим уровнем напряжения, чем для микроконтроллеров с питанием 5 В.
Алгоритмы обработки дискретных сигналов.
Все перечисленные выше источники неприятностей искажают сигнал на короткое время. Отсюда решение проблемы.
Не надо реагировать на слишком частое переключение сигнала. Если кнопка была нажата в течение, например, 0,001 сек, то здесь что-то не так. Не может кнопка сработать на такое короткое время. Значит это искажения, помехи, дребезг.
Решение - необходимо дождаться пока состояние кнопки будет устойчивым в течение определенного промежутка времени, и только после этого принимать решение.
Назовем этот способ – ожидание устойчивого состояния сигнала.
Для дискретной по времени системы метод можно сформулировать так.
Состояние сигнала считается равным определенному уровню, если в течение заданного количества считываний подряд его состояние не изменялось. Все результаты чтения сигнала были одинаковы.
Не буду изображать алгоритм. Все просто. Например, через каждую миллисекунду мы считываем состояние входа. Время подтверждения установили 10 мс. Так вот, если 10 подряд чтений были низкого уровня, значит, мы считаем сигнал равным низкому уровню. Если среди 10 чтений встретилась хотя бы одна 1, то начинаем отсчет заново.
Такой метод замечательно устраняет дребезг контактов, редкие импульсные помехи. Но с регулярными импульсными помехами он может не справиться. Вот диаграмма такого случая.
Верхняя диаграмма – это сигнал с дребезгом и регулярными импульсными помехами. Вторая диаграмма - счетчик подтверждения состояния. Короткие импульсы помехи сбрасывают его, и значение счетчика не достигает порога переключения.
Применительно к предыдущему примеру: 9 состояний низкого уровня и одно чтение высокого уровня. Счетчик никогда не достигнет 10, входной уровень никогда не определится, как низкий.
А визуально мы легко определяем, что в середине диаграммы сигнал переключился. Видим, что в первой половине диаграммы средний уровень сигнала высокий, а во второй половине – низкий. Отсюда второй алгоритм – усреднение сигнала.
- Создаем счетчик среднего значения сигнала.
- В цикле с определенным временем считываем состояние сигнала.
- Если оно высокое, то прибавляем 1 к счетчику, если низкое, то вычитаем. Таким образом, счетчик содержит среднее значение сигнала.
- Когда значение счетчика достигает 0, принимается решение, что сигнал имеет низкий уровень.
- Когда значение счетчика достигает максимального заданного значения (времени усреднения), принимается решение, что у сигнала высокий уровень.
Вот блок схема из уроков Ардуино.
Такой алгоритм достоверно выделяет сигнал среди регулярных импульсных помех, при условии, что средний уровень помех меньше среднего уровня сигнала.
Оба алгоритма цифровой фильтрации вносят задержку в определение состояния сигнала. Время задержки зависит от времени подтверждения или усреднения. Для механических контактов обычно используется время 5 – 50 мс.
В следующем уроке будем программно реализовывать алгоритмы цифровой фильтрации. Создадим класс для обработки дискретных сигналов.
Предыдущий урок Список уроков Следующий урок
STM32 это вещь!!! Главное не останавливайтесь )) А то инфо по STM32 вся разрозненная и трудна для понимания. А у Вас получается излагать доступно. Спасибо за Ваши старания!
Спасибо! Как раз оформляю новый урок.
Отличное объяснение алгоритма.
Я недавно начал с 32-ми. давай искать как люди обрабатывают кнопки «в лучших домах….»…что попало… большинство использует внешние прерывания для кнопок…
Нашел одного товарища, он текстом подобный алгоритм описал… я так и сделал, но наглядности никакой.
А тут прекрасные карнтинки! короче автору респект у уважуха!
Будет круто, если вы алгоритм доработаете для определения длительного и двойного нажатия кнопок, думаю можно как дополнение к этому уроку выпустить продвинутую версию алгоритма.
Я у себя сделал два порога, «короткое» и «длинное». но пока не реализовал «двойное».
У «Сименса» есть хорошие решения по отработке сигналов по «фронту» и «срезу». Считывание происходит в начале программного цикла, а запись в конце. В начале цикла происходит и установка меркеров (флагов или битов). И этот установленный меркер является запретом для обработки сигнала в какой-бы ветви обработки ПО оно не находилось в течении всего цикла выполнения программы, за исключением быстродействующих счетчиков. Приблизительное время выполнения одного цикла можно посмотреть в отладчике. Далее программист сам решает, надо-ли ему ставить цифровые фильтры и т.д. Всё просто.
Спасибо за развернутый ответ.
Через три года пришел в этот курс снова, прочитал ваш комметарий.
Очень толковаое решение, Сименсовское, возможно оно пришло из времен когда все делалось на ассмблере. Подозреваю, что в случае АСМа, такая реализация обработки кнопки была очень проста и понятна.
СПАСИБО!
Почему не использовать аппаратное подавление дребезгов, вот как хвалят микросхему mc14490?
Можно ли для надёжности использовать аппаратное + программное подавление?
Почему производители STM (ардуин и прочие) не сделали стандартных библиотек подавления дребезгов если проблема общемировая (пора бы было её давно решить в максимальном понимании качества/цены или хотя бы сделать десяток библиотек на любой вкус) и все программисты на сайтах делают по-своему «и говорят, что их программный код подавления идеален»?
Здравствуйте!
А чем вам не нравится программное подавление дребезга?
Оно не требует аппаратных элементов. Подавление происходит внутри микроконтроллера, т.е. устраняются помехи и наводки на связи внутри платы. Вы можете выбрать параметры подавления дребезга и помех.
Самый простой алгоритм подавления дребезга — помещать состояние ноги в младший (старший) бит переменной, и сдвигать ее в прерывании таймера вправо (влево). Как только переменная стала вся целиком стала состоять из нулей или единиц, выставляем флаг «точно нажато» / «точно отпущено».