PyUSB: reading from a USB device

后端 未结 5 1520
攒了一身酷
攒了一身酷 2021-01-22 10:36

This is an updated and shortened question.

Communicating with a USB-device should be easy via PyUSB. So, I\'m trying to read from a USB-device (oscilloscope) using PyUSB

5条回答
  •  猫巷女王i
    2021-01-22 11:11

    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. 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.

    Code:

    ### 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
    

    Result: (using gnuplot)

提交回复
热议问题