hp_curve_tracer/main.py
2022-07-14 00:07:59 -04:00

263 lines
7.8 KiB
Python

import sys
import math
import json
import random
import time
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QMessageBox
from PyQt5.QtGui import QPalette, QColor
from PyQt5.uic import loadUi
from PyQt5.QtChart import QChart, QLineSeries, QChartView
from agpib import Agpib
class Main(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self._ui = loadUi('main.ui')
self._ui.show()
# self.settings = QDialog()
# loadUi('./settings._ui', self.settings)
self._v_set = 0
self._i_set = 0
self._config = {}
self._gpib = None
self._chart = None
self.load_settings()
self.init_gpib()
self.init_chart()
def closeEvent(self, event):
self.save_settings()
self.deleteLater()
def init_gpib(self):
self._gpib = Agpib('/dev/ttyACM0')
if not self._gpib.interface_ping():
print('Failed to connect to gateway')
exit()
self._gpib.init()
self._gpib.remote(True)
self._gpib.output(3)
def init_chart(self):
self._chart = QChart()
self._chart.setTitle('Test')
self._ui.chart.setMouseTracking(True)
self._ui.chart.setInteractive(True)
self._ui.chart.setChart(self._chart)
self._ui.chart.setRubberBand(QChartView.RectangleRubberBand)
def _cmd(self, mode, v, i):
self._v_set = v
self._i_set = i
self._gpib.output(3)
self._gpib.write(f'M{mode} P{v}V C{i}A G')
def read_vm(self):
self._gpib.output(3)
self._gpib.write(f'T')
self._gpib.enter(3)
res = self._gpib.read()
res = res.decode('UTF-8')
status = res[0]
v_a = res[1]
val = float(res[2:7])
v = 0
a = 0
if v_a == 'V':
i = self._i_set
v = val
else:
i = val
v = self._v_set
return status, v, i
def perform_experiment(self):
v_series = QLineSeries()
i_series = QLineSeries()
v_series.setName('V')
i_series.setName('I')
self._chart.addSeries(v_series)
self._chart.addSeries(i_series)
self._chart.createDefaultAxes()
start_time = time.time()
v_axis_x = self._chart.axisX(v_series)
v_axis_y = self._chart.axisY(v_series)
i_axis_x = self._chart.axisX(i_series)
i_axis_y = self._chart.axisY(i_series)
v_minx = 1000
v_miny = 1000
v_maxx = -1000
v_maxy = -1000
i_minx = 1000
i_miny = 1000
i_maxx = -1000
i_maxy = -1000
v_avg = 0
i_avg = 0
print('Performing experiment')
cmds = np.linspace(self._ui.start.value(), self._ui.end.value(), self._ui.steps.value())
for cmd in cmds:
mode = None
if self._ui.mode.currentIndex() == 0:
mode = 1 # CV
else:
mode = 2 # CC
v_cmd = None
i_cmd = None
if self._ui.control_variable.currentIndex() == 0:
v_cmd = cmd
i_cmd = self._ui.other_variable.value()
else:
v_cmd = self._ui.other_variable.value()
i_cmd = cmd
self._cmd(mode, v_cmd, i_cmd)
time.sleep(self._ui.settle_time.value())
for _ in range(self._ui.samples.value()):
status, v, i = self.read_vm()
print(v, i)
x = time.time() - start_time
v_avg = (v_avg + v) / 2
i_avg = (i_avg + i) / 2
v_y = v_avg
i_y = i_avg
v_minx = min(v_minx, x)
v_maxx = max(v_maxx, x)
v_miny = min(v_miny, v_y)
v_maxy = max(v_maxy, v_y)
i_minx = min(i_minx, x)
i_maxx = max(i_maxx, x)
i_miny = min(i_miny, i_y)
i_maxy = max(i_maxy, i_y)
v_series.append(x, v_y)
i_series.append(x, i_y)
time.sleep(self._ui.sample_time.value())
print('Done experiment')
self._cmd(1, 0, 0)
v_axis_x.setMin(v_minx)
v_axis_x.setMax(v_maxx)
v_axis_y.setMin(v_miny)
v_axis_y.setMax(v_maxy)
i_axis_x.setMin(i_minx)
i_axis_x.setMax(i_maxx)
i_axis_y.setMin(i_miny)
i_axis_y.setMax(i_maxy)
def init_connections(self):
#############
# LED TAB #
#############
self._ui.perform.clicked.connect(self.perform_experiment)
# Light switch and mode
#self._ui.leds_enable.stateChanged.connect(self.enable_toggled)
#self._ui.leds_mode.currentIndexChanged.connect(self.leds.set_effect)
# RGB sliders
#self._ui.leds_r.sliderReleased.connect(self.color_changed)
#self._ui.leds_g.sliderReleased.connect(self.color_changed)
#self._ui.leds_b.sliderReleased.connect(self.color_changed)
#self._ui.leds_r_b.editingFinished.connect(self.color_changed)
#self._ui.leds_g_b.editingFinished.connect(self.color_changed)
#self._ui.leds_b_b.editingFinished.connect(self.color_changed)
# Brightness and speed
#self._ui.leds_brightness.sliderReleased.connect(self.brightness_changed)
#self._ui.leds_speed.sliderReleased.connect(self.speed_changed)
#####################
# SETTINGS DIALOG #
#####################
#self._ui.show_settings.clicked.connect(self.show_settings)
pass
#############
# LED TAB #
#############
def enable_toggled(self, state):
self.leds.set_effect(1 if state else 0)
def color_changed(self):
self.leds.set_effect(1)
self.leds.set_color(self._ui.leds_r.value(), self._ui.leds_g.value(), self._ui.leds_b.value())
def brightness_changed(self):
self.leds.set_brightness(self._ui.leds_brightness.value())
def speed_changed(self):
self.leds.set_speed(self._ui.leds_speed.value())
#############
# SETTINGS #
#############
def show_settings(self):
self.settings.show()
def save_settings(self):
with open('settings.json', 'w') as f:
self._config['mode'] = self._ui.mode.currentIndex()
self._config['control_variable'] = self._ui.control_variable.currentIndex()
self._config['other_variable'] = self._ui.other_variable.value()
self._config['start'] = self._ui.start.value()
self._config['end'] = self._ui.end.value()
self._config['steps'] = self._ui.steps.value()
self._config['settle_time'] = self._ui.settle_time.value()
self._config['samples'] = self._ui.samples.value()
self._config['sample_time'] = self._ui.sample_time.value()
json.dump(self._config, f)
def load_settings(self):
with open('settings.json', 'r') as f:
self._config = json.load(f)
self._ui.mode.setCurrentIndex(self._config['mode'])
self._ui.control_variable.setCurrentIndex(self._config['control_variable'])
self._ui.other_variable.setValue(self._config['other_variable'])
self._ui.start.setValue(self._config['start'])
self._ui.end.setValue(self._config['end'])
self._ui.steps.setValue(self._config['steps'])
self._ui.settle_time.setValue(self._config['settle_time'])
self._ui.samples.setValue(self._config['samples'])
self._ui.sample_time.setValue(self._config['sample_time'])
def main():
app = QApplication(sys.argv)
main = Main()
main.init_connections()
r = app.exec()
main.closeEvent(None)
sys.exit(r)
if __name__ == "__main__":
main()