CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

Arduino. Обработка кнопок при помощи АЦП

Есть много способов экономии выводов при подключении кнопок к микроконтроллеру. В этой статье мы рассмотрим способ при котором кнопки подключаются через резистивные делитель и их состояние считывается при помощи АЦП.

Подготовка к работе

На нашем TutorShield есть две кнопки, которые могут быть подключены как к цифровым выводам Arduino, так и к аналоговым входам. Если вы установите перемычку так, как показано на рисунке, кнопки будут подключены к аналоговому входу А3.

Установка перемычки

Установка перемычки

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

Схема подключения кнопок

Схема подключения кнопок

На TutorShield кнопки подписаны "2" и "3". При разных комбинациях их нажатий образуется делитель напряжения с разным коэффициентом передачи. Все возможные комбинации эквивалентных схем и напряжений на выводе А3 приведены ниже:

Эквивалентная схема

Эквивалентная схема

Напряжение на резистивном делителе определяется по формуле
Uвых=(Uвх*Rн)/(Rв+Rн)
, где Uвх — напряжение приложенное к верхнему плечу делителя (5В), Rв — сопротивление в верхнем плече делителя, Rн — сопротивление в нижнем плече делителя.
Считывать состояние данные с кнопок будем как в предыдущей статье. Мы будем использовать также только 8 разрядов, поэтому измерять напряжение будем с шагом 19.6мВ.
Итак, есть четыре возможные ситуации:

  1. Ни одна кнопка не нажата, на выводе А3 напряжение 5В, АЦП вернет значение "255"
  2. Если нажата кнопка "2",на А3 — 2,5В, АЦП пришлет значение 2,5/0.0196=128
  3. Нажата кнопка "3", на А3 — 3,3В, АЦП — 3,3/0.0196=169
  4. Обе кнопки, на А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. Если в этой переменной единица, то кнопка нажата. Если ноль, то отжата.
Перейдем к определению состояния кнопок. Можно, конечно, просто сравнивать полученное значение с измеренным заранее числом, но гораздо лучше задать определенный разброс параметров. Сделать это проще всего по середине диапазона. Зададим условие следующим образом:

  1. Если полученное значение больше 212, значит ни одна кнопка не нажата
  2. Если оно лежит в диапазоне от 212 до 149, то нажата кнопка "3"
  3. От 149 до 115, то нажата кнопка "2"
  4. Менее 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" второй справа.

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

Индивидуальные задания

  1. Модифицируйте программу так, чтобы при однократном нажатии на кнопку, соответствующий светодиод загорался и горел до тех пора та же кнопка не будет снова нажата.
  2. Подключите трехцветный светодиод (как в этой статье) и напишите программу в которой пока нажата одна кнопка яркость голубого светодиода будет плавно увеличиваться, а при зажатии другой — уменьшаться.

Остальные статьи цикла можно найти здесь.

Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Метки: , , Просмотров: 8341