Ардуино неправильно распознает скан коды клавиш
- Войдите на сайт для отправки комментариев
Сб, 03/09/2022 - 02:52
Приветствую.
Делаю я один проект который принимает сигналы с подключённой к компьютеру USB клавиатуры.
За основу взял код для кейлоггера от амперки. Использую плату Arduino PRO Mini 5V 16MHz ATMEGA328.
Проблема в том что часто коды распознаются неверно и в монитеоре порта я виже не те символы что нажимал.
С чем это может быть связано?
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
// библиотека для работы с протоколом USB
#include <usbdrv.h>
// библиотека для работы с Serial-портом
#include <uart.h>
// PID 8 бит идентификатор
// ADDR 7 бит адрес устройства
// Endpoint 4 бита номер конечной точки
// CRC 5 бит контрольная сумма
// итого 3 байта
#define IN_SIZE 3
// PID 8 бит идентификатор
// DATA 64 бита данные
// CRC 16 бит контрольная сумма
// итого 11 байт
#define USB_BUFSIZE 11
// количество принятых пакетов хранимых в памяти
// должно быть четным и соблюдаться условие
// (IN_SIZE + USB_BUFSIZE)*FIFO_BUF_SIZE < 255
#define FIFO_BUF_SIZE 10
// RX буфер: 3 байта запроса IN + 11 байт данных DATAx
unsigned char usbRxBuf[USB_BUFSIZE];
unsigned char FIFOBuf[(IN_SIZE+USB_BUFSIZE)*FIFO_BUF_SIZE];
// номер текущей записываемой пары IN-DATA (0-FIFO_BUF)
unsigned char CurWritePos = 0;
// номер текущей прочитываемой пары IN-DATA (0-FIFO_BUF)
unsigned char CurReadPos = 0;
// массив символов для декодирования скан-кодов при не нажатой клавиши Shift
unsigned char masskey[] = "abcdefghijklmnopqrstuvwxyz1234567890-=[]\\X;'`,./";
// массив символов для декодирования скан-кодов при зажатой клавиши Shift
unsigned char masskeyShift[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+{}|X:\"~<>?";
void setup()
{
// открываем последовательный порт
Serial.begin(115200);
// настраиваем прерывание
usbInit();
// печатаем о готовности устройства
Serial.print("UART init complet");
// разрешаем прерывания
sei();
}
void loop()
{
// если сработало прерывание
// то переменная CurWritePos изменит своё значение
if (CurWritePos != CurReadPos) {
// вызываем функцию printResult
printResult(FIFOBuf + CurReadPos*(USB_BUFSIZE+IN_SIZE) + IN_SIZE, USB_BUFSIZE);
CurReadPos++;
if (CurReadPos >= FIFO_BUF_SIZE) {
CurReadPos = 0;
}
}
}
void printResult(uchar *datakey, uchar len)
{
bool shift = 0;
// если во время очередного нажатия на клавишу
// была нажата кнопка Shift
if ((*(datakey + 1) == 0x2) || (*(datakey + 1) == 0x20))
shift = 1;
else
shift = 0;
// если 4 или 3 байт из массива данных пришёл не нулевой
// значит нажата одна из клавиш
if (*(datakey + 4) != 0) {
// вызываем функцию печати 2-го символа
printKey(*(datakey + 4), shift);
} else if (*(datakey + 3) != 0) {
// вызываем функцию печати 1-го символа
printKey(*(datakey + 3), shift);
}
}
void printKey(uchar key, bool shift)
{
// если нажата одна из клавиш английского алфавита
if (key >= 0x4 && key <= 0x27) {
// если нажат Shift декодируем скан-коды как заглавные буквы
if (shift == 1) {
Serial.write(masskeyShift[key-4]);
} else {
// если нет декодируем скан-коды как строчные буквы
Serial.write(masskey[key-4]);
}
} else if (key == 0x28) {
// если пришел скан-код клавиши Enter
Serial.print("\r\n");
} else if (key == 0x2B) {
// если пришел скан-код клавиши Tab
Serial.print("\t");
} else if (key == 0x2C) {
// если пришел скан-код клавиши Space
Serial.print(" ");
} else if (key >= 0x2d && key <= 0x38) {
// если пришел сканд-код из знаков пунктуации
if (shift == 1)
Serial.write(masskeyShift[key - 9]);
else
Serial.write(masskey[key - 9]);
} else {
// если пришёл скан-код которого мы не знаем
// печатаем его без декодирования
printHex(key);
}
}
// открываем последовательный порт
Serial.begin(115200);
Попробуйте уменьшить скорость
Но какого-то определенного значения нет. Но у каждой клавиши в основном свои часто встречающиеся неправильные коды.
Так же чаще всего регистрируются двойне нажатия
Вот например какие неправильные коды у цифры 1 и цифры 2
// открываем последовательный порт
Serial.begin(115200);
Попробуйте уменьшить скорость
Не помогает это.
Я даже без порта пробовал, удалял из кода это и проверял нажатие с помощью мигания светодиода.
Все те же ошибки. Тут с USB какая-то проблема
На ESP USB Host есть проблема с High Speed устройствами. Не все мыши и клавиатуры устойчиво работают. Скорости чипа не хватает, вроде как.
Потому что тут не полноценный аппаратный USB, а софтовая эмуляция. Видимо кварц не на 16 МГц попался ...