# -*- coding: utf-8 -*- # tectest.py from time import sleep, time, localtime from teccan import * #from tecsim 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()