Использование библиотеки клавиатуры для раскладки ISO-UK

Я создаю клавиатуру, и компьютер, с которым я ее использую, настроен для Великобритании, поэтому раскладка клавиатуры, которую он ожидает, такова

UK keyboard with UK - Us differences highlighted

Я выделил различия ISO-UK и ANSI-US, но единственный ключ, с которым у меня возникли реальные проблемы, - это ключ обратной косой черты.

Мой физический макет на самом деле такой (ортолинейный "Планк"), но он по сути тот же самый, за исключением двух логических слоев и вариаций позиционирования.

Planck style keyboard

Вышеописанная клавиатура представляет собой полностью функциональную клавиатуру с британской раскладкой, за исключением клавиши "\".

Скетч, который я использую, слишком велик и отвлекает, чтобы публиковать здесь, но следующий тестовый скетч

#include "Keyboard.h"

byte keylist[] = { '`', '2', '3', '\'', '#', '\\' }; 

void setup() {
  Keyboard.begin();
  delay(1000);

  // unshifted
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(keylist[i]);      delay(100);
    Keyboard.release(keylist[i]);    delay(100);
  }

  Keyboard.press(KEY_RETURN);
  Keyboard.releaseAll();

  // shift
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(KEY_LEFT_SHIFT);
    Keyboard.press(keylist[i]);
    delay(100);
    Keyboard.releaseAll();
    delay(100);
  }
}

void loop() {
  delay(1000);
}

Создает этот вывод (в окне Блокнота).

`23'£#
¬"£@£~ 

Я попробовал переключить фокус на инструмент диагностики клавиатуры - KeyHitter by Elite Keyboards, который показал разные результаты

12:31.0675 ` (0xDF, BIOS 0x29) DOWN
12:31.0771 ` (0xDF, BIOS 0x29) UP -> 100ms
12:32.0772 2 (0x32, BIOS 0x03) DOWN
12:32.0871 2 (0x32, BIOS 0x03) UP -> 100ms
12:33.0872 3 (0x33, BIOS 0x04) DOWN
12:33.0972 3 (0x33, BIOS 0x04) UP -> 100ms
12:34.0972 ' (0xC0, BIOS 0x28) DOWN
12:35.0072 ' (0xC0, BIOS 0x28) UP -> 100ms
12:36.0072 LShift (0x10, BIOS 0x2A) DOWN
12:36.0082 3 (0x33, BIOS 0x04) DOWN
12:36.0172 LShift (0x10, BIOS 0x2A) UP -> 100ms
12:36.0182 3 (0x33, BIOS 0x04) UP -> 100ms
12:37.0172 \ (0xDE, BIOS 0x2B) DOWN
12:37.0272 \ (0xDE, BIOS 0x2B) UP -> 100ms
12:38.0271 Enter (0x0D, BIOS 0x1C) DOWN
12:38.0273 Enter (0x0D, BIOS 0x1C) UP -> 2ms

...

Таким образом, библиотека клавиатуры Arduino переводит "#" в shift+3, что бесполезно для британских пользователей, но я озадачен, почему Keyhitter видит, что "\" производит ожидаемое \, но другие программы видят, что он производит #! Я предполагаю, что Keyhitter перехватывает нажатия клавиш на более низком уровне, чем обычные приложения - например, он правильно показывает нажатие Win, но не позволяет Windows открывать меню "Пуск".

Результат в Блокноте типичен для эффекта, получаемого в обычных приложениях. Так что это, наверное, более актуально.

Я могу обойти "#", производя сдвиг+3, так как "\\" производит #, но как тогда мне создать \?

, 👍1

Обсуждение

try for (байт i = 0; i <= 255; i++) { Keyboard.press(i) ....... .... одно из значений должно генерировать нужный символ ... затем используйте это значение вместо `\\"., @jsotola

@jsotola: Я немного опасаюсь непреднамеренного нажатия последовательностей специальных клавиш, таких как "Win", за которыми следует "F1", поэтому я попробовал приложение, которое, как я подозреваю, захватывает нажатия клавиш на низком уровне, но это было не слишком полезно. Я могу попробовать ваше предложение, если мне удастся поработать с некоторыми гарантиями, чтобы у меня было время разобраться в том, что происходит, прежде чем система погрузится в бешеный хаос., @RedGrittyBrick

вычислите значение байта , представляющее ключ Win , и исключите его ... if ( i != Win ) Keyboard.press(i);, @jsotola

@jsotola: Я был настроен скептически, но этот подход сработал. Мне пришлось использовать нажатие кнопки, чтобы увеличить мой индекс, потому что вы сталкиваетесь с большим количеством функциональных клавиш и т. Д., Вызывающих справочные окна и другие странные вещи, которые вам нужно время, чтобы оправиться от реальной клавиатуры. Keyboard.press (0xEC) производит "\" в Блокноте и при использовании в сочетании с shift производит ожидаемое "|"., @RedGrittyBrick


2 ответа


3

Протокол USB-клавиатуры не имеет понятия о символах. Он не знает и не заботится о том, какой символ представляет ключ. Вместо этого каждый код представляет расположение клавиши на клавиатуре, и программное обеспечение компьютера должно отображать эти местоположения в символы с помощью своей собственной карты клавиатуры.

Таким образом, Arduino должен делать обратное, когда вы хотите "напечатать" текст через клавиатуру - преобразовать этот текст в расположение клавиш на клавиатуре. И он делает это через массив _asciimap в Keyboard.cpp.

Чтобы использовать любую другую раскладку клавиатуры, кроме НАШЕЙ, вам необходимо изменить эту карту таким образом, чтобы каждое значение ASCII указывало на правильное расположение этого символа, определенное на карте клавиатуры вашего компьютера.

Вы можете найти список кодов расположения клавиатуры (названных в этом документе после отличительных знаков американской клавиатуры) здесь (стр. 53), который затем можно использовать для сопоставления любых изменений.

Например, в _asciimap двойная кавычка указана следующим образом:

     0x34|SHIFT,    // "

Который сопоставляется с клавиатурой " и" в USB. Но для Великобритании вы хотите, чтобы это был shift-2, то есть клавиатура 2 и @ в английской раскладке. Эта запись - hex 1F.

Таким образом, изменение цитаты на сдвинутую 0x1F должно дать вам желаемую цитату:

    0x1F|SHIFT, // "

Вам нужно будет сделать то же самое со всеми другими символами, которые нуждаются в повторном отображении (включая). Некоторым может потребоваться немного проб и ошибок, чтобы выяснить, что такое эквивалентная клавиша на британской клавиатуре, поскольку некоторые клавиши находятся в физически разных местах (особенно примечательно, что слева от Z на клавиатуре США нет клавиши, но есть дополнительная клавиша справа от ] ).

К сожалению, библиотека клавиатуры Arduino не предоставляет пользователю возможности предоставить свою собственную карту клавиатуры. Вместо этого вы должны изменить исходный код самой библиотеки.

,

Это имеет смысл, но происходит больше, потому что на моей клавиатуре на базе Arduino shift + 2 уже производит ", а не @ - так что в Windows есть некоторое дополнительное отображение, которое уже выполняет большую часть работы по тому, чтобы моя клавиатура вела себя как клавиатура ISO-UK. (Если интересно, "Keyboard.press (0xEC)" - это эффективная британская клавиша "\". Вся эта область кажется намного более сложной, чем я помню во времена сканкодов клавиатуры PC-XT и TSR, @RedGrittyBrick


2

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

#define KEY_BSLASH 0xEC

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

,

Если он работает на ISO-UK, он, скорее всего, будет работать на каждом макете ISO (например, give “<”в АЗЕРБАЙДЖАНЕ). И это делает ваш ответ более полезным в целом., @Edgar Bonet