2022-12-22 09:00:27 +01:00

351 lines
6.8 KiB
Python

# -*- coding: utf-8 -*-
# tectest.py
from time import sleep, time, localtime
from teccan import *
#from tecusb import *
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 ===============================================
CAN_Enable()
#tec5 = TEC(5)
#tec6 = TEC(6)
#tec7 = TEC(7)
#tec8 = TEC(8)
test = TecTest()
log = TecLog()
# CAN_Disable()
tecnum = [1,2,3,4,5,6,7,8]
tecs = []
for num in tecnum:
tecs.append(TEC(num))
def tecall(func, var1 = None, var2 = None, var3 = None):
ret = []
for tec in tecs:
ret.append(func(tec, var1, var2, var3))
sleep(0.01)
return ret
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
for tec in tecs:
tec.setUout(0)
sleep(0.01)
tec.pon()
sleep(0.01)
while test.isRunning():
for tec in 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)
for tec in tecs:
tec.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_102.txt')
while test.isRunning():
t = test.elapsedTime()
for tec in tecs:
Ui, Ii, Uo, Io = tec.getUI()
Tc, Th = tec.getTemp()
log.write('{:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.3f}, {:0.2f}, {:0.2f}, '.format(t, Ui[0], Ii[0], Uo[0], Io[0], Tc[0], Th[0]))
sleep(0.01)
log.write('\n')
sleep(0.5)
#if Th[0] > 35: # overheated
# for tec in tecs:
# tec.poff()
# test.stop()
# print('Peltier element overheated! Test aborted.')
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)))
for tec in tecs:
tec.setUout(u_out)
sleep(0.01)
tec.pon()
sleep(0.01)
if not talkingSleep(sec): return
print('TEC power off')
for tec in tecs:
tec.poff()
sleep(0.01)
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()