Кнопки, прерывания, LCD.
- Войдите на сайт для отправки комментариев
Чт, 29/03/2012 - 01:20
Доброй ночи. К ардуино подключено 6 кнопок (через 10к резисторы), LCD дисплей 20x4. Сводобных ног не так уж и много остается.
Пытаюсь сообразить подобие меню и организовать обработчик события по нажатию кнопки.
То есть ели нажата кнопка Up - вызов функции ну... блинкЗеленый. И моргает до тех пор пока не нажму кнопку Esc.
Down - вызов функции блинкКрасный, и соответственно моргаем пока не нажму Esc.
Озадачился, как же мне зациклить функцию, Loop один а фнкций будет тьма. Придумал засунутьее в
do...while, но, не вышло.
Пробовал писать код:
void fuckingBlink () {
do
{
EscState =digitalRead(buttonPinEsc); // EscState =0 - это у меня статус кнопки Esc. Кнопка поключена к 8 ноге.
digitalWrite(0, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(0, LOW); // set the LED off
delay(1000);
}
while (EscState ==HIGH); //
ну как бы моргаем пока на 8 ноге не будет HIGH
}
Диод моргает, но на кнопку не реагирует. Давай копаться, нашел про прерывания, замечательная вещь. Но вроде
как их всего пару штук и они на ногах которые у меня заняты уже LCD. Как быть, куды бечь?
Ну для начала лучше было бы если при нажитии кнопки digitalRead(button) выдавал 0, а не 1, но дело ваше.
Вам нужно обьявить глобальную переменную, которую будет менять нажатие кнопки и которая будет определять ход программы.
В вашем случае примерно вот так:
#define BUTTON1 2 #define BUTTON2 3 #define BUTTON3 4 //#define BUTTON.. .. //#define ..... int rezgim = 0; void setup() { pinMode(10, OUTPUT); //зеленый pinMode(11, OUTPUT); // красный } void loop() { if(digitalRead(BUTTON1)){ rezgim = 1; } if(digitalRead(BUTTON2)){ rezgim = 2; } if(digitalRead(BUTTON3)){ rezgim = 3; } /*if(digitalRead(BUTTON..)){ rezgim = ..; } */ switch (rezgim) { case 1: digitalWrite(10, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(10, LOW); // set the LED off delay(1000); break; case 2: digitalWrite(11, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(11, LOW); // set the LED off delay(1000); break; case 3: // код для выполнения break; case 4: // код для выполнения break; default: ;// код для выполнения } }Если реализовать приведенный вариант, то ждать реакции на нажатие кнопки придется по несколько секунд. Что в корне изничтожает удобство пользования.
Кнопки должны реагировать как и положено кнопкам - с задержкой, незаметной для пользователя. Поэтому:
определяем две переменные
oTime - момент последнего переключения "активного" светодиода
oState - последнее состояние "активного" светодиода
В setup() присваивааем этим переменным значения - текущего времени и любое (например, LOW) соответственно.
В loop():
if(millis()-oTime)>1000 { // прошла секунда? if(oState==LOW) oState=HIGH; else oState==LOW; // изменили состояние светодиода, теперь определяем, каким светодиодом рулим в настоящий момент -> nLED switch(regim) { ... } digitalWrite(nLED,oState); // готовимся к отсчету очередной секунды: oState=millis(); } // дальше - остальные операторы функции loop()Приведенное условие будет срабатывать каждую секунду и производить мигание светодиодом без существенной задержки (пара микросекунд не в счет) в работе программы.
Фактически мы программно моделируем прерывание - плавный ход программы неожиданно прерывается при достижении какого-то определенного условия, управление передается в "процедуру отработки прерывания", которая отрабатывается и возвращает управление основной ветке кода. И все опять успокаивается и течет плавненко - до следующего "прерывания"...
Да задержки лучше не использовать
Спасибо, какие же вы хорошие, отзывчивые люди!
тоже начинаю озадачиваться созданием меню...
пока нарыл инфу
http://arduino.ru/forum/programmirovanie/menyu-dlya-tekstovogo-lcd-pomog...
http://rln.nnov.ru/index.php?ind=reviews&op=entry_view&iden=211