基于python使用USB口控制示波器

示波器:普源MSO7054

电源:艾德克斯IT633A

测试背景:主要是为了抓取MCU控制器的上下电各个GPIO的波形

import time
import serial
import pyvisa

def init_scope(chL):
    scope.write(':TRIGger:EDGE:SOURce CHANnel{0}'.format(chL))  # 设置trigger channel 1,2,3,4依次使用
    scope.write('TRIG:EDGE:LEV 1.1')                            # 设置边沿触发1.1V
    scope.write(':TRIGger:MODE EDGE')                           # 设置触发模式为边沿触发
    scope.write(':TIMebase:MODE MAIN')                          # 设置模式为MAIN就是为YT模式
    scope.write(':TIMebase:MAIN:OFFSet 0')                      # 设置触发起始点为时间0点
    scope.write(':TIMebase:MAIN:SCALe 0.002')                   # 设置屏幕的时间坐标轴每格0.002s


def channel_enable(chL):
    # channel
    if chL == 1:
        scope.write(':CHANnel1:BWLimit 250M')                  # 设置通道1带宽为250M
        scope.write(':CHANnel1:COUPling DC')                   # 设置通道1测试模式为DC
        scope.write(':CHANnel1:DISPlay ON')                    # 打开通道1
        scope.write(':CHANnel2:DISPlay OFF')                   # 关闭通道2
        scope.write(':CHANnel3:DISPlay OFF')                   # 关闭通道3
        scope.write(':CHANnel4:DISPlay OFF')                   # 关闭通道4
        scope.write(':CHANnel1:SCALe 1')                       # 设置纵坐标为1V每格
        scope.write(':CHANnel1:OFFSet -1')                     # 设置起始值为-1V
        scope.write(':CHANnel1:IMPedance OMEG')                # 设置阻抗为1Mohm
        scope.write(':CHANnel1:PROBe 10')                      # 设置探棒比例为1比10
        scope.write(':MEASure:ITEM VPP,CHANnel1')              # 打开通道1的测量VPP
        scope.write(':MEASure:ITEM VMAX,CHANnel1')             # 打开通道1的测量VMAX
        scope.write(':MEASure:ITEM VMIN,CHANnel1')             # 打开通道1的测量VMIN
        scope.write(':MEASure:ITEM FREQuency,CHANnel1')        # 打开通道1的测量FREQuency
        scope.write(':MEASure:ITEM PERiod,CHANnel1')           # 打开通道1的测量PERiod


    elif chL == 2:
        scope.write(':CHANnel2:BWLimit 250M')
        scope.write(':CHANnel2:COUPling DC')
        scope.write(':CHANnel2:DISPlay ON')
        scope.write(':CHANnel1:DISPlay OFF')
        scope.write(':CHANnel3:DISPlay OFF')
        scope.write(':CHANnel4:DISPlay OFF')
        scope.write(':CHANnel2:SCALe 1')
        scope.write(':CHANnel2:OFFSet -1')
        scope.write(':CHANnel2:IMPedance OMEG')
        scope.write(':CHANnel2:PROBe 10')
        scope.write(':MEASure:ITEM VPP,CHANnel2')
        scope.write(':MEASure:ITEM VMAX,CHANnel2')
        scope.write(':MEASure:ITEM VMIN,CHANnel2')
        scope.write(':MEASure:ITEM FREQuency,CHANnel2')
        scope.write(':MEASure:ITEM PERiod,CHANnel2')


    elif chL == 3:
        scope.write(':CHANnel3:BWLimit 250M')
        scope.write(':CHANnel3:COUPling DC')
        scope.write(':CHANnel3:DISPlay ON')
        scope.write(':CHANnel1:DISPlay OFF')
        scope.write(':CHANnel2:DISPlay OFF')
        scope.write(':CHANnel4:DISPlay OFF')
        scope.write(':CHANnel3:SCALe 1')
        scope.write(':CHANnel3:OFFSet -1')
        scope.write(':CHANnel3:IMPedance OMEG')
        scope.write(':CHANnel3:PROBe 10')
        scope.write(':MEASure:ITEM VPP,CHANnel3')
        scope.write(':MEASure:ITEM VMAX,CHANnel3')
        scope.write(':MEASure:ITEM VMIN,CHANnel3')
        scope.write(':MEASure:ITEM FREQuency,CHANnel3')
        scope.write(':MEASure:ITEM PERiod,CHANnel3')


    elif chL == 4:
        scope.write(':CHANnel4:BWLimit 250M')
        scope.write(':CHANnel4:COUPling DC')
        scope.write(':CHANnel4:DISPlay ON')
        scope.write(':CHANnel1:DISPlay OFF')
        scope.write(':CHANnel2:DISPlay OFF')
        scope.write(':CHANnel3:DISPlay OFF')
        scope.write(':CHANnel4:SCALe 1')
        scope.write(':CHANnel4:OFFSet -1')
        scope.write(':CHANnel4:IMPedance OMEG')
        scope.write(':CHANnel4:PROBe 10')
        scope.write(':MEASure:ITEM VPP,CHANnel4')
        scope.write(':MEASure:ITEM VMAX,CHANnel4')
        scope.write(':MEASure:ITEM VMIN,CHANnel4')
        scope.write(':MEASure:ITEM FREQuency,CHANnel4')
        scope.write(':MEASure:ITEM PERiod,CHANnel4')

        return


def power_up_edge():
    for i in range(1, 5):
        channel_enable(i)                                                 # 打开对应的测试通道
        scope.write('TRIG:EDGE:SLOP POS')                                 # 设置触发为上升沿
        init_scope(i)                                                     # 示波器初始化
        time.sleep(3)                                                     # 等待时间3s
        scope.write(':TRIGger:SWEep SINGle')                              # 设置触发为single单次触发
        time.sleep(5)                                                     # 等待时间5s
        ser.write(b'OUTP ON\n')                                           # 起电
        time.sleep(3)                                                     # 等待3s,但是如果上电后3s没有波形,它是抓不到的
        scope.write(':SAVE:IMAGe D:/1-Test/CAN/UP{0}A.png'.format(i))     # 保存抓取到的图形,保持到对应的地址下
        time.sleep(5)                                                     # 等待5s
        scope.write(':MEASure:CLEar ALL')                                 # 清除所有测量值
        ser.write(b'OUTP OFF\n')                                          # 关闭电源


def power_down_edge():
    for i in range(1, 5):
        channel_enable(i)
        scope.write('TRIG:EDGE:SLOP NEG')                                # 设置触发为下降沿
        init_scope(i)
        ser.write(b'OUTP ON\n')
        time.sleep(3)
        scope.write(':TRIGger:SWEep NORM')                               # 设置触发为normal多次触发
        scope.write('TRIG:EDGE:LEV 0.15')                                # 设置边沿触发0.15V
        scope.write(':TIMebase:MAIN:OFFSet 0.04')                        # 设置初始位置为0.04s
        scope.write(':TIMebase:MAIN:SCALe 0.04')                         # 设置每格为0.04s
        time.sleep(3)
        ser.write(b'OUTP OFF\n')
        time.sleep(5)
        scope.write(':SAVE:IMAGe D:/1-Test/CAN/DOWN{0}A.png'.format(i))
        time.sleep(8)
        scope.write(':MEASure:CLEar ALL')


def power_hold_edge():
    for i in range(1, 5):
        time.sleep(3)
        ser.write(b'OUTP ON\n')
        channel_enable(i)
        init_scope(i)
        scope.write('TRIG:EDGE:SLOP POS')
        scope.write(':TIMebase:MAIN:SCALe 0.0001')
        time.sleep(2)
        scope.write(':TRIGger:SWEep AUTO')                               # 设置测试模式为AUTO实时模式
        time.sleep(3)
        scope.write(':SAVE:IMAGe D:/1-Test/CAN/Hold{0}A.png'.format(i))
        time.sleep(8)
        scope.write(':MEASure:CLEar ALL')


def Roll_mode_test():
    for i in range(1, 5):
        scope.write(':RUN')
        channel_enable(i)
        time.sleep(4)
        scope.write(':TIMebase:MODE ROLL')                              # 设置运行模式有YT改为ROLL模式
        scope.write(':TIMebase:MAIN:SCALe 2')
        time.sleep(9)
        ser.write(b'OUTP ON\n')
        time.sleep(9)
        ser.write(b'OUTP OFF\n')
        time.sleep(6)
        scope.write(':STOP')                                            # 示波器暂停
        scope.write(':SAVE:IMAGe D:/1-Test/CAN/Roll{0}A.png'.format(i))

        time.sleep(10)
        scope.write('*RST')                                             # 示波器初始化
        time.sleep(10)


##MAIN =======================================================================

# 初始化接口
rm = pyvisa.ResourceManager()
scope = rm.open_resource('USB0::0x1AB1::0x0514::DS7F241300147::INSTR')  # 确保USB地址对应你的示波器地址

scope.write('*RST')
time.sleep(8)
scope.write(':DISPlay:RULers ON')                                          # 打开示波器横纵坐标的标尺
time.sleep(2)
scope.write(':STOP')
print("Scope is OK")

ser = serial.Serial()
ser.port = 'COM8'
ser.baudrate = 9600
ser.open()
ser.write(b'VOLT 24\n')
ser.write(b'OUTP OFF\n')
print("Serial is OK")

# ======
Roll_mode_test()
power_up_edge()
scope.write('*RST')
time.sleep(10)
power_down_edge()
power_hold_edge()
ser.write(b'OUTP OFF\n')

print("Test is Done")

实践中发现有很多问题:

1,时间控制不好(可以通过更改s/div),有些GPIO口的上电(这个上升沿)需要很长的时间,有些管脚上电很快所有该程序不一定可以cover 所有的应用场景。

2,有些管脚动作要等很长时间才会上电,就不一定能过抓取到,有比较大的局限性(这个就要根据实际情况改变等待时间)

3,下电瞬间不好抓取,尤其是信号管脚,他一直在发送的信号就有下降沿,抓不到最后的瞬间,只能有roll mode的图片代替了。

4,Roll mode下测的信号很容易受到测量环路的影响,噪声很大,要先办法规避,地尽量选择近一点

5,探棒使用的时候需要注意尽量使用原装的,用其他的牌子的探棒尤其是那种可以从1:1 转换成1:10的那种很容易设定结束出现1:100的情况。

一、设备通过USB连接

rm = pyvisa.ResourceManager()
scope = rm.open_resource('USB0::0x1AB1::0x0514::DS7F241300147::INSTR')  # 确保USB地址对应你的示波器地址

可以在驱动的详细信息里面的设备实例路径下找到,上图并非示波器的驱动VID和PID。

二、设备驱动安装

需要安装IVI VISA的驱动,可以去NI的官网找,这个驱动,安装之后基本上很多可编程设备都可以直接用

设置与USB仪器的通信 - NI

三、示波器编程手册

MSO7000-普源精电科技-RIGOL TECHNOLOGIES, Co. LTD

手册都是中文对新手很友好。

总结:

本程序还有很多值得优化的地方,比较应用场景比较单一,只能由于测一测GPIO控制管脚的上下电瞬间的波形。欢迎同道多多指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值