| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
| products:aruno:exp5_2 [2020/06/26 16:15] – alexnik | products:aruno:exp5_2 [2020/08/28 11:36] (текущий) – alexnik |
|---|
| ===== Эксперимент 5.2. Эмуляция кнопки с фиксацией ===== | ===== Эксперимент 5.2. Эмуляция кнопки с фиксацией ===== |
| | |
| В предыдущем эксперименте мы столкнулись с явлением которое характерно для всех кнопок и выключателей - **дребезг контактов**. Это паразитное явление, которое вносит проблемы преимущественно в электронных схемах. \\ | В предыдущем эксперименте мы столкнулись с явлением которое характерно для всех кнопок и выключателей - **дребезг контактов**. Это паразитное явление, которое вносит проблемы преимущественно в электронных схемах. \\ |
| Дребезг контактов возникает при нажатии на кнопку и переключатель, он возникает из-за реальных вибраций контактной пластины при её перемещении. Любой переключатель устроен так, что у него есть подвижный и неподвижный контакт. Как видно из названия, подвижным называется тот, что соединен с толкателем или рычагом, на который уже нажимает человек или механизм при работе устройства.\\ | Дребезг контактов возникает при нажатии на кнопку и переключатель, он возникает из-за реальных вибраций контактной пластины при её перемещении. Любой переключатель устроен так, что у него есть подвижный и неподвижный контакт. Как видно из названия, подвижным называется тот, что соединен с толкателем или рычагом, на который уже нажимает человек или механизм при работе устройства.\\ |
| Пример осциллограммы дребезга контактов изображен на рисунке ниже: | Пример осциллограммы дребезга контактов изображен на рисунке ниже: |
| {{ :products:ardu:drebezg-kontaktov.png?nolink&400 |}} | {{ :products:ardu:drebezg-kontaktov.png?nolink&400 |}} |
| Чтобы устранить эффект дребезга контактов, параллельно кнопке включают конденсатор, сглаживающий скачки напряжения и делающий процесс переключения более плавным. Обычно номинал конденсатора делают не слишком большим, порядка 0.1 мкФ (микрофарад), иначе он будет заряжаться слишком долго и время | Чтобы устранить эффект дребезга контактов есть два способа программный и аппаратный.\\ |
| переключения кнопки станет заметно больше. | Один из вариантов программного устранения дребезга, это после первого изменения состояния кнопки, установить паузу в несколько миллисекунд, для того чтобы контакт стабилизировался и дребезг был проигнорирован.\\ |
| Сглаживающий конденсатор заряжается до уровня HIGH почти мгновенно, а во время дребезга контактов разряжается, повышая уровень напряжения в цепи. Таким образом скачки напряжения значительно уменьшаются. | |
| Теперь кнопка будет работать правильно, но схема все еще нуждается в доработке. Предположим, что во время написания программы, мы ошиблись и случайно определили вывод контроллера не как INPUT, а как OUTPUT. В этом случае через ножку контроллера потечет ток короткого замыкания, превышающий предельно допустимый и контроллер выйдет из строя. | |
| Чтобы защитить контроллер, последовательно с кнопкой добавим токоограничительный резистор 1 кОм. | |
| |
| ==== Схема эксперимента ==== | ==== Схема эксперимента ==== |
| {{ :products:ardu:exp5_2.png?nolink&400 |}} | Схема эксперимента не изменилась по сравнению с прошлым, изменения будут только в программной части |
| | |
| | {{ :products:ardu:exp3.4.png?nolink |}} |
| //Рисунок 1. Электрическая принципиальная схема эксперимента// | //Рисунок 1. Электрическая принципиальная схема эксперимента// |
| |
| |
| void setup() { | void setup() { |
| pinMode(BUTTON, INPUT); | pinMode(BUTTON, INPUT); |
| pinMode(LED, OUTPUT); | pinMode(LED, OUTPUT); |
| } | } |
| |
| void loop() { | void loop() { |
| if (switchState == HIGH) { | if (switchState == HIGH) { |
| lightsOn = !lightsOn; | lightsOn = !lightsOn; |
| } | delay(20); |
| } | } |
| if(lightsOn) { | } |
| | if(lightsOn) { |
| digitalWrite(LED, HIGH); // зажигаем светодиод | digitalWrite(LED, HIGH); // зажигаем светодиод |
| } | } |
| else { | else { |
| digitalWrite(LED, LOW); // гасим светодиод | digitalWrite(LED, LOW); // гасим светодиод |
| } | } |
| } | } |
| </file> | </file> |
| | Электрическая принципиальная схема и монтажная схема эксперимента остаются без изменений, в программном коде добавляется строка с функцией **delay(20)**, которая приостанавливает выполнение программы на 20 миллисекунд для игнорирования дребезга контактов.\\ |
| в начале программы определим две **константы** ''LED'' и ''BUTTON'' для хранения номеров пинов к которым подключены кнопка и светодиод.\\ | Аппаратный способ устранения дребезга рассмотрим в следующем эксперименте.\\ |
| далее для реализации задуманного нам понадобятся переменные: | |
| * ''switchState'' - переменная для хранения текущего уровня считанного сигнала с пина. | |
| * ''oldSwitchState'' - будем использовать для хранения результата прошлой проверки состояния кнопки. Это нам потребуется для выявления факта нажатия на кнопку. Если при прошлой проверке кнопка была не нажата, а при текущей проверке нажата — значит только что произошло нажатие. | |
| * ''lightsOn'' будем использовать для хранения текущего состояния светодиода — включен он или выключен. Для того, чтобы менять это состояние на противоположное после фиксации факта нажатия на кнопку. | |
| | |
| выражение ''switchState = digitalRead(BUTTON);'' записывает в переменную **switchState** текущий уровень сигнала на пине кнопки, далее идет проверка события "была ли нажата кнопка". | |
| в строке 18 оператором **if** сравниваются переменные **switchState** и **oldSwitchState** в которые записан текущий сигнал и сигнал считанный и записанный ранее. | |
| Оператор ''!='' — оператор неравенства. | |
| Если значение переменной **switchState** не равно значению переменной **oldSwitchState** (была нажата кнопка), то мы перезаписываем старое значение на новое и переходим к проверке того, какой именно поступает текущий сигнал. Если сигнал соответствует **HIGH**, то значение переменной **lightsOn** необходимо изменить на противоположное, поскольку была нажата кнопка.\\ | |
| Обратите внимание, что эта проверка происходит только если выполняется условие предыдущей проверки.\\ | |
| третий оператор **if** проверяет значение переменной ''lightsOn'', если значение равно **true** то выполняется выражение ''digitalWrite(LED, HIGH);'', светодиод загорается, и будет гореть до тех пор пока не будет нажата кнопка, после этого значение переменной измениться на **false**, и выполнится выражение ''digitalWrite(LED, LOW);'', и светодиод погаснет. | |
| | |
| ==== Дополнительные задания ==== | |
| | |
| <WRAP center round tip 60%> | |
| Модифицируй программу так, чтобы светодиод зажигался или выключался только после двух нажатий. Подсказка: потребуется переменная для хранения количества нажатий. | |
| </WRAP> | |