Проблемы с HID-проектами с перечислениями кодов ключей

У меня возникли некоторые проблемы с проектом HID, использующим мой микро arduino в качестве клавиатуры. Я использую API BootKeyboard, я хочу, чтобы в конечном итоге у меня была возможность хранить и возвращать коды ключей из EEPROM, но в нынешнем виде мой проект хранит коды ключей в массиве и возвращает их из массива, чтобы отправить их. Прочитав много источников, я нашел перечисление в файле
HID-API\Улучшенные отчеты.h

глядя на перечисление моих типов данных для хранения кодов ключей, которые должны быть uint8_t, я определил:

uint8_t keycode; // моя рабочая переменная для хранения кодов
uint8_t keycodes    [9][9] = {0}; // мой массив для хранения всех кодов ключей

если я определю код ключа в массиве, используя:

keycodes[0][0] = KEY_LEFT_SHIFT;

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

keycode = keycodes[0][0];

делая это:

BootKeyboard.press(keycode);
BootKeyboard.release(keycode);

на компьютер ничего не поступает (у меня есть скрипт на python, который я использую для отслеживания нажатий клавиш)
Однако, если я использую:

BootKeyboard.press(KEY_LEFT_SHIFT);
BootKeyboard.release(KEY_LEFT_SHIFT);

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

Почему это происходит? и если не считать массивного переключателя/корпуса или огромной стопки "если", как я могу это обойти?

ПРАВКА:
хорошо, поэтому после еще нескольких поисков я думаю, что понял, почему это происходит, но это не хороший обходной путь.
Класс BootKeyboard не имеет метода нажатия/выпуска, они унаследованы от DefaultKeyboardAPI, определения которого следующие:

inline size_t press(ConsumerKeycode k);
inline size_t release(ConsumerKeycode k);

ConsumerKeycode-это еще одно перечисление, определенное в HID-Project\src\HID-API\ConsumerAPI.h

DefaultKeyboardAPI наследует два метода печати / выпуска от KeyboardAPI:

inline size_t press(KeyboardKeycode k);
inline size_t release(KeyboardKeycode k);

inline size_t press(uint8_t k);
inline size_t release(uint8_t k);

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

Проблема в том, что функция на основе int проверяет, находится ли ключ в asciimap, и ничего не делает, если нет, очевидно, что специальные клавиши, такие как shift/control, не отображаются в asciimap, поэтому ничего не происходит.

но я не вижу способа обойти это поведение без изменения самой библиотеки...

, 👍0

Обсуждение

В приведенном выше примере вы передаете весь массив кодов ключей (uint8_t [] []), а не один uint8_t. Может быть, в этом и проблема?, @uint128_t

нет? я извлекаю один "uint8_t" из массива в позиции [index1][index2], @James Kent

"однако, если я сохраню значение перечисления в переменную, оно преобразуется в значение int" - какая переменная? Пожалуйста, опубликуйте [Минимальный, полный и поддающийся проверке пример](http://stackoverflow.com/help/mcve) - не [фрагмент](http://snippets-r-us.com/)., @Nick Gammon

Переменная кода ключа, которая имеет тип "uint8_t", в моем примере включает все детали?, @James Kent

Извините, я думал, что вы передаете весь массив кодов ключей в методе .press/.release, потому что вашими переменными являются "код ключа" и "коды ключей". Я на самом деле не понимаю, зачем вам нужен "код ключа", почему бы не попробовать напрямую ссылаться на массив кодов ключей, например " BootKeyboard.press(коды ключей[0][0]);`, @uint128_t

в этом урезанном примере я мог бы пропустить его использование, но это не решило бы проблему, на самом деле в коде у меня есть несколько массивов, и в зависимости от некоторых других переменных он может исходить от любого из них, если вы прочитали правку моего вопроса, я действительно добрался до сути вопроса "почему", и я взломал обходной путь, к сожалению, это означало значительное изменение библиотеки для этого (подробнее в комментарии к ответу ниже)., @James Kent


1 ответ


0

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

,

все они являются глобальными переменными, по соображениям скорости я объявляю свои переменные в глобальном пространстве имен, а не повторно объявляю их в цикле снова и снова, они не выходят за рамки, я уверен, что причина, которую я указал в своем редактировании, заключается в том, почему, но без значительного изменения библиотеки я не вижу решения., @James Kent

Черт возьми, это было бы самое простое решение. Еще раз взглянув на то, что вы сказали в своем обходном пути, почему вы определяете коды клавиш[][] как _uint_8, а не коды клавиш KeyboardKeycode[][]?, @Code Gorilla

KeyboardKeycode-это перечисление, попытка сделать это приводит к ошибке компилятора..., @James Kent

лично я бы предпочел, чтобы библиотека была изменена, чтобы разрешить метод необработанного кода ключа, поэтому я собираюсь заняться этим, я знаю, что это немного странное требование, поэтому сопровождающий может не захотеть объединять изменения, но я думаю, что это единственный способ, которым я могу делать то, что хочу., @James Kent

Теперь я изменил библиотеку (сильно) в соответствии со своими целями, я удалил ранее определенные функции, которые принимают "uint8_t" в качестве аргумента, а затем изменил функции, которые принимают "KeyboardKeycode", чтобы использовать "uint8_t", теперь я могу использовать необработанные числа, а не символы, определенные в перечислении, и в какой-то момент я сделаю то же самое для "ConsumerKeycode", который использовал "uint16_t" для перечисления. Однако я не думаю, что отправлю его обратно сопровождающему, так как менее ясно понять, какая функция на самом деле вызывается для данного аргумента. Я опубликую более подробную информацию сегодня вечером., @James Kent