Arduino. Обработка кнопок при помощи АЦП
Есть много способов экономии выводов при подключении кнопок к микроконтроллеру. В этой статье мы рассмотрим способ при котором кнопки подключаются через резистивные делитель и их состояние считывается при помощи АЦП.
Подготовка к работе
На нашем TutorShield есть две кнопки, которые могут быть подключены как к цифровым выводам Arduino, так и к аналоговым входам. Если вы установите перемычку так, как показано на рисунке, кнопки будут подключены к аналоговому входу А3.
Схема подключения кнопок при этом будет выглядеть следующим образом:
На TutorShield кнопки подписаны "2" и "3". При разных комбинациях их нажатий образуется делитель напряжения с разным коэффициентом передачи. Все возможные комбинации эквивалентных схем и напряжений на выводе А3 приведены ниже:
Напряжение на резистивном делителе определяется по формуле
Uвых=(Uвх*Rн)/(Rв+Rн)
, где Uвх — напряжение приложенное к верхнему плечу делителя (5В), Rв — сопротивление в верхнем плече делителя, Rн — сопротивление в нижнем плече делителя.
Считывать состояние данные с кнопок будем как в предыдущей статье. Мы будем использовать также только 8 разрядов, поэтому измерять напряжение будем с шагом 19.6мВ.
Итак, есть четыре возможные ситуации:
- Ни одна кнопка не нажата, на выводе А3 напряжение 5В, АЦП вернет значение "255"
- Если нажата кнопка "2",на А3 — 2,5В, АЦП пришлет значение 2,5/0.0196=128
- Нажата кнопка "3", на А3 — 3,3В, АЦП — 3,3/0.0196=169
- Обе кнопки, на А3 — 2В, АЦП — 2/0,0196=102
Обратите внимание, что АЦП всегда округляет полученное значение в большую сторону! Также расхождение возможно из-за того, что сопротивление резисторов отличается от номинального, меняется от напряжение питания и т.д.
Первый пример
Для начала повторим пример из предыдущей статьи. Попробуем просто читать состояние вывода A3 и будем передавать его в COM-порт с периодичностью раз в секунду:
int val; void setup() { Serial.begin(9600); } void loop() { val = analogRead(A3)>>2; Serial.println(val); delay(1000); }
Нажимая кнопки и наблюдая за данными в мониторе COM-порта (Ctrl+Shift+M), проверьте, какие значения соответствуют нажатиям кнопок.
Плата, на которой мы запускали этот код, присылала значения 255, 128, 170 и 102. Небольшое расхождение возможно из-за не одинаковых питающий напряжений, различия сопротивлений резисторов и т.д. Это означает, что нужно задать определенный разброс значений для определения состояния кнопок.
Второй пример
Теперь в программе нужно принимать решения о состоянии кнопок. Нам нужно разработать код, который будет проверять состояние вывода и выставлять флаги о состоянии кнопок.
Флагом в программировании называют переменную, которая характеризует состояние какого-либо объекта. Мы заведем два флага — button2 и button3. Если в этой переменной единица, то кнопка нажата. Если ноль, то отжата.
Перейдем к определению состояния кнопок. Можно, конечно, просто сравнивать полученное значение с измеренным заранее числом, но гораздо лучше задать определенный разброс параметров. Сделать это проще всего по середине диапазона. Зададим условие следующим образом:
- Если полученное значение больше 212, значит ни одна кнопка не нажата
- Если оно лежит в диапазоне от 212 до 149, то нажата кнопка "3"
- От 149 до 115, то нажата кнопка "2"
- Менее 115 — нажаты обе кнопки
Чтобы визуально контролировать состояние кнопок, подключите два светодиода к выводам D0 и D1 (вспомнить как это сделать можно здесь)
#define STATE_LED2 0 #define STATE_LED3 1 int val = 0; int button2 = 0; int button3 = 0; void setup() { pinMode(STATE_LED2, OUTPUT); pinMode(STATE_LED3, OUTPUT); } void loop() { button2=button3=0; val = analogRead(A3)>>2; if(val>212) button2=button3=0; else { if(val>149) button3=1; else { if(val>115) button2=1; else button2=button3=1; } } if(button2==1) digitalWrite(STATE_LED2,HIGH); else digitalWrite(STATE_LED2,LOW); if(button3==1) digitalWrite(STATE_LED3,HIGH); else digitalWrite(STATE_LED3,LOW); }
Кнопке номер два соответствует крайний правый светодиод, а кнопке "3" второй справа.
В основном цикле сначала высчитывается состояние кнопок, а потом оно просто транслируется на светодиодах. Конечно, если бы кнопки были подключены к отдельным выводам, то проверка их состояния происходила бы гораздо быстрее, но в задачах, где важна экономия выводов, этот способ вполне применим.
Индивидуальные задания
- Модифицируйте программу так, чтобы при однократном нажатии на кнопку, соответствующий светодиод загорался и горел до тех пора та же кнопка не будет снова нажата.
- Подключите трехцветный светодиод (как в этой статье) и напишите программу в которой пока нажата одна кнопка яркость голубого светодиода будет плавно увеличиваться, а при зажатии другой — уменьшаться.
Остальные статьи цикла можно найти здесь.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.
Метки: АЦП, делитель напряжения, кнопка Просмотров: 14539