Отправка мультимедийных клавиш клавиатуры с помощью библиотеки клавиатур

У меня есть Arduino Pro Micro (ATmega32U4), который я хочу использовать в качестве ИК-приемника для мультимедийного ПК, и мне нужно посылать такие коды, как Volume Up, Media Home, Play и т. Д. Но когда я ищу коды сканирования для них и отправляю их на Клавиатуру.нажмите (), он просто печатает "0" каждый раз.

Как отправить эти команды с клавиатуры?

, 👍3

Обсуждение

Включите свой скетч. Предоставьте ссылку на то, где вы искали коды сканирования и т. Д., так как большинство диаграмм не имеют в списке медиаключей, @James Waldby - jwpat7

Я использовал приложение, которое давным-давно написал на C#, чтобы захватывать сканирующие коды. Медиа-дом, по-видимому, 128., @Adam Haile


5 ответов


1

Keyboard.press() нажимает клавишу и “удерживает ее нажатой” до тех пор, пока не будет выдан Keyboard.release() или releaseAll (). То есть, Keyboard.press() не подходит для имитации простого нажатия и отпускания клавиши, если только вы не выполните ее с задержкой и отпусканием.

Также см. раздел Keyboard.write(). Но обратите внимание на следующее из документации Keyboard.write ():

Поддерживаются только символы ASCII, которые находятся на клавиатуре. Например, будет работать ASCII 8 (backspace), но не будет работать ASCII 25 (Подстановка).

В моей системе Linux xev (используется с помощью клавиатуры xev-событий) показывает следующие данные для мультимедийных клавиш, помеченных как показано на рисунке.

  Excerpt from info displayed by xev           Picture
keycode 180 (keysym 0x1008ff18, XF86HomePage)   house
keycode 179 (keysym 0x1008ff81, XF86Tools)   quarter-notes
keycode 163 (keysym 0x1008ff19, XF86Mail)      envelope
keycode 172 (keysym 0x1008ff14, XF86AudioPlay)  >/||
keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume)  speaker
keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume)  speaker
keycode 121 (keysym 0x1008ff12, XF86AudioMute)  x'd-speaker
keycode 148 (keysym 0x1008ff1d, XF86Calculator)  Calculator
,

Я знаю... Я делаю press();delay();releaseAll(). Но если я дам ему код 128, например, он ничего не сделает., @Adam Haile


3

Вам нужно внести некоторые изменения в библиотеки usbkeyboard, которые поставляются с IDE.

Для видеоурока взгляните на это:

Arduino Leonardo в качестве мультимедийной клавиатуры

Который использует информацию с этого сайта, если вы предпочитаете только текст:

Мультимедийные клавиши Arduino Leonardo

Леонардо и ПроМикро используют ATmega32U4 и оба должны работать с этими настройками. Если вам нужно больше функций, чем те, которые дает вам эта настройка, вам нужно углубиться в дескрипторы usb на usb.org для команд, которые вам нужны.

,

Что означает "4" для первого параметра HID_SendReport()? Это для того, чтобы притворяться ИК-пультом дистанционного управления?, @Peter Mortensen

Хорошо, после долгого, долгого поиска я нашел его: 4 для "Контроля потребителей" (для "идентификатора отчета"). Более полный список (опущено только 3) находится [в библиотеке]. (https://github.com/NicoHood/HID/blob/master/src/HID-Settings.h), с символическими названиями: 1: Мышь, 2: Клавиатура, 4: Управление потребителем (с регуляторами громкости/мультимедийным управлением), 5: Управление системой, 6: Геймпад, 7: Абсолютная мышь, 8: Клавиатура NKRO, 9: Крошечная клавиатура, 10: Набор с поверхности, @Peter Mortensen

продолжение "- (определяет (константы) "HID_REPORTID_MOUSE", "HID_REPORTID_KEYBOARD", "HID_REPORTID_CONSUMERCONTROL", "HID_REPORTID_SYSTEMCONTROL", "HID_REPORTID_GAMEPAD", "HID_REPORTID_MOUSE_ABSOLUTE", "HID_REPORTID_NKRO_KEYBOARD", "HID_REPORTID_TEENSY_KEYBOARD", "HID_REPORTID_SURFACEDIAL', соответственно)., @Peter Mortensen

Хотя идентификаторы отчетов могут быть произвольными (определяемыми самостоятельно)?, @Peter Mortensen


3

Это действительно возможно, а также без необходимости изменять саму среду Arduino. Просто зарегистрируйте дескриптор HID для "идентификатора отчета" для "Управления потребителем" (код 4 (константа kHID_ReportID_ConsumerControl), где код "идентификатор отчета" для клавиатуры и мыши равен 2 и 1 соответственно):

static HIDSubDescriptor node(HID_ReportDescriptor_ConsumerControl,
                             sizeof(HID_ReportDescriptor_ConsumerControl));

HID().AppendDescriptor(&node);

После регистрации HID().SendReport() теперь работает для "идентификатора отчета", равного 4 (первый параметр), и громкость звука может быть изменена и т. Д.

Регистрация должна быть выполнена один раз и может быть введена в функцию init (), например, после вызовов Keyboard.begin(); и Mouse.begin ();.

Использование

Пример использования, увеличение громкости звука на один шаг:

uint8_t data[2];
data[0] = kVolumeUp;
data[1] = 0;
HID().SendReport(kHID_ReportID_ConsumerControl, data, 2);

Константы находятся в конце.

Примечания

"Управление потребителем" имеет мультимедийные элементы управления увеличением громкости, уменьшением громкости, отключениемзвука, воспроизведением и т.д.

Регистрация аналогична тому, как это делают конструкторы для встроенных библиотек клавиатуры и мыши. HID_ReportDescriptor_ConsumerControl и константы перечислены в конце, потому что они довольно длинные, но они должны быть первыми (например, в начале файла).

Все это можно было бы упаковать в многоразовую форму. Здесь я продемонстрировал это в форме "вставь и забудь", чтобы сделать это короче.

Спрятал().SendReport() выглядит странно, но спрятал() - это глобальная функция, которая возвращает экземпляр класса HID_ (все построено на стандартных библиотек Arduino, по-видимому, чтобы избежать инициализации того, проблемы с глобальными/статическими объектами - я думал, что Скотт Мейерс решил, что давным-давно (47. в первой книге)).

HID().SendReport() также можно использовать для обхода ограничения презумпции клавиатуры. Например, используя код 100, стр. 56 (и kHID_ReportID_Keyboard, как в клавиатуре стандартного класса) для эмуляции 102-й клавиши на европейских клавиатурах (например, испанская клавиатура).

Были протестированы только увеличение и уменьшение громкости.

Определение HID_ReportDescriptor_ConsumerControl и констант:


// Для прямого использования USB HID (да, 3 не указано)
const uint8_t kHID_ReportID_Mouse           =  1;
const uint8_t kHID_ReportID_Keyboard        =  2;
const uint8_t kHID_ReportID_ConsumerControl =  4;
const uint8_t kHID_ReportID_SystemControl   =  5;
const uint8_t kHID_ReportID_Gamepad         =  6;
const uint8_t kHID_ReportID_MouseAbsolute   =  7;
const uint8_t kHID_ReportID_NKRO_keyboard   =  8;
const uint8_t kHID_ReportID_TeensyKeyboard  =  9;
const uint8_t kHID_ReportID_SurfaceDial     = 10;

// Для использования в "Контроле за потребителями". Они немного закодированы.
const uint8_t kVolumeUp   = 1 << 0; // Bit 0
const uint8_t kVolumeDown = 1 << 1; // Bit 1
const uint8_t kVolumeMute = 1 << 2; // Bit 2


static const uint8_t HID_ReportDescriptor_ConsumerControl[] PROGMEM =
{
    0x05, 0x0c, // Страница использования ("Потребительские устройства")
    0x09, 0x01, // Использование (Контроль потребителей)
    0xa1, 0x01, // Коллекция (приложение)
    0x85, kHID_ReportID_ConsumerControl, // "Идентификатор отчета"
    0x15, 0x00, // Логический минимум (0)
    0x25, 0x01, // Логический максимум (1)
    0x09, 0xe9, // Использование (Увеличение громкости)
    0x09, 0xea, // Использование (Уменьшение громкости)
    0x75, 0x01, // Размер отчета (1)
    0x95, 0x02, // Количество отчетов (2)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xe2, // Использование (Отключение звука)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb0, // Использование (Воспроизведение)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb1, // Использование (Пауза)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb7, // Использование (Остановка)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb5, // Использование (Следующее)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb6, // Использование (предыдущее)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb3, // Использование (Быстрая перемотка вперед)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x09, 0xb4, // Использование (перемотка назад)
    0x95, 0x01, // Количество отчетов (1)
    0x81, 0x06, // Ввод (Данные, Переменная, Относительная)

    0x95, 0x06, // Количество отчетов (6) Количество бит, оставшихся в байтах
    0x81, 0x07, // Ввод (постоянный, Переменный, Относительный)
    0xc0 // Конечная коллекция
}; // Таблица для USB HID "Управление потребителем" (для регулировки громкости звука и т. Д.)

Платформа

Это было проверено с помощью:

  • Arduino Leonardo (уже используется в качестве макро-клавиатуры, используя старую клавиатуру PS/2. Для проверки громкости звука вверх / вниз были назначены две новые макрокоманды).
  • Arduino Leonardo подключен к дополнительному текущему порту USB-концентратора D-Link (необходимо по неизвестным причинам-вероятно, локальная проблема).
  • Arduino IDE v. 1.18.10
  • Linux, Ubuntu 19.10 (Eoan Ermine), но с гномом-багги, замененным Корицей.
,

У меня была такая же проблема, и имеющейся здесь информации было недостаточно. Позже я нашел и протестировал решение. И вот результат!, @Peter Mortensen

Некоторые мелочи: Это началось из-за того, что колесико регулировки громкости на клавиатуре вело себя странно. Эмуляция была попыткой изолировать проблему. Оказалось, что это, скорее всего, механическая проблема (раньше у нее были проблемы с некоторыми ключами (которые решаются))., @Peter Mortensen

Хотя, являются ли идентификаторы отчетов полностью произвольными (самоопределяющимися)? Неужели они просто оказались 2 и 1 для клавиатуры и мыши в стандартной библиотеке Arduino? Или существуют какие-то соглашения/значения по умолчанию/стандарт?, @Peter Mortensen

Спасибо вам за этот рецепт, он был единственным, который сработал для меня! Использование Arduino Micro (не Pro) с ИК-приемником+пульт дистанционного управления, хорошо работающий в Ubuntu 20.04., @miguev

Ссылка на испанскую клавиатуру должна была быть ссылкой на это практическое руководство (на этом сайте), но я не буду сталкиваться с этим в настоящее время., @Peter Mortensen


2

Если вы получаете нули, наиболее вероятной причиной является библиотека для ИК. Переустановите или обновите библиотеку. Иногда вам приходится переустанавливать систему более одного раза. Это должно сработать.

Что касается мультимедийных ключей, библиотека клавиатуры не имеет функций мультимедийных ключей, поэтому вам нужно использовать другой. Этот вариант сработал для меня: https://github.com/NicoHood/HID

После установки этой библиотеки необходимо изменить код. Код для нажатия клавиш мультимедиа отличается. Вы должны использовать Consumer.write, например, Consumer.write(MEDIA_VOLUME_UP) для увеличения громкости. Вы можете найти название каждого ключа здесь: https://github.com/NicoHood/HID/wiki/Consumer-API

Для обычных клавиш просто используйте Keyboard.write(). Если хотите, я могу прислать вам код, который сделал для этого.

,

0

Ответ Питера, вероятно, заключается в том, чтобы начать работу с нуля. Но если вы хотите начать с чего-то, есть еще одна библиотека от BleKeyboard https:// github.com/T-vK/ESP32-BLE-Keyboard/blob/master/BleKeyboard.cpp. Здесь показан практически весь процесс создания репортажа для СМИ.

// ------------------------------------------ ------- Медиа-ключи
  USAGE_PAGE(1),      0x0C,          // USAGE_PAGE (Потребитель)
  USAGE(1),           0x01,          // ИСПОЛЬЗОВАНИЕ (Потребительский контроль)
  COLLECTION(1),      0x01,          // КОЛЛЕКЦИЯ (Приложение)
  REPORT_ID(1),       MEDIA_KEYS_ID, // REPORT_ID (3)
  USAGE_PAGE(1),      0x0C,          // USAGE_PAGE (Потребитель)
  LOGICAL_MINIMUM(1), 0x00,          // LOGICAL_MINIMUM (0)
  LOGICAL_MAXIMUM(1), 0x01,          // ЛОГИЧЕСКИЙ_МАКСИМУМ (1)
  REPORT_SIZE(1),     0x01,          // REPORT_SIZE (1)
  REPORT_COUNT(1),    0x10,          // REPORT_COUNT (16)
  USAGE(1),           0xB5,          // USAGE (сканировать следующую дорожку) ; бит 0: 1
  USAGE(1),           0xB6,          // USAGE (сканирование предыдущей дорожки) ; бит 1:2
  USAGE(1),           0xB7,          // ИСПОЛЬЗОВАНИЕ (Стоп) ; бит 2: 4
  USAGE(1),           0xCD,          // ИСПОЛЬЗОВАНИЕ (Воспроизведение/Пауза) ; бит 3: 8
  USAGE(1),           0xE2,          // USAGE (Mute) ; бит 4: 16
  USAGE(1),           0xE9,          // USAGE (приращение объема) ; бит 5: 32
  USAGE(1),           0xEA,          // USAGE (Уменьшение объема) ; бит 6: 64
  USAGE(2),           0x23, 0x02,    // Использование (домашняя страница WWW) ; бит 7: 128
  USAGE(2),           0x94, 0x01,    // Использование (Мой компьютер) ; бит 0: 1
  USAGE(2),           0x92, 0x01,    // Использование (калькулятор) ; бит 1:2
  USAGE(2),           0x2A, 0x02,    // Использование (избранное WWW) ; бит 2: 4
  USAGE(2),           0x21, 0x02,    // Использование (WWW-поиск) ; бит 3: 8
  USAGE(2),           0x26, 0x02,    // Использование (остановка WWW) ; бит 4: 16
  USAGE(2),           0x24, 0x02,    // Использование (обратная ссылка на WWW) ; бит 5: 32
  USAGE(2),           0x83, 0x01,    // Использование (Выбор носителя) ; бит 6: 64
  USAGE(2),           0x8A, 0x01,    // Использование (Почта) ; бит 7: 128
  HIDINPUT(1),        0x02,          // ВВОД (Данные,Var,Abs,Без переноса,Линейный,Предпочитаемое состояние,Нет нулевой позиции)
  END_COLLECTION(0)                  // END_COLLECTION

Если вам интересно, почему работает эта кнопка мультимедиа, вы можете просмотреть USB-документ https:/ /www.usb.org/sites/default/files/documents/hut1_12v2.pdf, стр. 75, где указано, почему используется каждый ключ.

,