Arduino как USB HID замедляется, когда ПК не читает события

usb arduino-micro linux hid events

У меня есть Arduino Micro, который работает как HID-устройство для ПК с Linux.

Я использую этот вызов для отправки значений HID:

HID().SendReport(1, _values, sizeof(_values));

В принципе это работает, но я заметил одну проблему:

Если мой ПК с Linux не считывает активно события с Arduino, значит Arduino работает медленнее. Мои поворотные энкодеры пропускают сигналы, это один из симптомов.

Но как только я читаю события на своем ПК с Linux, цикл Arduino снова работает на полной скорости.

Я подозреваю, что это связано с задержкой времени ожидания приема/отправки в коде ядра USB? Потому что я заметил это в USBCore.cpp:

тайм-аут u8 = 250; // Тайм-аут 250 мс при отправке? СДЕЛАТЬ

Во всяком случае, я пытался решить эту проблему следующими способами:

Проверьте конфигурацию и приостановку с помощью:

     if (USBDevice.configured())
      if (!USBDevice.isSuspended())
         ...

Что не сработало.

Я также пытался отслеживать приращения номера кадра:

  // Проверяем, показывает ли USB активность.
  static uint8_t prev_fr_num = UDFNUML;
  static uint8_t num_times_idle = 0;
  uint8_t fr_num = UDFNUML;
  if (fr_num == prev_fr_num )
  {
    if (num_times_idle < 255)
      num_times_idle++;
  }
  else
  {
    num_times_idle = 0;
    prev_fr_num = fr_num;
  }

И затем отправлять, только если num_times_idle меньше порогового значения. Опять же, это не помогло.

Единственный способ сделать это быстро — читать события с помощью Linux, например так:

$ jstest /dev/input/js0

или альтернативно:

$ evtest /dev/input/event5

Как я могу сделать так, чтобы USB HID не замедлял мой циклический код, когда ПК не обращает внимания?

Спасибо!

Брэм

, 👍1

Обсуждение

пожалуйста, уменьшите код до наименьшего кода, который все еще демонстрирует проблему, и добавьте листинг кода к своему вопросу., @jsotola

USB активно опрашивается хостом, и клиент не может инициировать связь. Может буфер заполняется?, @TwoD


1 ответ


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

2

Для тех, кто столкнулся с той же проблемой, вот как я ее решил:

Открыть информацию USB_SendSpace() в интерфейсе HID, отредактировав

/usr/local/arduino-1.8.12/hardware/arduino/avr/libraries/HID/src/HID.cpp

u8 HID_::SendSpace(void)
{
        return USB_SendSpace(pluggedEndpoint);
}

И добавление интерфейса к классу HID_ в:

/usr/local/arduino-1.8.12/hardware/arduino/avr/libraries/HID/src/HID.h

Таким образом, перед вызовом HID().SendReport() вы можете проверить доступное место в буфере отправки, вызвав метод HID().SendSpace().

Если места нет, просто пропустите вызовы SendReport(), и цикл Arduino больше не будет замедляться из-за тайм-аутов.

,