Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Скорость изменения параметра в зависимости от длительности удержания клавиши
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
SZ0
Если клавишу нашимаем на короткий промежуток времени, то параметр увеличивается на единицу.
Если продолжаем удерживать, то скорость увеличения параметра или количество приращиваемых единиц за один раз, возрастает. Какие есть вариатны решения?

Прогу пишу на С.
INT1
Да вроде как особых проблем нет, если в прОге задействовано "системное время". Главное, имхо, правильно подобрать значения времЕн и количество ступений изменения скорости набора, чтобы эргономика была на уровне. Часто, даже бренды этому мало придают значение, что иногда - раздражает. То идет слишком медленно, а потом улетает с неимоверной скоростью.
aaarrr
Когда-то использовал такой алгоритм для перемещения движка с тремя скоростями:

Участок кода вызывается по таймеру (60Гц).
Код
int adj_step;

if(!key)
{
    // Кнопка отпущена
    adj_step = 0;
}
else
{
    if(adj_step < 0x10)
    {
        if(adj_step++ & 0x07) break; // или return или goto, как удобнее
    }
    else if(adj_step < 0x20)
    {
        if(adj_step++ & 0x01) break;
    }

    // Здесь инкрементируем или декрементируем значение
    ...
}


Приятность в простоте и легкости подстройки.
rezident
Это реализуется в функции опроса и устранения дребезга, которая вызывается с определенным периодом (у меня обычно этот период в диапазоне 10мс-100мс). Алгоритм примерно такой
1. заполняем матрицу кнопок, опросам и проверяем нажата ли хоть одна клавиша? если нет, то выход
2. состояние (матрицы) кнопок по сравнению с предыдущим не изменилось? если изменилось, то запоминаем его и выход
3. раз состояние совпадает, то значит дребезг окончился, формируем код нажатой клавиши и проверяем совпадает ли он с предыдущим? если нет, то записываем его в буфер клавиатуры и на выход
4. раз код совпадает, то значит нужно формировать повтор. Проверяем флаг, окончания паузы перед началом повтором. Если флаг не установлен, то проверяем окончилась ли пауза задержки начала формирования кода повтора, если не окончилась, то на выход, если же окончилась, то устанавливаем флаг повтора и записываем тот же код клавиши в буфер клавиатуры и фиксируем время формирования кода.
5. раз флаг уже установлен, то смотрим закончилось ли время паузы между повторами. Если нет, то на выход
6. раз пауза между повторами закончилась, то записываем код клавиши в буфер, фиксируем отметку времени и на выход.
Вот здесь на 6 этапе, можно дополнительно фиксировать общее время, прошедшее с начала формирования кодов повтора и по истечении заданного периода изменять (уменьшать) паузы между повторами. Естественно, что фиксировать время начала повтора для этой функции (ускорения выдачи кодов повтора) нужно на этапе 4.
Т.е. структура клавиатуры примерно такая
Код
typedef struct kbd_t
{ unsigned int matrix;  //состояние матрицы кнопок, формируется при каждом вызове функции
  unsigned int state;  //устойчивое состояние матрицы кнопок, после устранения дребезга
  unsigned int bfrPause;  //отметка времени (мс), для формирования задрежку перед началом повтора
  unsigned int btwnPause;  //отметка времени (мс), паузы между повторами
  unsigned int wIdx;  //индекс для записи скан-кодов в буфер клавиатуры
  unsigned int rIdx;  //индекс для извлечения скан-кодов из буфера клавиатуры
  unsigned int cntr;  //счетчик скан-кодов, находящихся в буфере клавиатуры
  unsigned char key_code;  //код последней нажатой клавиши, NULL если клавиша не нажата
  unsigned char flg;  //флаг или битовые флаги управления алгоритмом
  unsigned char buf[MAXNUMKEY]; //буфер клавиатуры
} kbd_t;

Соответственно, изменяя в процессе вызова функции опроса и устранения дребезга, значения переменной btwnPause, вы сможете управлять скоростью выдачи повторных скан-кодов.
Два индекса потому, что я предполагаю использование циклического буфера. Если хочется, то вы можете использовать линейный буфер и избавится от одного индекса, используя вместо него счетчик скан-кодов. Только тогда нужно обеспечить атомарность одновременного сброса индекса и счетчика при полном опустошении буфера.
rv3dll(lex)
Цитата(SZ0 @ Aug 29 2008, 22:01) *
Если клавишу нашимаем на короткий промежуток времени, то параметр увеличивается на единицу.
Если продолжаем удерживать, то скорость увеличения параметра или количество приращиваемых единиц за один раз, возрастает. Какие есть вариатны решения?

Прогу пишу на С.

клавиши где?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.