PyUSB:从USB设备读取 [英] PyUSB: reading from a USB device
问题描述
这是更新和缩短的问题.
This is an updated and shortened question.
通过 PyUSB 与USB设备进行通讯应该很容易.因此,我试图在Win10下使用PyUSB从USB设备(示波器)读取数据.显然,由于找到了设备,因此USB驱动程序(libusb-win32 v1.2.6.0)正确安装了,并且我从print(dev)
得到了一些响应(请参见下文).
由此可见,输出端点地址为0x3
,输入端点地址为0x81
Communicating with a USB-device should be easy via PyUSB. So, I'm trying to read from a USB-device (oscilloscope) using PyUSB under Win10. Apparently, the USB-driver (libusb-win32 v1.2.6.0) is installed correctly since the device is found and I get some response from print(dev)
(see below).
From this I can see that the output endpoint address is 0x3
and the input endpoint address is 0x81
根据示波器手册,我应该发送:SDSLSCPI#
到设备以将其设置为SCPI模式,并应获得响应':SCPION'.
但是,在发送:SDSLSCPI#
时,示波器的监视器可复制地将冻结并重新启动.
According to the Oscilloscope manual, I'm supposed to send :SDSLSCPI#
to the device to set it into SCPI-mode and should get the reponse ':SCPION'.
However, when sending :SDSLSCPI#
the monitor of the oscilloscope reproduceably will freeze and it will restart.
如果我发送*IDN?
,我应该得到响应,P1337,1842237,V2.4.0->
.但仅当设备已经处于SCPI模式时.显然不是,我收到超时错误(请参见下文).
If I send *IDN?
I should get the response ,P1337,1842237,V2.4.0->
. But only if the device is already in SCPI-mode. Apparently, it is not and I get a timeout error (see below).
那么,我在这里做错了什么? 我在 PyUSB教程中缺少什么信息. 我使用的是错误的PyUSB命令/参数,还是因为缺少其他驱动程序,还是与Win10或设备硬件相关的硬件?感谢您提供有关如何找出问题所在的提示.
So, what am I doing wrong here? What information am I missing in the PyUSB tutorial. Am I using the wrong PyUSB commands/parameters or is it about missing additional drivers or is it about the hardware, either Win10 or the device hardware? Thank you for hints on how to find out what's going wrong.
顺便说一句,dev.read(0x81,7)
中的第二个值是多少?要读取的字节数?好吧,通常我不知道设备将发送多少字节.我期望命令在超时时间内读取到换行符或其他终止符为止.在哪里可以找到有关PyUSB的万无一失"的文档,教程和示例?
By the way, what is the second value in dev.read(0x81,7)
? Number of bytes to read? Well, usually I don't know how many bytes the device will send. I was expecting a command to read until a linefeed or some other terminator character within the timeout time. Where can I find "fool-proof" documentation, tutorials and examples about PyUSB?
代码:
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x5345, idProduct=0x1234)
if dev is None:
raise ValueError('Device is not found')
# device is found :-)
print(dev)
dev.set_configuration()
msg = ':SDSLSCPI#'
print("Write:", msg, dev.write(3,msg))
print("Read:", dev.read(0x81,7))
print(dev)
的输出:
Output from print(dev)
:
DEVICE ID 5345:1234 on Bus 000 Address 001 =================
bLength : 0x12 (18 bytes)
bDescriptorType : 0x1 Device
bcdUSB : 0x200 USB 2.0
bDeviceClass : 0x0 Specified at interface
bDeviceSubClass : 0x0
bDeviceProtocol : 0x0
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0x5345
idProduct : 0x1234
bcdDevice : 0x294 Device 2.94
iManufacturer : 0x1 System CPU
iProduct : 0x2 Oscilloscope
iSerialNumber : 0x3 SERIAL
bNumConfigurations : 0x1
CONFIGURATION 1: 500 mA ==================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x2 Configuration
wTotalLength : 0x20 (32 bytes)
bNumInterfaces : 0x1
bConfigurationValue : 0x1
iConfiguration : 0x5 Bulk Data Configuration
bmAttributes : 0xc0 Self Powered
bMaxPower : 0xfa (500 mA)
INTERFACE 0: Physical ==================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x4 Interface
bInterfaceNumber : 0x0
bAlternateSetting : 0x0
bNumEndpoints : 0x2
bInterfaceClass : 0x5 Physical
bInterfaceSubClass : 0x6
bInterfaceProtocol : 0x50
iInterface : 0x4 Bulk Data Interface
ENDPOINT 0x81: Bulk IN ===============================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x81 IN
bmAttributes : 0x2 Bulk
wMaxPacketSize : 0x200 (512 bytes)
bInterval : 0x0
ENDPOINT 0x3: Bulk OUT ===============================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x3 OUT
bmAttributes : 0x2 Bulk
wMaxPacketSize : 0x200 (512 bytes)
bInterval : 0x0
错误消息:
Traceback (most recent call last):
File "Osci.py", line 15, in <module>
print("Read:", dev.read(0x81,7))
File "C:\Users\Test\Programs\Python3.7.4\lib\site-packages\usb\core.py", line 988, in read
self.__get_timeout(timeout))
File "C:\Users\Test\Programs\Python3.7.4\lib\site-packages\usb\backend\libusb0.py", line 542, in bulk_read
timeout)
File "C:\Users\Test\Programs\Python3.7.4\lib\site-packages\usb\backend\libusb0.py", line 627, in __read
timeout
File "C:\Users\Test\Programs\Python3.7.4\lib\site-packages\usb\backend\libusb0.py", line 431, in _check
raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] b'libusb0-dll:err [_usb_reap_async] timeout error\n'
更新:
我从供应商那里得到了答复.并且他确认在发送命令:SDSLSCPI#
时,示波器(或至少是该特定系列)崩溃了.他将与开发商联系,该开发商将在下周返回.好的,到目前为止,我似乎没有机会让它与该特定设备和可用文档一起运行:-(.
I got a reply from the vendor. And he confirms that the oscilloscope (or at least this specific series) crashes when sending the command :SDSLSCPI#
. He will contact the developers which will back next week. OK, it seems so far no chance for me to get it to run with this specific device and the available documentation :-(.
推荐答案
我想除非有人已经遇到了同样的问题,否则 没有机会 . 我为你们所有人(@Alex P.,@ Turbo J,@ igrinis,@ 2xB)花了很多时间提出建议提供帮助而感到抱歉.
I guess there was no chance to answer this question unless somebody already went through the very same problems. I'm sorry for all of you (@Alex P., @Turbo J, @igrinis, @2xB) who took your time to make suggestions to help.
我的发现:(我希望它们对其他人有用)
My findings: (I hope they will be useful to others):
- PyUSB似乎一切正常.
- 供应商提供了过时且错误的文档.我非常希望他们能尽快更新其首页上的文档.
- 发送命令
:SDSLSCPI#
无需进入SCPI模式(但实际上会导致崩溃/重新启动) - 例如:
:CHAN1:SCAL 10v
是错误的,它必须是:CH1:SCALe 10v
(显然不能的命令缩写,尽管在文档中提到:CH1:SCAL 10v
也应该起作用.)
手册中缺少 - 获取数据
:DATA:WAVE:SCREen:CH1?
的基本命令.
- Everything seems to be OK with PyUSB.
- the vendor has provided outdated and wrong documentation. I hope very much that they will soon update the documentation on their homepage.
- Sending the command
:SDSLSCPI#
is not necessary to enter SCPI-mode (but actually leads to a crash/restart) - For example:
:CHAN1:SCAL 10v
is wrong, it has to be:CH1:SCALe 10v
(commands apparenty can't be abbreviated, although mentioned in the documentation that:CH1:SCAL 10v
should also work.) - the essential command to get data
:DATA:WAVE:SCREen:CH1?
was missing in the manual.
(到目前为止)它为我工作的方式:
The way it is working for me (so far):
以下是我期望供应商/制造商提供的最少代码.但是相反,我浪费了很多时间来调试他们的文档. 但是,仍然发生了一些奇怪的事情,例如似乎只有事先请求标头才能获得数据.但是,这不是原始问题的主题.
The following would have been the minimal code I expected from the vendor/manufacturer. But instead I wasted a lot of time debugging their documentation. However, still some strange things are going on, e.g. it seems you get data only if you ask for the header beforehand. But, well, this is not the topic of the original question.
代码:
### read data from a Peaktech 1337 Oscilloscope (OWON)
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x5345, idProduct=0x1234)
if dev is None:
raise ValueError('Device not found')
else:
print(dev)
dev.set_configuration()
def send(cmd):
# address taken from results of print(dev): ENDPOINT 0x3: Bulk OUT
dev.write(3,cmd)
# address taken from results of print(dev): ENDPOINT 0x81: Bulk IN
result = (dev.read(0x81,100000,1000))
return result
def get_id():
return send('*IDN?').tobytes().decode('utf-8')
def get_data(ch):
# first 4 bytes indicate the number of data bytes following
rawdata = send(':DATA:WAVE:SCREen:CH{}?'.format(ch))
data = []
for idx in range(4,len(rawdata),2):
# take 2 bytes and convert them to signed integer using "little-endian"
point = int().from_bytes([rawdata[idx], rawdata[idx+1]],'little',signed=True)
data.append(point/4096) # data as 12 bit
return data
def get_header():
# first 4 bytes indicate the number of data bytes following
header = send(':DATA:WAVE:SCREen:HEAD?')
header = header[4:].tobytes().decode('utf-8')
return header
def save_data(ffname,data):
f = open(ffname,'w')
f.write('\n'.join(map(str, data)))
f.close()
print(get_id())
header = get_header()
data = get_data(1)
save_data('Osci.dat',data)
### end of code
结果 :(使用gnuplot)
Result: (using gnuplot)
这篇关于PyUSB:从USB设备读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!