roboforum.ru

Технический форум по робототехнике.

 

Смена действий по удержанию кнопки

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Смена действий по удержанию кнопки

Сообщение space » 25 апр 2014, 21:21

Ребят, нужна небольшая подмога.
Пишу программу в CVAVR. И ни как не могу допереть до момента одного. Есть три режима и кнопка без фиксации. Изначально при включение девайса, работает 1 режим. при нажатие на кнопку и отпускание ее включается второй режим, при нажатие еще раз, возвращается предыдущий режим. А вот при удержание этой клавиши должен включаться 3 трежим, после его включения клавишу нужно отпустить, но при это режим не должен смениться. Помоги те добить эту часть

кусок того что я написал.

Код: Выделить всёРазвернуть
 
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {   
                                                if (Strobe==0&&buttonPushed==0) { //если нажата первый раз
                                                                                 buttonPushed=1; //фиксируем, что уже нажали   
                                                }                                           
                                                if (Strobe==1&&buttonPushed==1) { //если было нажато и отпустили
                                                                                 if (task==0) { //если тыкнули первый раз
                                                                                               button=1;
                                                                                               ++task; //готовы выполнять следующее действие
                                                                                 }
                                                                                  else if (task==1){ //делаем следующее
                                                                                                    button=0;
                                                                                                    task=0;
                                                                                  }
                                                                                                    buttonPushed=0; //фиксируем, что уже не нажато
                                                } 
}
Аватара пользователя
space
 
Сообщения: 548
Зарегистрирован: 17 июн 2007, 23:44
Откуда: Тула
прог. языки: Bascom AVR Basic, CodeVisionAVR
ФИО: Замотаев Кирилл Игоревич

Re: Смена действий по удержанию кнопки

Сообщение avr123.nm.ru » 25 апр 2014, 23:49

я бы в прерывании только считал время нажатия кнопки в условных единицах и писал в переменную. и ставить признак-флаг "отпущена".

а анализ и выбор действий в основном цикле неспеша делать.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14200
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Смена действий по удержанию кнопки

Сообщение space » 25 апр 2014, 23:56

дык мне надо чтобы основной цикл выполнял определенное действие с определенными переменными. А все остальное происходило именно в прерывание, чтобы эти переменные можно было менять в процессе работы основного цикла.
Банально пример. В основном цикле моргает светодиод один раз в секунду. А из прерывания меняю переменную задержки допустим вместо секунды на пол секунды. И пока меняю эту переменную светодиод все чаще и чаще начинает моргать пока уменьшаю задержку до 0.5с

Добавлено спустя 49 секунд:
avr123.nm.ru писал(а):я бы в прерывании только считал время нажатия


а как это время нажатия зафиксировать в прерывание, можешь написать??
Аватара пользователя
space
 
Сообщения: 548
Зарегистрирован: 17 июн 2007, 23:44
Откуда: Тула
прог. языки: Bascom AVR Basic, CodeVisionAVR
ФИО: Замотаев Кирилл Игоревич

Re: Смена действий по удержанию кнопки

Сообщение avr123.nm.ru » 26 апр 2014, 00:19

Если это прерывание только для кнопки и происходит каждые 15-30 мс то

Код: Выделить всёРазвернуть
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{   
if(кнопка нажата)
{ длительность нажатия ++;
   кнопка отпущена = 0;
}
else { кнопка отпущена = 1; }
}


а в основном цикле

Код: Выделить всёРазвернуть
 if(кнопка нажата){
   if (длительность нажатия > то что считается "долго"){
           длительность нажатия = 0;

          флаг_нажата_долго = 1  или делать то что надо при долгом }

      else if (кнопка отпущена) { кнопка отпущена = 0; // обнулить флаг отпускания кн.
        тут посчитать проанализ который раз нажата кнопка. и делать действия
                                }
                   }


возможно будет работать.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14200
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Смена действий по удержанию кнопки

Сообщение space » 26 апр 2014, 12:03

avr123.nm.ru писал(а):Если это прерывание только для кнопки и происходит каждые 15-30 мс то

Код: Выделить всёРазвернуть
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{   
if(кнопка нажата)
{ длительность нажатия ++;
   кнопка отпущена = 0;
}
else { кнопка отпущена = 1; }
}


а в основном цикле

Код: Выделить всёРазвернуть
 if(кнопка нажата){
   if (длительность нажатия > то что считается "долго"){
           длительность нажатия = 0;

          флаг_нажата_долго = 1  или делать то что надо при долгом }

      else if (кнопка отпущена) { кнопка отпущена = 0; // обнулить флаг отпускания кн.
        тут посчитать проанализ который раз нажата кнопка. и делать действия
                                }
                   }


возможно будет работать.


ну на половину получилосб. теперь при удержание срабатывает третье действие, но как только отпускаю кнопку срабатывает первое действие. И как этот момент блокировать не сообразил пока

Код: Выделить всёРазвернуть
 interrupt [TIM0_OVF] void timer0_ovf_isr(void) {   
if (Strobe==0&&buttonPushed==0) { //если нажата первый раз
buttonPushed=1; //фиксируем, что уже нажали
}                                           
if (Strobe==1&&buttonPushed==1) { //если было нажато и отпустили
if (task==0) { //если тыкнули первый раз
button=1; ++task; //готовы выполнять следующее действие
}
else if (task==1){ //делаем следующее
button=0;task=0;         
}  buttonPushed=0; //фиксируем, что уже не нажато   
}
if (Strobe==0) { //если нажали кнопку
if (button==1) {
ButtonTimer++; if (ButtonTimer>5000)  { ЕСЛИ УДЕРЖИВАЕМ КНОПКУ ПОКА НЕ ВЫПОЛНИТСЯ УСЛОВИЕ
ButtonTimer=0;button=2;  //делаем дела
Аватара пользователя
space
 
Сообщения: 548
Зарегистрирован: 17 июн 2007, 23:44
Откуда: Тула
прог. языки: Bascom AVR Basic, CodeVisionAVR
ФИО: Замотаев Кирилл Игоревич

Re: Смена действий по удержанию кнопки

Сообщение dccharacter » 02 май 2014, 22:27

Тебе надо почитать, что такое конечный автомат: http://ru.wikipedia.org/wiki/%D0%9A%D0% ... 0%B0%D1%82
Дальше рисуешь простенькую схему состояний, у тебя будет два входных сигнала - состояние кнопки и состояние счетчика. типа:
1. Ожидание. Ничего не делаем.
сигнал1: нажата кнопка, переходим в состояние 2, включаем таймер
2. Работает таймер, ждем, пока отпустят кнопку
сигнал1: отпустили кнопку, при этом таймер ниже порога "короткого нажатия", выполняем действие по "короткому" нажатию, переходим в состояние 1
сигнал2: таймер перевалил порог "короткого нажатия", переходим в состояние 3
3. Выполняем (в цикле) действие при длительном удержании кнопки
сигнал 1: отпустили кнопку. Выполняем (опционально) финальное действие по длинному нажатию и переходим в состояние 1.

Как видишь, если кнопка не отпущена до того, как таймер перетикал за порог, "короткое" действие никогда не выполнится. Тут надо быть осторожным с переполнением таймера, например тормозить его при выходе за порог короткого нажатия. Потому что он нам уже не нужен.

Реализуется это обычно оператором switch по состоянию state. Дальше в каждом case описываешь состояние из своей таблички и все работает!

Добавлено спустя 8 минут 39 секунд:
Код: Выделить всёРазвернуть
static uint8_t state = 0;
switch (state) {
case 1: //idle state
if (buttonPushed = PRESSED) {
state = 2;
ButtonTimer = 0;
startButtonTimer();
}
break;

case 2: //short press area
if (buttonPushed = RELEASED && ButtonTimer < SHORT_THRESHOLD) {
state = 1;
stopButtonTimer();
doShortPress();
} else {
if (buttonPushed = RELEASED && ButtonTimer > SHORT_THRESHOLD) {
state = 3;
stopButtonTimer();
}
break;

case 3: //button is pressed
if (buttonPushed = RELEASED) {
state = 1;
doFinalLongPress();
} else {
if (buttonPushed = PRESSED) {
repeatLongPressTask();
}
break;
}
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4881
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Mail.ru counter