|
|
|
нажатие кнопки, в течение определенного интервала |
|
|
|
Aug 19 2010, 08:35
|
Местный
Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077
|
Здравствуйте,
программно необходимо читать нажата ли кнопка и если да, то как долго удерживается нажатие (есоли 3сек., то выполнить одно, если 5 сек. то другое).
Есть библиотека gpio от производителя чипа с функциями чтения/записи пина и пр. (вообще это нужно сделать под линуксом, на данном этапе это будет демон, в дальнейшем хотелось бы перенести в ядро), но я решил запостить здесь, потому как меня интересует алгоритм.
Т.е. языком псевдокода как это будет выглядеть? Очевидно, нужно проверять состояние пина, и если кнопка нажата, то запускать таймер - но возникает проблема, как отслеживать два разных тайминга - 3сек и 5 ?
Буду очень признателен за идеи и советы !
|
|
|
|
|
Aug 19 2010, 15:46
|
Гуру
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882
|
Не нужно запускать/останавливать таймер. Таймер должен "тикать" всегда. Ведь интересуют-то относительные временные отсчеты, которые есть разность между временем свершения одного и другого события. А сама процедура, требуемая топикстартеру, представляет из себя конечный автомат с 4-мя состояниями. 1. Ожидаем нажатия кнопки. Если нажали кнопку - засечка времени, генерируем событие "нажали кнопку". Переход в состояние 2. 2. Следим - отпустили кнопку или нет, если нет, то сравниваем засечку времени с текущим временем, если прошло 3 секунды, генерируем событие "3 секунды" и переход в состояние 3. Если отпустили кнопку, то генерируем событие "кнопку отпустили" и переход в состояние 1. 3. Опять бдим за состоянием кнопки и временем, если кнопка о сих пор нажата и прошло 5 секунд с момента засечки, то генерируем событие "5 секунд" и переходим в состояние 4. Если отпустили кнопку, то генерируем событие "кнопку отпустили" и переход в состояние 1. 4. Далее уже просто слежение за тем когда кнопку отпустят, за временем следить не требуется. При отпускании кнопки генерируем событие "кнопку отпустили" и переход в состояние 1.
|
|
|
|
|
Aug 20 2010, 09:06
|
Профессионал
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357
|
Цитата(romez777 @ Aug 19 2010, 12:35) программно необходимо читать нажата ли кнопка и если да, то как долго удерживается нажатие (есоли 3сек., то выполнить одно, если 5 сек. то другое). Общий принцип такой: Код // проверка кнопок CButton* pb = &btn[shift_cntr]; if((PINA & BT1) != 0) { // отпущена pb->PressTime = SysTime; if(pb->Pressed != RELEASED) pb->Pressed = ((BTN_PROC)pgm_read_word_near(&BtnProc[shift_cntr]))(RELEASED); } else { // нажата if(pb->Pressed != PRESSED && SysTime - pb->PressTime > 50) pb->Pressed = ((BTN_PROC)pgm_read_word_near(&BtnProc[shift_cntr]))(PRESSED); } } Во-первых, имеется структура CButtun описывающаю состояние каждой кнопки: Код typedef struct tagCButton { uint8_t Pressed; uint16_t PressTime; uint8_t pad; enum { RELEASED = 0, PRESSED, WAITING }; } CButton; btn - массив таких структур, shift_cntr - номер текущей обрабатываемой кнопки. В структуре содержится состояние кнопки (нажата, отпущена или неопределенной состояние, которое как раз и используется для определения длительных нажатий) и системное время. Если кнопка отпущена, время непрерывно записывается в эту переменную. Когда она нажимается, мы попадаем во вторую половину if'а. Если ее состояние не PRESSED (т.е. отпущена или неопределенное) и разность с текущим системным временем больше некоторого значения, необходимого для подавления дребезга, то вызывается функция обработки данной кнопки. Дальше эта функция может сразу выполнить некоторое действие, вернуть значение PRESSED которое будет записано в ее структуру и благодаря этому она больше не будет вызвана пока ее не отпустят. Если же действие необходимо выполнить через некоторое время, то она может возвращать WAITING до тех пор, пока разность между временем, записанным в ее структуре и системным временем не достигнет требуемого значения. Тогда она возвращает PRESSED и больше не вызывается до отпускания.
|
|
|
|
|
Aug 20 2010, 10:53
|
неотягощённый злом
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643
|
Цитата(sergeeff @ Aug 20 2010, 13:29) Классная программа: На любителя... ИМХО. Идеологически более правильно использовать буфер клавиатуры и всё свести к стандартным getc putc. PS: и через этот же буфер можно постить и все остальные сообщения, а не только коды клавиатуры...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 20 2010, 11:15
|
неотягощённый злом
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643
|
Можно и не ждать: получил 0 - буфер пуст... Цитата(sergeeff @ Aug 20 2010, 14:58) Автора интересовало различие короткое/длинное нажатие на кнопку. ... Чего не может быть в getch() putch(x). ещё как может, у меня же сделано:-) +KEYS_HOLD_OFFSET к коду клавиши - вот Вам и длинное нажатие, оно же и repeat.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|