PyUSB:从USB设备读取 [英] PyUSB: reading from a USB device

查看:771
本文介绍了PyUSB:从USB设备读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是更新和缩短的问题.

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

  1. PyUSB似乎一切正常.
  2. 供应商提供了过时且错误的文档.我非常希望他们能尽快更新其首页上的文档.
  3. 发送命令:SDSLSCPI#无需进入SCPI模式(但实际上会导致崩溃/重新启动)
  4. 例如::CHAN1:SCAL 10v是错误的,它必须是:CH1:SCALe 10v(显然不能的命令缩写,尽管在文档中提到:CH1:SCAL 10v也应该起作用.)
  5. 手册中缺少
  6. 获取数据:DATA:WAVE:SCREen:CH1?的基本命令.
  1. Everything seems to be OK with PyUSB.
  2. the vendor has provided outdated and wrong documentation. I hope very much that they will soon update the documentation on their homepage.
  3. Sending the command :SDSLSCPI# is not necessary to enter SCPI-mode (but actually leads to a crash/restart)
  4. 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.)
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆