Commit 64da2a2f authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Make calibrator use curses, add sopport for tes-harness

parent 8756dffa
......@@ -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)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment