Бинарные часы с будильником и таймером на Arduino Uno

Привет, Хабр!



Уже достаточно давно меня интересовала платформа Arduino, но никак до неё не доходили руки. И вот, недавно я приобрёл две платы Arduino и различные радиодетали. Наигравшись с парой диодов, я решил собрать что-нибудь полезное и интересное. Я давно хотел обзавестись бинарными часами и быстро понял, что приобретение Arduino — замечательная возможность сделать бинарные часы по своему вкусу.

С точки зрения электроники, собрать схему бинарных часов не так сложно. Я усложнил себе задачу и решил не отказывать себе в количестве кнопок и светодиодов. По начальному плану, на проект должно было пойти 22 диода, 6 кнопок и 1 пьезопищалка. Сначала я хотел собрать часы на Arduino Mega, т.к. на Arduino Uno недостаточно пинов для управления всем этим напрямую, однако потом я отказался от этой идеи и решил приобрести несколько выходных сдвиговых регистров 77HC595, так как это более рациональное решение проблемы.

Подготовка


Я решил начать с подсчёта того, что понадобится для построения девайса на макетной плате. В конечном итоге, получился вот такой список:

1 Arduino Uno.
2 Breadboard (полноразмерных, на 840 точек).
24 светодиода (я взял 7 красных, 7 зелёных, 6 синих, 2 жёлтых и 2 белых).
25 резисторов на 220 ом.
1 пьезопищалка.
6 тактовых кнопок.
3 выходных сдвиговых регистра 74HC595 в DIP-16 корпусе.
Соединительные провода и/или перемычки (у меня ушло около 90 штук).
Grove RTC — модуль часов реального времени от Seeed Studio на базе RTC-чипа DS1307.

Как это всё будет работать


Есть 10 видов бинарных часов. Одни показывают время в двоично-десятичном (BCD) представлении, вторые — в виде двоичных чисел. BCD-часы мне совсем не нравятся, поэтому я решил делать чисто двоичные часы. Возможно, их немного сложнее читать, чем BCD-часы, но мне кажется, что разница небольшая, так как быстро переводить короткие двоичные числа (до 6 бит) в десятичную систему счисления совсем не сложно. Также, я решил, что обязательно сделаю индикацию секунд на часах.

Схема распределения диодов такая:



Также, я решил сделать 6 кнопок:

Set — переход в режим настройки часов/будильника/таймера и сохранение текущего значения параметра в режиме настройки.
Mode — переключение между режимами часов, будильника и таймера.
Up — при настройке часов/будильника/таймера, увеличивает текущий параметр на единицу. В режиме таймера и будильника отвечает за активацию и отключение соответствующего режима. При срабатывании сигнала — отключает сигнал будильника/таймера.
Down — при настройке часов/будильника/таймера, уменьшает текущий параметр на единицу. В режиме таймера приостанавливает таймер без сброса отсчёта к начальному состоянию. При срабатывании сигнала будильника — будильник откладывается на 5 минут (snooze).
24/12 — переключение между 24-часовым и 12-часовым представлением времени.
Dim — отключает/включает светодиоды (при отключенных светодиодах никакие кнопки кроме Dim не работают).

Подключение компонентов


Все светодиоды должны подключаться последовательно с резистором (я использовал резисторы на 220 Ом), иначе можно сжечь не только сам диод, но и повредить Arduino. Резистор можно подключать как к катоду светодиода, так и к аноду. Общаться с диодами мы будем через сдвиговые регистры 74HC595. Это чип с 16-ю контактами. Они позволяют управлять большим числом выводов, используя всего 3 цифровых пина на Arduino.



Распиновка 74HC595:

Q0-Q7 — это выводы сдвигового регистра. К ним мы будем подключать светодиоды.
Vcc — это пин для питания. На него мы подаём 5В.
GND — земля. Соединяем её с GND на Ардуино.
OE — активация выводов. Этот пин инвертированный, т.е. для активации выводов нужно снять напряжение, а для отключения — наоборот подать. В нашем случаи управлять этим пином не обязательно, поэтому его можно просто замкнуть на землю.
MR — очистка регистра. Этот пин также инвертированный и нам не нужно им управлять, поэтому его можно подключить к 5В.
ST_CP — это пин, отвечающий за обновление состояния сдвигового регистра. Во время записи нового состояния на этот пин следует подать LOW, а после записи — HIGH, чтобы обновить состояние выводов. Его нужно подключить к цифровому пину на Ардуино. Соединить все ST_CP на всех трёх регистрах можно параллельно.
SH_CP — это пин, отвечающий за сдвиг регистра на 1 бит. Его нужно подключить к цифровому пину на Ардуино. Соединить три SH_CP на всех микросхемах также можно параллельно.
DS — Пин, на который мы подаём данные. Его нужно подключить к цифровому пину на Ардуино.
Q7' — Пин для каскадного соединения с другими 74HC595. Нужно соединить Q7' первого регистра с DS второго и Q7' второго с DS третьего регистра. На третьем регистре Q7' никуда подключать не нужно.

Получается примерно такая схема подключения:



Пьезопищалку я подключил к третьему пину Ардуино последовательно с 220-омным резистором. Нужно отметить, что для работы с пьезопищалкой нужен пин, поддерживающий ШИМ (PWM). На Arduino Uno это пины 3, 5, 6, 9, 10 и 11.



С кнопками было два варианта: либо использовать внешние резисторы, либо использовать встроенные в Arduino подтягивающие резисторы, которые включаются так:

pinMode(pin,INPUT_PULLUP);

Единственное отличие такого подхода — что при нажатии кнопки будет считываться LOW, а при отпускании — HIGH, но при этом не потребуются внешние резисторы, поэтому я выбрал именно такой вариант. Нужно просто соединить одну сторону кнопок с землёй, а другую — с цифровыми пинами Ардуино.



Итоговая конструкция должна была выглядеть примерно так:



Сборка устройства на Breadboard


Когда я приобрёл все недостающие детали, я приступил к сборке девайса на Breadboard. В принципе, внешний вид получился вполне предсказуемый:



Конечно, результат оказался далёк от того, что я хотел получить. Всё-таки Breadboard сильно ограничивает свободу размещения компонентов. К тому же, пучок проводов, нависающий над макеткой не добавляет эстетического удовольствия. Впрочем, на то макетная плата и существует, чтобы собирать на ней макеты устройств, а не готовые устройства.

Написание кода


Я решил не использовать чужие наработки и реализовать программную часть полностью самостоятельно, с нуля. Начал я разработку с написания подпрограммы, которая при включении мигает всеми светодиодами и пищит пьезопищалкой. Это позволяет убедиться в том, что цепь (не считая кнопок) собрана правильно и не развалилась с момента прошлого включения. Многие устройства делают нечто подобное при включении.

Я не буду подробно рассматривать реализацию отдельных функций, так как скетч получился весьма объёмный. Поэтому я кратко рассмотрю некоторые аспекты реализации.

Работа со светодиодами

Так как мы общаемся с диодами через сдвиговый регистр, первым делом нужно было реализовать подпрограммы для удобной работы с диодами. Состояние всех светодиодов хранится в массиве led из трёх элементов типа unsigned char и выводится через сдвиговые регистры в конце каждой итерации основного цикла. Для упрощения работы с диодами реализован целый ряд вспомогательных функций, позволяющий легко устанавливать нужные биты в led в соответствии со входными аргументами, например часы, минуты и т.д. Также я реализовал различные эффекты анимации диодов. Например, если часы не настроены — часовые и минутные диоды будут мигать (по аналогии с обычными цифровыми часами, которые обычно мигают «0:00» если они не настроены). Для секундных диодов есть анимация, когда один диод бегает влево-вправо по полосе секундных диодов. Она используется, например, в режиме будильника (т.к. секундные диоды там не имеют более рационального применения) или во время настройки часов. Это придаёт более интересный внешний вид часам.

Основной цикл

Основная логика программы, фактически, представляет собой конечный автомат. В зависимости от текущего состояния, часы выводят соответствующую информацию, и переходят из одного состояния в другое при нажатии кнопок и событиях таймера. Реализовано это как большое число вложенных условий. На каждой итерации loop проверяется состояние кнопок и таймеров и вызов их обработчиков, после чего состояние диодов обновляется.

Ввод

Для обработки ввода понадобится массив, содержащий состояние кнопок (для того, чтобы при нажатии кнопки обработчик срабатывал только один раз для каждого нажатия). Когда напряжение на пине кнопки переходит в LOW — мы ставим соответствующий кнопке элемент массива в true (если он уже true — то не делаем ничего) и вызываем обработчик нажатия. Когда напряжение возвращается в HIGH — сбрасываем элемент массива в false. Проверка состояния кнопок реализована в виде одной подпрограммы.

Таймеры

Основная работа выполняется при срабатывании таймеров. В проекте я использовал два таймера. Один — с секундным разрешением (для обработки состояния часов, будильника и таймера, а также некоторых анимаций) и второй — с разрешением в 1/8 секунды. Он используется для вывода текущего времени (чтобы увеличить скорость визуального отклика часов при смене режимов), для анимации секундных светодиодов и подачи сигнала будильника. Оба таймера реализованы достаточно просто. С помощью значения, полученного от millis(), проверяем, прошёл ли определённый интервал времени с момента прошлого срабатывания таймера, и, если интервал прошёл — вызываем обработчик и сохраняем новое время срабатывания таймера. Также, реализована простая корректировка таймера. Если по какой-то причине, таймер сработал на несколько миллисекунд позже, чем нужно — то интервал следующего срабатывания уменьшится на такое же количество миллисекунд для компенсации опоздания.

Полный исходный код скетча доступен на Github:

Смотрим, что получилось


С программной точки зрения, полученный девайс работал идеально (во всяком случаи, на первый взгляд). Всё, что я хотел видеть в девайсе было реализовано и работало стабильно.



Но не обошлось и без ложки дёгтя. При практической проверке выяснилось, что часы отстают примерно на 1 секунду в час, что приводит к накоплению весьма значительной ошибки за короткое время. Подробное изучения вопроса показало, что проблема была в том, что оригинальная Arduino Uno использует для тайминга не кварцевый, а керамический резонатор, который не обладает достаточной точностью для измерения времени на длительных отрезках времени. Получился просчёт — крупный кварцевый резонатор на плате используется только для контроллера USB-To-Serial и использовать его для тайминга не представляется возможным. Было несколько вариантов решения проблемы. Наиболее интересным и удобным мне показался вариант с использованием часов реального времени. Кроме решения проблемы отставания часов они дают приятный бонус — при отключении питания Arduino часы не сбиваются за счёт батарейки-таблетки.

Я приобрёл модуль Grove RTC от Seeed Studio. Это уже готовая для использования плата с чипом часов реального времени DS1307. Также на плате расположен часовой кварц, три резистора и держатель для батарейки. Выглядит она так:



RTC-модуль общается с Arduino по шине I2C. Пины SDA и SCL подключаются на Arduino Uno к пинам A4 и A5 соответственно. GND цепляется к земле. 5V уже занят платой часов, так что подключить Vcc RTC-модуля некуда. Однако, так как RTC-модуль потребляет мало тока (в пределах допустимой нагрузки на цифровые пины) — его можно запитать от одного из цифровых пинов, который будет находиться в HIGH постоянно.

Доработка кода


Для работы с модулем RTC на сайте Seeed Studio доступна готовая библиотека. При реализации работы с RTC в первую очередь возник вопрос, как определять при включении, что нужно считывать текущее время из RTC. Для этих целей было решено использовать флаг в EEPROM. Если значение нулевого байта в EEPROM отличается от нуля — берём время из RTC, если байт равен нулю — то мы выполняем «первый запуск» с ненастроенными часами, мигающими 0:00. Также, было логично заодно реализовать и сохранение в EEPROM последнего установленного времени будильника и таймера. Для возможности отката к «заводским» настройкам я немного расширил процедуру самотестирования при включении — если зажать во время включения кнопку SET — EEPROM будет очищен и девайс произведёт программную перезагрузку (путём выставления счётчика команд в 0).

Затем я реализовал подмножество необходимых функций для работы с RTC в проекте и оставалось только правильно интегрировать их в остальной код. Я перенёс из секундного таймера в отдельный секундный таймер, привязанный к RTC все обработчики, связанные со временем. Старый секундный таймер я оставил под некритичные к точности задачи (например, анимацию мигания светодиодов).

В отличие от остальных таймеров, которые проверяются на каждой итерации основного цикла, проверка RTC-таймера вложена в обработчик таймера на 1/8 секунды. Работа с I2C — достаточно ресурсоёмкая операция и постоянный опрос RTC в цикле приводит к нежелательным эффектам, вроде опаздывания таймеров и искажённого звучания пьезопищалки. Проверка RTC-таймера из секундного таймера привела бы к тому, что часы периодически отсчитывали бы две секунды (т.к. керамический резонатор моей Arduino немного отстаёт от реального времени), а это крайне нежелательно, поэтому обработка RTC в таймере на 1/8 секунды была наиболее оптимальным вариантом.

Придаём устройству завершённый вид

Насколько бы ни была хороша программная часть, внешний вид полученного устройства всё равно оставляет желать лучшего. Поэтому я решил перенести его с Breadboard на полноценную печатную плату. Первым делом, нужно было сделать разводку платы. Для этих целей я использовал Fritzing, так как у меня там уже была построена схема устройства и вид на Breadboard. Я не стал доверять работу автотрассировщику и произвёл трассировку платы вручную. Этот процесс занимает определённое время, но в итоге я получил готовый для производства проект печатной платы:



Я решил заказывать производство печатной платы в китае. У Seeed Studio есть сервис по производству печатных плат Fusion PCB. Fritzing умеет экспортировать проекты печатных плат в формат Extended Gerber (RS-274X), с которым работает большинство производителей печатных плат (в т.ч. и Seeed Studio). Я заказал производство плат и уже через две недели получил посылку с изготовленными платами:



Осталось только припаять все компоненты на плату. Раньше мне никогда не доводилось заниматься пайкой, но я быстро освоился. Как мне кажется, для первого раза получилось довольно неплохо:



Конечный результат выглядит намного лучше, чем макет на Breadboard.

Заключение

Я получил то, что хотел — свои собственные бинарные часы с будильником и таймером. Если использовать батарейный отсек — то получаются вполне автономные часы, которые могут стоять где угодно. Платформа Arduino полностью оправдала мои ожидания и я думаю, что я ещё не раз буду использовать её в своих проектах.

Ссылки

Каскадное соединение нескольких выходных сдвиговых регистров 74HC595
Использование встроенных подтягивающих резисторов
Исходный код скетча бинарных часов

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 46

  • UFO just landed and posted this here
      +4
      Спорный вопрос, но уж делая плату, я бы поставил на нее и МК, тем более, что насколько я вижу, ардуинка у вас с DIP-вариантом атмеги в панельке, то есть никаких проблем впаять уже зашитую микросхему, не морочась с программированием на плате.
        0
        Ну, в том-то и дело, что я не был уверен, что я не буду перепрограммировать. Последние изменения в код я внёс уже после того, как припаял всё (нашёл один небольшой косяк в коде). Постоянно перепаивать не будешь, да и к тому же я не исключал добавление новых фич.
          0
          Так можно либо подпаяться к нужным проводкам, либо сделать вывод на эти проводки, либо сам контролер «запихать» в разъем.
        +3
        Фи! Собирать часы на логических элементах как пушкой по воробьям. Было бы гораздо интересней, если бы часы собирались на транзисторах или лампах.
          +3
          Не, только механика есть труъ. Только шаговые искатели и свободный маятник Шорта в качестве частотозадающего элемента.
            +3
              0
                0
                Там же двигатель, который вращается в соответствии с частотой промышленной сети. Точность правда неважнецкая.
                  0
                  Секунды иногда проскакивают.
                    +3
                    На тиратронах красивее:

                    0
                    Класс, есть шаговые искатели… спасибо за идею.
              +1
              Переключение 12/24 на бинарных часах, это оригинально! Я не сразу понял в чем будет разница, пока не заметил отдельностоящую пару светодиодов. Хотя в любом случае непонятно зачем это переключение в устройстве конструируемом не для массового рынка.
                0
                А, туплю, разница-то будет. Просто для этого можно было бы задействовать светодиод старшего разряда. В общем, первая часть комментария не имеет смысла.
                  0
                  Ну, на самом деле я долго думал, делать переключение, или нет. Я его сделал в первую очередь потому, что я равнялся на обычные цифровые часы, у которых оно есть. Светодиод старшего разряда я не стал использовать потому, что было бы неочевидно, в каком формате выводится время, если не знать заранее. К тому же светодиоды AM/PM имеют дополнительную функцию в режиме таймера (AM — таймер остановлен, PM — таймер идёт, AM+PM — таймер на паузе).
                0
                Всё здорово, кроме применяемой базы компонентов. Одна MAX7219/7221 позволит вам заменить все сдвиговые регистры и токозадающие резисторы. А еще она умеет программно изменять яркость и кучу других приятных плюшек.

                Если же говорить о этапе прототипирования, то и тут она сэкономит кучу нервов: чем меньше контактов на такой макетке, тем меньше проблем с ними.

                И еще. Ардуина вам тут совсем не нужна. Поставьте atmega328p на плату с часами в такую же цанговую кроватку, из рассыпухи для запуска надо 3 конденсатора, резистор, кварц. А если вам сойдет 8Мгц системной частоты, то просто 1 конденсатор. Наконец RTC можно также реализовать на атмеге, поставив 32.768кГц кварц на ноги второго генератора и по нему тактировать таймер атмеги.

                В общем, успехов в доработке)
                  0
                  Можно вовсе выбросить отдельный контроллер светодиодов, собрать из них матрицу 6*8, а динамическую индикацию генерировать самим контроллером. Дополнительные транзисторы не нужны — выводов контроллера хватит на запитку светодиодов.
                    0
                    У автора ток на светодиод — 22мА. А у атмеги328 по питанию максимум — 200мА. Так что не хватит(если «в лоб»). Конечно, можно накрутить ШИМ для светодиодов, но получится значительно сложнее. К тому же, тогда придеться вернуть токоограничивающие резистора на плату, а их много. Зачем усложнять себе жизнь, если уже есть хорошие инструменты для решения подобных задач?
                      0
                      Так одновременно будут светить максимум 6 светодиодов, 6*22=132, 132 < 200. 6 резисторов потребуется поставить, разве это много?
                        0
                        Тогда я вас не догнал. Почему только 6? По 5 разрядов на часы/минуты/секунды + диоды режимов. Впрочем, можно слегка погасить диоды, тогда точно хватит…
                      +1
                      (5 В — 2,2 В) / 220 Ом = 13 мА на светодиод сейчас. На синих и белых поменьше, т.к. больше падение напряжения на светодиоде.

                      Ну и для индикаторных нужд в домашней обстановке при приличных светодиодах обычно можно и 5-7 мА ставить, они яркие, — тогда в 200 мА атмеги вписаться легко.
                    0
                    Ну, насколько я понял, MAX7219 и 7221 — это драйверы для матричных светодиодных дисплеев? Мне они не нравятся, таких часов на матричных дисплеях у китайцев хватает.

                    Насчёт Ардуины не спорю, вполне можно было собрать на голой атмеге, я думал насчёт этого. Но с Ардуиной проще править код, можно легко добавить фичи или вообще задействовать плату для какой-нибудь другой задачи. Постоянно перетыкать атмегу между Ардуино и платой как-то неудобно. А основной плюс отдельного RTC в том, что он благодаря батарейке сохраняет время при выключенной ардуине.
                      0
                      На этот драйвер можно и отдельные светодиоды сажать, и матрицу, и семисегментники. Все зависит от того, как запрограммировать. А голая атмега хороша тем, что когда закончится этап отладки кода, то захочется все на одной плате, а не мезонины с проводами...)
                        0
                        Я ещё добавлю про MAX72xx, что у них ток всех светодиодов задаётся одним резистором — поэтому легко регулировать яркость.
                          +1
                          Перетыкать всё время не надо, погуглите ArduinoISP. В кратце можно вывести пины для программирования и програмировать так же. Ещё вариант приобрести USBUART и программировать через бутлоадер.
                        +2
                        Как красиво разведена печатка, да Вы, батенька, эстет!
                          0
                          >>DS1307

                          Если нужна точность хода юзайте DS3231 или DS3232
                            +3
                            Маленькая подсказка: дорожки на плате можно проводить и по диагонали тоже.
                              +4
                              А можно и так...

                              Бессеточный трассировщик TopoR, отечественная разработка, не имеет аналогов :)
                                +1
                                Можно и так, если у вас есть деньги на его покупку.
                                  0
                                  О, расширенный вариант аватарки vvzvlad )
                                  +1
                                  Да, я знаю, я сознательно развёл плату именно таким образом :) Я сначала хотел как раз диагональными дорожками соединить, но потом решил, что дорожки лесенкой будут смотреться интереснее, чем просто набор диагональных дорожек.
                                    0
                                    Не понимаю, что тут интересного, но раз развели и всё работает, то всё хорошо.
                                  0
                                  А можно узнать во склько вышло производства и доставка плат?
                                    0
                                    59.82$ за производство 5-ти плат и 9.22$ за доставку, всего обошлось в 69.04$ (чуть больше 3000 рублей).
                                    0
                                    Внимание грабли.
                                    Ты пишешь «проверка RTC-таймера вложена в обработчик таймера на 1/8 секунды.»
                                    Если в момент проверки пропадет питание, то время испортится. Какая вероятность? Я опрашивал 100 раз в секунду и часы сбрасывались часто. После этого переписал алгоритм и стал опрашивать раз в сутки.
                                    Правильное же решение сделать супервизор питания. Перед операцией чтения выполнять замер напряжения питания и только убедившись что оно в норме начинать операцию чтения. И при этом надо немного модифицировать цепи питания, рассчитать на сколько хватит заряда конденсатора,…

                                    Еще у большинства RTC есть выход «1гц». Его можно подцепить на пин контроллера и обрабатывать прерывания от него.

                                    Проблема касается любых RTC. Эти грабли проверены на DS1307, DS3231, PCF2129T, PCF8523.
                                      0
                                      на ds1307 выход SQW/OUT дает синхру нужной частоты (1гц, 4, 6, 32 кгц)
                                        0
                                        Хм, интересно, не знал. Пока ещё ни разу не наступал. Я сначала тоже думал переделать синхронизацию с RTC, например, на 1 раз в час, а в остальное время тикать родным резонатором, но это было бы чревато другими багами, т.к. код был изначально написан в расчёте на то, что время изменяется с разрешением в 1 секунду, а здесь бы появилась возможность отката на несколько секунд назад/вперёд в момент синхронизации, которую нужно было бы корректно обрабатывать. Поэтому я выбрал наиболее простой вариант решения проблемы. В принципе, раз в полсекунды вполне хватило бы, но для этого нужно было бы отдельный таймер писать. На платке RTC-модуля, который у меня выведены только питание с землёй и два пина I2C, так что прицепиться к пину 1 Гц достаточно сложно.
                                      +2
                                      Последователям на заметку — использовать чистый сдвиговый регистр типа 77HC595 неразумно, тк. он всего лишь восьмибитный и требует по резистору на каждый светодиод. Сейчас существует масса микросхем-драйверов LED, которые, являются и сдвиговыми регистрами, и стабилизаторами тока LED одновременно. Лично я использовал stp16cp05, который поддерживает 16 светодиодов, и тербует всего 1 резистора для настройки тока по всем выходным ногам сразу. В принципе подобные микросхемы(из тех, что я встречал) поддерживают до 28 светодиодов.
                                        +2
                                        но при этом не потребуются внешние резисторы для подавления дребезга


                                        Подтягивающие резисторы совсем не для подавления дребезга используются, что внутренние, что внешние.
                                          0
                                          Да, я знаю, что они не для подавления дребезга предназначены. Просто в данном случаи их можно было использовать в этих целях. Мне очень не хотелось добавлять ещё 6 внешних (не подтягивающих) резистора для кнопок на плату, и так 25 резисторов вышло на плате.
                                            +2
                                            Резисторами дребезг не давится ни в каком случае вообще.

                                            Либо RC-цепочка (для надёжности — с триггером Шмитта после, но в общем и без него будет работать), либо программное подавление: если кнопки опрашиваются циклом — опрашивать, скажем, раз в 100-200 мс (дребезг длится несколько десятков миллисекунд). Если нажатие генерирует прерывание, то желательно делать аппаратное подавление, иначе после каждого нажатия контроллер будет получать лавину прерываний.
                                              0
                                              Хм, интересно. Спасибо, буду знать. Видимо, это распространённое заблуждение, т.к. я в нескольких местах читал, что резистор на кнопку вешается именно для этого. Правда, тогда остаётся непонятным, почему у меня дребезг никак не проявляется. Программного подавления нет и опрос кнопок идёт напрямую из loop, который выполняется довольно быстро (если не срабатывает таймер с тяжёлым телом).
                                                +2
                                                Кнопки хорошие (тактовые — вообще одни из самых приличных с точки зрения дребезга). При хорошей кнопке дребезг вполне может миллисенкуд в пять укладываться, совет опрашивать раз в 100-200 мс — это, во-первых, для довольно дрянных кнопок, во-вторых, исходя из того, что при такой задержке реакции человек эту задержку, как правило, ещё не замечает.

                                                А требование RC-цепочки довольно очевидно: дребезг — это пачка ВЧ-импульсов, возникающая в момент срабатывания кнопки. Чтобы её задавить, нужен фильтр, простейший фильтр — RC. Вот тут всякое на тему, например: esxema.ru/?p=4416 (простейшее: esxema.ru/wp-content/uploads/2012/12/18.jpg)

                                                Триггер Шмитта нужен, чтобы на выходе сформировать прямоугольный импульс из сравнительно плавного изменения напряжения на конденсаторе, потому как вообще обычная логика, включая микроконтроллер, не обязана адекватно реагировать на плавное изменение. На практике при нормальных кнопках и, соответственно, небольшой потребной ёмкости конденсатора и без него всё обычно нормально.

                                                Но проще всего с микроконтроллером таки тупо опрашивать по таймеру раз в 100-200 мс :)

                                        Only users with full accounts can post comments. Log in, please.