Это старая версия документа!


Эксперимент 5.2. Эмуляция кнопки с фиксацией

В предыдущем эксперименте мы столкнулись с явлением которое характерно для всех кнопок и выключателей - дребезг контактов. Это паразитное явление, которое вносит проблемы преимущественно в электронных схемах.
Дребезг контактов возникает при нажатии на кнопку и переключатель, он возникает из-за реальных вибраций контактной пластины при её перемещении. Любой переключатель устроен так, что у него есть подвижный и неподвижный контакт. Как видно из названия, подвижным называется тот, что соединен с толкателем или рычагом, на который уже нажимает человек или механизм при работе устройства.
Так как кнопки имеют механическое устройство, то от их качества зависит то, как точно они отрабатывают нажатия. При этом в любом случае полностью устранить явление дребезга нельзя. К чему он приводит?
Если клавиша управляет каким-то электронным устройством с цифровым входом, например, микроконтроллера, логического элемента и пр., то его вход распознает столько нажатий, сколько было импульсов послано в результате возникновения дребезга.
Пример осциллограммы дребезга контактов изображен на рисунке ниже: Чтобы устранить эффект дребезга контактов, параллельно кнопке включают конденсатор, сглаживающий скачки напряжения и делающий процесс переключения более плавным. Обычно номинал конденсатора делают не слишком большим, порядка 0.1 мкФ (микрофарад), иначе он будет заряжаться слишком долго и время переключения кнопки станет заметно больше. Сглаживающий конденсатор заряжается до уровня HIGH почти мгновенно, а во время дребезга контактов разряжается, повышая уровень напряжения в цепи. Таким образом скачки напряжения значительно уменьшаются. Теперь кнопка будет работать правильно, но схема все еще нуждается в доработке. Предположим, что во время написания программы, мы ошиблись и случайно определили вывод контроллера не как INPUT, а как OUTPUT. В этом случае через ножку контроллера потечет ток короткого замыкания, превышающий предельно допустимый и контроллер выйдет из строя. Чтобы защитить контроллер, последовательно с кнопкой добавим токоограничительный резистор 1 кОм.

Схема эксперимента

Рисунок 1. Электрическая принципиальная схема эксперимента

Соберем эту схему: Рисунок 2. Монтажная схема эксперимента

Программный код эксперимента

Exp5
  1. // инициализация констант
  2.  
  3. #define LED 2 //определение константы LED с номером пина 2
  4. #define BUTTON 12 //определение константы BUTTON с номером пина 12
  5.  
  6. // инициализация переменных
  7. int switchState = 0; // актуальный статус кнопки
  8. int oldSwitchState = 0; // статус последней проверки кнопки
  9. boolean lightsOn = false; // статус светодиода on = true или off = false
  10.  
  11. void setup() {
  12. pinMode(BUTTON, INPUT);
  13. pinMode(LED, OUTPUT);
  14. }
  15.  
  16. void loop() {
  17. switchState = digitalRead(BUTTON);
  18. if (switchState != oldSwitchState) {
  19. oldSwitchState = switchState;
  20. if (switchState == HIGH) {
  21. lightsOn = !lightsOn;
  22. }
  23. }
  24. if(lightsOn) {
  25. digitalWrite(LED, HIGH); // зажигаем светодиод
  26. }
  27. else {
  28. digitalWrite(LED, LOW); // гасим светодиод
  29. }
  30. }

в начале программы определим две константы 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);, и светодиод погаснет.

Дополнительные задания

Модифицируй программу так, чтобы светодиод зажигался или выключался только после двух нажатий. Подсказка: потребуется переменная для хранения количества нажатий.