使用Python辅助完成HP3245A的校准



  • 我的3245A买来后,上下外壳就拆给碰上“大骗子”的3458A用了。 因为缺少外壳一直放着也没兴趣去搬出来玩。最近TiN尝试用恒流源+万用表的方法来测试JRL 1 ohm,取得了很好的结果,尤其是使用HP3245A作为恒流源时。自然的也就想起了我还有台3245在角落里吃灰。
    昨天真是我的幸运日,MM说他买到了一套3458的外壳,问我要不要。哈哈,当然要!
    正好,在这篇帖子里http://bbs.1ppm.cn/topic/42/julie-research-lab-resistor-jrl-tests-and-results/15,老大发现了3245,100mA档在测试中有较大的漂移。替代文字
    赶紧翻手册, 把3245搬出来,100mA检流电阻是一个S102K,功率余量有些不足,并且这个电阻非常靠近热源。
    经过一番搜索,VPR220/VPR220Z是一个不错的替换,货源相对好找,价格不太离谱。
    vpr220z1.jpg
    问题是12.4R没有货源,只有12R,那么就要试一下更换为12R时能否通过校准。
    3245A 的校准流程比较简单:
    1.首先复位HP3245A, 命令是RESET
    然后选择通道,命令是USE 0, 表示选择A通道,USE 100 表示选择B通道。
    接着写入CAL 3245, 就进入校准流程了。
    2.用万用表测量3245输出的电压值
    3.通过指令CAL VALUE 来对3245进行校准, 比如 第一个读数是9.53076136,则写入CAL VALUE 9.53076136
    4. 通过GPIB写入数据,数据写入后,3245 会自动进入下一个校准项目,并输出新电压。
    重复2-4步骤(在进行到第45个数据时,3458要切换到100V量程,其余的都使用自动量程)
    DCV校准一共有47个数据,DCI有24个数据。
    以下是校准使用的代码:只花了几分钟时间完成,比较简陋,用于验证是足够了,仅供参考

    code_text
    # -*- coding: cp936 -*-
    #python 2.7.14
    import sys
    import visa
    import time
    import numpy as np
    from openpyxl import load_workbook
    from openpyxl.styles import PatternFill, Border, Side, Alignment
    from openpyxl.styles import colors, Font, Fill, NamedStyle
    
    rm = visa.ResourceManager()
    HP3245A   = rm.open_resource("GPIB0::9::INSTR")
    dmm = rm.open_resource("GPIB0::22::INSTR") #reference DMM HP3458A
    
    ########## DMM and MFC ##########   
    HP3245A.write("RESET")
    time.sleep(5)
    HP3245A.write("USE 0") #change "USE 0" to "USE 100" before calibrating Channel B OPT 01
    HP3245A.write("CAL 3245")
    HP3245A.timeout = 30000
    print "SRC configured"
    
    dmm.write("RESET")
    dmm.write("END ALWAYS")
    dmm.write("DCV AUTO")
    dmm.write("NPLC 100")
    dmm.write("NDIG 8")
    dmm.write("TRIG AUTO")
    dmm.write("MATH OFF")
    #dmm.write("INBUF ON")
    dmm.timeout = 30000
    print "DUT configured"
        
    
    #DCV Calibration
    print("DCV calibration")
    for ix in range (0,47):
        array = []
        sdev = 0.0
        median = 0.0
        vout = 0
        dmm.write("TARM SGL")
        time.sleep(5)
        if ix == 44:
            dmm.write("DCV 100")
        if ix == 45:
            dmm.write("DCV AUTO")
        for i in range (0,5):        
            dmm.write("TARM SGL")
            volt = float(dmm.read())
            array.extend([volt])
        sdev = np.std(array[1:],ddof = 1)
        median = np.median(array[1:])
        HP3245A.write("CAL VALUE %s" % median)
        print("Rdg# = %d, dmm = %.8f V,  sdev = %.3f uV" % (ix, median, sdev*1e6))
    
    
    #########################
    #remove all cable and short bar, connect a Twisted pair cable for current testing
    while 1:
        str_input = raw_input("Reconnect the cable for Current testing, and then input:Continue testing")
        if cmp(str_input,'Continue testing') == 0:
            break
        else:
            print("input again")
    #########################
           
    #DCI Calibration
    print("DCI calibration")
    dmm.write("DCI AUTO")
    for ix in range (0,24):
        array = []
        sdev = 0.0
        median = 0.0
        iout = 0
        dmm.write("TARM SGL")
        time.sleep(5)
        for i in range (0,5):        
            dmm.write("TARM SGL")    
            iolt = float(dmm.read())
            array.extend([iolt])
        sdev = np.std(array[1:],ddof = 1)
        median = np.median(array[1:])
        HP3245A.write("CAL VALUE %s" % median)
        print("Rdg# = %d, dmm = %.8f A,  sdev = %.3f uA" % (ix, median, sdev*1e6))
    
    #Reset the DMM and MFC####
    time.sleep(5)
    HP3245A.write("RESET")
    dmm.write("RESET")
    dmm.write("END ALWAYS")
    dmm.write("DCV 1000")
    
    

    校准过程中打印的数据
    ================ RESTART: D:\3245Acalibration\calkit_3245.py ================
    SRC configured
    DUT configured
    DCV calibration
    Rdg# = 0, dmm = 9.53076136 V, sdev = 1.605 uV
    Rdg# = 1, dmm = -9.52166667 V, sdev = 2.800 uV
    Rdg# = 2, dmm = -9.08771562 V, sdev = 0.378 uV
    Rdg# = 3, dmm = 9.05085953 V, sdev = 0.479 uV
    Rdg# = 4, dmm = -0.01531307 V, sdev = 0.432 uV
    Rdg# = 5, dmm = -0.01285309 V, sdev = 0.250 uV
    Rdg# = 6, dmm = -0.01013366 V, sdev = 0.366 uV
    Rdg# = 7, dmm = -0.01531233 V, sdev = 0.302 uV
    Rdg# = 8, dmm = 9.05368596 V, sdev = 0.283 uV
    Rdg# = 9, dmm = -9.08488660 V, sdev = 0.356 uV
    Rdg# = 10, dmm = 1.14402690 V, sdev = 0.136 uV
    Rdg# = 11, dmm = -1.14767631 V, sdev = 0.299 uV
    Rdg# = 12, dmm = 9.32640471 V, sdev = 24.872 uV
    Rdg# = 13, dmm = -8.33483375 V, sdev = 19.316 uV
    Rdg# = 14, dmm = 9.58162260 V, sdev = 5.452 uV
    Rdg# = 15, dmm = 2.13806966 V, sdev = 39.515 uV
    Rdg# = 16, dmm = 4.66827515 V, sdev = 20.908 uV
    Rdg# = 17, dmm = -4.17063389 V, sdev = 19.088 uV
    Rdg# = 18, dmm = 2.35602129 V, sdev = 8.411 uV
    Rdg# = 19, dmm = -2.10349284 V, sdev = 5.638 uV
    Rdg# = 20, dmm = 1.17963632 V, sdev = 4.299 uV
    Rdg# = 21, dmm = -1.05184202 V, sdev = 1.425 uV
    Rdg# = 22, dmm = 0.59108763 V, sdev = 0.640 uV
    Rdg# = 23, dmm = -0.52565391 V, sdev = 1.091 uV
    Rdg# = 24, dmm = 0.29676915 V, sdev = 0.790 uV
    Rdg# = 25, dmm = -0.26252116 V, sdev = 0.344 uV
    Rdg# = 26, dmm = 0.14833522 V, sdev = 0.383 uV
    Rdg# = 27, dmm = -0.12981343 V, sdev = 1.017 uV
    Rdg# = 28, dmm = 7.81093337 V, sdev = 11.957 uV
    Rdg# = 29, dmm = 7.87539164 V, sdev = 31.922 uV
    Rdg# = 30, dmm = -7.85309600 V, sdev = 11.832 uV
    Rdg# = 31, dmm = -8.54103496 V, sdev = 16.353 uV
    Rdg# = 32, dmm = 3.90984786 V, sdev = 3.039 uV
    Rdg# = 33, dmm = -3.92931424 V, sdev = 2.750 uV
    Rdg# = 34, dmm = 1.97338821 V, sdev = 1.501 uV
    Rdg# = 35, dmm = -1.98171105 V, sdev = 0.774 uV
    Rdg# = 36, dmm = 0.98820159 V, sdev = 0.441 uV
    Rdg# = 37, dmm = -0.99087351 V, sdev = 0.606 uV
    Rdg# = 38, dmm = 0.49529160 V, sdev = 0.251 uV
    Rdg# = 39, dmm = -0.49513966 V, sdev = 0.493 uV
    Rdg# = 40, dmm = 0.24879750 V, sdev = 0.737 uV
    Rdg# = 41, dmm = -0.24723451 V, sdev = 0.765 uV
    Rdg# = 42, dmm = 0.12447927 V, sdev = 1.010 uV
    Rdg# = 43, dmm = -0.12220943 V, sdev = 0.633 uV
    Rdg# = 44, dmm = 0.02507640 V, sdev = 149.547 uV
    Rdg# = 45, dmm = 9.99622528 V, sdev = 6.445 uV
    Rdg# = 46, dmm = -10.00135406 V, sdev = 31.512 uV
    Reconnect the cable for Current testing, and then input:Continue testingContinue testing
    DCI calibration
    Rdg# = 0, dmm = 0.02948624 A, sdev = 0.097 uA
    Rdg# = 1, dmm = -0.02978723 A, sdev = 0.041 uA
    Rdg# = 2, dmm = 0.00970707 A, sdev = 0.002 uA
    Rdg# = 3, dmm = -0.00974602 A, sdev = 0.005 uA
    Rdg# = 4, dmm = 0.00084060 A, sdev = 0.000 uA
    Rdg# = 5, dmm = -0.00084371 A, sdev = 0.000 uA
    Rdg# = 6, dmm = 0.00008407 A, sdev = 0.000 uA
    Rdg# = 7, dmm = -0.00008438 A, sdev = 0.000 uA
    Rdg# = 8, dmm = 0.06913683 A, sdev = 0.380 uA
    Rdg# = 9, dmm = -0.05852022 A, sdev = 0.694 uA
    Rdg# = 10, dmm = 0.00755249 A, sdev = 0.025 uA
    Rdg# = 11, dmm = -0.00642025 A, sdev = 0.062 uA
    Rdg# = 12, dmm = 0.00065615 A, sdev = 0.002 uA
    Rdg# = 13, dmm = -0.00055789 A, sdev = 0.003 uA
    Rdg# = 14, dmm = 0.00006564 A, sdev = 0.000 uA
    Rdg# = 15, dmm = -0.00005581 A, sdev = 0.000 uA
    Rdg# = 16, dmm = 0.08222245 A, sdev = 0.098 uA
    Rdg# = 17, dmm = -0.08244283 A, sdev = 0.104 uA
    Rdg# = 18, dmm = 0.00869402 A, sdev = 0.043 uA
    Rdg# = 19, dmm = -0.00878601 A, sdev = 0.037 uA
    Rdg# = 20, dmm = 0.00077836 A, sdev = 0.001 uA
    Rdg# = 21, dmm = -0.00078338 A, sdev = 0.001 uA
    Rdg# = 22, dmm = 0.00007807 A, sdev = 0.000 uA
    Rdg# = 23, dmm = -0.00007855 A, sdev = 0.000 uA

    测试中,在12.4 ohm 电阻上并联了一个392 ohm 电阻,图中可以看到。 并联后,输出的100mA电流,变为100.3xxxmA。
    通过校准后,读数为100.000xxmA。
    20190413_213450.jpg

    校准中
    20190413_213556.jpg

    校准后验证一下
    20190413_222628.jpg



  • 干的漂亮!
    看来Python是下一个学习目标了。
    校准通过GPIB吧?和电脑怎么接的?
    HP貌似对校准源很宽容,比如3458A用7V甚至更低的电压都可以校准。

    那个12.4欧的电阻是有点热,影响100mA的温漂和精度,但看来不影响0.1Hz-10Hz的噪声,不过这个100mA的噪声这么低真没想到,比指标也低得多。



  • @lymex
    我用的是NI 的GPIB USB HS,其他常见的类似E5810A,Agilent 82357B,CONTEC GP-IB(USB)FL之类的都是可以的。只要卡的驱动支持visa就可以。我提到的这几个GPIB卡我都试过。
    GPIB卡要先装好驱动软件,我用的NI的卡,装了NI MAX,里面包含有NI-488.2,以及NI-visa。
    连接方式是这样的。GPIB卡的USB连接电脑,万用表和3245之间用GPIB电缆连接,GPIB接口接到GPIB电缆上。



  • @pipelie 好的谢谢。我用笔记本,有个Agilent 82357B,但不知道放哪里去了



  • 我也有一个,也是不知道放哪里去了,只用过一次,安装后比操作系统还大,感觉很难用就没有再试了。



  • @redtony 你说的是3254还是gpib卡



  • @redtony
    如果仅仅是用到GPIB的驱动的话,不要装那个什么IO suit,臃肿的很,而且很讨厌。
    装这个就可以Agilent T&M toolkit 2.1

    只记得以前17.x版本的时候安装包体积很大,运行起来也慢。我查了一下我现在用的电脑,有安装Keysight IO Libraries Suite 2018。烦人的是keysight license manager以及keysight license service,如果不安装keysight benchvue就不需要这两个,BenchVue我另一台电脑以前有安装,体积大很多。我这台没有安装,对我来说没什么用。

    仅仅安装Agilent T&M toolkit 2.1是不行的,我弄错了,抱歉!
    以下是我以前安装的
    ks.jpg



  • @pipelie使用Python辅助完成HP3245A的校准 中说:

    Agilent T&M toolkit 2.1

    请教下,Agilent T&M toolkit 2.1官网有下载吗 ?谢谢



  • @forzero
    我之前弄错了,Agilent T&M toolkit 2.1是给安捷伦USB虚拟仪器用的,我是用在U2702A上。而Measurement Manager (AMM)包含了Agilent T&M toolkit 2.1。
    还是需要下载安装IO suite Libraries Suite 才可以。
    我今天重新安装了一遍。
    ks IO.jpg



  • R609变化了以后,100mA直流电流随之改变,这个容易校准,不知道100mA的交流电流改变了没有?是否也需要校准?



  • 3245A 应该没有交流电流ACI功能吧。



  • @pipelie 这个是HP3245A的技术指标的一部分,看起来应该是有交流电流的。
    47f3ff45-d5a4-413c-bbaf-fc43673d72b6-image.png



  • a976c150-1871-4aff-b956-f4bcbf03b56a-image.png
    这个是整个交流电流的指标,精度不算高,90天为1%+0.5%range。



  • 能有交流就不错了,频率范围也不算窄,还好几种波形。



  • haha, 真的有? 从面板上看是看不出有交流电流ACI功能的。从之前了解的情况看也没有人提到交流电流这个功能。
    校准流程是3245内部控制的,我以前写程序时大概浏览过校准手册也没看到交流电流啊。

    我又重新看了下校准手册的目录,确实没有ACI啊。从面板上看,不知ACI是如何用的。
    替代文字



  • @水手07 我查看了我所有的3245a 的手册也没有找到ACI, 请问你的手册是什么版本的?



  • 把手册从头翻到尾(无法搜索)终于在手册的最后几页找到了。明天试一下ACI功能。



  • @pipelie 要搞个带ocr功能的pdf阅读器了哈哈



  • @pipelie 交流电流一定不需要校准,精度那么低,估计直流校准后就可以了。