Python PyUsb USB 条码扫描器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14575403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:52:28  来源:igfitidea点击:

PyUsb USB Barcode Scanner

pythonubuntupyusb

提问by Michael

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 (http://gitorious.org/other/metro-usb) 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.

我正在尝试在 Ubuntu 中使用 Honeywell USB 3310g 扫描仪从条形码或二维码输出字符串。我有 libusb 和一个名为 Metro-usb ( http://gitorious.org/other/metro-usb)的库,它们使我的扫描仪能够工作。如果我打开 gedit 并扫描,我成功地获得了二维码数据!我需要能够以务实的方式构建它并将数据发送到 Web 服务。

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:

我已经下载并安装了 pyusb,这似乎是我研究中最好的解决方案。我有一个基于我在网上找到的东西的脚本,它等待扫描并成功地给我一个扫描结果。但是,我不确定如何读取数据。我得到了一系列没有任何意义的数据。我也不熟悉 USB 编程或 Python。任何人都可以指导我从 USB 条形码扫描中简单地获取数据字符串的最佳方法吗?我很可能会弄清楚其余的。此外,我收到一个错误,当我尝试 set_configuration 时,我总是必须注释掉才能运行程序。我总是收到一条错误消息,说 Resource is Busy...不确定这是否与它有关...我已经从网络上获取了这个脚本,以及来自我的 lsusb 命令的产品 ID 和供应商 ID。

Waiting to read...

When scanned:

扫描时:

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 <module>
  print lecture_code_barre()
File "reader.py", line 76, in lecture_code_barre
lecture+=NO_SCAN_CODE[data[n+2]]
KeyError: 11

Here is the py script:

这是py脚本:

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) < 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()

Output from device with looping:

带有循环的设备输出:

....
print device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
...

parallels@ubuntu:~/Documents/pyusb$ sudo python scan.py 
<usb.core.Device object at 0x7fa5f34df610>
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])

采纳答案by Pashka

Grab a Quick Start Guide, scan "USB Serial"-mode barcode, then "Save" barcode to make this setting permanent. Now your 3310g is in serail emulation mode, note new /dev/ttyACM0 or /dev/ttyUSB0 device. Read serial port with simple file operations from python:

获取快速入门指南,扫描“USB 串行”模式条码,然后“保存”条码以使此设置永久化。现在您的 3310g 处于串行仿真模式,注意新的 /dev/ttyACM0 或 /dev/ttyUSB0 设备。从python中通过简单的文件操作读取串口:

f = open('/dev/ttyACM0')
print f.read(13)

回答by Alex L

The error you're receiving is from this line:

您收到的错误来自这一行:

lecture+=NO_SCAN_CODE[data[n+2]]

and data[n+2] = 11, which equates to doing the following

data[n+2] = 11,这相当于执行以下操作

NO_SCAN_CODE[11]

NO_SCAN_CODEis a dictionary that only contains values for the keys [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40], not 11.

NO_SCAN_CODE是一个只包含键值的字典[30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],不包含11.

The fact that you're getting this error means that you've received a usb.core.USBError, and len(data) >= DATA_SIZE.

您收到此错误的事实意味着您收到了usb.core.USBError, 和len(data) >= DATA_SIZE



If I was debugging this, I'd add a whole lot more print statements. I suggest trying something simple like this initially, then adding more logic when you figure out what the device is returning:

如果我正在调试这个,我会添加更多的打印语句。我建议最初尝试像这样简单的事情,然后在确定设备返回的内容时添加更多逻辑:

# Initialise variables
VENDOR_ID = 0x0c2e
PRODUCT_ID = 0x0b61

# Set up device
device = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
print device

# Do more setup things here
# detach_kernel_driver and set_configuration ?
# Perhaps try these in combination with reading the usb.core documentation, and see what happens?

# Loop 10 times (to start with - try more later?)
for i in range(10):
    # Don't catch any errors, just print what the device is returning
    print device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)