2016-05-18 9 views
0

Ich habe vor kurzem ein 2D-Barcode-Scanner-Modul aus China gekauft. Laut ihrem Datenblatt funktionierte es beim Scannen von Barcodes, wenn ich einen Notizblock öffnete. Alles, was ich tun muss, ist libusb zu benutzen und den Barcode auf meinem c-Code zu lesen. Ich benutze Intel Edison mit Adrunio Breakout Board, das als USB-Host konfiguriert ist.HID-Gerät kann nicht den tatsächlichen Wert erhalten

Ich habe libusb-1.0.20 installiert und konnte leider libusb-1.0.20-devel nicht installieren. Bitte beachten Sie, dass ich libusbx und libusbx-devel hier nicht verwende.

Wie es ist Barcodelesegerät, sollte es als HID-Tastatur erkannt werden. Ja, war es.

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 

Und mein c-Code ist:

#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; 
} 

Ich konnte Lage, den Code scannen, öffnen, lesen Sie das Gerät zu kompilieren und auszuführen. Aber die Daten, die ich lesen konnte, sind alle null. Obwohl es wMaxPacketSize 0x0008 1x 8 bytes und bLength 18 sagt gab es mir Fehler, wenn ich mit der Länge als 8,16,18 versuchte. Also änderte ich auf 24. Meine tatsächliche Barcode (1D) Datengröße beträgt 12 Bytes.

Ist es etwas falsch am Code oder sollte ich mehr Kern hinzufügen müssen, um den tatsächlichen bardcode zu lesen.

+0

Sind wirklich alle Bytes null? Normalerweise sollte 1 oder 2 von 8 Bytes einen Wert haben! = 0 wobei alle anderen 0 sein sollen, weil HID so funktioniert. – dryman

+0

nicht alle ersten und dritten Bytes haben einige Werte – kar

+0

Ja, wie Sie bereits in Ihrer Antwort geschrieben haben Sie nur die HID-Daten. Das soll so sein. – dryman

Antwort

0

Ich habe verstanden, dass, da es als ein HID-Tastaturgerät erkennt, die Daten, die ich erhalten habe, nicht im ASCII-Format sein werden (was ich erwartet hatte). Ich habe den Code entsprechend geändert https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html

Obwohl das Dokument 16-Bit-Schlüsselcode sagt, bekam ich nur korrekte Daten, wenn ich 16 Bytes lese. basierend auf dem Schlüsselcode habe ich eine Tabelle erstellt, die den HID-Schlüsselcode in ASCII umwandelt.

Aber immer noch funktioniert das nicht auf meinem Windows-Rechner, da es sagt, dass es das Gerät nicht öffnen kann.

+0

Über die Sache mit nicht funktioniert unter Windows: Haben Sie ein Backend driveR installiert? Windows gibt HID-Tastaturen und -Mäuse nicht aus, ohne den Treiber zu ändern. – dryman

+0

ich versuche es .. ist es libusb-win32 oder WinUSB? Gibt es einen bestimmten Link, der mir helfen könnte? – kar

+0

Da Sie Libusb 1 verwenden, können Sie selbst wählen, welche Sie bevorzugen. libusb-win32 ist afaik opensource aber nicht mehr gepflegt und WinUSB ist proprietär, wird aber von Microsoft gepflegt. Eine einfache Möglichkeit, einen Treiber für libusb zu erstellen und/oder zu installieren, ist Zadig. Zadig automatisiert mehr oder weniger den gesamten Prozess. – dryman

Verwandte Themen