Package: yc-pyvisa
YICHIP 仪器控制UPDATE:2022-02-17：第三次更新,修改示波器获取电压函数,现在更加精准2022-02-17：第二次更新,新增RIGOL DP832A三通道直流电源驱动2022-01-29：第一次更新,初始代码可对示波器(ZDS1104,ZDS2014),电源(AgilentE3649A,Agilent66319D),台式万用表(Agilent34410A)YC-PYVISA介绍VISA，虚拟仪器软件架构，是对带有GPIB、VXI、PXI、串口(RS232/485)、以太网、USB和/或IEEE 1394接口的仪器系统进行配置、编程和故障排除的标准。简单的说就是两个人沟通，类似于语言的中介，VISA将你的语言转换变成仪器能听懂的命令.PyVisa是通过上述接口用来控制各种各样的测量仪器的Python包.本项目对YICHIP使用的部分仪器通过PyVisa进行了二次封装,以达到更方便的控制仪器,进行自动化测试的目的安装Using pip:pip3 install yc-pyvisa物理接口前面说到visa是对带有GPIB、VXI、PXI、串口(RS232/485)、以太网、USB和/或IEEE 1394接口的仪器系统进行配置、编程和故障排除的标准,所以针对不同的接口,需要安装不同的驱动,不能直接安装使用.以下任意一个接口连接到电脑,且安装好驱动,都可直接被pyvisa控制.GPIB接口比较通用的是GPIB接口,大概长这样GPIB控制器GPIB接口注意:一个GPIB控制器可以控制多个GPIB设备,通过以下线材可拓展多个接口USB接口USB接口应该比较方便辨认,通常是type-B(2.0)接口,就我们平时电脑连接Jlink的线材,我就不贴图片了一般情况下USB设备的驱动都可以在对应的厂商的官网找到,但是个人觉得打驱动比较麻烦,所以如果仪器有GPIB接口并且你有GPIB控制器的话最好直接用GPIB去连接仪器,不过我发现我们公司的示波器都没有GPIB接口,而且我目前控制的ZLG的示波器,按照官网提供的方法是没有办法在Win10上安装驱动的,所以后面我会提供一篇教程,专门用于ZLG示波器的驱动安装RS-232接口用串口来进行收发指令和数据,这也是我比较推荐的一种方式,毕竟打串口驱动是一件相对容易的事情,只需要一根RS-232的线就好了,大概长这样RS-232网口关于网口直接连接就行,一般仪器里面都可以直接设置,具体需要大家自己翻手册.驱动安装必要安装:下载NI VISA,完成后直接一直下一步安装即可,里面集成了GPIB的控制器驱动,并可为部分仪器提供USB驱动,同时为pyvisa提供后端支持Agilent_34410A台式万用表USB驱动:由于安装文件巨大,所以这里不提供该驱动,在内网进行下载:\192.168.2.16\public\xubo\Agilent 34410A Driver.zip安装IntruiLinkApp，安装文件路径：CD1\IntuiLinkApp\Setup.exe安装IOLib，安装文件路径：CD2\Autorun\auto.exe安装IVI_COM，安装文件路径：CD1\ivi-com\Agilent34410.1.0.18.0.msi安装完后重启电脑即可通过USB控制台式万用表ZLG示波器驱动USB驱动安装:目前只提供ZDS1104 和 ZDS2014 usb驱动文件,由于该驱动是通过NI-VISA DRIVER WIZARD生成,未经过签名,所以win10是不允许安装的,需要禁用驱动程序强制签名,然后双击安装文件即可串口驱动安装:RS232的线在公司是比较稀少的，里面的串口芯片是比较老的存在，直接插上win10 是不识别的，这个时候进驱动管理器会发现驱动已经安装，但是不能使用，这个时候只需要发动万能的BING就可以了PL2303win10驱动安装教程，安装完之后就可以愉快的使用串口对仪器进行控制了，但是需要注意的是，串口仪器是不能直接使用的因为串口涉及到波特率的问题，所以我们还是需要设置一下波特率，一般仪器支持串口控制，波特率是可以修改的，如果无法找到就去官网下载手册看看哪里有问题。具体设置波特率的代码我已经在ZLG2014上进行体现了,如果你们用其他仪器的话，就复制粘贴这句话到它的对象初始化函数里面去，去设置对应的波特率就好了self.instr.baud_rate=115200网口:网口是不需要安装驱动的,只需要该电脑和设备处于同一网段即可(注意 ZLG系列的示波器LAN控制不稳定,不建议使用)代码控制在上面安装完模块过后直接导入本模块fromyc-pyvisaimport*然后初始化对应的仪器,里面有默认的对应设备的仪器地址,若地址有变动在初始化的时候填入地址参数就好oscilloscope=ZLG1104()#示波器oscilloscope2=ZLG2014()#示波器multimeter=Agilent_34410A()#台式万用表power=Agilent_66319d()#电源power2=AgilentE3649A()#电源GPIB的地址需要通过仪器自己去设置,也可通过在上面安装完 NI VISA之后出现的一个配置管理软件(NI MAX),遍历对应的设别地址，也可通过代码去遍历对应的设备地址。rm=visa.ResourceManager()new=rm.list_resources()#返回一个数组，里面包含了所有的地址但是在我实践下来发现通过代码ZLG的示波器是不能够遍历到他的USB地址的，所以这个时候你只能通过NI MAX去遍历它的地址，同时ZLG示波器的USB地址都是完全一样的且无法更改，所以当你需要同时控制两台以上的示波器的时候，只能通过1个USB+n个串口去控制示波器。后面控制仪器就用对应的函数控制就好,比如:fre=oscilloscope.Get_Frequency(1)就能够获取到对应示波器通道1的输入频率进阶如果我提供的库里面的函数无法满足需求，也不必担心，示波器的功能很多，由于时间原因只实现了目前用得到的一些函数和功能，可以通过去官网下载对应的手册，（同时这里也会提供一些我下载到的手册，在同目录下）去查找它对应的某些功能的SCIP指令，然后整理成函数就好。当然如果能通过gitee 提交上来就更好了，我会把每一次正确提交都发布上去，供大家使用，当然希望大家能够对自己提交的每一个对象（仪器），函数都写好注释，方便大家理解其功能（虽然第一版有很多函数都没写注释。。。，但是后面有时间会改的）完整样例代码下面是YC3122的应急筛片程序提供一个样例fromastimportWhilefromdistutilsimportextensionfromemailimportcharsetimportosimportglobfrompickleimportFALSE,NONE,TRUEfromtimeimportsleepimportsysfromwebbrowserimportgetfromyc_pyvisaimport*importopenpyxlimportthreadingfromloggerimport*max_val=0otp_buff=[]defget_cmd_result(cmd):result=os.popen(cmd)res=result.read()returnresdefe_p():while('CPU Stopped'notinget_cmd_result("e p")):continuereturndefe_c():while('CPU Running'notinget_cmd_result("e c")):continuereturndeffile_name(file_name):globalmax_valfile_txt=glob.glob(file_name)if(file_txt==[]):max_val=0x100returnforfilenameinfile_txt:try:str1=str(os.path.basename(filename))str1=str1.replace('.txt',"").replace("id","")str1=int(str1,16)if(max_val<str1):max_val=str1exceptExceptionase:print(e)passmax_val+=1defcount_bits_2(value):count=0while(value):value&=value-1count+=1returncountdefauto_set_fre():get_cmd_result("e 20004 0155")sleep(0.2)get_cmd_result("e 20000 02")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEfre1=oscilloscope.Get_Frequency()print(fre1)get_cmd_result("e 20004 0165")get_cmd_result("e 20000 02")sleep(0.2)if("01"notinget_cmd_result("e 20001")):returnFALSEfre2=oscilloscope.Get_Frequency()print(fre2)fer=int((fre2-fre1)/16)result=int(0x155+(24000000-fre1)/fer)get_cmd_result("e 20004 "+hex(result).replace("0x",""))get_cmd_result("e 20000 02")sleep(0.2)if("01"notinget_cmd_result("e 20001")):returnFALSEfre3=oscilloscope.Get_Frequency()print(fre3)if(fre3<24050000andfre3>23950000):returnresultwhile(fre3>24050000):result-=1get_cmd_result("e 20004 "+hex(result-30).replace("0x",""))get_cmd_result("e 20000 02")sleep(0.2)if("01"notinget_cmd_result("e 20001")):returnFALSEfre3=oscilloscope.Get_Frequency()if(fre3<24050000andfre3>23950000):returnresultwhile(fre3<23950000):result+=1get_cmd_result("e 20004 "+hex(result).replace("0x",""))get_cmd_result("e 20000 02")sleep(0.2)if("01"notinget_cmd_result("e 20001")):returnFALSEfre3=oscilloscope.Get_Frequency()if(fre3<24050000andfre3>23950000):returnresultreturnresult# power.setVoltage(5,2)# set_rc192_val(0x5c)# power.setVoltage(0,2)# sleep(0.1)# power.setVoltage(5,2)# fre1 = oscilloscope.Get_Frequency()# print(fre1)# set_rc192_val(0x65)# power.setVoltage(0,2)# sleep(0.1)# power.setVoltage(5,2)# fre2 = oscilloscope.Get_Frequency()# print(fre2)# fer = int((fre2-fre1)/16)# result = int(0x55 + (24000000 - fre1)/fer)# set_rc192_val(result)# fre3 = oscilloscope.Get_Frequency()# power.setVoltage(0,2)# sleep(0.1)# power.setVoltage(5,2)# print(fre3)# if(fre3 <24050000 and fre3 >23950000):#     return result# while(fre3 >24050000):#     result-=1#     set_rc192_val(result)#     fre3 = oscilloscope.Get_Frequency()#     power.setVoltage(0,2)#     sleep(0.1)#     power.setVoltage(5,2)#     if(fre3 <24050000 and fre3 >23950000):#         return result# while(fre3 < 23950000):#     result+=1#     set_rc192_val(result)#     fre3 = oscilloscope.Get_Frequency()#     power.setVoltage(0,2)#     sleep(0.1)#     power.setVoltage(5,2)#     if(fre3 <24050000 and fre3 >23950000):#         return result# return resultdefset_rc192_val(input_val):while(True):if('CPU Stopped'inget_cmd_result("e p")):get_cmd_result("e f0c18 00000000")get_cmd_result("e f0c1c 00000000")get_cmd_result("e f0c49 30")get_cmd_result("e f8703 10")get_cmd_result("e faaa0 55")get_cmd_result("e faaa0 aa")get_cmd_result("e faaa0 17")get_cmd_result("e faaa4 01")get_cmd_result("e fa802 "+hex(input_val).replace("0x",""))print("input_val =%x"%input_val)breakdefdown_otp(cmd):get_cmd_result("e 20000 "+cmd)sleep(0.1)while("01"notinget_cmd_result("e 20001")):continue# while(True):#     if('CPU Stopped' in get_cmd_result("e p")):#         get_cmd_result("e f853c 88")#         if('f8530 :                                     88'in get_cmd_result("e f853c")):#             get_cmd_result("e r pc c0")#             if('read cm0 reg f = c0\n'in get_cmd_result("e r pc")):#                 get_cmd_result("e otw 12c " + hex(input_val).replace("0x",""))#                 if(count_bits_2(input_val) % 2 == 1):#                     get_cmd_result("e otw 12d 81")#                 elif(count_bits_2(input_val) % 2 == 0):#                     get_cmd_result("e otw 12d c1")#                 breakreturndefRC192_test():cail_val=auto_set_fre()if(cail_val==None):error("RC192 cail_val ERROR "+str(cail_val))print(cail_val)otp_buff.append(hex(cail_val))down_otp("03")defdown_ft_code():e_p()os.system("tool\d.bat")defosc_32k_cal():get_cmd_result("e 20000 04")sleep(0.1)if("01"notinget_cmd_result("e 20001")):returnFalseoscilloscope.Set_Timebase("10us")osc32k_cail_val=oscilloscope.Get_Frequency()oscilloscope.Set_Timebase("100us")oscilloscope.write(":CHANnel1:DISPlay OFF")print(osc32k_cail_val)otp_buff.append((hex)(osc32k_cail_val))get_cmd_result("e 20004 "+to_hex(osc32k_cail_val))down_otp("05")returnosc32k_cail_valdefDVDD_test():DVDD_V=oscilloscope.Get_Vol(2)if(DVDD_V>1.3orDVDD_V<1.15):error("DVDD_V ERROR "+str(DVDD_V))defft_test_init():power.setVoltage(0,2)sleep(1)CURR_VUBT=multimeter.Read_Curr()if(CURR_VUBT<1e-06orCURR_VUBT>3e-06):error("VBUT ERROR"+str(CURR_VUBT))power.setVoltage(5,2)power.setVoltage(3.3,1)DVDD_test()bist_test()down_ft_code()sleep(0.6)defxw_toExcel(data,excelname):# xlsxwriter库储存数据到exceltry:workbook=openpyxl.load_workbook(excelname)# 打开工作簿worksheet1=workbook.active# 创建子表exceptExceptionasa:print(a)workbook=openpyxl.Workbook(excelname)workbook.save(filename=excelname)# 关闭表workbook.close()workbook=openpyxl.load_workbook(excelname)# 打开工作簿worksheet1=workbook.activerows=worksheet1.max_rowj=0foriindata:j+=1worksheet1.cell(row=rows+1,column=j).value=iworkbook.save(filename=excelname)# 关闭表workbook.close()defCreat_Thread(thread,*args1):thread_uart_read=threading.Thread(target=thread,args=args1)thread_uart_read.setDaemon(True)thread_uart_read.start()defCheck_CurrThread():whileTrue:CURR_CHARG_IN=power.Get_Curr(2)if(CURR_CHARG_IN>0.02):error("CURR_CHARG_IN ERROR "+str(CURR_CHARG_IN))sleep(1)defread_id_txt(max_val):withopen(".\AB_NEW_ID\id"+hex(max_val).replace("0x","")+".txt","r")asf:str=f.read().replace("\n","")returnstrdefWrite_OtpBySelf():power.setVoltage(5,2)# val = int(otp_buff[6],16)# xor_val = 0# for i in range(0,4):#     xor_val^=val>>i&0x1# val|=0x80# val|=xor_val<<6# input_check = input("确认烧录otp？(y/n):")# if((input_check.lower() != 'y')):#     sys.exit()power.setVoltage(0,2)sleep(0.5)power.setVoltage(5,2)xw_toExcel(otp_buff,"3122_opt.xlsx")while(True):if('CPU Stopped'inget_cmd_result("e p")):get_cmd_result("e f853c 88")if('f8530 :                                     88'inget_cmd_result("e f853c")):get_cmd_result("e r pc c0")if('read cm0 reg f = c0\n'inget_cmd_result("e r pc")):get_cmd_result("e otp .\AB_NEW_ID\id"+hex(max_val).replace("0x","")+".txt 2")sleep(0.1)get_cmd_result("e otp flash_178.txt 178")sleep(0.1)get_cmd_result("e otw 139 8f")breakdefbist_test():os.system(r"tool\bist.bat")str=get_cmd_result("e f8518l8")if("ff ff 03 00 00 00 00 00"notinstr):error("bist test_error")defgen_id():dir=(os.getcwd()+r"\AB_NEW_ID\*.txt")file_name(dir)str1="python f_gen3122id.py "+hex(max_val).replace("0x","")get_cmd_result(str1)otp_buff.append(read_id_txt(max_val))defto_hex(val):returnhex(val).replace("0x","")defHvLdo_test():cail_val=0x6get_cmd_result("e 20004 06")sleep(0.2)get_cmd_result("e 20000 0a")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(3)if(vol<=3.35andvol>=3.25):returncail_valwhile(vol<=3.25):cail_val-=1get_cmd_result("e 20004 0"+to_hex(cail_val))sleep(0.2)get_cmd_result("e 20000 0a")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(3)if(vol<=3.35andvol>=3.25):returncail_valif(cail_val<=0x0):returnFalsewhile(vol>=3.35):cail_val+=1get_cmd_result("e 20004 0"+to_hex(cail_val))sleep(0.2)get_cmd_result("e 20000 0a")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(3)if(vol<=3.35andvol>=3.25):returncail_valif(cail_val>=0xf):returnFalsereturncail_valdefVcard_test(val):cail_val=0x4if(val==0):valmax=1.85valmin=1.75if(val==1):valmax=3.05valmin=2.95get_cmd_result("e 20004 010"+to_hex(cail_val)+"0"+str(val))sleep(0.2)get_cmd_result("e 20000 0e")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(4)if(vol<valmaxandvol>valmin):returncail_valwhile(vol<valmin):cail_val+=1get_cmd_result("e 20004 010"+to_hex(cail_val)+"0"+str(val))sleep(0.2)get_cmd_result("e 20000 0e")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(4)if(vol<valmaxandvol>valmin):returncail_valif(cail_val>=0xf):returnFalsewhile(vol>valmax):cail_val-=1get_cmd_result("e 20004 010"+to_hex(cail_val)+"0"+str(val))sleep(0.2)get_cmd_result("e 20000 0e")sleep(1)if("01"notinget_cmd_result("e 20001")):returnFALSEvol=oscilloscope.Get_Vol(4)if(vol<valmaxandvol>valmin):returncail_valif(cail_val<=0):returnFalsereturncail_valdefcharg_test():get_cmd_result("e fa820 321800")cail_val=0x8get_cmd_result("e fa823 0"+to_hex(cail_val))sleep(0.2)vol=oscilloscope2.Get_Vol(1)valmax=4.25valmin=4.15if(vol<valmaxandvol>valmin):returncail_valwhile(vol<valmin):cail_val+=1get_cmd_result("e fa823 0"+to_hex(cail_val))sleep(0.2)vol=oscilloscope2.Get_Vol(1)if(vol<valmaxandvol>valmin):returncail_valif(cail_val>=0xf):returnFalsewhile(vol>valmax):cail_val-=1get_cmd_result("e fa823 0"+to_hex(cail_val))sleep(0.2)vol=oscilloscope2.Get_Vol(1)if(vol<valmaxandvol>valmin):returncail_valif(cail_val<=0):returnFalsereturncail_valoscilloscope=ZLG1104()oscilloscope2=ZLG2014()multimeter=Agilent_34410A()power=Agilent_66319d()# zlg_2014 = ZLG1104("USB0::0x04CC::0x121C::123456789::RAW")# os.environ['BAUD']="320"if__name__=="__main__":power.setVoltage(0,2)sleep(0.1)power.setVoltage(5,2)while(True):if('CPU Stopped'inget_cmd_result("e p")):get_cmd_result("e f853c 88")if('f8530 :                                     88'inget_cmd_result("e f853c")):get_cmd_result("e r pc c0")if('read cm0 reg f = c0\n'inget_cmd_result("e r pc")):get_cmd_result("e otw 0 1111")breakft_test_init()Creat_Thread(Check_CurrThread)gen_id()RC192_test()print(osc_32k_cal())val=HvLdo_test()otp_buff.append(val)print(val)down_otp("0b")val=Vcard_test(0)otp_buff.append(val)print(val)down_otp("0f")val=Vcard_test(1)otp_buff.append(val)print(val)down_otp("0f")# char_val = charg_test()# otp_buff.append(char_val)# print(char_val)print(otp_buff)Write_OtpBySelf()