Объясните мне ghosting
Feb. 6th, 2025 10:41 amЯ понимаю, что занимаюсь левыми вещами, но иногда надо отвлечься...
У клавиатур есть такое понятие, как ghosting. Обычно его описывают так: если в матрице на пересечении двух строк и двух столбцов нажаты три клавиши, то надо сразу отвергнуть якобы нажатие четвёртой, потому что его реально нет. (Вариант с диодом на каждую клавишу не считаем, банально.) Описание недостаточное, проблема начинается уже при двух клавишах.
Обозначим клавиши как строка/столбец, перебор идёт по строкам со считыванием значений столбцов. Пусть у нас уже зажаты две клавиши: 1/1 и 2/2. Любое из нажатий 1/2 и 2/1 (если физически определены обе) уже должно быть отсечено, потому что мы не можем распознать, какая из них реально нажата.
Возьмём QMK как, вероятно, самый отработанный проект. Смотрим quantum/keyboard.c, matrix_task() и has_ghost_in_row(). Выполняется рескан текущего состояния клавиш. Если есть изменения, перебираем строки. Текущая строка сравнивается со всеми прочими, и если в bitand текущей строки с какой-то другой есть >=2 установленных бита из реально существующих клавиш (отсутствующие согласно карте раскладки - удаляются до этого bitand), то объявляется "призрак" и строка пропускается из рассмотрения на данном этапе.
Теперь добавляем в реальную картину дребезг. Нажимаем 1/2. Пусть пока мы добежали в скане до 1/2, на ней читается отсутствие контакта. Но когда добежали до 2/1, контакт есть и через путь 1/1-1/2-2/2 читается реальный призрак на 2/1. Фиксируем нажатие 2/1, а когда на следующем скане 1/2 окончательно зафиксируется, игнорируем её. В результате срабатывает совсем не то, что должно было бы.
Что я не учёл?
У клавиатур есть такое понятие, как ghosting. Обычно его описывают так: если в матрице на пересечении двух строк и двух столбцов нажаты три клавиши, то надо сразу отвергнуть якобы нажатие четвёртой, потому что его реально нет. (Вариант с диодом на каждую клавишу не считаем, банально.) Описание недостаточное, проблема начинается уже при двух клавишах.
Обозначим клавиши как строка/столбец, перебор идёт по строкам со считыванием значений столбцов. Пусть у нас уже зажаты две клавиши: 1/1 и 2/2. Любое из нажатий 1/2 и 2/1 (если физически определены обе) уже должно быть отсечено, потому что мы не можем распознать, какая из них реально нажата.
Возьмём QMK как, вероятно, самый отработанный проект. Смотрим quantum/keyboard.c, matrix_task() и has_ghost_in_row(). Выполняется рескан текущего состояния клавиш. Если есть изменения, перебираем строки. Текущая строка сравнивается со всеми прочими, и если в bitand текущей строки с какой-то другой есть >=2 установленных бита из реально существующих клавиш (отсутствующие согласно карте раскладки - удаляются до этого bitand), то объявляется "призрак" и строка пропускается из рассмотрения на данном этапе.
Теперь добавляем в реальную картину дребезг. Нажимаем 1/2. Пусть пока мы добежали в скане до 1/2, на ней читается отсутствие контакта. Но когда добежали до 2/1, контакт есть и через путь 1/1-1/2-2/2 читается реальный призрак на 2/1. Фиксируем нажатие 2/1, а когда на следующем скане 1/2 окончательно зафиксируется, игнорируем её. В результате срабатывает совсем не то, что должно было бы.
Что я не учёл?
no subject
Date: 2025-02-07 12:14 pm (UTC)no subject
Date: 2025-02-07 01:07 pm (UTC)Из того, что я успел нагуглить - решается через то, что debouncing делается раньше и передаются на следующий уровень только подтверждённые нажатия. Но этого явно недостаточно, можно копать дальше.