init
This commit is contained in:
commit
a9e6d7d69c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.txt
|
||||||
|
*.pyc
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"python.analysis.extraPaths": ["../pc_coldbox"]
|
||||||
|
|
||||||
|
}
|
48
plot_tecstep.py
Normal file
48
plot_tecstep.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
# Open the file in read mode
|
||||||
|
with open("tecstep.txt", "r") as f:
|
||||||
|
# Read the contents of the file
|
||||||
|
data = f.read()
|
||||||
|
|
||||||
|
# Split the data into rows
|
||||||
|
rows = data.split("\n")
|
||||||
|
|
||||||
|
if rows[-1] == "":
|
||||||
|
rows.pop()
|
||||||
|
|
||||||
|
# Initialize lists to store the x and y data for each set
|
||||||
|
x_data = []
|
||||||
|
y_data = [[] for _ in range(8)]
|
||||||
|
|
||||||
|
# Iterate over each row
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
# Split the row by the comma
|
||||||
|
values = row.split(",")
|
||||||
|
|
||||||
|
# Check that there are at least 6 values
|
||||||
|
if len(values) < 6:
|
||||||
|
print(f"Error: row {i+1} has less than 6 values")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Append the first value (time point) to the x_data list
|
||||||
|
try:
|
||||||
|
x_data.append(float(values[0].strip()))
|
||||||
|
except ValueError:
|
||||||
|
print(f"Error: could not convert value to float in row {i+1}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Append the sixth value to the y_data list for the corresponding set
|
||||||
|
for j in range(8):
|
||||||
|
try:
|
||||||
|
y_data[j].append(float(values[(2*(j+1))-1].strip()))
|
||||||
|
except ValueError:
|
||||||
|
print(f"Error: could not convert value to float in row {i+1}")
|
||||||
|
|
||||||
|
# Iterate over each data set
|
||||||
|
for y in y_data:
|
||||||
|
# Plot the x and y data
|
||||||
|
plt.plot(x_data, y)
|
||||||
|
|
||||||
|
# Show the plot
|
||||||
|
plt.show()
|
338
tectest.py
Normal file
338
tectest.py
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# tectest.py
|
||||||
|
|
||||||
|
from time import sleep, time, localtime
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append('../pc_coldbox') # path of coldbox script
|
||||||
|
from coldbox import *
|
||||||
|
|
||||||
|
LINE_UP = '\033[1A'
|
||||||
|
LINE_CLEAR = '\x1b[2K'
|
||||||
|
|
||||||
|
def print_del(txt:str):
|
||||||
|
"""print and delete line before"""
|
||||||
|
print(LINE_UP, end=LINE_CLEAR)
|
||||||
|
print(txt)
|
||||||
|
|
||||||
|
|
||||||
|
class TecTest:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.__runTimeStart = 0
|
||||||
|
self.__running = False
|
||||||
|
self.__thread = None
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def start(self, proc = None):
|
||||||
|
self.__runTimeStart = time()
|
||||||
|
if proc:
|
||||||
|
self.__running = True
|
||||||
|
self.__thread = Thread(target=proc).start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.__running = False
|
||||||
|
if self.__thread: self.__thread.join(2)
|
||||||
|
|
||||||
|
def isRunning(self):
|
||||||
|
return self.__running
|
||||||
|
|
||||||
|
def elapsedTime(self):
|
||||||
|
return time() - self.__runTimeStart
|
||||||
|
|
||||||
|
|
||||||
|
class TecLog:
|
||||||
|
def __init__(self, filename = None):
|
||||||
|
self.__n = 0
|
||||||
|
self.__file = None
|
||||||
|
if filename:
|
||||||
|
self.open(filename)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def open(self, filename):
|
||||||
|
if self.__file: # close an already open file
|
||||||
|
self.close()
|
||||||
|
self.__file = open(filename, 'w')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def timestamp():
|
||||||
|
t = localtime(time())
|
||||||
|
# Format: 2021.10.04 07:50
|
||||||
|
return '{0:4d}.{1:02d}.{2:02d} {3:02d}:{4:02d}:{5:02d}'\
|
||||||
|
.format(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self.__file: # if file open
|
||||||
|
self.__file.close()
|
||||||
|
self.__file = None
|
||||||
|
|
||||||
|
def write(self, msg):
|
||||||
|
if not self.__file:
|
||||||
|
return
|
||||||
|
self.__file.write(msg)
|
||||||
|
self.__n += 1
|
||||||
|
if self.__n > 10: # flush file buffer
|
||||||
|
self.__file.flush()
|
||||||
|
self.__n = 0
|
||||||
|
|
||||||
|
|
||||||
|
# === Test procedures ===============================================
|
||||||
|
|
||||||
|
test = TecTest()
|
||||||
|
log = TecLog()
|
||||||
|
box = Coldbox()
|
||||||
|
|
||||||
|
|
||||||
|
def talkingSleep(sec):
|
||||||
|
n = sec // 10; # floor integer division
|
||||||
|
r = sec - n*10
|
||||||
|
for i in range(n):
|
||||||
|
if not test.isRunning(): return False
|
||||||
|
sleep(10)
|
||||||
|
print('elapsed time: {:0.1f}'.format(test.elapsedTime()))
|
||||||
|
if r > 0.01: sleep(r)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# --- PID -----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _pidLoop():
|
||||||
|
global tec, test, log, T_set
|
||||||
|
#kp = 1.2
|
||||||
|
#ki = 0.028
|
||||||
|
umax = 10.0
|
||||||
|
umin = -2.0
|
||||||
|
|
||||||
|
kp = 1.2
|
||||||
|
ki = 0.03
|
||||||
|
kd = 0.0
|
||||||
|
|
||||||
|
dT = 0.5
|
||||||
|
y_int = 0.0
|
||||||
|
|
||||||
|
box.tecall.setVoltage(0)
|
||||||
|
sleep(0.01)
|
||||||
|
box.tecall.pon()
|
||||||
|
sleep(0.01)
|
||||||
|
|
||||||
|
while test.isRunning():
|
||||||
|
for tec in box.tecs:
|
||||||
|
Tc, Th = tec.getTemp()
|
||||||
|
sleep(0.01)
|
||||||
|
# -error
|
||||||
|
x = Tc[0] - Tset
|
||||||
|
|
||||||
|
# proportional term
|
||||||
|
yp = kp*x
|
||||||
|
|
||||||
|
# integral term
|
||||||
|
y_int += x*dT
|
||||||
|
yi = ki*y_int
|
||||||
|
|
||||||
|
# derivative term
|
||||||
|
yd = kd*(x-tec.x_last)/dT
|
||||||
|
tec.x_last = x
|
||||||
|
|
||||||
|
# total
|
||||||
|
y = yp + yi + yd
|
||||||
|
|
||||||
|
# limitter
|
||||||
|
if y > umax:
|
||||||
|
y = umax
|
||||||
|
elif y < umin:
|
||||||
|
y = umin
|
||||||
|
|
||||||
|
tec.setUout(y)
|
||||||
|
sleep(0.01)
|
||||||
|
sleep(dT)
|
||||||
|
box.tecall.poff()
|
||||||
|
sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
|
def pidTest(kp=0.0, ki=0.0, kd=0.0):
|
||||||
|
global tec, test, log, Tset
|
||||||
|
log.open('pid_0001.txt')
|
||||||
|
#test.start(_pidLoop)
|
||||||
|
|
||||||
|
Tset = -25.0
|
||||||
|
#kp = 0.17
|
||||||
|
#ki = 0.015
|
||||||
|
#kd = 0.25
|
||||||
|
|
||||||
|
tecall(TEC.setTemp, Tset)
|
||||||
|
tecall(TEC.setPID, kp, ki, kd)
|
||||||
|
tecall(TEC.pon)
|
||||||
|
tecall(TEC.mode, 0)
|
||||||
|
|
||||||
|
|
||||||
|
print("start")
|
||||||
|
for t in range(120):
|
||||||
|
if t == 60:
|
||||||
|
Tset = -10.0
|
||||||
|
#tecall(TEC.setTemp, Tset)
|
||||||
|
#t = test.elapsedTime()
|
||||||
|
for tec in tecs:
|
||||||
|
Ui, Ii, Uo, Io = tec.getUI()
|
||||||
|
sleep(0.01)
|
||||||
|
Tc, Th = tec.getTemp()
|
||||||
|
log.write('{:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.2f}, {:0.2f}, '.format(t/2, Ui[0], Ii[0], Uo[0], Io[0], Tc[0], Th[0]))
|
||||||
|
sleep(0.01)
|
||||||
|
log.write('\n')
|
||||||
|
sleep(0.5)
|
||||||
|
#test.stop()
|
||||||
|
tecall(TEC.mode, 1)
|
||||||
|
tecall(TEC.poff)
|
||||||
|
print("finished")
|
||||||
|
log.close()
|
||||||
|
|
||||||
|
# --- Step response test --------------------------------------------
|
||||||
|
|
||||||
|
def _observeTec():
|
||||||
|
global tec, test, log
|
||||||
|
log.open('tecstep.txt')
|
||||||
|
while test.isRunning():
|
||||||
|
t = test.elapsedTime()
|
||||||
|
#UI = box.tecall.getUI()
|
||||||
|
Temp = box.tecall.getTemp()
|
||||||
|
for i, tec in enumerate(box.tecs):
|
||||||
|
#Ui, Ii, Uo, Io = UI
|
||||||
|
Tc = Temp
|
||||||
|
#log.write('{:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.2f}, '.format(t, Ui[i], Ii[i], Uo[i], Io[i], Tc[i]))
|
||||||
|
log.write('{:0.3f}, {:0.3f}, '.format(t, Tc[i]))
|
||||||
|
log.write('\n')
|
||||||
|
#if Th[0] > 35: # overheated
|
||||||
|
# for tec in tecs:
|
||||||
|
# tec.poff()
|
||||||
|
# test.stop()
|
||||||
|
# print('Peltier element overheated! Test aborted.')
|
||||||
|
|
||||||
|
while((test.elapsedTime() - t) < 1.01):
|
||||||
|
sleep(0.001)
|
||||||
|
log.close()
|
||||||
|
|
||||||
|
|
||||||
|
def runStepresponse(u_out, sec):
|
||||||
|
global test, tec
|
||||||
|
test.start(_observeTec)
|
||||||
|
print('test running: ...')
|
||||||
|
|
||||||
|
print('Uout = {:0.3}V'.format(float(u_out)))
|
||||||
|
box.tecall.setVoltage(u_out)
|
||||||
|
box.tecall.pon()
|
||||||
|
|
||||||
|
if not talkingSleep(sec): return
|
||||||
|
|
||||||
|
print('TEC power off')
|
||||||
|
box.tecall.poff()
|
||||||
|
|
||||||
|
if not talkingSleep(sec): return
|
||||||
|
|
||||||
|
test.stop()
|
||||||
|
print('test ended after {:0.1f}s runtime'.format(test.elapsedTime()))
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Peltier stress test -------------------------------------------
|
||||||
|
|
||||||
|
def _tecCycling():
|
||||||
|
global test, log, tec
|
||||||
|
n = 0
|
||||||
|
cooling = False
|
||||||
|
while test.isRunning():
|
||||||
|
Ui, Ii, Uo, Io = tec.getUI()
|
||||||
|
Tc, Th = tec.getTemp()
|
||||||
|
|
||||||
|
# log and change temperature every 6th event (60 s interval)
|
||||||
|
n += 1
|
||||||
|
if n >= 60:
|
||||||
|
n = 0
|
||||||
|
log.write('{}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.2f}, {:0.2f}\n'.\
|
||||||
|
format(TecLog.timestamp(), Ui, Ii, Uo, Io, Tc, Th))
|
||||||
|
print('Io:{:5.2f}A; Tc:{:5.1f}°C; Th:{:5.1f}°C'.format(Io, Tc, Th))
|
||||||
|
if cooling:
|
||||||
|
tec.poff()
|
||||||
|
cooling = False
|
||||||
|
else:
|
||||||
|
tec.pon()
|
||||||
|
cooling = True
|
||||||
|
|
||||||
|
# check for overheating every 1 s
|
||||||
|
if Th > 30:
|
||||||
|
tec.poff()
|
||||||
|
test.stop()
|
||||||
|
print('Peltier element overheated! Test aborted at {}'.format(TecLog.Timestamp()))
|
||||||
|
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def startTest():
|
||||||
|
global test, log
|
||||||
|
log.open('teclog_0004.txt')
|
||||||
|
test.start(_tecCycling)
|
||||||
|
tec.setUout(10)
|
||||||
|
print('Peltier stress test started at {}'.format(TecLog.timestamp()))
|
||||||
|
|
||||||
|
|
||||||
|
def stopTest():
|
||||||
|
global test, log, tec
|
||||||
|
test.stop()
|
||||||
|
log.close()
|
||||||
|
tec.poff()
|
||||||
|
print('Peltier stress test stopped at {}.'.format(TecLog.timestamp()))
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
def vout(v):
|
||||||
|
global tec
|
||||||
|
tec.setUout(v)
|
||||||
|
tec.pon()
|
||||||
|
sleep(4)
|
||||||
|
ui, ii, uo, io = tec.getUI()
|
||||||
|
print('{:0.3f}V {:0.3f}A {:0.3f}V {:0.3f}A'.format(ui, ii, uo, io))
|
||||||
|
sleep(0.5)
|
||||||
|
ui, ii, uo, io = tec.getUI()
|
||||||
|
print('{:0.3f}V {:0.3f}A {:0.3f}V {:0.3f}A'.format(ui, ii, uo, io))
|
||||||
|
sleep(0.5)
|
||||||
|
ui, ii, uo, io = tec.getUI()
|
||||||
|
print('{:0.3f}V {:0.3f}A {:0.3f}V {:0.3f}A'.format(ui, ii, uo, io))
|
||||||
|
tc, th = tec.getTemp()
|
||||||
|
print('{:0.2f}°C {:0.2f}°C'.format(tc, th))
|
||||||
|
tec.poff()
|
||||||
|
|
||||||
|
# --- ADC Test histogram ------------------------------------------
|
||||||
|
|
||||||
|
def adctest(n, uout=5):
|
||||||
|
global test, log
|
||||||
|
log.open('adctest.txt')
|
||||||
|
tec.setUout(uout)
|
||||||
|
tec.pon()
|
||||||
|
sleep(120)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
Ui, Ii, Uo, Io = tec.getUI()
|
||||||
|
log.write('{:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}\n'.format(Ui[0], Ii[0], Uo[0], Io[0]))
|
||||||
|
#sleep(0.01)
|
||||||
|
|
||||||
|
tec.poff()
|
||||||
|
log.close()
|
||||||
|
|
||||||
|
def rawadctest(n, uout=5):
|
||||||
|
global test, log
|
||||||
|
log.open('rawadctest.txt')
|
||||||
|
tec.setUout(uout)
|
||||||
|
tec.pon()
|
||||||
|
sleep(120)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
Ui, Ii, Uo, Io = tec.rawgetUI()
|
||||||
|
log.write('{}, {}, {}, {}\n'.\
|
||||||
|
format(Ui, Ii, Uo, Io))
|
||||||
|
#sleep(0.01)
|
||||||
|
|
||||||
|
tec.poff()
|
||||||
|
log.close()
|
Loading…
x
Reference in New Issue
Block a user