the*_*ozh 8 python usb libusb pyusb
这是一个更新和缩短的问题。
通过PyUSB与 USB 设备通信应该很容易。因此,我尝试在 Win10 下使用 PyUSB 从 USB 设备(示波器)读取数据。显然,自从找到设备以来,USB 驱动程序 (libusb-win32 v1.2.6.0) 已正确安装,并且我得到了一些响应print(dev)(见下文)。由此我可以看到输出端点地址是0x3,输入端点地址是0x81
根据示波器手册,我应该发送:SDSLSCPI#到设备以将其设置为 SCPI 模式,并且应该得到响应“:SCPION”。然而,当:SDSLSCPI#可再现地发送示波器的监视器时,它会冻结并且会重新启动。
如果我发送,*IDN?我应该得到回复,P1337,1842237,V2.4.0->。但前提是设备已处于 SCPI 模式。显然,事实并非如此,我收到超时错误(见下文)。
那么,我在这里做错了什么?我在PyUSB 教程中缺少哪些信息。我是否使用了错误的 PyUSB 命令/参数,或者是否缺少额外的驱动程序,或者是否与硬件(Win10 或设备硬件)有关?感谢您提供有关如何找出问题所在的提示。
顺便问一下, 中的第二个值是多少dev.read(0x81,7)?要读取的字节数?嗯,通常我不知道设备将发送多少字节。我期望在超时时间内读取一个命令,直到出现换行符或其他终止符。在哪里可以找到有关 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))
Run Code Online (Sandbox Code Playgroud)
输出来自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
Run Code Online (Sandbox Code Playgroud)
错误信息:
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'
Run Code Online (Sandbox Code Playgroud)
更新:
我收到了供应商的回复。他确认示波器(或至少这个特定系列)在发送命令时崩溃:SDSLSCPI#。他将联系开发商,开发商将于下周回来。好吧,到目前为止我似乎还没有机会让它在这个特定的设备和可用的文档上运行:-(。
我想除非有人已经经历过同样的问题,否则没有机会回答这个问题。我对你们所有人(@Alex P.、@Turbo J、@igrinis、@2xB)表示抱歉,他们花时间提出建议来提供帮助。
我的发现:(我希望它们对其他人有用):
:SDSLSCPI#并不是进入 SCPI 模式所必需的(但实际上会导致崩溃/重新启动):CHAN1:SCAL 10v是错误的,它必须是:CH1:SCALe 10v(命令显然不能缩写,尽管在文档中提到:CH1:SCAL 10v也应该有效。):DATA:WAVE:SCREen:CH1?手册中缺少获取数据的基本命令。它对我的工作方式(到目前为止):
以下是我期望供应商/制造商提供的最少代码。但我却浪费了很多时间来调试他们的文档。然而,仍然发生了一些奇怪的事情,例如,似乎只有在您事先询问标头时才能获得数据。但是,这不是原来问题的主题。
代码:
### 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
Run Code Online (Sandbox Code Playgroud)
结果:(使用 gnuplot)
| 归档时间: |
|
| 查看次数: |
35727 次 |
| 最近记录: |