Отправка пользовательских скрытых значений вместо ключей

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

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

Это то, что я получил до сих пор:

#include <Keypad.h>

const byte rows = 3;
const byte cols = 5;

char keys[rows][cols] = {
  { '1', '2', '3', '4', '5' },
  { 'q', 'w', 'e', 'r', 't' },
  { 'a', 's', 'd', 'f', 'g' }
};

byte rowPins[rows] = { 10, 16, 14 };
byte colPins[cols] = { 9, 8, 7, 6, 5 };

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

void setup(){
  Serial.begin(9600);
}

void loop(){
  char key = keypad.getKey();

  if (key != NO_KEY){
    Serial.println(key);
  }
}

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


Обновить

Я изменил код в соответствии с ответом Маенко:

#include <HID-Project.h>
#include <HID-Settings.h>

uint8_t rawhidData[255];

byte rows[] = { 10, 16, 14 };
byte cols[] = { 9, 8, 7, 6, 5 };

const int rowCount = sizeof(rows)/sizeof(rows[0]);
const int colCount = sizeof(cols)/sizeof(cols[0]);

void setup() {
  for (int row = 0; row < rowCount; row++) {
    pinMode(rows[row], OUTPUT);
    digitalWrite(rows[row], HIGH);
  }

  for (int col = 0; col < colCount; col++) {
    pinMode(cols[col], INPUT_PULLUP);
  }

  RawHID.begin(rawhidData, sizeof(rawhidData));
}

void loop() {
  for (int row = 0; row < rowCount; row++) {
    digitalWrite(rows[row], LOW);

    for (int col = 0; col < colCount; col++) {
      if (digitalRead(cols[col]) == LOW) {
        String coordinatesString = String(row+1) + String(col+1);
        uint8_t coordinates = coordinatesString.toInt();

        uint8_t megabuff[sizeof(coordinates)];

        megabuff[0] = coordinates;
      
        RawHID.write(megabuff, sizeof(megabuff));
        
        while (digitalRead(cols[col]) == LOW) {
          delay(50);
        }
        break;
      }
    }

    digitalWrite(rows[row], HIGH);
  }
}

Я удалил последовательный вывод, так как он мне больше не нужен. Код выглядит грубым и нуждается в дальнейшем рефакторинге, но он действительно работает.

, 👍2


1 ответ


Лучший ответ:

3

ХИД - странный зверь, от которого можно прийти в себя.

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

Когда вы используете клавиатуру.h вы подключаете дескриптор отчета клавиатуры к конечной точке USB HID, и компьютер знает, как интерпретировать поступающие данные как нажатия клавиш. Когда вы используете мышь.h вы подключаете дескриптор отчета мыши, и компьютер знает, как интерпретировать поступающие данные как движения мыши и нажатия кнопок.

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

Для Arduino есть библиотека "Raw HID", которая делает это - она использует "пустой" дескриптор отчета, который просто дает вам простой 64-байтовый блок данных для выполнения того, что вы хотите.

Существует хорошая библиотека HID от Nico Hood, которая реализует режим raw (а также другие).

Для получения данных на вашем компьютере вам необходимо, чтобы ваша программа напрямую взаимодействовала с системой USB HID. Существует множество библиотек для большинства языков, которые сделают это за вас (hidapi в C / C ++, hid в Python, hid4java для Java и т. Д.).

,

Отличная информация. Для тех, кто ищет, есть критическая ошибка в упомянутой библиотеке HID, которая ломает RawHID.write(); . Помните об этой ошибке, прежде чем идти по этому пути. https://github.com/NicoHood/HID/issues/133, @spuder