2016-05-18 31 views
0

我最近从中国购买了二维条码扫描仪模块。根据他们的数据表,当我打开记事本时,它可以很好地扫描条形码。我所需要做的就是尝试使用libusb并读取我的c代码上的条形码。我使用Intel爱迪生与配置为USB主机的Adrunio breakout板。HID设备无法获得实际价值

我已经安装了libusb-1.0.20,不幸的是我无法安装libusb-1.0.20-devel。请注意我没有在这里使用libusbx和libusbx-devel。

因为它是bardcode扫描仪设备,它应该被检测为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 

而我的C代码:

#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 bytesbLength 18它给了我错误,当我尝试与长度为8,16,18。所以我改为24.我的实际条码(1D)数据大小为12bytes。

这是代码上的错误,或者我需要添加更多的核心来读取实际的bardcode。

+0

真的所有字节都是零吗?通常8个字节中的1或2个应该有一个值!= 0,其余所有的应该是0,因为这就是HID的工作方式。 – dryman

+0

并非所有的第一个和第三个字节都有一些值 – 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上不工作的东西:你安装了一个后端驱动器R吗? Windows不会在不更改驱动程序的情况下放弃HID键盘和鼠标。 – dryman

+0

我正在尝试它..它是libusb-win32还是WinUSB?是否有任何特定的链接可以帮助我 – kar

+0

既然你使用libusb 1,你可以选择你自己喜欢哪一个。 libusb-win32是afaik开源,但不再维护,WinUSB是专有的,但由Microsoft维护。创建和/或安装libusb驱动程序的简单方法是Zadig。 Zadig或多或少地自动完成整个过程。 – dryman