diff --git a/hp4155/Custom_SMU/lib/help.py b/hp4155/Custom_SMU/lib/help.py new file mode 100644 index 0000000000000000000000000000000000000000..db79fc9b17de8f601c7791b57313c42a437b7f29 --- /dev/null +++ b/hp4155/Custom_SMU/lib/help.py @@ -0,0 +1,32 @@ + +# Check the functionalities of smus VAR1,VAR2 and VARD +def check_sweep_func(smus:list,func:str): + for i, smu in enumerate(smus): + if smu["func"] == func: + return True + return False + +# Check if there is a pulsed smu for sweep smu +def check_sweep_pulse(smus:list): + for smu in smus: + if "PULSE" in smu["mode"]: + return True: + return False + +# Check if there any constant smus and return their numbers +def check_sweep_cons(smus:list): + cons_smu_numbers = [] + for i,smu in enumerate(smus): + if smu['func']=='CONS' and smu['mode']!='COMM': # Non Grounded SMUs + cons_smu_numbers.append(i+1) # for the actual number of smus + + return cons_smu_numbers + +# Setup the axes in tool +def setup_axes(axes_info:list,device): + axes_plot = ['X','Y1','Y2'] + for ax_plot,ax_info in zip(axes_plot,axes_info): + if ax_plot == 'Y2' and ax_info['name'] == "": # Y2 axis can be empty + pass + else: + device.display_variable() \ No newline at end of file diff --git a/hp4155/Custom_SMU/main.py b/hp4155/Custom_SMU/main.py index 4b573a8d0141b901352e3b1db074074b4790d0cb..a1c8010238c4ef48e597c7de1fc58e8af105ff65 100644 --- a/hp4155/Custom_SMU/main.py +++ b/hp4155/Custom_SMU/main.py @@ -24,66 +24,176 @@ output = widgets.Output() display(start,output) -#device = hp4155a.HP4155a('GPIB0::17::INSTR') +device = hp4155a.HP4155a('GPIB0::17::INSTR') def on_start_clicked(b): with output: change_state(first_page,second_page,third_page,fourth_page,fifth_page) - # Step 1 create the dictionaries + + # Reset the device + device.reset() - #first page - smus = [] - #iterate over the rows - for i in range(1,5): - smus.append(create_dict(vname = first_page[i,1].value,iname=first_page[i,2].value,mode = first_page[i,3].value,func = first_page[i,4].value,disabled=first_page[i,5].value)) + # Step 1 create the dictionaries appropriately for every measurement - - # second page - user_functions = [] - #iterate over the rows - for i in range(1,7): - user_functions.append(create_dict(name = second_page[i,0].value,unit=second_page[i,1].value,expression = second_page[i,2].value)) - - # third_page + # read general information measurement_mode = third_page[0,0].value + measurement_name = fifth_page[0,0].value + processing_nr = fifth_page[1,0].value + sample_series = fifth_page[2,0].value + dut = fifth_page[3,0].value integration = third_page[0,1].value - stress_duration = third_page[0,2].value - - #match hysteris checkbox with the command forwarded to the tool - if third_page[9,0].value == True: - hyst = 'DOUB' - else: - hyst = 'SING' - - var1 = create_dict(start = third_page[4,0].value, stop = third_page[5,0].value,step = third_page[6,0].value,comp = third_page[7,0].value,pcomp =third_page[8,0].value,mode = hyst) - var2 = create_dict(start = third_page[4,1].value,stop = third_page[5,1].value,points = third_page[6,1].value,comp = third_page[7,1].value,pcomp=third_page[8,1]) - vard = create_dict(offset=third_page[4,2].value,ratio = third_page[5,2].value,comp = third_page[7,2].value,pcomp=third_page[8,2].value) - pulse = create_dict(period=third_page[4,3].value,width = third_page[5,3].value,base = third_page[6,3].value) - - - #sampling and stress parameters - parameters= create_dict(mode=third_page[12,0].value,interval=third_page[13,0].value,hold=third_page[16,0].value,points=third_page[14,0].value,filter=third_page[17,0].value) - duration = third_page[13,0].value + # we need constant smus for all measurements # Constant Smus cons_smus = [] for j in range(1,5): cons_smus.append(create_dict(value = third_page[21,j].value,comp=third_page[22,j].value)) + - # Page 4 - axes = [] # 0 is x-axis , 1 is y1-axis and 2 is y2-axis - for j in range(1,4): #iterate over the column - axes.append(create_dict(name = fourth_page[1,j].value,scale = fourth_page[2,j].value,min =fourth_page[3,j].value,max = fourth_page[4,j].value)) - - # Page 5 - measurement_name = fifth_page[0,0].value - processing_nr = fifth_page[1,0].value - sample_series = fifth_page[2,0].value - dut = fifth_page[3,0].value + # first sweep + if measurement_mode == 'SWEEP': + #page 1 + smus = [] + #iterate over the rows + for i in range(1,5): + smus.append( + create_dict( + vname = first_page[i,1].value, + iname = first_page[i,2].value, + mode = first_page[i,3].value, + func = first_page[i,4].value, + disabled = first_page[i,5].value + ) + ) + + + # 2nd page + user_functions = [] + #iterate over the rows + for i in range(1,7): + user_functions.append( + create_dict( + name = second_page[i,0].value, + unit=second_page[i,1].value, + expression = second_page[i,2].value + ) + ) + + # Page 3 + + #match hysteris checkbox with the command forwarded to the tool + if third_page[9,0].value == True: + hyst = 'DOUB' + else: + hyst = 'SING' + + var1 = create_dict( + start = third_page[4,0].value, + stop = third_page[5,0].value, + step = third_page[6,0].value, + comp = third_page[7,0].value, + pcomp =third_page[8,0].value, + mode = hyst + ) + var2 = create_dict( + start = third_page[4,1].value, + stop = third_page[5,1].value, + points = third_page[6,1].value, + comp = third_page[7,1].value, + pcomp=third_page[8,1] + ) + vard = create_dict( + offset=third_page[4,2].value, + ratio = third_page[5,2].value, + comp = third_page[7,2].value, + pcomp=third_page[8,2].value + ) + + pulse = create_dict( + period=third_page[4,3].value, + width = third_page[5,3].value, + base = third_page[6,3].value + ) + + + # Page 4 + axes = [] # 0 is x-axis , 1 is y1-axis and 2 is y2-axis + for j in range(1,4): #iterate over the column + axes.append( + create_dict( + name = fourth_page[1,j].value, + scale = fourth_page[2,j].value, + min =fourth_page[3,j].value, + max = fourth_page[4,j].value + ) + ) + + # Page 5 + variables = [] + for i in range(8): + variables.append( + create_dict( + name = fifth_page[6+i,0].value, + unit =fifth_page[6+i,1].value + ) + ) + + # Now execute measurement + + #setup sweep measurement mode + device.measurement_mode('SWE') + + #disable all irrelevant units + device.disable_not_smu() + + # First Setup Smus + for i,smu in enumerate(smus): + if smu['disabled'] == False: + device.setup_smu(i+1,smu) + else: #disabled + device.smu_disable(i+1) + + + # Setup User Functions + for user_function in user_functions: + device.user_function(user_function['name'],user_function['unit'],user_function['expression']) + + + # Setup VAR1 (always in sweep measurements) + device.setup_var1(var1) # device will check for errors + + # Now set the 3 additional columns + if check_sweep_func(smus,'VAR2') == True: + device.setup_var2(var2) + if check_sweep_func(smus,'VARD') == True: + device.setup_vard(vard) + if check_sweep_pulse(smus)== True: + device.setup_pulse(pulse) + + # Check for constant SMUs but not grounded + cons_smu_numbers = check_sweep_cons(smus) + for i, cons_smu in enumerate(smus): + if i+1 in cons_smu_numbers: # check if the constant smu was found in the first page func + device.setup_cons_smu(i+1,cons_smu) + + # Now set the axes + # Set X-axis + device.display_variable('X',axes[0]['name']) + device.axis_scale('') + - variables = [] - for i in range(8): - variables.append(create_dict(name = fifth_page[6+i,0].value,unit =fifth_page[6+i,1].value)) + # Sampling Measurement Mode + elif measurement_mode=='SAMPLING': + # sampling parameters + parameters= create_dict( + mode=third_page[12,0].value, + interval=third_page[13,0].value, + hold=third_page[16,0].value, + points=third_page[14,0].value, + filter=third_page[17,0].value + ) + duration = third_page[13,0].value + diff --git a/hp4155/Custom_SMU/test_interface.ipynb b/hp4155/Custom_SMU/test_interface.ipynb index d1b0521512f35acb7cbe632412b216227a1cfb86..660c39a5b730e61b6d05049179956d24802d9df3 100644 --- a/hp4155/Custom_SMU/test_interface.ipynb +++ b/hp4155/Custom_SMU/test_interface.ipynb @@ -9,7 +9,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "881e72368c0d4a38a12413a23d573b7d", + "model_id": "5fc385773f324e7e8311f6f3ee1528f2", "version_major": 2, "version_minor": 0 }, @@ -23,7 +23,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b63db9b2c25d444eb3d18bc611032968", + "model_id": "abd9668c0feb4d8da9566970b335cd5d", "version_major": 2, "version_minor": 0 }, @@ -37,7 +37,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f88cceabc2954893adb3528ea5aa9307", + "model_id": "ab085a875eae4ea48042af2fcc1c5b49", "version_major": 2, "version_minor": 0 }, @@ -78,7 +78,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.0" } }, "nbformat": 4,