2016-05-18 7 views
0

Недавно я купил модуль сканера штрих-кода 2D из Китая. В соответствии с их спецификацией, он работал с точными штрих-кодами сканирования, когда я открывал блокнот. Все, что мне нужно сделать, это попробовать использовать libusb и прочитать штрих-код на моем c-коде. Я использую Intel edison с платой Adrunio, которая настроена как хост usb.Устройство HID не может получить фактическое значение

У меня установлен libusb-1.0.20 и, к сожалению, я не смог установить libusb-1.0.20-devel. Обратите внимание: я не использую libusbx и libusbx-devel здесь.

Как и устройство сканера штрих-кода, предполагается, что он обнаружен как клавиатура HID. Да, это было так.

Bus 001 Device 003: ID 1eab:8203 
Device Descriptor: 
    bLength    18 
    bDescriptorType   1 
    bcdUSB    1.10 
    bDeviceClass   0 (Defined at Interface level) 
    bDeviceSubClass   0 
    bDeviceProtocol   0 
    bMaxPacketSize0  64 
    idVendor   0x1eab 
    idProduct   0x8203 
    bcdDevice   1.00 
    iManufacturer   1 NewLand 
    iProduct    2 HidKeyBoard 
    iSerial     0 
    bNumConfigurations  1 
    Configuration Descriptor: 
    bLength     9 
    bDescriptorType   2 
    wTotalLength   34 
    bNumInterfaces   1 
    bConfigurationValue  1 
    iConfiguration   0 
    bmAttributes   0x80 
     (Bus Powered) 
    MaxPower    200mA 
    Interface Descriptor: 
     bLength     9 
     bDescriptorType   4 
     bInterfaceNumber  0 
     bAlternateSetting  0 
     bNumEndpoints   1 
     bInterfaceClass   3 Human Interface Device 
     bInterfaceSubClass  1 Boot Interface Subclass 
     bInterfaceProtocol  1 Keyboard 
     iInterface    0 
     HID Device Descriptor: 
      bLength     9 
      bDescriptorType  33 
      bcdHID    1.10 
      bCountryCode   0 Not supported 
      bNumDescriptors   1 
      bDescriptorType  34 Report 
      wDescriptorLength  63 
     Report Descriptors: 
      ** UNAVAILABLE ** 
     Endpoint Descriptor: 
     bLength     7 
     bDescriptorType   5 
     bEndpointAddress  0x84 EP 4 IN 
     bmAttributes   3 
      Transfer Type   Interrupt 
      Synch Type    None 
      Usage Type    Data 
     wMaxPacketSize  0x0008 1x 8 bytes 
     bInterval    1 
Device Status:  0x0001 
    Self Powered 

И мой с код:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
//gcc -o usbtest usbtest.c -lusb-1.0 
//libusbx-devel, libusbx 
#include <libusb-1.0/libusb.h> 
void print_devices(libusb_device *dev) 
{ 
    struct libusb_device_descriptor desc; 
    struct libusb_config_descriptor *config; 
    const struct libusb_interface *inter; 
    const struct libusb_interface_descriptor *interdesc; 
    const struct libusb_endpoint_descriptor *endpointdesc; 

int ret; 
int i,j,k; 

ret = libusb_get_device_descriptor(dev, & desc); 
if(ret < 0) 
{ 
    fprintf(stderr, "error in getting device descriptor\n"); 
    return; 
} 

printf("Number of possible configs is %d\n",desc.bNumConfigurations); 
printf("Vendor ID : 0x%x\n", desc.idVendor); 
printf("Product ID : 0x%x\n", desc.idProduct); 

libusb_get_config_descriptor(dev, 0, &config); 

printf("Interface %d\n", config->bNumInterfaces); 

for(i=0; i < config->bNumInterfaces; i++) 
{ 
    inter = &config->interface[i]; 
    printf("Number of alternate settings : %d\n", inter->num_altsetting); 
    for(j=0; j < inter->num_altsetting; j++) 
    { 
     interdesc = &inter->altsetting[j]; 
     printf(" Interface number : %d, ", interdesc->bInterfaceNumber); 
     printf(" Num of endpoints : %d\n", interdesc->bNumEndpoints); 
     for(k=0; k < interdesc->bNumEndpoints; k++) 
     { 
      endpointdesc = &interdesc->endpoint[k]; 
      printf("  Desc type : %d ",endpointdesc->bDescriptorType); 
      printf("  EP Addr: %d\n", endpointdesc->bEndpointAddress); 
     } 
    } 
} 
printf("\n\n"); 
libusb_free_config_descriptor(config); 
} 


int main(int argc, char *argv[]) 
{ 
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices 
    libusb_context *context = NULL; //a libusb session 
    libusb_device_handle *dev_handle; //a device handle 

size_t list; 
size_t iter; 
int retVal; 
int kernelDriverDetached  = 0; /* Set to 1 if kernel driver detached */ 

retVal = libusb_init(&context); 
if(retVal < 0) 
{ 
    perror("libusb_init"); 
    exit(1); 
} 

libusb_set_debug(context, 3); //set verbosity level to 3, as suggested in the documentation 

list = libusb_get_device_list(context, &devs); 
if(list < 0){ 
    fprintf(stderr, "Error in getting device list\n"); 
    libusb_free_device_list(devs, 1); 
    libusb_exit(context); 
    exit(1); 
} 

printf("There are %d devices found\n",list); 

for(iter = 0; iter < list; iter++) 
{ 
    /* print devices specs */ 
    print_devices(devs[iter]); 
} 

dev_handle = libusb_open_device_with_vid_pid(context, 0x1eab, 0x8203/*0x1d6b,0x0002*/); //these are vendorID and productID I found for my usb device 
    if(dev_handle == NULL) { 
    fprintf(stderr, "Unable to open device.\n"); 
     return 1; 

} 

/* Check whether a kernel driver is attached to interface #0. If so, we'll 
* need to detach it. 
*/ 
if (libusb_kernel_driver_active(dev_handle, 0)) 
{ 
     retVal = libusb_detach_kernel_driver(dev_handle, 0); 
     if (retVal == 0) 
     { 
      kernelDriverDetached = 1; 
     } 
     else 
     { 
      fprintf(stderr, "Error detaching kernel driver.\n"); 
      return 1; 
     } 
} 

/* Claim interface #0. */ 
retVal = libusb_claim_interface(dev_handle, 0); 
if (retVal != 0) 
{ 
     fprintf(stderr, "Error claiming interface.\n"); 
     return 1; 
} 

printf("Scanner Device Opened\n"); 

    struct libusb_transfer *transfer = libusb_alloc_transfer(0); 
char buf[24]; 
int actualbytes;  
retVal = libusb_interrupt_transfer(dev_handle, /*0x84*/(4 | LIBUSB_ENDPOINT_IN), buf, 24, &actualbytes, 0); 
if(retVal == 0) { 
    printf("Received %d bytes\n",actualbytes); 
} 
else 
{ 
    fprintf(stderr, "Error Receiving message. retVal : %d, Actual : %d\n",retVal,actualbytes); 
} 

for(iter = 0; iter < actualbytes; iter++){ 
    printf("Data[%d] = %d\n",iter,buf[iter]); 
} 

/* Release interface #0. */ 
retVal = libusb_release_interface(dev_handle, 0); 
if (0 != retVal) 
{ 
     fprintf(stderr, "Error releasing interface.\n"); 
} 

/* If we detached a kernel driver from interface #0 earlier, we'll now 
* need to attach it again. */ 
if (kernelDriverDetached) 
{ 
     libusb_attach_kernel_driver(dev_handle, 0); 
} 

/* Shutdown libusb. */ 
libusb_free_device_list(devs, 1); //free the list, unref the devices in it 
libusb_exit(context); 


return 0; 
} 

я мог скомпилировать и запустить код, сканирование, открытие, чтение устройства. Но данные, которые я мог прочитать, равны нулю. Даже если он говорит wMaxPacketSize 0x0008 1x 8 bytes и bLength 18, он дал мне ошибку, когда я пробовал с длиной как 8,16,18. Таким образом, я изменился на 24. Мой фактический размер штрих-кода (1D) составляет 12 байт.

Это что-то не так в коде, или мне нужно добавить больше ядра для чтения реального барда.

+0

Действительно ли все байты равны нулю? Обычно 1 или 2 из 8 байтов должны иметь значение! = 0, где все остальные должны быть равны 0, потому что именно так работает HID. – dryman

+0

не все первые и 3-й байты имеют некоторые значения в нем – kar

+0

Да, как вы уже писали в своем ответе, вы получили только данные HID. Это должно быть так. – dryman

ответ

0

Я понял, что, поскольку он обнаруживает в качестве устройства клавиатуры HID, данные, которые я получил, не будут в формате ASCII (это то, чего я ожидал). Я изменил код в соответствии с https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html

Несмотря на то, что в документе говорится о 16-битовом ключевом коде, я получал правильные данные, только если прочитал 16 байтов. основанный на ключевом коде, я создал таблицу, которая преобразует код ключа HID в ASCII.

Но все равно это не работает на моей машине с Windows, так как говорит, что он не может открыть устройство.

+0

О том, что не работает в Windows: Установили ли вы задний диск? Windows не будет сдавать клавиатуру и мыши HID без изменения драйвера. – dryman

+0

Я пытаюсь для этого .. это libusb-win32 или WinUSB? Есть ли какая-то конкретная ссылка, которая могла бы мне помочь – kar

+0

Поскольку вы используете libusb 1, вы можете сами выбрать, какой из них вы предпочитаете. libusb-win32 является открытым исходным кодом, но не поддерживается больше, а WinUSB является собственностью, но поддерживается Microsoft. Простым способом создания и/или установки драйвера для libusb является Zadig. Zadig автоматизирует более или менее полный процесс. – dryman

 Смежные вопросы

  • Нет связанных вопросов^_^