Помогите с алгоритмом нажатия клавиш Arduino Micro.

Приветствую, впервые пользуюсь Arduino.

Поэтому я использую Arduino Micro в качестве HID-клавиатуры. Он принимает произвольные входные данные из программы Node-JavaScript, которую я запускаю (поэтому у меня есть полная свобода в передаче данных на микропроцессор).

Цель состоит в том, чтобы данные, передаваемые на микроконтроллер, включали информацию о нажатии клавиши: была ли она нажата или отпущена, и какая это клавиша. С последовательными соединениями все в порядке, у меня только есть вопросы относительно логики нажатия клавиш.

Что касается программы JavaScript, нажатие клавиши обнаруживается на основе кода клавиши, а не кода символа, поэтому при нажатии «a», код символа 97, Arduino micro получает «A», код символа 65, поскольку Код ключа, обнаруженный JavaScript, равен 65. Так что все это похоже на проблемы с JavaScript (а это так и есть), но помните, что у меня есть свобода в отображении информации, отправляемой в микро.

При этом вместо обнаружения по кодам клавиш и кодам символов в JavaScript я мог бы просто передать букву, например, «a» с некоторым идентификатором для нажатия/выпуска, например «+a» для выпуска и «-a» для нажатия. . Моя проблема заключается в том, как мне обрабатывать клавиши-модификаторы с помощью библиотеки клавиатуры.

Должен ли я обрабатывать символьные клавиши и клавиши-модификаторы отдельно, например Keyboard.write для символов и Keyboard.press/release для модификаторов, или есть случаи, когда это имеет смысл нажмите и удерживайте «a» (что также отличается от нажатия и удерживания «A»)?

Ниже приведен мой исходный код, в котором используются коды клавиш и идентификаторы «u/d» для обозначения вверх или вниз (сейчас я думаю, что «u/d» можно легко спутать с буквой, если я решу передавать символы как символы:

/*
  Receives from the hardware serial, sends to software serial.
  Receives from software serial, sends to hardware serial.

  The circuit:
   RX is digital pin 10 (connect to TX of other device)
   TX is digital pin 11 (connect to RX of other device)

  Not all pins on the Leonardo and Micro support change interrupts,
  so only the following can be used for RX:
  8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
*/

#include <SoftwareSerial.h>
#include <Keyboard.h>

SoftwareSerial rpiSerial(10, 11); // прием, Передача

void setup() {
  // Открытие последовательной связи и ожидание открытия порта:
  Serial.begin(115200);
  // Устанавливаем скорость передачи данных для порта SoftwareSerial
  rpiSerial.begin(115200);
  // инициализируем управление клавиатурой:
  Keyboard.begin();
  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для собственного порта USB
  }

  Serial.println("Keyboard Serial Connection Established");
}

String keyCode = "";
char state;

void loop() {
  while (rpiSerial.available() > 0) {
    // «Тип» с помощью кодов клавиш (рекомендуется для модификаторов)
    // https://www.arduino.cc/en/Reference/KeyboardWrite ведет себя не так, как ожидалось

    int data = rpiSerial.read();
    if (isDigit(data)) {
      keyCode += (char)data;
    }

    if (isAlpha(data)) {
      state = (char)data;
    }

    if (data == '\n') {
      Serial.print(state);
      Serial.println(keyCode.toInt());

      if (state == 'd') {
        Keyboard.press(keyCode.toInt());
      }

      if (state == 'u') {
        Keyboard.release(keyCode.toInt());
      }

      keyCode = "";
      char state;
    }
  }
}

Я также заметил, что данные последовательного соединения, анализируемые микроконтроллером, иногда неверны, т.е. код ключа будет определен неправильно. Например, при многократном нажатии «a» в моей программе JavaScript программа JavaScript последовательно идентифицирует код ключа 65, но Arduino большую часть времени идентифицирует полученные данные как код ключа 65, а затем случайным образом код ключа 64. Это происходит и с другими клавишами, и keyCode не всегда бывает на единицу меньше и не всегда возникает после нажатия «n».

, 👍1

Обсуждение

SoftwareSerial ненадежен на скорости 115200. Используйте скорость 9600 бод., @Juraj

Хорошо знать! Я попробую это @Juraj, @Sterling Butters

Код ASCII для «A» — 65, а для «a» — 97. http://www.asciitable.com/ клавиша на клавиатуре — «A», а не «a»., @Juraj

Итак, как бы вы порекомендовали определить с помощью микроконтроллера, что клавиша была нажата/отпущена?, @Sterling Butters

что вы хотите делать в эскизе Arduino, пока нажата клавиша?, @Juraj

@Юрай, Я думаю, ничего, кроме того, чтобы держать клавишу нажатой, пока она не будет отпущена., @Sterling Butters

Что ты имеешь в виду?, @Sterling Butters

извини. Я не знал, что функции нажатия/отпускания работают для любой клавиши., @Juraj

Может быть, есть какие-то особенности, @Sterling Butters


1 ответ


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

1

Клавиши-модификаторы ничем не отличаются от обычных клавиш.

Библиотека клавиатуры Arduino содержит код для сопоставления различных клавиш из внутреннего списка макросов с конкретными нажатиями клавиш:

  • Если значение ключа >= 138, это непечатаемый специальный ключ (вычтите 138).
  • Если значение ключа >= 128, это ключ-модификатор (1 << (k - 128))
  • В противном случае найдите код в таблице сопоставления.

Это означает, что вы можете использовать:

Keyboard.press(KEY_LEFT_SHIFT);

или

Keyboard.release(KEY_RIGHT_GUI);

Полный список клавиш-модификаторов:

#define KEY_LEFT_CTRL   0x80
#define KEY_LEFT_SHIFT    0x81
#define KEY_LEFT_ALT    0x82
#define KEY_LEFT_GUI    0x83
#define KEY_RIGHT_CTRL    0x84
#define KEY_RIGHT_SHIFT   0x85
#define KEY_RIGHT_ALT   0x86
#define KEY_RIGHT_GUI   0x87

Чтобы написать заглавную букву А, вы можете использовать:

Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('a');
Keyboard.release('a');
Keyboard.release(KEY_LEFT_SHIFT);

Есть также ярлык:

Keyboard.press('A');
Keyboard.release('A');

Символ «A» в таблице поиска совпадает с символом «a», за исключением того, что установлен старший бит результата, который вызывает добавление «Нажмите или отпустите клавишу Shift» в коде сопоставления.

>

Отчет USB-клавиатуры состоит из 8 байт:

  • До 8 клавиш-модификаторов (растровое изображение).
  • Один зарезервированный байт
  • 6 байт для обозначения нажатых клавиш.

Это означает, что вы можете одновременно нажать до 6 клавиш, а также клавиши-модификаторы. Никогда больше этого. Таким образом, вам не нужно обрабатывать больше, чем это, в вашем коде.

Текущий список нажатых клавиш сохраняется клавиатурой и отправляется в каждом отчете. Нет понятия «нажато» или «отпущено» как таковое — только список того, что нажимается в данный момент. Если клавиша отпущена, она просто удаляется из списка нажатых клавиш.

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

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

  • Все данные протокола содержат символы ASCII от 32 до 127 включительно.
  • Это освобождает управляющие символы (<32) для управления протоколом.

Самый простой способ — использовать один управляющий символ (например, \n), который будет служить концом строки и разбивать данные на пакеты. Каждый пакет может содержать список инструкций.

Например, вы можете выбрать протокол следующего вида:

P,129\n
P,97\n
R,97\n
R,129\n

Рассматривая каждую строку как целостный объект, вы знаете, что хотите Нажать клавишу 129 (#define KEY_LEFT_SHIFT 0x81), нажать клавишу 97 («a») , выпуск 97, затем выпуск 129.

Нет путаницы, поскольку все команды представляют собой один символ верхнего регистра, а все ключи — десятичные числа.

Однако для вашего приложения «необработанный» интерфейс доступа будет более полезен, поскольку на самом деле вы не хотите, чтобы Arduino что-то интерпретировал за вас. Однако API не предоставляет таких вещей. Так что вам просто нужно максимально использовать то, что у вас есть, и работать над этим.

,