title: PyUsb USB Barcode Scanner
body: <p>I'm trying to output a string from a barcode or qrcode using a Honeywell USB 3310g scanner in Ubuntu. I have libusb and a library called metro-usb (<a href="http://gitorious.org/other/metro-usb" rel="nofollow">http://gitorious.org/other/metro-usb</a>) which are enabling my scanner to work. If i open gedit and scan, I successfully get the qrcode data fine! I need to be able to build this pragmatically and send the data to a web service.</p>
  
  <p>I've downloaded and instally pyusb and this seems to be the best solution best on my research. I have a script based on things i've found on the web that waits for the scan and successfully gives me a result on the scan even. however, I am unsure how to read the data. I get an array of data that doesn't really make any sense. I'm not familiar with USB programming or Python either. Can anyone direct me to the best way to simply get the string of data from the USB barcode scan? I can most-likely figure out the rest. Also, I am getting an error that I always have to comment out to get the program to run when I try to set_configuration. I always get a Error saying Resource is Busy...not sure if this has anything to do with it..I've gotten this script off the web, and the Product ID and Vendor ID from my lsusb command. When i run this with the set_configuration commented out, I get:</p>
  
  <pre><code>Waiting to read...
  </code></pre>
  
  <p>When scanned:</p>
  
  <pre><code>0x0 0x0 0xb 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x17 0x0 0x0 0x0 0x0 0x0
  Traceback (most recent call last):
    File "reader.py", line 81, in &lt;module&gt;
    print lecture_code_barre()
  File "reader.py", line 76, in lecture_code_barre
  lecture+=NO_SCAN_CODE[data[n+2]]
  KeyError: 11
  </code></pre>
  
  <p>Here is the py script:</p>
  
  <pre><code>import sys
  import usb.core
  import usb.util
  
  def lecture_code_barre():
  VENDOR_ID = 0x0c2e
  PRODUCT_ID = 0x0b61
  #VENDOR_ID = 0x04b4
  #PRODUCT_ID = 0x0100
  DATA_SIZE = 16 # 224
  NO_SCAN_CODE = {0x1E:'1', 0x1F:'2', 0x20:'3', 0x21:'4', 0x22:'5', 0x23:'6', 0x24:'7'
      , 0x25:'8', 0x26:'9', 0x27:'0', 0x28:''} # 28=enter
  
  device = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
  
  if device is None:
      sys.exit("Could not find Id System Barcode Reader.")
  
  if device.is_kernel_driver_active(0):   # On détache le périphérique du kernel, plus d'envoi sur stdin
      try:
          device.detach_kernel_driver(0)
      except usb.core.USBError as e:
          sys.exit("Could not detatch kernel driver: %s" % str(e))
  
  #try:
  #    device.set_configuration()
  #    device.reset()
  #except usb.core.USBError as e:
  #    sys.exit("Could not set configuration: %s" % str(e))
  
  endpoint = device[0][(0,0)][0]
  data = []
  lu = False
  print "Waiting to read..."
  lecture=''
  
  while 1:
      try:
          data += device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
  
          if not lu:
              print "Waiting to read..."
          lu = True
  
      except usb.core.USBError as e:
          if e.args == (110,'Operation timed out') and lu:
              if len(data) &lt; DATA_SIZE:
                  print "Lecture incorrecte, recommencez. (%d bytes)" % len(data)
                  print "Data: %s" % ''.join(map(hex, data))
                  data = []
                  lu = False
                  continue
              else:
                  for n in range(0,len(data),16):
                      print ' '.join(map(hex,data[n:n+16]))
                      lecture+=NO_SCAN_CODE[data[n+2]]
                  break   # Code lu
  return lecture
  
  if __name__ == '__main__':
  print lecture_code_barre()
  </code></pre>
  
  <p>Output from device with looping:</p>
  
  <pre><code>....
  print device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
  ...
  
  parallels@ubuntu:~/Documents/pyusb$ sudo python scan.py 
  &lt;usb.core.Device object at 0x7fa5f34df610&gt;
  array('B', [0, 0, 38, 0, 0, 0, 0, 0])
  array('B', [2, 0, 0, 0, 0, 0, 0, 0])
  array('B', [2, 0, 11, 0, 0, 0, 0, 0])
  array('B', [2, 0, 22, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 81, 0, 0, 0, 0, 0])
  array('B', [2, 0, 0, 0, 0, 0, 0, 0])
  array('B', [2, 0, 24, 0, 0, 0, 0, 0])
  array('B', [2, 0, 14, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 81, 0, 0, 0, 0, 0])
  array('B', [0, 0, 11, 0, 0, 0, 0, 0])
  array('B', [0, 0, 23, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 23, 0, 0, 0, 0, 0])
  array('B', [0, 0, 19, 0, 0, 0, 0, 0])
  array('B', [2, 0, 0, 0, 0, 0, 0, 0])
  array('B', [2, 0, 51, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 56, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 56, 0, 0, 0, 0, 0])
  array('B', [0, 0, 26, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 26, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 26, 0, 0, 0, 0, 0])
  array('B', [0, 0, 55, 0, 0, 0, 0, 0])
  array('B', [0, 0, 5, 0, 0, 0, 0, 0])
  array('B', [0, 0, 21, 0, 0, 0, 0, 0])
  array('B', [0, 0, 18, 0, 0, 0, 0, 0])
  array('B', [0, 0, 26, 0, 0, 0, 0, 0])
  array('B', [0, 0, 17, 0, 0, 0, 0, 0])
  array('B', [0, 0, 5, 0, 0, 0, 0, 0])
  array('B', [0, 0, 18, 0, 0, 0, 0, 0])
  array('B', [0, 0, 0, 0, 0, 0, 0, 0])
  array('B', [0, 0, 18, 0, 0, 0, 0, 0])
  array('B', [0, 0, 14, 0, 0, 0, 0, 0])
  array('B', [0, 0, 55, 0, 0, 0, 0, 0])
  array('B', [0, 0, 17, 0, 0, 0, 0, 0])
  array('B', [0, 0, 8, 0, 0, 0, 0, 0])
  array('B', [0, 0, 23, 0, 0, 0, 0, 0])
  array('B', [0, 0, 81, 0, 0, 0, 0, 0])
  array('B', [0, 0, 22, 0, 0, 0, 0, 0])
  array('B', [0, 0, 8, 0, 0, 0, 0, 0])
  array('B', [0, 0, 21, 0, 0, 0, 0, 0])
  array('B', [0, 0, 25, 0, 0, 0, 0, 0])
  array('B', [0, 0, 12, 0, 0, 0, 0, 0])
  array('B', [0, 0, 6, 0, 0, 0, 0, 0])
  array('B', [0, 0, 8, 0, 0, 0, 0, 0])
  </code></pre>