Optimized R-vals with shunt
authorDan White <dan@whiteaudio.com>
Sun, 29 Jan 2012 23:13:10 +0000 (17:13 -0600)
committerDan White <dan@whiteaudio.com>
Sun, 29 Jan 2012 23:13:10 +0000 (17:13 -0600)
sch-pcb/devboard/vreg.py

index ba0692eb59e1d77e7ca54607f451e98bc395c1d0..9068031b7cbeedcc9295e09c632569f90b696182 100644 (file)
@@ -1,6 +1,8 @@
 #!/usr/bin/env python
 
 from pylab import *
+from scipy import optimize as opt
+
 from wag import engstr as es
 
 def rvals(Vrange, Rpot):
@@ -10,8 +12,17 @@ def rvals(Vrange, Rpot):
     R1 = (R2 + Rpot) * (2*Vmin - 1)
     return [R1, R2]
 
-def vout(n, r1, r2, Rpot=1.0, Vref=0.5):
-    return Vref*(1 + ((1-n)*Rpot+r1)/(n*Rpot+r2))
+def vout(n, r1, r2, Rpot=1.0, Vref=0.5, Rshunt=None):
+    ra = ((1-n)*Rpot+r1)
+    rb = (n*Rpot+r2)
+    if Rshunt:
+        return Vref*(1 + ra/(rb*Rshunt/(rb+Rshunt)))
+    else:
+        return Vref*(1 + ra/rb)
+
+def shuntR(Vini, Vref, r1, r2, Rpot):
+    y = Vini/Vref - 1
+    return (2*r1 + Rpot) * (2*r2 + Rpot) / (2*(2*y*r2 - 2*r1 + y*Rpot - Rpot))
 
 n = arange(0, 1, 1/256.0)
 
@@ -20,26 +31,106 @@ Rpot = 100e3
 Vref = 0.5
 Vmin = 0.5
 Vmax = 1.8
+Vini = Vmin + (Vmax-Vmin)/2 - 50e-3
+Vmax = 2*(Vini-Vref) + Vref
 assert(Vmin >= Vref)
 
 r1, r2 = rvals([Vmin, Vmax], Rpot)
 
 print es(r1), es(r2)
 
+def dolimits():
+    yticks(arange(Vref, Vmax+1, 0.1))
+    ylim([0.5, 2.0])
+    xticks(arange(0, 1.1, 0.1))
+
 close('all')
 
 subplot(131)
 plot(1-n, vout(n, r1, r2, Rpot, Vref), 'x')
+dolimits()
+
+
+print 'Rshunt:', es(Rshunt)
+
+
+def parallel(x,y):
+    return x*y/(x+y)
+
+
+
+xopt = []
+def optfunc(x):
+    #r1 = x[0]
+    r2 = x[0]
+    rs = x[1]
+    rs = 53.6e3
+
+    xopt.append(x)
+
+    #saturate
+    if r2 < 0.0:
+        r2 = 0.0
+        print 'clipped r2'
+    if rs < 0.0:
+        rs = 0.0
+        print 'clipped rs'
+
+    g0 = Vref*(1 + (Rpot + r1)/parallel(r2, rs)) - Vmax
+    g0 = 1000*g0
+    #if g0 > 0:
+        #g0 = 1000*g0
+    #else:
+        #g0 = 100*g0
+    g1 = Vref*(1 + (Rpot/2 + r1)/parallel(rs, (Rpot/2 + r2))) - Vini
+    g1 = 100*g1
+
+    #print x
+
+    return [g0, g1]
+
+#xini = [r1, r2, Rpot]
+xini = [r2, Rpot/2]
+xout = opt.nonlin.broyden3(optfunc, xini, iter=10, alpha=0.2, verbose=True)
+xout = array(xout)
+
+print 'r2opt:', es(xout[0])
+print 'rsopt:', es(xout[1])
+
+
 
 subplot(132)
-r2mod = ((r1+Rpot/2)/1.4-Rpot/2)
-plot(1-n, vout(n, r1, r2mod, Rpot, Vref), 'x')
-ylabel('fixed r1')
+r2, Rshunt = xout
+plot(1-n, vout(n, r1, r2, Rpot, Vref, Rshunt=Rshunt), 'x')
+plot(1-n, (Vmax-Vmin)*(1-n)+Vref)
+plot(0.5, 1.2, 'or')
+plot(0.5, Vini, 'og')
+dolimits()
+xlabel('optimized shunt')
+
 
 subplot(133)
-r1mod = (1.4*(r2+Rpot/2)-Rpot/2)
-plot(1-n, vout(n, r1mod, r2, Rpot, Vref), 'x')
-ylabel('fixed r2')
+#r2opt:  187.100E+03
+#rsopt:   52.170E+03
+r2 = 187e3
+#Rshunt = 51.1e3
+Rshunt = 52.3e3
+#Rshunt = 53.6e3
+plot(1-n, vout(n, r1, r2, Rpot, Vref, Rshunt=Rshunt), 'x')
+plot(1-n, (Vmax-Vmin)*(1-n)+Vref)
+plot(0.5, 1.2, 'or')
+plot(0.5, Vini, 'og')
+dolimits()
+xlabel('discretized shunt')
+
+#fit a polynomial to the function
+vo = vout(n, r1, r2, Rpot, Vref, Rshunt=Rshunt)
+p = np.polyfit((1-n), vo, 2)
+print p
+
+figure()
+plot([j[0] for j in xopt], [j[1] for j in xopt], '-o')
 
-print 'r1mod:', es(r1mod)
-print 'r2mod:', es(r2mod)
+figure()
+plot(n[:-1], -diff(vo))
+print mean(-diff(vo))