WIP vdiv regulator control
authorDan White <dan@whiteaudio.com>
Mon, 30 Jan 2012 18:18:54 +0000 (12:18 -0600)
committerDan White <dan@whiteaudio.com>
Mon, 30 Jan 2012 18:18:54 +0000 (12:18 -0600)
sch-pcb/devboard/vreg.py

index 9068031b7cbeedcc9295e09c632569f90b696182..4ecf4fe3e1fd2f4fa70b0b7415cb6231d8c12401 100644 (file)
@@ -5,6 +5,9 @@ from scipy import optimize as opt
 
 from wag import engstr as es
 
+close('all')
+
+
 def rvals(Vrange, Rpot):
     Vmax = max(Vrange)
     Vmin = min(Vrange)
@@ -12,11 +15,13 @@ def rvals(Vrange, Rpot):
     R1 = (R2 + Rpot) * (2*Vmin - 1)
     return [R1, R2]
 
-def vout(n, r1, r2, Rpot=1.0, Vref=0.5, Rshunt=None):
+def vout(n, r1, r2, Rpot=1.0, Vref=0.5, Rshunt=None, Rtop=None):
     ra = ((1-n)*Rpot+r1)
     rb = (n*Rpot+r2)
     if Rshunt:
         return Vref*(1 + ra/(rb*Rshunt/(rb+Rshunt)))
+    elif Rtop:
+        return Vref*(1 + (ra*Rtop/(ra+Rtop))/rb)
     else:
         return Vref*(1 + ra/rb)
 
@@ -24,34 +29,12 @@ 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)
-
-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):
@@ -59,14 +42,12 @@ def parallel(x,y):
 
 
 
-xopt = []
-def optfunc(x):
-    #r1 = x[0]
+def optfunc0(x):
     r2 = x[0]
     rs = x[1]
-    rs = 53.6e3
+    #rs = 53.6e3
 
-    xopt.append(x)
+    xopt0.append(x)
 
     #saturate
     if r2 < 0.0:
@@ -78,10 +59,6 @@ def optfunc(x):
 
     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
 
@@ -89,48 +66,192 @@ def optfunc(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)
-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)
-#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')
-
-figure()
-plot(n[:-1], -diff(vo))
-print mean(-diff(vo))
+def optfunc1(x):
+    r2 = x[0]
+    rs = x[1]
+    r1 = x[2]
+
+    xopt1.append(x)
+
+    #saturate
+    if r2 < 0.0:
+        r2 = 1.0
+        print 'clipped r2'
+    if rs < 0.0:
+        rs = 1.0
+        print 'clipped rs'
+
+    g0 = Vref*(1 + (Rpot + r1)/parallel(r2, rs)) - Vmax
+    g0 = 1000*g0
+
+    g1 = Vref*(1 + (Rpot/2 + r1)/parallel(rs, (Rpot/2 + r2))) - Vini
+    g1 = 100*g1
+
+    g2 = Vref*(1 + (r1)/parallel(rs, (Rpot + r2))) - Vmin
+    g2 = 1000*g2
+
+    return [g0, g1, g2]
+
+
+#
+# 1.2 nominal supply
+#
+if 1:
+    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)
+
+    n = arange(0, 1, 1/256.0)
+
+    def dolimits():
+        yticks(arange(Vref, Vmax+1, 0.1))
+        ylim([0.5, 2.0])
+        xticks(arange(0, 1.1, 0.1))
+
+    #no shunt, calculated values
+    figure()
+    suptitle('1.2 V supply')
+    subplot(131)
+    plot(1-n, vout(n, r1, r2, Rpot, Vref), 'x')
+    dolimits()
+    xlabel('No shunt')
+    title('r1=%s\nr2=%s' % (es(r1), es(r2)))
+
+    # find an optimixed r2 and Rshunt
+    #xini = [r1, r2, Rpot]
+    xopt0 = []
+    xini = [r2, Rpot/2]
+    xout = opt.nonlin.broyden3(optfunc0, xini, iter=10, alpha=0.2, verbose=True)
+    xout = array(xout)
+
+    print 'r2opt:', es(xout[0])
+    print 'rsopt:', es(xout[1])
+
+    subplot(132)
+    r2opt, Rsopt = xout
+    plot(1-n, vout(n, r1, r2opt, Rpot, Vref, Rshunt=Rsopt), 'x')
+    plot(1-n, (Vmax-Vmin)*(1-n)+Vref)
+    plot(0.5, 1.2, 'or')
+    plot(0.5, Vini, 'og')
+    dolimits()
+    xlabel('optimized shunt')
+    title('r1=%s\nr2=%s\nrs=%s' % (es(r1opt), es(r2opt), es(Rsopt)))
+
+
+    subplot(133)
+    r2fix = 187e3
+    Rshuntfix = 52.3e3
+    plot(1-n, vout(n, r1, r2fix, Rpot, Vref, Rshunt=Rshuntfix), 'x')
+    plot(1-n, (Vmax-Vmin)*(1-n)+Vref)
+    plot(0.5, 1.2, 'or')
+    plot(0.5, Vini, 'og')
+    dolimits()
+    xlabel('discretized shunt')
+    title('r1=%s\nr2=%s\nrs=%s' % (es(r1fix), es(r2fix), es(Rshuntfix)))
+
+    savefig('rdac-1v2.pdf')
+
+    #fit a polynomial to the discretized function
+    vo = vout(n, r1, r2fix, Rpot, Vref, Rshunt=Rshuntfix)
+    p = np.polyfit((1-n), vo, 2)
+    print '2nd order polynomial fit to Vout vs n:'
+    print p
+
+    #figure()
+    #plot([j[0] for j in xopt0], [j[1] for j in xopt0], '-o')
+    #title('Optimization path')
+
+
+#
+# 2.5 nominal supply
+#
+if 1:
+    Rpot = 100e3
+    Vref = 0.5
+    Vmin = 1.2
+    Vmax = 2.7
+    #Vmin = 2.3
+    #Vmax = 2.7
+    #Vini = 2.5
+    Vini = Vmin + (Vmax-Vmin)/2 #- 100e-3
+    #Vmax = 2*(Vini-Vref) + Vref
+    assert(Vmin >= Vref)
+
+    r1, r2 = rvals([Vmin, Vmax], Rpot)
+
+    print es(r1), es(r2)
+
+    n = arange(0, 1, 1/256.0)
+
+    def dolimits():
+        yticks(arange(Vref, Vmax+1, 0.1))
+        ylim([0.5, 3.0])
+        xticks(arange(0, 1.1, 0.1))
+
+    #no shunt, calculated values
+    figure()
+    suptitle('2.5 V supply')
+    subplot(131)
+    plot(1-n, vout(n, r1, r2, Rpot, Vref), 'x')
+    dolimits()
+    xlabel('No shunt')
+    title('r1=%s\nr2=%s' % (es(r1), es(r2)))
+
+    # find an optimixed r2 and Rshunt
+    #xini = [r1, r2, Rpot]
+    xopt1 = []
+    #xini = [r2, r2*100, r1]
+    xini = [r2*10, r2, r1]
+    xout = opt.nonlin.broyden3(optfunc1, xini, iter=10, alpha=0.2, verbose=True)
+    xout = array(xout)
+
+    print 'r2opt:', es(xout[0])
+    print 'rsopt:', es(xout[1])
+    print 'r1opt:', es(xout[2])
+
+    subplot(132)
+    r2opt, Rsopt, r1opt = xout
+    plot(1-n, vout(n, r1opt, r2opt, Rpot, Vref, Rshunt=Rsopt), 'x')
+    plot(1-n, (Vmax-Vmin)*(1-n)+Vmin)
+    plot(0.5, 2.5, 'or')
+    plot(0.5, Vini, 'og')
+    dolimits()
+    xlabel('optimized shunt')
+    title('r1=%s\nr2=%s\nrs=%s' % (es(r1opt), es(r2opt), es(Rsopt)))
+
+
+    subplot(133)
+    #r2opt:  210.668E+03
+    #rsopt:   40.261E+03
+    #r1opt:   49.033E+03
+    r2fix = 210e3
+    Rsfix = 40.2e3
+    r1fix = 48.7e3
+    plot(1-n, vout(n, r1fix, r2fix, Rpot, Vref, Rshunt=Rsfix), 'x')
+    plot(1-n, (Vmax-Vmin)*(1-n)+Vmin)
+    plot(0.5, 2.5, 'or')
+    plot(0.5, Vini, 'og')
+    dolimits()
+    xlabel('discretized shunt')
+    title('r1=%s\nr2=%s\nrs=%s' % (es(r1fix), es(r2fix), es(Rsfix)))
+
+    savefig('rdac-2v5.pdf')
+
+    #fit a polynomial to the discretized function
+    vo = vout(n, r1fix, r2fix, Rpot, Vref, Rshunt=Rsfix)
+    p = np.polyfit((1-n), vo, 2)
+    print '2nd order polynomial fit to Vout vs n:'
+    print p
+
+    #figure()
+    #plot([j[0] for j in xopt1], [j[1] for j in xopt1], '-o')
+    #title('Optimization path')
+