diff --git a/china_io-2019/python/calibrator.py b/china_io-2019/python/calibrator.py index 51423c5770ef23ecacbcba47a7dcad864a9abdbc..81f4160264d8132231f676bec595cc9d5b7e1f7e 100755 --- a/china_io-2019/python/calibrator.py +++ b/china_io-2019/python/calibrator.py @@ -6,6 +6,7 @@ import numpy import traceback from serialio import SerialIO import math +import curses class Welford: @@ -27,7 +28,7 @@ class Welford: return self.M def stddev(self): - if self.k==1: + if self.k==1: # Loop until external ref disabled return 0 return math.sqrt(self.S/(self.k-1)) @@ -41,22 +42,53 @@ class ChinaIO: AIN_STEP = 20/(1<<18) # 20V, 18 bit resolution AOUT_STEP = 20/(1<<16) # 20V, 18 bit resolution - def __init__(self, port): + def __init__(self, stdscr, port): + self.stdscr = stdscr self.io = SerialIO(port) self.action_msg = "" self.status_msg = "" + begin_x = 20; begin_y = 7 + height = 5; width = 40 + if self.stdscr: + self.iowin = curses.newwin(2 + len(self.io.analogIn()), 80, 0,0) + self.gotoxy(0,0) + pass pass def close(self): self.io.setchannel(self.ANALOG_OUT_0, 0x8000) self.io.setchannel(self.ANALOG_OUT_1, 0x8000) + pass + + def gotoxy(self, x, y): + if self.stdscr == None: + return + self.iowin.move(y,x) + + def print(self, *args, **kwargs): + if self.stdscr == None: + print(*args, **kwargs) + return + + for s in args: + try: + self.iowin.addstr(s) + except: + pass + pass + if not 'end' in kwargs or kwargs['end'] != '': + self.iowin.refresh() + pass def measure(self, analogIn, N=100, message=''): time.sleep(0.1) stat = {} for b in range(N): - print(message, '[', end='') - for i,c in analogIn.items(): + self.gotoxy(0,0) + self.print(message, end='') + channels = analogIn.items() + for i,c in channels: + self.gotoxy(0,i+2) value = (self.io.getchannel(i) - (1<<17)) * self.AIN_STEP if not i in stat: stat[i] = Welford(value) @@ -64,11 +96,11 @@ class ChinaIO: else: stat[i].update(value) pass - print('%s ' % stat[i], end='') + self.print('%s ' % stat[i], end='') pass - print(']', end='\r') + self.print(end='\r') pass - print() + self.print() return [ stat[i] for i in sorted(stat.keys()) ] def setCalibration(self, index, value): @@ -90,10 +122,11 @@ class ChinaIO: pass pass time.sleep(0.1) # Let values settle - sample = self.measure(analogIn, N=N, message=message) - for e,v in zip(expect, sample): + self.gotoxy(0,1) + self.print("Ref=", str(ref), " Expecting=", str(expect)) + self.sample = self.measure(analogIn, N=N, message=message) + for e,v in zip(expect, self.sample): if e != None and (v.mean() < e[0] or e[1] < v.mean()): - print(" Expected:", expect) return False pass return True @@ -132,13 +165,41 @@ class ChinaIO: self.setCalibration(0, 0x8000) self.setCalibration(1, 0x8000) - # Read values from grounded inputs - while not self.expect(analogIn, - [ -9, 9 ], - [ (-0.1, 0.1), (-0.1, 0.1), - (-0.1, 0.1), (-0.1, 0.1) ], - N=500, - message='Ground all input pins'): + # Loop while connected to test harness 5V ref + badSamples = 0 + inHarness = 0 + while True: + badSamples += 1 + if self.expect(analogIn, + [ 0, 0 ], + [ (4.5, 5.5), (-0.1, 0.1), + (4.5, 5.5), (-0.1, 0.1) ], + N=50, + message='Checking if in test harness 1'): + badSamples = 0 + pass + if self.expect(analogIn, + [ 0, 0 ], + [ (-0.1, 0.1), (4.5, 5.5), + (-0.1, 0.1), (4.5, 5.5) ], + N=50, + message='Checking if in test harness 2'): + badSamples = 0 + pass + inHarness += 1 + if badSamples > 4: + break + pass + + if inHarness < 10: + # Read values from grounded inputs + while not self.expect(analogIn, + [ -9, 9 ], + [ (-0.1, 0.1), (-0.1, 0.1), + (-0.1, 0.1), (-0.1, 0.1) ], + N=500, + message='Ground all input pins'): + pass pass # Connect AOut0 -> AIn0,AIn2 (+9V) @@ -197,7 +258,7 @@ class ChinaIO: pass best = [ sorted(candidate[0], key=lambda x: abs(x[1].mean())), sorted(candidate[1], key=lambda x: abs(x[1].mean())) ] - print("Done %x %x : %x %x" % (v0, v1, best[0][0][0], best[1][0][0])) + self.print("Done %x %x : %x %x" % (v0, v1, best[0][0][0], best[1][0][0])) v0 = best[0][0][0] v1 = best[0][0][0] self.setCalibration(0, v0) @@ -210,9 +271,9 @@ class ChinaIO: self.setVoltage(0, 9) self.setVoltage(1, 9) max_sample = self.measure(analogIn, N=200, message='Max (+9V)') - print("0: Min: %f, Max: %f" % (min_sample[0].mean() / 9 * 10, + self.print("0: Min: %f, Max: %f" % (min_sample[0].mean() / 9 * 10, max_sample[0].mean() / 9 * 10)) - print("1: Min: %f, Max: %f" % (min_sample[1].mean() / 9 * 10, + self.print("1: Min: %f, Max: %f" % (min_sample[1].mean() / 9 * 10, max_sample[1].mean() / 9 * 10)) def millivolt(v): return int(v * 1000) @@ -228,15 +289,19 @@ class ChinaIO: tmp = (int(-value * 1000) << 8) | 0x80 | index else: tmp = (int(value * 1000) << 8) | index - print("%d %8x" % (index, tmp)) + self.print("%d %8x" % (index, tmp)) self.io.setchannel(31, tmp, 0xffffffff) -if __name__ == "__main__": - io = ChinaIO(sys.argv[1]) + +def main(stdscr): + io = ChinaIO(stdscr, sys.argv[1]) try: io.calibrate() - except: - traceback.print_exc() pass + finally: + io.close() + pass + pass - io.close() +if __name__ == "__main__": + curses.wrapper(main)