Подключение Vive Tracker к Arduino Nano/Mini через USB Host-shield 2.0

ARPavel
Offline
Зарегистрирован: 15.01.2018

Доброе утро!)

Возникла необходимость подключиться к Vive трекеру с помощью Arduino Pro-mini + UsbHost module.

Тестовый код отлично отлично работает на Arduino Due (т.к. на борту платы имеется встроенный usb-host).

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

связке: Arduino Pro-mini(плата) + UsbHost module(железо)+ USB_Host_Shield_2.0(софт) не хочет.

 

Я прошелся по логу ошибок и выяснил, что для успешного запуска понадобится лишь переписать ViveTrackerController.h из старой библиотеки и изменить пару переменных в тестовом проекте. 

 

Копаю ViveTrackerController.h, постепенно исчезает ошибка за ошибкой, и надеюсь получится за пару недель допилить.

И всеже прошу вашей поддержки и помощи с кодом. Для моего уровня это не так легко как хотелось бы (не имел опыта работы с usb интерфейсом), и если кому-либо это задача на 15 минут буду очень благодарен за помощь!)

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Скопируйте сюда лог ошибок компилятора. А то у вас какой то пустой вопрос - просто просьба сделать, только "тапками закидают".

ARPavel
Offline
Зарегистрирован: 15.01.2018


In file included from C:\Users\RadugaDi\AppData\Local\Temp\arduino_modified_sketch_685237\ViveTracker.ino:8:0:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:40: error: 'HID_PROTOCOL_NONE' was not declared in this scope

 class ViveTrackerBoot : public HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS> {

                                        ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:59: error: 'HID_NONE_SUBCLASS' was not declared in this scope

 class ViveTrackerBoot : public HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS> {

                                                           ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:76: error: wrong number of template arguments (2, should be 1)

 class ViveTrackerBoot : public HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS> {

                                                                            ^

In file included from C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:11:0,

                 from C:\Users\RadugaDi\AppData\Local\Temp\arduino_modified_sketch_685237\ViveTracker.ino:8:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/hidboot.h:201:7: error: provided for 'template<unsigned char BOOT_PROTOCOL> class HIDBoot'

 class HIDBoot : public USBHID //public USBDeviceConfig, public UsbConfigXtracter

       ^

In file included from C:\Users\RadugaDi\AppData\Local\Temp\arduino_modified_sketch_685237\ViveTracker.ino:8:0:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:16: error: 'HID_PROTOCOL_NONE' was not declared in this scope

  using HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS>::HIDBoot;

                ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:35: error: 'HID_NONE_SUBCLASS' was not declared in this scope

  using HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS>::HIDBoot;

                                   ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:52: error: wrong number of template arguments (2, should be 1)

  using HIDBoot<HID_PROTOCOL_NONE, HID_NONE_SUBCLASS>::HIDBoot;

                                                    ^

In file included from C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:11:0,

                 from C:\Users\RadugaDi\AppData\Local\Temp\arduino_modified_sketch_685237\ViveTracker.ino:8:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/hidboot.h:201:7: error: provided for 'template<unsigned char BOOT_PROTOCOL> class HIDBoot'

 class HIDBoot : public USBHID //public USBDeviceConfig, public UsbConfigXtracter

Вот часть ошибок. В основном это разность в количестве аргументов.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

найдите поиском в вашем проекте где определяются константы

HID_PROTOCOL_NONE

HID_NONE_SUBCLASS

типа:    #define HID_PROTOCOL_NONE bla-bla-bla

Вообще это определено в файле hid.h, по какой причине вы его не подключили к своему проекту я не знаю

....
/* HID Interface Class SubClass Codes */
#define HID_NONE_SUBCLASS           0x00
#define HID_BOOT_INTF_SUBCLASS      0x01

/* HID Interface Class Protocol Codes */
#define HID_PROTOCOL_NONE           0x00
#define HID_PROTOCOL_KEYBOARD       0x01
#define HID_PROTOCOL_MOUSE          0x02
....

 

ARPavel
Offline
Зарегистрирован: 15.01.2018

Они есть в старой версии драйверов.

/* HID Interface Class Protocol Codes */
  #define HID_PROTOCOL_NONE 0x00
  #define HID_PROTOCOL_KEYBOARD 0x01
  #define HID_PROTOCOL_MOUSE 0x02

а нет) нашел и в новой, но класс имеет другое имя и переменные тоже немного отличаются:

hid.h (старая) = usbhid.h (новая версия)

HID_PROTOCOL_NONE = USB_HID_PROTOCOL_NONE

ARPavel
Offline
Зарегистрирован: 15.01.2018

Нужные хэдеры подключил и имена переменных поправил. Теперь следующее:

In file included from C:\Users\RadugaDi\Documents\Arduino\ViveTracker2\ViveTracker2.ino:8:0:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:73:19: error: 'virtual uint32_t ViveTrackerBoot::Init(uint32_t, uint32_t, uint32_t)' marked override, but does not override

  virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed) override {

                   ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:81:19: error: conflicting return type specified for 'virtual uint32_t ViveTrackerBoot::Release()'

  virtual uint32_t Release() override {

                   ^

In file included from C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:12:0,

                 from C:\Users\RadugaDi\Documents\Arduino\ViveTracker2\ViveTracker2.ino:8:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/hidboot.h:564:9: error:   overriding 'uint8_t HIDBoot<BOOT_PROTOCOL>::Release() [with unsigned char BOOT_PROTOCOL = 0u; uint8_t = unsigned char]'

 uint8_t HIDBoot<BOOT_PROTOCOL>::Release() {

         ^

In file included from C:\Users\RadugaDi\Documents\Arduino\ViveTracker2\ViveTracker2.ino:8:0:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:89:19: error: conflicting return type specified for 'virtual uint32_t ViveTrackerBoot::Poll()'

  virtual uint32_t Poll() override {

                   ^

In file included from C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:12:0,

                 from C:\Users\RadugaDi\Documents\Arduino\ViveTracker2\ViveTracker2.ino:8:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/hidboot.h:578:9: error:   overriding 'uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() [with unsigned char BOOT_PROTOCOL = 0u; uint8_t = unsigned char]'

 uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {

         ^

In file included from C:\Users\RadugaDi\Documents\Arduino\ViveTracker2\ViveTracker2.ino:8:0:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h: In constructor 'ViveTrackerController::ViveTrackerController(USB*, uint8_t, uint8_t, uint8_t)':

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:110:100: error: invalid initialization of reference of type 'USB&' from expression of type 'USB*'

   : usb(usb), hostTracker(&usb), _hostType(hostType), _chargeEnabled(chargeEnabled), _osType(osType) {}

                                                                                                    ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:110:100: error: no matching function for call to 'ViveTrackerBoot::ViveTrackerBoot(USB**)'

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:110:100: note: candidates are:

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:40: note: ViveTrackerBoot::ViveTrackerBoot(USB*, bool)

  using HIDBoot<USB_HID_PROTOCOL_NONE>::HIDBoot;

                                        ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:40: note:   candidate expects 2 arguments, 1 provided

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:40: note: ViveTrackerBoot::ViveTrackerBoot(USB*)

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:71:40: note:   no known conversion for argument 1 from 'USB**' to 'USB*'

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:7: note: constexpr ViveTrackerBoot::ViveTrackerBoot(const ViveTrackerBoot&)

 class ViveTrackerBoot : public HIDBoot<USB_HID_PROTOCOL_NONE> {

       ^

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:7: note:   no known conversion for argument 1 from 'USB**' to 'const ViveTrackerBoot&'

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:7: note: constexpr ViveTrackerBoot::ViveTrackerBoot(ViveTrackerBoot&&)

C:\Users\RadugaDi\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0/ViveTrackerController.h:69:7: note:   no known conversion for argument 1 from 'USB**' to 'ViveTrackerBoot&&'

exit status 1
Ошибка компиляции для платы Arduino/Genuino Uno.

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

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

ARPavel
Offline
Зарегистрирован: 15.01.2018

Все равно спасибо) Буду копать дальше

P.s: написал автору исходника на reddit. Надеюсь ответит.

ARPavel
Offline
Зарегистрирован: 15.01.2018

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

Пока в тупике...

ARPavel
Offline
Зарегистрирован: 15.01.2018

После пролистывания некоторой литературы таки смог запустить соединение и отправку.

Тема закрыта. Кому понадобится - пользуйтесь на здоровье.

P.s: для работы необходима библиотека USB_Host_Shield_2.0 и железяка

Последовательность запуска:

1. Подключить Vive-трекер к USB-хосту

2. Включть плату

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

#include <usbhid.h>
#include <hiduniversal.h>

#define VIVETRACKER_BUTTON_TRIGGER       (1 << 0)
#define VIVETRACKER_BUTTON_GRIP          (1 << 1)
#define VIVETRACKER_BUTTON_MENU          (1 << 2)
#define VIVETRACKER_BUTTON_SYSTEM        (1 << 3)
#define VIVETRACKER_BUTTON_PADTRIGGERED  (1 << 4)
#define VIVETRACKER_BUTTON_PADTOUCHED    (1 << 5)

#define VIVETRACKER_LPF_DEFAULT          0
#define VIVETRACKER_LPF_184HZ            0
#define VIVETRACKER_LPF_5HZ              1
#define VIVETRACKER_LPF_10HZ             2
#define VIVETRACKER_LPF_20HZ             3


/**
 * \struct Vive Tracker Feature Report 0xB3
 */
struct __attribute__((__packed__)) ViveTrackerFeatureReportB3 {
  uint8_t address = 0xB3;
  uint8_t payloadSize = 4;
  uint8_t hostType;
  uint8_t chargeEnable;
  uint8_t osType;
  uint8_t lpfConfig;
  ViveTrackerFeatureReportB3(uint8_t hostType = 3, uint8_t chargeEnable = 0, uint8_t osType = 0, uint8_t lpfConfig = VIVETRACKER_LPF_DEFAULT)
    : hostType(hostType), chargeEnable(chargeEnable), osType(osType), lpfConfig(lpfConfig) {}
};

/**
 * \struct Vive Tracker Feature Report 0xB4
 */
struct __attribute__((__packed__)) ViveTrackerFeatureReportB4 {
  uint8_t address = 0xB4;
  uint8_t payloadSize = 10;
  uint8_t tagIndex = 0;
  uint8_t buttons;
  int16_t padX;
  int16_t padY;
  uint16_t trigger;
  uint16_t batteryLevel;
  ViveTrackerFeatureReportB4(uint8_t buttons = 0, int16_t padX = 0, int16_t padY = 0, uint16_t trigger = 0, uint16_t batteryLevel = 0)
    : buttons(buttons), padX(padX), padY(padY), trigger(trigger), batteryLevel(batteryLevel) {}
} ;

// Initialize USB Host Controller
uint8_t _hostType = 3;
uint8_t _chargeEnabled = 0;
uint8_t _osType = 0;
bool isConnected = false;

USB usb;
HIDUniversal hostTracker(&usb);

uint32_t _initConnection() {
    return sendUsbReportB3(_hostType, _chargeEnabled, _osType, VIVETRACKER_LPF_DEFAULT);
  }

uint32_t sendUsbReportB3(uint8_t hostType, uint8_t chargeEnabled, uint8_t osType, uint8_t lpfConfig) {
  ViveTrackerFeatureReportB3 report(hostType, chargeEnabled, osType, lpfConfig);
  return hostTracker.SetReport(0, 2, 3, 0, sizeof(ViveTrackerFeatureReportB3), (uint8_t*)&report);

  }

uint32_t setTrackerStatus(uint8_t buttons = 0, int16_t padX = 0, int16_t padY = 0, uint8_t trigger = 0, uint16_t batteryLevel = 0) {
    if (isConnected) {
      Serial.println("Try Send");
      ViveTrackerFeatureReportB4 report(buttons, padX, padY, trigger << 8, batteryLevel);
      return hostTracker.SetReport(0, 2, 3, 0, sizeof(ViveTrackerFeatureReportB4), (uint8_t*)&report);
    }
    return -1;
  }


void setup() {
	Serial.begin(115200);
	Serial.println("Hello! Wait sync...");

  if (usb.Init() == -1)
      Serial.println("Error.");
  else
    isConnected = true;
}


void loop() {

  usb.Task();
  if (_initConnection() == 0)
  {
    uint8_t buttons = VIVETRACKER_BUTTON_GRIP | VIVETRACKER_BUTTON_MENU;
    int16_t padX = 1234;
    int16_t padY = -333;
    uint8_t trigger = 200;
    uint16_t batteryLevel = 0;

    if (setTrackerStatus(buttons, padX, padY, trigger, batteryLevel) != -1)
    {
      Serial.println("Ok");
    }
    else
    {
      Serial.println("Fail");
    }
  }

	delay(10);
}