#!/user/bin/env python3 """ SPD3303X-E CONTROL APPLICATION - PSU_CONTROl_TEST_APP.PY - ENTRY POINT OF APPLICATION VERSION: 1.0 AUTHOR: D. RICE 19/11/2025 © 2025 ARRIVE """ # Imports import numpy as np from PySide6.QtCore import (QTimer) from PySide6.QtWidgets import (QApplication, QMainWindow, QFileDialog) import pyvisa import time import sys import csv from ui_mainwindow import Ui_MainWindow # Global variables test_state_flag = False chan1_state_flag = False chan2_state_flag = False setup_del = 0.2 # Setup delay in seconds meas_del = 0.05 # Measure delay in seconds file_name = "" test_data = list() test_time_counter = 0 test_state = 0 test_length = 0 test_time_target = 0 repeat_state = 0 repeat_length = 0 VISA_ADDRESS = "TCPIP::192.168.45.3::INSTR" rm = pyvisa.ResourceManager() devices = rm.list_resources() print (devices) SPD = rm.open_resource( VISA_ADDRESS, write_termination='\n', read_termination='\n' ) # Main window class class MainWindow(QMainWindow): def __init__(self): global SPD global setup_del # Initialise main window super(MainWindow, self).__init__() # Finish main window initial setup self.ui = Ui_MainWindow() self.ui.setupUi(self) # Set up timer prototype self.counter = 0 # Hold process reference. self.p = None # Add file browser button action #self.ui.filebrowseButton.setCheckable(True) #self.ui.filebrowseButton.clicked.connect(self.file_browse_button_press) # Add test button action #self.ui.testButton.setCheckable(True) #self.ui.testButton.clicked.connect(self.test_button_press) # Add channel button action self.ui.chan1Button.setEnabled(True) self.ui.chan1Button.setCheckable(True) self.ui.chan1Button.clicked.connect(self.chan1_button_press) self.ui.chan2Button.setEnabled(True) self.ui.chan2Button.setCheckable(True) self.ui.chan2Button.clicked.connect(self.chan2_button_press) # Enable voltage/current entry self.ui.chan1_v_lab.setEnabled(True) self.ui.chan1_i_lab.setEnabled(True) self.ui.chan2_v_lab.setEnabled(True) self.ui.chan2_i_lab.setEnabled(True) # Setup LEDs - show black/gray initially self.ui.chan1_blk.setHidden(False) self.ui.chan1_grn.setHidden(True) self.ui.chan1_red.setHidden(True) self.ui.chan2_blk.setHidden(False) self.ui.chan2_grn.setHidden(True) self.ui.chan2_red.setHidden(True) #self.ui.test_blk.setHidden(False) #self.ui.test_grn.setHidden(True) #self.ui.test_red.setHidden(True) # Setup QT timers self.chan1timer = QTimer() self.chan1timer.setInterval(200) self.chan1timer.timeout.connect(self.chan1_timer) self.chan2timer = QTimer() self.chan2timer.setInterval(200) self.chan2timer.timeout.connect(self.chan2_timer) #self.testledtimer = QTimer() #self.testledtimer.setInterval(500) #self.testledtimer.timeout.connect(self.test_led_timer) #self.testtimer = QTimer() #self.testtimer.setInterval(100) #self.testtimer.timeout.connect(self.test_timer) # Configure Power Supplys #SPD.write_termination='\n' #SPD.read_termination='\n' SPD.write('CH1:VOLT ' + str(0.0)) # Send power supply source voltage time.sleep(setup_del) SPD.write('CH1:CURR ' + str(1.0)) # Send power supply current limit time.sleep(setup_del) SPD.write('CH2:VOLT ' + str(0.0)) # Send power supply source voltage time.sleep(setup_del) SPD.write('CH2:CURR ' + str(1.0)) # Send power supply current limit time.sleep(setup_del) # Disable power supply output source SPD.write('OUTP CH1,OFF') # Enable supply output SPD.write('OUTP CH2,OFF') # Enable supply output def file_browse_button_press (self): global file_name fname=QFileDialog.getOpenFileName(self, 'Open file', 'C:\\Users\\david.rice\\Documents\\Python\\DRIVER CONSOLE TEST\\TEST FILES', 'CSV UTF-8 (*.csv)') file_name = fname[0] self.ui.tfp_val.setText(fname[0]) def test_button_press (self): global test_state_flag global SPD global file_name global test_data global test_time_counter global test_state global test_length global test_time_target global repeat_state global repeat_length self.ui.testButton.toggle() test_time_target = 0 if test_state_flag == False: test_state_flag = True if file_name != "": self.ui.testButton.setText("STOP TEST") self.testledtimer.start() # Enable power supply output source self.ui.chan1Button.setEnabled(False) self.ui.v_lab.setEnabled(False) self.ui.i_lab.setEnabled(False) SPD.write('OUTP CH1,ON') # Enable supply output # Read test file contents with open(file_name, newline='') as csvfile: test_data_l = list(csv.reader(csvfile)) test_data = test_data_l[0] test_length = len(test_data) - 2 repeat_state = 0 repeat_length_str = test_data[1] repeat_length = int(repeat_length_str) test_time_counter = 0 test_state = 1 self.testtimer.start() else: test_state_flag = False self.testtimer.stop() self.ui.testButton.setText("RUN TEST") self.testledtimer.stop() self.ui.test_blk.setHidden(False) self.ui.test_grn.setHidden(True) self.ui.test_red.setHidden(True) self.ui.chan1Button.setEnabled(True) self.ui.v_lab.setEnabled(True) self.ui.i_lab.setEnabled(True) self.ui.it_val.setText("0.00") self.ui.vt_val.setText("0.00") self.ui.vt_val.setText("00.0") # Disable power supply output source #SPD.write('OUTP CH1,OFF') # Disable supply output def chan1_button_press (self): global chan1_state_flag global setup_del global SPD if chan1_state_flag == False: chan1_state_flag = True self.ui.chan1_v_lab.setEnabled(False) self.ui.chan1_i_lab.setEnabled(False) voltage = self.ui.chan1_v_val.text() current = self.ui.chan1_i_val.text() self.ui.chan1_blk.setHidden(True) self.ui.chan1_grn.setHidden(False) self.ui.chan1_red.setHidden(True) SPD.write('CH1:VOLT ' + voltage) #Send power supply source voltage time.sleep(setup_del) SPD.write('CH1:CURR ' + current) #Send power supply current limit time.sleep(setup_del) # Enable power supply output source SPD.write('OUTP CH1,ON') # Enable supply output # Enable timer to get data self.chan1timer.start() else: chan1_state_flag = False self.ui.chan1_v_lab.setEnabled(True) self.ui.chan1_i_lab.setEnabled(True) self.ui.chan1_blk.setHidden(False) self.ui.chan1_grn.setHidden(True) self.ui.chan1_red.setHidden(True) # Disable power supply output source SPD.write('OUTP CH1,OFF') # Disable supply output # Disable timer self.chan1timer.stop() self.ui.chan1_mv_val.setText("0.00") self.ui.chan1_mi_val.setText("0.00") self.ui.chan1_mp_val.setText("0.00") def chan2_button_press (self): global chan2_state_flag global setup_del global SPD if chan2_state_flag == False: chan2_state_flag = True self.ui.chan2_v_lab.setEnabled(False) self.ui.chan2_i_lab.setEnabled(False) voltage = self.ui.chan2_v_val.text() current = self.ui.chan2_i_val.text() self.ui.chan2_blk.setHidden(True) self.ui.chan2_grn.setHidden(False) self.ui.chan2_red.setHidden(True) SPD.write('CH2:VOLT ' + voltage) #Send power supply source voltage time.sleep(setup_del) SPD.write('CH2:CURR ' + current) #Send power supply current limit time.sleep(setup_del) # Enable power supply output source SPD.write('OUTP CH2,ON') # Enable supply output # Enable timer to get data self.chan2timer.start() else: chan2_state_flag = False self.ui.chan2_v_lab.setEnabled(True) self.ui.chan2_i_lab.setEnabled(True) self.ui.chan2_blk.setHidden(False) self.ui.chan2_grn.setHidden(True) self.ui.chan2_red.setHidden(True) # Disable power supply output source SPD.write('OUTP CH2,OFF') # Disable supply output # Disable timer self.chan2timer.stop() self.ui.chan2_mv_val.setText("0.00") self.ui.chan2_mi_val.setText("0.00") self.ui.chan2_mp_val.setText("0.00") def chan1_timer (self): global SPD global meas_del # get voltage/current/power SPD.write("MEAS:VOLT? CH1") time.sleep(meas_del) voltage = SPD.read() SPD.write("MEAS:CURR? CH1") time.sleep(meas_del) current = SPD.read() SPD.write("MEAS:POWE? CH1") time.sleep(meas_del) power = SPD.read() self.ui.chan1_mv_val.setText(voltage) self.ui.chan1_mi_val.setText(current) self.ui.chan1_mp_val.setText(power) QApplication.processEvents() def chan2_timer (self): global SPD global meas_del # get voltage/current/power SPD.write("MEAS:VOLT? CH2") time.sleep(meas_del) voltage = SPD.read() SPD.write("MEAS:CURR? CH2") time.sleep(meas_del) current = SPD.read() SPD.write("MEAS:POWE? CH2") time.sleep(meas_del) power = SPD.read() self.ui.chan2_mv_val.setText(voltage) self.ui.chan2_mi_val.setText(current) self.ui.chan2_mp_val.setText(power) QApplication.processEvents() def test_led_timer (self): self.counter += 1 # Toggle light blue/dark blue LED for 'load_cell_zero' test if self.counter == 1: self.ui.test_red.setHidden(False) self.ui.test_blk.setHidden(True) else: self.ui.test_blk.setHidden(False) self.ui.test_red.setHidden(True) self.counter = 0 QApplication.processEvents() def test_timer (self): global test_time_counter global test_time_target global test_state global test_data global test_length global test_state_flag global psu_state_flag global repeat_state global repeat_length if repeat_state <= repeat_length: if test_state <= test_length: if test_time_counter >= test_time_target: test_state = test_state + 1 print ("TEST STATE: " + str(test_state) + " | TEST LENGTH:" + str(test_length)) print ("REPEAT STATE: " + str(repeat_state) + " | REPEAT LENGTH: " + str(repeat_length)) if test_state % 2 == 0: if test_state < test_length + 1: voltage_set = test_data[test_state] test_time_target = 0 SPD.write('CH1:VOLT ' + voltage_set) # Send power supply source voltage current_t = self.ui.i_val.text() self.ui.it_val.setText(current_t) self.ui.vt_val.setText(voltage_set) self.ui.tt_val.setText("00.0") print ("VOLTAGE: " + voltage_set + " | CURRENT: " + current_t) test_time_counter = 0 else: time_set = test_data[test_state] ts_f = float(time_set) test_time_target = int(ts_f * 10) if ts_f < 10: self.ui.tt_val.setText("0" + time_set + ".0") else: self.ui.tt_val.setText(time_set + ".0") else: test_time_counter = test_time_counter + 1 time_now = test_time_target - test_time_counter t_div = time_now / 10 t_mod = t_div % 1 int_t_modmult = int (t_mod * 10) int_t_div = int(t_div) if int_t_div < 10: self.ui.tt_val.setText("0" + str(int_t_div) + "." + str(int_t_modmult)) else: self.ui.tt_val.setText(str(int_t_div) + "." + str(int_t_modmult)) else: repeat_state = repeat_state + 1 test_state = 1 test_time_counter = 0 else: test_state_flag = False self.testtimer.stop() self.ui.testButton.setText("RUN TEST") self.testledtimer.stop() self.ui.test_blk.setHidden(False) self.ui.test_grn.setHidden(True) self.ui.test_red.setHidden(True) self.ui.psuButton.setEnabled(True) psu_state_flag = False self.ui.psuButton.setText("PSU ON") self.ui.v_lab.setEnabled(True) self.ui.i_lab.setEnabled(True) self.ui.it_val.setText("0.00") self.ui.vt_val.setText("0.00") # Disable power supply output source #SPD.write('OUTP CH1,OFF') # Disable supply output QApplication.processEvents() # Run main if __name__ == '__main__': # Send debug information print("SPD3303X-E CONTROL/TEST APPLICATION") print("------------------------------------") print("PROGRAM STARTED...") # Launch main window app = QApplication(sys.argv) app.setStyle('Fusion') window = MainWindow() window.show() app.exec() # Exit app print("EXITING APPLICATION...") sys.exit()