|
Удержание кнопки 6 секунд |
|
|
|
Apr 3 2009, 07:13
|
Группа: Участник
Сообщений: 4
Регистрация: 25-05-08
Пользователь №: 37 799

|
Подскажите с алгоримом удержания кнопки 6 секунд. Опрос кнопок реализован, оталось сделать что бы при нажатии выводилась уставка прибора, а при удержании 6 секунд войти в меню, прибора. Я пока сделал, что при нажатии сразу в меню попадаю, но требуют вывод уставки и 6 секунд.
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Apr 3 2009, 07:28
|

извечный пессимист
    
Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125

|
Цитата(decsal @ Apr 3 2009, 11:13)  Подскажите с алгоримом удержания кнопки 6 секунд. Опрос кнопок реализован, оталось сделать что бы при нажатии выводилась уставка прибора, а при удержании 6 секунд войти в меню, прибора. Я пока сделал, что при нажатии сразу в меню попадаю, но требуют вывод уставки и 6 секунд. Если кнопка нажата , то запускаете таймер на 6 секунд, далее смотрите, если кнопка отжата, а таймер еще тикает, то входим в уставку, если таймер дотикал, и кнопка все еще нажата, то входим в меню.
--------------------
Slaves are those of this world Given freedom to lay chains upon The Master The wolf is no longer free Release the chains and come for me
|
|
|
|
|
Apr 3 2009, 08:55
|
Профессионал
    
Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347

|
можно завести счетчик нажатия и запоминать предыдущее состояние кнопок. так легко организуется разная длительность нажатия, автоповтор и т.д. алгоритм такой (опрос оптимально делать с частотой прибл. 100 Гц, счетчик - uint8,uint16 в зависимости от нужной макс. длительности нажатия) : Код - прочитать текущее сост.кнопок (uint8,uint16,uint32 в зависимости от количества кнопок) - сравнить с предыдущим : - если не равны - обнулить счетчик, пред.сост=тек.сост. - если равны - - счетчик++, - если нажата кнопка меню и счетчик=6сек - войти в меню, - иначе обработать другой код кнопок и длительность....
Сообщение отредактировал ukpyr - Apr 3 2009, 09:05
|
|
|
|
|
Apr 3 2009, 10:10
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
да... пора уже коллекцию ФАКов собирать... или ссылок на них... чтобы заново каждый раз не вбивать... Значит так. Проверенный самой Жизнью алгоритм. 1. По таймеру (T=1,2,5,10... ms) сканируем кнопки. 2. Если ничего не нажато, сбрасываем все флаги (эвенты) 3. Если что-то нажато, сравниваем с предыдущим состоянием. Если совпадает, инкрементируем счётчик тиков. Если нет, сбрасываем счётчик и все флаги (дребезг) 4. Если счётчик >= задержки антидребезга, выставляем флаг KeyPressed 5. Если счётчик >= задержки залипания (1,2,6 секунд), выставляем флаг "Locked" Итого по результатам работы имеем скан-код и набор флагов, которыми могут пользоваться любые заинтересованные процессы Цитата(Herz @ Apr 3 2009, 13:40)  По-моему, по нажатию кнопки просто следует запускать таймер для определения времени нажатого состояния (с учётом возможного дребезга, конечно). И только после отжатия принимать решение о переходе в нужное место программы. Ага, у меня телефон филибз так работает. Разработчика интерфейса придушил бы собственноручно. Вот, дарю на память... CODE //******************************************************************************** // Функция сканирования клавиатуры (запускается по таймеру) // © MrYuran //******************************************************************************** void KbrdScan() { if(kbrd_in & lock) // Проверяем ключ блокировки клавиатуры { Mode |= Locked; kbrd_out &= ~kbrd; } else { Mode &= ~Locked; kbrd_out |= kbrd; }
unsigned char temp = kbrd_in&0xf0;
if((temp != 0) || (Kbrd.scanned != 0)) // что-то нажато { if(temp != Kbrd.scanned) // дребезг { Kbrd.scanned = temp; Kbrd.PressedTime = 0; Kbrd.pressed = 0; } else // вроде уже не дребезг { Kbrd.scanned = temp; Kbrd.PressedTime ++; // считаем время нажатия if(Kbrd.PressedTime == press_delay) // кнопка считается нажатой { if(!(Kbrd.pressed & KeyLocked)) // если не залипла { //Beep(50); // пикаем Kbrd.pressed = Kbrd.scanned | KeyTick; // выставляем код кнопки и тик //Kbrd.PressedTime = 0; } } if(Kbrd.PressedTime == lock_delay) // кнопка считается залипнутой { Kbrd.pressed |= KeyLocked; // выставляем флаг залипания Kbrd.PressedTime = 0; Kbrd.pressed |= KeyTick; } if(Kbrd.PressedTime == lock_interval) // быстрые тики при залочке { if(Kbrd.pressed & KeyLocked) // если залипнута { Kbrd.PressedTime = 0; Kbrd.pressed |= KeyTick; } } } } }
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 3 2009, 10:46
|

Гуру
     
Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287

|
Цитата(MrYuran @ Apr 3 2009, 12:10)  Ага, у меня телефон филибз так работает. Разработчика интерфейса придушил бы собственноручно. Не знаю про телефон "филибз", тут речь идёт вроде об одной кнопке. Вы всё правильно пишете: Цитата Итого по результатам работы имеем скан-код и набор флагов, которыми могут пользоваться любые заинтересованные процессы , но как предполагаете принимать решения о событии до того, как оно произошло? Не станете ведь отрицать, что о времени, которое была нажата кнопка, можно судить лишь по её отжатию? (Если это нужно, конечно). То бишь, залипнет ли кнопка - заранее неизвестно...
|
|
|
|
|
Apr 3 2009, 11:18
|

Местный
  
Группа: Свой
Сообщений: 409
Регистрация: 29-10-07
Пользователь №: 31 836

|
Цитата(Herz @ Apr 3 2009, 13:46)  Не знаю про телефон "филибз", тут речь идёт вроде об одной кнопке. Вы всё правильно пишете: , но как предполагаете принимать решения о событии до того, как оно произошло? Не станете ведь отрицать, что о времени, которое была нажата кнопка, можно судить лишь по её отжатию? (Если это нужно, конечно). То бишь, залипнет ли кнопка - заранее неизвестно... По отпусканию кнопки неудобно! Представте пользователя.. он нажал кнопку.. и ждет перехода в режим меню.. и думает -"прошло ли 6секунд или нет? можно ли отпускать клавишу?"... И что? А если после нажатия считать интервал времени. Если прошло 6 секунд, а кнопка нажата то переходить в меню. Если отпустили раньше другое действие. Защита от залипания так: прошло , к примеру, 12секунд а кнопа нажата.. то ахтунг и т.д.
Причина редактирования: Устранение дублирования в содержании сообщения.
--------------------
Умный программист пишет тупым кодом гениальные вещи, а не наоборот...
|
|
|
|
|
Apr 3 2009, 12:02
|
Профессионал
    
Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347

|
Цитата MrYuran не нужно никаких флагов, состояние клавиатуры однозначно определяется текущим и предыдущим состоянием битов клавиш и счетчиком текущего состояния (антидребезг, задержка и автоповтор получаются автоматически) : CODE kbd_buf[1] = kbd_rd(); // читаем текущее сост.клавиш
if (kbd_buf[2] != kbd_buf[1]) { // сравнение с предыдущим - не равно kbd_buf[2] = kbd_buf[1]; // запомнить тек.состояние kbd_pr_cnt = 0; // обнулить счетчик } else { // состояние не изменилось - обработать if (kbd_pr_cnt < KBD_PR_MAX) kbd_pr_cnt++; // нет переполнения - увеличить счетчик U8 kbd_co = kbd_buf[1]; // код клавиш - в локальную переменную для ускорения сравнений
if ((kbd_pr_cnt >= KBD_PR_EXIT)&&(kbd_co == KBD_CO_NONE)) { // кнопки долго не нажимались - авто возвр. в пред.сост.индикации ind_param = 0; } else if ((kbd_pr_cnt == KBD_PR_SHORT)&&(kbd_co == KBD_CO_UP)) { // кнопка +, короткое нажатие - увеличить параметр if (ind_param == (IND_PA_MAX_NORMAL - 1)) ind_param = 0; else ind_param++; } else if ((kbd_pr_cnt >= KBD_PR_SHORT)&&(kbd_co == KBD_CO_CORR)) { // кнопка коррекции, короткое нажатие cli(); if (rtc.min > 30) { rtc.sec = 59; rtc.min = 59; } else { rtc.sec = 0; rtc.min = 0; } sei(); ind_param = 0; } else if ((kbd_pr_cnt == KBD_PR_SHORT)&&(kbd_co == KBD_CO_SETUP)) { // кнопка настройки, короткое нажатие - перейти в режим настройки ind_param = 0; ind_mode = IND_MO_SETUP; } else if ((kbd_pr_cnt == KBD_PR_SETUPEXT)&&(kbd_co == KBD_CO_SETUP)) { // кнопка настройки, длинное нажатие - перейти в режим расширенной настройки } else if ... { // и так далее.... } } }
Причина редактирования: Уменьшение размера цитаты исходника.
|
|
|
|
|
Apr 3 2009, 12:04
|

извечный пессимист
    
Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125

|
Цитата(adc @ Apr 3 2009, 15:18)  По отпусканию кнопки неудобно! Представте пользователя.. он нажал кнопку.. и ждет перехода в режим меню.. и думает -"прошло ли 6секунд или нет? можно ли отпускать клавишу?"... И что? А если после нажатия считать интервал времени. Если прошло 6 секунд, а кнопка нажата то переходить в меню. Если отпустили раньше другое действие. Защита от залипания так: прошло , к примеру, 12секунд а кнопа нажата.. то ахтунг и т.д. Самое смешное, что вы как раз и будете производить действие по отжатию  Кроме того если у вас прошло 6 сек., то вы смотрите 6 сек прошло - да, кнопка нжата - да, и переходите в меню. Тут другой вопрос, если в меню используется таже кнопка, то тогда надо на какое то время надо отрубать действие кнопки иначе получится фигня.
--------------------
Slaves are those of this world Given freedom to lay chains upon The Master The wolf is no longer free Release the chains and come for me
|
|
|
|
|
Apr 4 2009, 21:02
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Внесу свои 5 копеек. Поскольку как я понял у топикстартера кнопок несколько, то имеет смысл делать функции кнопок не на задержках, а на комбинации нажатий кнопок. Правда схемотехникой подключения клавиатуры должна обеспечиваться возможность распознавания одновременного нажатия нескольких кнопок. Я недавно в одном простеньком проекте "реле с таймером" на трех кнопках реализовывал пять различных скан-кодов. Две кнопки "↑" и "↓" в обычном режиме генерировали коды нажатий. Причем с автоповтором. А третья кнопка ("УСТ") генерировала код отпускания и одновременно служила кнопкой ALTернативной функции. Т.е. комбинации нажатой "УСТ" с нажатиями какой-либо из первых двух генерировали еще два дополнительных скан-кода нажатия: функции "запомнить" и "сохранение". Кстати, а в другом проекте, где каждая из 14 кнопок, должна была иметь возможность генерировать автоповтор независимо от других, я делал иначе. Снималась матрица состояний кнопок. После устранения дребезга определялся факт нажатия и фиксировался момент времени нажатия для каждой кнопки. "Очищенная" от дребезга матрица состояний выдавалась "наружу". А по истечении определенного интервала времени, которое опять же индивидуально для каждой кнопки, соответствующие биты "выходной" матрицы состояний инвертировались до тех пор, пока соответствующий бит "на входе" функции, соответствовал нажатой кнопке.
|
|
|
|
|
Apr 4 2009, 21:07
|

извечный пессимист
    
Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125

|
Цитата(_Pasha @ Apr 4 2009, 18:54)  Этот момент надо обустроить так: при нажатии на кнопку должно выводиться какое-либо сообщение, типа "НА! нажатая я!" а потом, после злополучных 6 секунд тихо переходить в меню и ждать отпускания (залипшей) кнопки. А если юзер отпустил кнопку раньше - сообщение убрали. Имхо, конечно. у него вместо сообщения должна выводится уставка, хотя... хотя.. вы правы, ведь эту уставку можно сделать мигающей например.. to rezident вы предложили как раз самое правильное решение, если кнопка не одна конечно...
--------------------
Slaves are those of this world Given freedom to lay chains upon The Master The wolf is no longer free Release the chains and come for me
|
|
|
|
|
May 7 2009, 09:52
|

Участник

Группа: Участник
Сообщений: 52
Регистрация: 6-05-09
Из: Москва
Пользователь №: 48 733

|
Ребят, а подскажите, как лучше сделать обработку действия кнопки? Я взял за основу алгоритм от MrYuran , http://electronix.ru/forum/index.php?showt...st&p=571913 . У меня пока что три кнопки (учусь на них), без матрицы. Я хочу, чтобы у меня была процедура опроса кнопок (вызывается, скажем, каждые 10мс). Она отвечает за выставление флагов "Нажато", "Долго нажато" и выдаёт биты того, что нажато. Но меня смущает, что это чудо занимает уже под 100 байт кода, и 5 регистров. Всего для 3х кнопок. Направьте на мысль, как бы обойти такую ситуацию в интерфейсе пользователя: скажем, юзер нажал кнопку, уставка увеличилась. А он кнопку отпускает и держит пальцем (естессно, что мы обработали нажатие один раз). Пока что я вручную скидываю бит нажатой кнопки после того, как обработал её нажатие. А при определении "Долго нажата" снова ставлю бит нажатой кнопки и флаг LOCKED. И ещё вопрос - как лучше оформлять данные, возвращаемые процедурой сканирования клавиатуры? Как умные делают? В идеале я хочу получать и обрабатывать состояния: Нажата, Долго нажата, Отпущена. Автоповтор пока не нужен. У меня пока что флаги PRESSED и LOCKED стоят битами (на все кнопки), и ещё есть биты, которые показывают нажатие каждой кнопки. Может, завести для каждой клавиши свой набор флагов?  З.Ы. Пишу на АСМе, на Си мне вообще ни черта не понятно
Сообщение отредактировал C.S. - May 7 2009, 09:53
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|