Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/103: Рейтинг темы: голосов - 103, средняя оценка - 4.60
2 / 2 / 1
Регистрация: 18.09.2013
Сообщений: 28

Работа с HID (библиотека libusb-1.0)

26.09.2013, 00:36. Показов 19679. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Снова здравствуйте!

Есть такое устройство:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Bus 003 Device 009: ID 04d9:8010 Holtek Semiconductor, Inc. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x04d9 Holtek Semiconductor, Inc.
  idProduct          0x8010 
  bcdDevice            1.00
  iManufacturer           0 
  iProduct                2 Scale
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      53
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               8
Device Status:     0x0000
  (Bus Powered)
Пытаюсь прочитать с него данные (пока хотя какие-то):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
int r, i;
int transferred;
unsigned char answer[ PACKET_INT_LEN ];
 
libusb_init( NULL );
libusb_device_handle devh = libusb_open_device_with_vid_pid( NULL, VENDOR, PRODUCT);
libusb_detach_kernel_driver( devh, INTERFACE );
libusb_claim_interface( devh, INTERFACE );
 
r = libusb_interrupt_transfer( devh, 0x81, answer, sizeof(answer), &transferred, 8000);
if(!r)
cout << libusb_error_name(r) << endl;
else
cout << transferred << endl;
...
В ответ:
LIBUSB_ERROR_TIMEOUT

Если заместо 8000 передать -1, то чтение будет длиться вечно.

Делал все по образу и подобию этого:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
 
"""
ID 04d9:8010 Holtek Semiconductor, Inc. 
"""
import usb.core
import usb.util as util
from array import array
import sys
from optparse import OptionParser, make_option
import pickle
from struct import unpack
 
dev = None
 
VID = 0x04d9
PID = 0x8010
 
# define HID constants
 
REQ_HID_GET_REPORT   = 0x01
REQ_HID_GET_IDLE     = 0x02
REQ_HID_GET_PROTOCOL = 0x03
 
REQ_HID_SET_REPORT   = 0x09
REQ_HID_SET_IDLE     = 0x0A
REQ_HID_SET_PROTOCOL = 0x0B
 
HID_REPORT_TYPE_INPUT   = 1<<8
HID_REPORT_TYPE_OUTPUT  = 2<<8
HID_REPORT_TYPE_FEATURE = 3<<8
 
def openDev():
    global dev
    dev = usb.core.find(idVendor=VID, idProduct=PID)
    if dev is None:
        raise ValueError('Device not found')
 
    if dev.is_kernel_driver_active(0):
        dev.detach_kernel_driver(0)
    dev.set_configuration() # do reset and set active conf. Must be done before claim.
    util.claim_interface(dev, None)
 
def setReport(reportId, data):
    r = dev.ctrl_transfer(
        util.build_request_type(util.CTRL_OUT, util.CTRL_TYPE_CLASS, util.CTRL_RECIPIENT_INTERFACE), # bmRequestType,
        REQ_HID_SET_REPORT,
        HID_REPORT_TYPE_OUTPUT | reportId,
        0,                 # feature_interface_num
        data,              # data
        3000               # timeout (1000 was too small for C_FREE)
    )
    print >> (HID_REPORT_TYPE_OUTPUT)
    return r
 
def read():
    openDev()
    try:
        dev.read(0x81,64) #flush 
    except usb.core.USBError:
        pass
     
    setReport(9, array('B',(0x10,0,0,0,0,0,0,0)))
 
    # Every user can have upto 12 variables
    # and additional 8*64 for user data
    r = []
    for i in xrange(120+8):
        x = dev.read(0x81,64)
        if not x:
            print >> sys.stderr, "Read failed"
            exit(1)
        if x[0]==0xff and (i<120):
            print >> sys.stderr,"Invalid data",x
            exit(1)
        r.append(x)    
 
    # Each variable can have upto 32 values
    frmt = "!" + "H"*32
    s = []
    for i in xrange(120) :
        x = unpack(frmt, r[i])
         
        # Variables 5 .. 10 are not available on my scale
        if i>5 and i<10:
            err = [item for item in x if item!=0]
        else:
            err = [item for item in x if item==0xffff]
        if len(err):
            print >> sys.stderr, "INVALID:", err
            exit(1)
 
        s.append(x)
    return s
 
def printUser(s, user):
    # Transpose from 12x32 to 32x12 and format
 
    j = 12*user
    for i in xrange(32):
        x = s[j+5][i] # date
        if not x:
           break
        print "{:d}-{:02d}-{:02d}T07:00:00 {:.1f} {:.1f} {:.1f} {:.1f} {:.1f} {:d} {:d}".format(
           1920+(x>>9), x>>5&0xf, x&0x1f,
           s[j+0][i]/10., s[j+1][i]/10., s[j+2][i]/10., s[j+3][i]/10., s[j+4][i]/10., s[j+10][i], s[j+11][i])
 
def main():
 
    option_list = [
        make_option("-c", "--cached", action="store_true", dest="cached"),
        #make_option("-w", "--write",action="store",      dest="output_file"),
        make_option('-u', '--user', action='store',      dest='user'),
    ]
 
    parser = OptionParser(option_list=option_list, usage='Usage: %prog [options]')
    options, args = parser.parse_args()
 
    if options.cached:
        with open("dump.pickle") as f: s = pickle.load(f)
    else:
        s = read()
        with open("dump.pickle","w") as f: pickle.dump(s,f)
 
    user = 0
    if options.user:
        user=int(options.user)-1
 
    printUser(s, user)
 
 
if __name__ == '__main__':
    main()
К сожалению, PyUSB отличается от libusb, и у меня не получается понять, в чем тут дело и почему это работоспособно.

Прошу помощи! Уже 3 дня ломаю голову над всем этим... Заранее спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.09.2013, 00:36
Ответы с готовыми решениями:

Raspberry Pi. Доступ к USB HID через libusb
Все привет. Есть устройство работающее как USB HID.Но не могу написать программу считывания данных с нее. Есть код, могу выложить сюда, он...

библиотека LibUSB
Подскажите, как правильно использовать библиотеку LibUSB совместно с C++ Builder? Возможно не там искал, но смог найти только пример...

Библиотека libusb и C++
Имеется несколько устройств libusb устройств типа HackRF One. Они одинаковые, поэтому, и классы для них одинаковые - несколько экземпляров...

1
2 / 2 / 1
Регистрация: 18.09.2013
Сообщений: 28
29.09.2013, 01:00  [ТС]
Работа завершена успешно. Возможно, это кому-нибудь когда-нибудь будет нужно, так что выкладываю всю информацию:

1. Устройство - весы Beurer BG64.
2. ОС: Windows (libusbx), Linux (libusb-1.0).
3. Написал 2 программы:
1ая считывает данные в бинарном формате и записывает их в файл;
2ая парсит файл и печатает результат.
Написаны были на Qt, но я переписал их на STL.

Чтение данных с устройства:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <libusb.h>
#include <fstream>
 
using namespace std;
 
#define VENDOR_ID 0x4d9
#define PRODUCT_ID 0x8010
 
int main() {
    unsigned char data[] = {0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // Контрольная передача
    unsigned char input[8]={0}; // Входные данные (размер может быть любым, хоть по 128, хоть по 256, кому что удобно парсить...)
    int len=0; // Размер полученных данных
    int count = 0, bytes=0; // Счетчик пакета
    libusb_init(); // Инициализация контекста (можно передать NULL, так как в данном случае используется только 1 контекст
    ofstream file("output.raw", ios::out | ios::binary);
 
    // Открываем устройство по vid и pid
    libusb_device_handle *dev = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID);
 
    if(dev==NULL) {
        cout << "Error: Device not found." << endl;
        system("pause");
        return -1; }
 
    // Отбираем контроль у драйвера
#ifdef __linux__
    if(libusb_attach_kernel_driver(dev, 0))
       cout << "Driver: " <<  libusb_detach_kernel_driver(dev, 0) << endl;
#endif
    // Конфигурируем устройство - в нашем случае нужна именно "1"
    cout << "Conf: " <<  libusb_set_configuration(dev, 1) << endl;
 
    // Выбираем интерфейс. У нашего устройства он 1, так что его порядковый номер "0"
    cout << "Interface: " <<  libusb_claim_interface(dev, 0) << endl;
    // Посылаем контрольную передачу
    libusb_control_transfer(dev, // Указатель на устройство
                            LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, // Тип запроса
                            0x09, // Запрос (или куда его отправлять
                            0x300, // Значение (специфично для каждого устройства, я полагаю)
                            0, // Индекс
                            data, // Сам запрос, который был объявлен и определен в начале функции
                            sizeof(data), // Количество байт (специфично для каждого устройства)
                            3000 // время ожидание реакции (можно и 1000=1сек, но я подстраховался)
                            );
 
    // Читаем, пока libusb_interrupt_transfer = 0, то есть SUCCES
    while(!libusb_interrupt_transfer(dev, 0x81, input, sizeof(input),&len, 1000)) {
        cout << count++ << ": Len = " << len << endl;
        bytes += len;
        file.write((const char*)&input, len);
    }
    cout << "Totel " << bytes << " bytes are transferred. " << endl;
    libusb_release_interface(dev, 0); // Освобождаем интерфейс (важно! иначе потом не сможете работать с устройством)
#ifdef __linux__    
    libusb_attach_kernel_driver(dev, 1); // Возвращаем управление драйверу
#endif
    libusb_close(dev); // Закрываем устройство
    libusb_exit(NULL); // Закрываем контекст
    file.close();
#ifdef WIN32
    system("pause");
#endif
    return 0;
}
На выходе получаем бинарный файл output.raw, который можно скормить этой программе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <fstream>
#include <vector>
 
#ifdef WIN32
    #include <windows.h>
    #include <winsock.h>
    #include <winsock2.h>
#else
    #include <netinet/in.h>
#endif
typedef unsigned short UShort;
using namespace std;
 
int main()
{
    vector<vector <UShort> > DATA; // Структура данных
 
    ifstream file("output.raw", ios::in | ios::binary); // Входные данные
    UShort data[32]={0}; // Читаем массив из 32 элементов
 
    for(int i=0;i<120; i++) {
        vector<UShort> x; // Вектор
        file.read((char*)data, sizeof(data)); // Читаем массив
        for(int j=0; j<32; x.push_back(ntohs(data[j++]))); // Засовываем все в вектор и меняем порядок байт с network в host
        DATA.push_back(x); // Добавляем в вектор
    }
 
    // 10 пользователей, у каждого до 32 измерений, которые лежат в 12 переменных (в BG64 некоторые отсутствуют)
    for(int user=0;user<10;user++) {
        cout<< "User " << user << ": " << endl;
        for(int i=0;i<32;i++) {
            unsigned short date = DATA.at(user*12+5).at(i); // Дата
            if(date==0) // Если дата пуста, но измерение не проводилось
                break;
            cout << 1920 + (date>>9) << "."
                << ((date>>5) & 0xf) << "."
                << (date & 0x1f) << ": "
                << DATA.at(user*12+0).at(i)/10. << " "
                << DATA.at(user*12+1).at(i)/10. << " "
                << DATA.at(user*12+2).at(i)/10. << " "
                << DATA.at(user*12+3).at(i)/10. << " "
                << DATA.at(user*12+4).at(i)/10. << " "
                << DATA.at(user*12+10).at(i) << " "
                << DATA.at(user*12+11).at(i) << endl;
        }
        cout << endl;
    }
 
    file.close();
#ifdef WIN32
    system("pause");
#endif
    return 0;
}
Объединять не стал, так как потом все равно буду писать класс для 3х устройств на Qt. Кому надо, можете сделать это самостоятельно, думаю, это не сложно!

Выражаю благодарность raxp за помощь и подсказки.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.09.2013, 01:00
Помогаю со студенческими работами здесь

Проблема с циклом While, управление мишью Libusb Linux while C, libusb, Minaev, usb control
друзья! Есть проблема с циклом While, задача: Считывать нажатие средней (колесо), левой и правой кнопок мыши и выводить на экран факты...

Приложение или библиотека C:\WINDOWS\system32\HID.DLL не является образом программы для Windows NT
Прошу помочь в решении следующего вопроса: У меня Windows XP. Во время работы компьютера отключили свет и после этого при попытке...

USB-HID библиотека с st.com STM32f105 "Устройство USB не .."
Товарищи. Взял USB библиотеку с st.com (On-The-Go host omd divice library), для STM32F105 connectivity line. Запускаю и &quot;Устройство...

Работа с hid устройством блокирует интерфейс
Доброй ночи! подключено hid устройство, оно выполняет некоторые действия и когда их запускаешь, то блокируется сам интерфейс. А мне...

Работа c USB HID в dll-библиотеке
У меня есть приложение , которое использует Jedi компонент HID . Всё работало хорошо, пока я не решил сделать dll библиотеку с тем же...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru