Подключение USB HID в QT
Как подключить самодельное устройство по USB, когда нужна невысокая скорость передачи данных? Можно ли использовать USB как альтернативу COM-порту, где взять удобные для использования функции отправки и приема данных? В этой статье рассмотрен способ подключения микроконтроллера по USB используя свободную библиотеку QT и usbhid.dll
На данный момент существует много информации по подключения своего девайса, мигающего светодиодами. В основе большинства статей рассмотрен способ подключения при помощи библиотеки libusb. Способ проверенный, зарекомендовал себя очень хорошо, но имеет один существенный недостаток: перед тем как подключить свой девайс, необходимо провести инсталляцию фильтра для нового устройства. Мелочь, но неприятно, т.к. обычно предпочитают выпускать программное обеспечение без всяких инасталляторов или вообще "чтобы работало с флешки". В этом случае libusb уже не так хорошо подходит...
Как альтернативу можно использовать другие библиотеки. В основе данной программы - hidapi.dll. Разработчик утверждает, что библиотека кроссплатфоременная, но я не проверял, обычно ограничивался windows сборкой. Чтобы не вдаваться в принцип работы библиотеки USB и вообще сделать посылки максимально удобными для работы, я постарался сделать наиболее высокоуровневые функции USBInit, USBRead, USBWrite. Да. при это теряется часть функционала (например, невозможность ловить сигналы по приходу новых данных, т.е. событию), но для очень многих случаев нужен прием и передача данных read и write.
Теперь немного подробнее о самих функциях и принципе работы. USB устройства имеют VendorID и ProductID (или VID и PID), чтобы можно было определить именно наше устройство. Для теста у себя дома их можно выбрать любыми, но если девайс делается в коммерческих целях, то диапазон надо покупать. В программе USB-hid считывает данные порциями по 256 байт. Чтобы считать данные с устройства, необходимо сначала отправить запрос на считывание функцией Write, затем подождать несколько мсек для формирования ответа и считать.
Теперь комментарии к программе
Вначале создаем экземпляр класса работы с usb hid устройством
hidControl hid;
hid = new hidControl();
Далее проводим инициализацию
if (hid->init(atoi(argv[1]), atoi(argv[2])) < 0)
В качестве аргументов функции инициализации - VID, затем PID, получаем их из аргументов командной строки. Если функция возратила значение меньше 0, то иницилизация устройства не прошла и мы выходим из программы.
Чтобы считать данные с устройства используем функцию read
int cmd = atoi(argv[4]);
hid->buf[1] = cmd;
hid->read();
Перед использованием метода read небходимо заполнить массив данными на отправку запроса (я использую один байт для запроса данных).
Запись осуществляется методом write
strcpy((char*)hid->buf, (char*)argv[4]);
hid->write();
printf("writted data, cmd %s\n", argv[4]);
return 2;
Только передается массив с данными из 255 байт. первый байт в передаче не принимается.
int main(int argc, char *argv[]) { hidControl hid;
hid = new hidControl();
if (argc < 5)
{
printf("usage:\nusb.exe [VID] [PID] -r [CMD]\n");
printf("or\nusb.exe [VID] [PID] -w [CMD]\n");
printf("VID and PID must be in dec format, not hex\n");
return -1;
}
if (hid->init(atoi(argv[1]), atoi(argv[2])) < 0)
return -2;
if (!strcmp(argv[4], "-r"))
{
int cmd = atoi(argv[4]);
hid->buf[1] = cmd;
hid->read();
printf("readed data, cmd %d\n", argv[4]);
printf("%s\n", hid->buf);
return 1;
}
if (!strcmp(argv[4], "-w"))
{
strcpy((char*)hid->buf, (char*)argv[4]);
hid->write();
printf("writted data, cmd %s\n", argv[4]);
return 2;
}
return 0;
}
Это консольное приложение, чтобы считать или записать данные на устройство, необходимо запустить программу с ключами '-r' и '-w' соответственно, но в начале надо задать VID и PID (Windows->Выполнить->cmd.exe)
Исходный код
Иногда могут понадобиться библиотеки для запуска ПО