Веселые делители
АЦП Arduino измеряет напряжение на входах A0-A5 (обычно от 0 до 5 вольт) и преобразует его в чиселки от 0 до 1023.
Прежде всего подтянем аналоговый вход A0 на +5В через резистор с сопротивлением x. АЦП будет все время считывать с него 1023, что является максимальным значением.
Подключим к этому же входу кнопку, которая будет тупо соединять вход с землей. При нажатии кнопки АЦП будет считывать примерно 0. На самом деле, здесь определяющую роль играет сопротивление кнопки и проводов, но мы это не учитываем.
С остальными кнопками поступим хитро. Один конец подключим к земле, а второй - через резистор на вход. Если сопротивления резисторов будут различны, то при нажатии кнопки АЦП будет считывать разные значения.
Легко заметить, что при нажатии кнопки с резистором образуется делитель напряжения, и АЦП измеряет падение напряжение на нижнем резисторе.
В случае, если сопротивление в ветви с кнопкой равно x Ом, так же, как и в питающей ветви, что АЦП измерит U*x/(x+x) = U/2. Если нижнее сопротивление будет равно 2x, то измерится U*2x/(x+2x) = 2/3*U. И так далее.
Мы сможем легко определить, какая именно кнопка нажата, по характерному измеренному значению напряжения.
Хардверная реализация
У меня под рукой, как всегда, только резисторы по 220 Ом, поэтому я буду соединять из последовательно, чтобы получить бОльшее сопротивление. Это немного некрасиво, зато работает. Итак, схема:
Здесь желтыми проводками все подключено ко входу АЦП, красный и черный, традиционно, - питание и земля.
Софтверная реализация
Итак, при нажатии первой кнопки АЦП считывает значение между 60 и 75, второй - 513-514, третьей - 683-684, четвертой - 768 -769.
Разобьем всю шкалу от 0 до 1023 на 5 промежутков так, чтобы каждое считываемое значение попало только в один промежуток:
static int key_values[4]={100,600,700,800};
Будем сравнивать считываемое значение с границами промежутков, начиная с левой. Для этого заведем функцию, которая будет сразу возвращать номер нажатой кнопки:
int get_key(int value){
for (int i=0; i<4; i++){
if (value < key_values[i]) return i+1;
}
}
Весь код:
//определяем переменные для хранения измеряего значения
int value, old_value;
//храним референсные значения
static int key_values[4]={100,600,700,800};
void setup(){
//инициализируем последовательное соединение
Serial.begin(9600);
}
void loop(){
//считываем значение со входа
value = analogRead(0);
Serial.println(value);
//если значение отличается от предыдущего больше,
//чем на 50, и оно меньше 1000
if (abs(value-old_value) > 50 && value < 1000){
//выводим текст
Serial.print("key ");
//выводим номер нажатой кнопки
Serial.print(get_key(value));
//выводим еще текст
Serial.println(" pressed");
}
//запоминаем значение
old_value = value;
//пауза
delay(100);
}
//функция для определения номера нажатой кнопки
int get_key(int value){
//пробегаем по массиву референсных значений
for (int i=0; i<4; i++){
//если измеренное значение попало в промежуток между
//референсными значениями, выводим номер промежутка
if (value < key_values[i]) return i+1;
}
}
Здесь как раз видна разница между функциями Serial.print() и Serial.println(): первая после вывода не делает перевод строки, а вторая делает.int value, old_value;
//храним референсные значения
static int key_values[4]={100,600,700,800};
void setup(){
//инициализируем последовательное соединение
Serial.begin(9600);
}
void loop(){
//считываем значение со входа
value = analogRead(0);
Serial.println(value);
//если значение отличается от предыдущего больше,
//чем на 50, и оно меньше 1000
if (abs(value-old_value) > 50 && value < 1000){
//выводим текст
Serial.print("key ");
//выводим номер нажатой кнопки
Serial.print(get_key(value));
//выводим еще текст
Serial.println(" pressed");
}
//запоминаем значение
old_value = value;
//пауза
delay(100);
}
//функция для определения номера нажатой кнопки
int get_key(int value){
//пробегаем по массиву референсных значений
for (int i=0; i<4; i++){
//если измеренное значение попало в промежуток между
//референсными значениями, выводим номер промежутка
if (value < key_values[i]) return i+1;
}
}
В данной программе я всего лишь вывожу номер нажатой кнопки, но стоит понимать, что я могу прикрутить абсолютно любой обработчик нажатия.
Видео
На сколько я понимаю у такой схемы только одна проблема - нельзя нажать сразу несколько кнопок.
ОтветитьУдалитьЛегко. Ставим резисторы по степеням двойки и дело в шляпе. Только много кнопок не получится и резисторы точные нужны.
ОтветитьУдалить1xbet korean sports betting - Sports betting for android
ОтветитьУдалитьIn this guide, we will introduce you to 1xbet korean sports betting android apps. There are currently 1xbet 64 22 betting sites that offer online