# arduino_rfid_controller / ThreeWireMatrix / rl.py

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141``` ```import itertools,time,sys from math import sqrt # This assumes a pin arrangement of: # GND->a->p1->b->p2->c->p3->d->p4->e->p5->f->p6->g->p7->h->VCC class AnalogMatrixKeypadSolver: def __init__(self,cols,rows,tap): self.tap = tap self.rows = rows self.cols = cols def calcResistances(self,resistors): ka = {} assert len(resistors) == len(self.rows)+len(self.cols)+1 for r in range(0,len(self.rows)): for c in range(0,len(self.cols)): key = r*len(self.cols)+c+1 if self.rows[r] < self.cols[c]: a = self.rows[r] b = self.cols[c] else: b = self.rows[r] a = self.cols[c] totalResistanceList = list(resistors) del totalResistanceList[a:b] groundResistanceList = list(resistors[0:self.tap]) del groundResistanceList[a:b] ka[key] = {'g':groundResistanceList,'t':totalResistanceList} return ka def printKeyFunctions(self,resistors): assert len(resistors) == len(self.rows)+len(self.cols)+1 rs = self.calcResistances(resistors) for r in rs: print "k%02i = (%s)/(%s)" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']])) def printKeyFunctions(self,resistors): assert len(resistors) == len(self.rows)+len(self.cols)+1 rs = self.calcResistances(resistors) for r in rs: print "k%02i = (%s)/(%s)" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']])) def printKeyFunctionsSolved(self,resistors): assert len(resistors) == len(self.rows)+len(self.cols)+1 rs = self.calcResistances(resistors) for r in rs: print "k%02i = (%s)/(%s) = %s" % (r,"+".join([str(s) for s in rs[r]['g']]),"+".join([str(s) for s in rs[r]['t']]),float(sum(rs[r]['g']))/float(sum(rs[r]['t']))*1024) def minDiff(self,resistors,m=None): # assert len(resistors) == len(self.rows)+len(self.cols)+1,"Expecting %s resistor values, but got %s" % (len(self.rows)+len(self.cols)+1,len(resistors)) rs = self.calcResistances(resistors) numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t'])))*1024 for r in rs] if len(set(numberList)) < len(numberList): return 0 a=sorted(numberList) b= [] for x,y in zip(a,a[1:]): s = y-x if s < m: return 0 b.append(s) return int(min(b)) #return int(min(y-x for x,y in zip(a,a[1:]))) def printKeyRanges(self,resistors): rs = self.calcResistances(resistors) numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t'])))*1024 for r in rs] for i,r in enumerate(rs): print "k%02i = %s" % (r,numberList[i]) def stdDev(self,resistors): assert len(resistors) == len(self.rows)+len(self.cols)+1,"Expecting %s resistor values, but got %s" % (len(self.rows)+len(self.cols)+1,len(resistors)) rs = self.calcResistances(resistors) numberList = [(float(sum(rs[r]['g']))/float(sum(rs[r]['t']))) for r in rs] n = len(numberList) mean = sum(numberList) / float(n) std = 0 for a in numberList: std = std + (a - mean)**2 std = sqrt(std / float(n-1)) return std*1024 ############################################################################### TAP_PIN = 3 MATRIX_ROWS = [2,7,6,4] MATRIX_COLS = [3,1,5] RESISTORS = [ 560, # a 8200, # b 18000, # c 910, # d 9100, # e 15000, # f 5100, # g 51 # h ] RESISTORS_NAME = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ] def main(args): start = 0 if len(args) > 0: start = int(args[0]) E12 = [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2] E12C = itertools.product(E12 + [x * 10 for x in E12] + [x * 100 for x in E12] + [x * 1000 for x in E12] + [x * 10000 for x in E12] + [x * 100000 for x in E12] + [x * 1000000 for x in E12] + [x * 10000000 for x in E12], repeat=len(MATRIX_COLS)+len(MATRIX_ROWS)+1) E12C = itertools.product(E12 + [x * 10 for x in E12] + [x * 100 for x in E12] + [x * 1000 for x in E12], repeat=len(MATRIX_COLS)+len(MATRIX_ROWS)+1) E12C = itertools.permutations([x * 100 for x in E12], len(MATRIX_COLS)+len(MATRIX_ROWS)+1) E12C = itertools.permutations([1000,1200,1500,1800,2200,2700,3300,3900,4700,5600,6800,8200], len(MATRIX_COLS)+len(MATRIX_ROWS)+1) E12C = itertools.permutations([560,8200,18000,910,9100,15000,5100,51], len(MATRIX_COLS)+len(MATRIX_ROWS)+1) E12C = itertools.permutations([x*100 for x in E12] + [x*1000 for x in E12], len(MATRIX_COLS)+len(MATRIX_ROWS)+1) amks = AnalogMatrixKeypadSolver(MATRIX_COLS,MATRIX_ROWS,TAP_PIN) amks.printKeyFunctions(RESISTORS_NAME) amks.printKeyFunctionsSolved([1000, 1200, 10000, 1500, 4700, 8200, 1800, 2200]) return g = 1 skip = start t1 = time.time() i = 0 try: for i,p in enumerate(itertools.islice(E12C,skip,None)): g1 = amks.minDiff(list(p),g) if g1 >= g: g = g1 print i+skip,g,":",list(p) except KeyboardInterrupt: print print "ending on %s" % i t2 = time.time() #print 'took %0.3f ms' % (((t2-t1)*1000.0)/50000) if __name__ == '__main__': main(sys.argv[1:]) ```