Differences

This shows you the differences between two versions of the page.

Link to this comparison view

gnucap:manual:examples:phase_shift_oscillator [2015/12/11 15:39] (current)
Line 1: Line 1:
 +====== Phase shift oscillator ======
  
 +===== Getting started =====
 +
 +In this example, we will analyze a phase shift oscillator.  It was designed in a hurry, so the specs are not expected to be very good.  We will see.
 +
 +It uses a single BJT, plus an emitter follower, and runs on a single-ended 12 volt supply.
 +
 +Some measurements might include:
 +
 +  - Oscillation frequency
 +  - Start-up time (how long it takes to stabilize)
 +  - Distortion
 +
 +Of course, we will look at the waveform.
 +
 +I did this on the 2008-07-07 development snapshot, using some new features.  I am not showing some of the mistake and trial steps, so your results may be a little different.
 +
 +I am using an external waveform viewer "gwave" to display the waveforms.
 +
 +That's enough for now, let's go...
 +
 +===== The circuit =====
 +
 +{{gnucap:pso.tar.gz|Here's a netlist for the circuit:}}
 +
 +  ' phase shift oscillator
 +  .model npn npn bf=100
 +  Vcc (vcc 0) pulse(iv=0 pv=12 rise=.01)
 +  Rb1 (vcc b) 100k
 +  Rb2 (b 0)   10k
 +  Rc  (vcc c) 10k
 +  Re  (e 0)   1k
 +  Ce  (e 0)   5000u
 +  Re2 (e2 0)  1k
 +  Q1  (c b e)    npn
 +  Q2  (vcc c e2) npn
 +  C1  (e2 f1) .01u
 +  C2  (f1 f2) .01u
 +  C3  (f2 b)  .01u
 +  Rf1 (f1 0)  10k
 +  Rf2 (f2 0)  10k
 +
 +There are some tricks here ..
 +
 +First, the power supply (Vcc).  It is a voltage source, but instead of just saying "DC=12" to make it a constant 12 volt supply, I made it a pulse.  It starts at zero, and waits until time=.01 to switch on.  I did this because I want to see how it starts.
 +
 +With just plain "DC=12" it would still oscillate, but I cannot be sure of the actual start waveform.  For one, the emitter bypass would already be charged.
 +
 +Next, I used a simple model of the BJT, specifying only the beta.
 +
 +The emitter bypass gives a time constant of 5 seconds, which should make the start-up nice and slow.
 +
 +Finally, to show some contempt for good design, I just picked R and C for the filter arbitrarily, with no real idea what the frequency would be.
 +
 +===== Setting up =====
 +
 +Run it interactively ...
 +
 +  $$$$$$$gnucap
 +  Gnucap 2008.07.07 RCS 26.86
 +  The Gnu Circuit Analysis Package
 +  Never trust any version less than 1.0
 +  Copyright 1982-2007, Albert Davis
 +  Gnucap comes with ABSOLUTELY NO WARRANTY
 +  This is free software, and you are welcome
 +  to redistribute it under the terms of 
 +  the GNU General Public License, version 3 or later.
 +  See the file "COPYING" for details.
 +  gnucap> get pso.ckt
 +  ' phase shift oscillator
 +
 +Load the circuit .. it echos the title line.
 +
 +As a check, list it, see if it is what you expected.
 +
 +  gnucap> list
 +  .model npn npn ( level=1 kf=NA( 0.) af=NA( 1.) bf= 100. br=NA( 1.) is=NA( 100.E-18) nf=NA( 1.) nr=NA( 1.) isc=NA( 
 +   0.) re=NA( 0.) rc=NA( 0.) cjc=NA( 0.) cje=NA( 0.) cjs=NA( 0.) fc=NA( 0.5) mjc=NA( 0.33) mje=NA( 0.33) mjs=NA( 0.)
 +   tf=NA( 0.) tr=NA( 0.) xtf=NA( 0.) xtb=NA( 0.) xti=NA( 3.) eg=NA( 1.11))
 +  Vcc ( vcc 0 ) pulse iv= 0. pv= 12. delay=NA( 0.) rise= 0.01 fall=NA( 0.) width=NA( Inf) period=NA( Inf)
 +  Rb1 ( vcc b )  100.K
 +  Rb2 ( b 0 )  10.K
 +  Rc ( vcc c )  10.K
 +  Re ( e 0 )  1.K
 +  Ce ( e 0 )  0.005
 +  Re2 ( e2 0 )  1.K
 +  Q1 ( c b e )  npn NA( 1.)
 +  Q2 ( vcc c e2 )  npn NA( 1.)
 +  C1 ( e2 f1 )  10.n
 +  C2 ( f1 f2 )  10.n
 +  C3 ( f2 b )  10.n
 +  Rf1 ( f1 0 )  10.K
 +  Rf2 ( f2 0 )  10.K
 +
 +Looks good ..  note the "NA" fields ....  NA(5) means that the value is unspecified, but assumed to be 5.  You can see what parameters were specified, and which took the defaults.
 +
 +Before making a run, you need to set a few things up ...
 +
 +Pick the points you want to view (all node voltages):
 +  gnucap> print tran v(nodes)
 +
 +Pick the points you want to be able to do things like "measure" on (all probes named "v" on anything, including nodes, devices, etc):
 +  gnucap> store tran v(*)
 +
 +Now, check the options.  We may want to change some:
 +  gnucap> opt 
 +  .options  noacct  nolist  mod  nopage  nonode  noopts  gmin= 1.p  reltol= 0.001  abstol= 1.p  vntol= 1.u  trtol= 7
 +  0  limtim=2  limpts=201  lvlcod=2  lvltim=2  method=trap  maxord=2  itl1=100  itl2=50  itl3=6  itl4=20  itl5=5000 
 +  er  dampmax= 1.  dampmin= 0.5  dampstrategy=0  floor= 1.E-21  vfloor= 1.f  roundofftol= 100.f  temperature= 27.  s
 +  ansits=2  nodupcheck  bypass  incmode  lcbypass  lubypass  fbbypass  traceload  itermin=1  vmax= 5.  vmin=-5.  dtm
 +  old= 1.E+99  trstepshrink= 2.  trreject= 0.5  trsteporder=3  trstepcoef1= 0.25  trstepcoef2= 0.04166667  trstepcoe
 +   units=spice
 +
 +The only one I will change now is the printing precision .. Set it to 8 digits.  Starting an oscillator takes a long time.
 +  gnucap> opt numdgt=8
 +
 +===== Get started, run to steady state =====
 +
 +For starters, let's run it for 10 seconds, with a trial time step of .01.  "trace all" says to output all of the internal time steps too.  Otherwise, you will just get the ones you asked for.
 +
 +I directed it to a file, boringly called "z".  Then look at it with "gwave".  The bang (!) says to run a command through the shell.  The ampersand (&) says to leave it running and return, just like a shell command.  That way we can keep the waveforms on the screen and keep going.
 +
 +  gnucap> tran 0 10 .01 trace all >z
 +  gnucap> !gwave z &
 +
 +
 +
 +
 +Here's the waveform.  It looks like it doesn't start oscillating until about 1 second.
 +Then takes until about 5 seconds to settle.  It looks like 10 seconds was a good guess.
 +
 +{{gnucap:w1.png}}
 +
 +Here's an expanded view just as it starts to oscillate:
 +
 +{{gnucap:w7.png}}
 +
 +The last few cycles at the end of the run:
 +
 +{{gnucap:w8.png}}
 +
 +===== The measurements we want =====
 +
 +Now, tighten the tolerance, so we can get good measurements.  The default settings are fine most of the time, but for this we need better.
 +
 +See what they are:
 +  gnucap> opt
 +  .options  noacct  nolist  mod  nopage  nonode  noopts  gmin= 1.p  reltol= 0.001  abstol= 1.p  vntol= 1.u  trtol= 7.  chgtol= 10.f  pivtol= 100.f
 +  pivrel= 0.001  numdgt=8  tnom= 27.  cptime=30000  limtim=2  limpts=201  lvlcod=2  lvltim=2  method=trap  maxord=2  itl1=100  itl2=50  itl3=6
 +  itl4=20  itl5=5000  itl6=0  itl7=1  itl8=99  defl= 100.u  defw= 100.u  defad= 0.  defas= 0.  clobber  dampmax= 1.  dampmin= 0.5  dampstrategy=0
 +  floor= 1.E-21  vfloor= 1.f  roundofftol= 100.f  temperature= 27.  short= 10.u  out=9999  ydivisions= 4.  phase=degrees  order=auto  mode=mixed
 +  transits=2  nodupcheck  bypass  incmode  lcbypass  lubypass  fbbypass  traceload  itermin=1  vmax= 5.  vmin=-5.  dtmin= 1.p  dtratio= 1.G  rstray
 +  cstray  harmonics=9  trstepgrow= 1.E+99  trstephold= 1.E+99  trstepshrink= 2.  trreject= 0.5  trsteporder=3  trstepcoef1= 0.25  trstepcoef2=
 +  0.04166667  trstepcoef3= 0.005208333  noquitconvfail  edit  recursion=20  language=acs  insensitive  units=spice
 +
 +Now tighten "reltol" and "trtol".
 +  gnucap> opt reltol=.0001 trtol=1
 +
 +and run for another .01 seconds, continuing...
 +  gnucap> tran 10.01 .001 trace all >z
 +  gnucap> !gwave z &
 +
 +and make some measurements...
 +  gnucap> measure t2=cross("v(e2)", cross=7, rise, last)
 +  t2= 10.00943
 +  gnucap> measure t1=cross("v(e2)", cross=7, rise, last, before=t2)
 +  t1= 10.00778
 +  gnucap> param frequency={1/(t2-t1)}
 +  gnucap> eval frequency
 +  frequency= 606.060606060714
 +
 +For the Fourier analysis, pick a fundamental of half of the real fundamental, as an indicator of accuracy.  We all know, there should be nothing there.  If the component at the odd frequencies is too big, it means the frequency we specified is slightly in error, and we need to tighten tolerances and fine tune.
 +
 +  gnucap> eval frequency/2
 +  (frequency / 2)= 303.030303030357
 +  gnucap> print fourier v(e2)
 +  gnucap> fourier 0 10k 303.030303030357
 +  #Time          v(e2)        
 +   10.0133       8.9974012    
 +   10.013326     8.7969959    
 +   10.013352     8.5847199  
 +
 +   10.016574     9.0517243    
 +   10.0166       8.8549586    
 +  # v(e2)     --------- actual ---------  -------- relative --------
 +  #freq       value        dB      phase  value        dB      phase
 +   0.         7.0656      16.98   90.000  2.2861       7.18  -44.748
 +   303.03     0.034076   -29.35  118.607  0.011025   -39.15  -16.141
 +   606.06     3.0907       9.80  134.748  1.           0.00    0.000
 +   909.09     0.040746   -27.80  -43.182  0.013183   -37.60 -177.930
 +   1.2121K    0.3894      -8.19  -94.915  0.12599    -17.99  130.337
 +   1.5152K    0.017954   -34.92   17.761  0.0058088  -44.72 -116.987
 +   1.8182K    0.15704    -16.08    4.083  0.05081    -25.88 -130.665
 +   2.1212K    0.0042367  -47.46   67.220  0.0013708  -57.26  -67.528
 +   2.4242K    0.079307   -22.01   94.762  0.02566    -31.82  -39.986
 +
 +303 Hz has a relative amplitude of -39 db.  Not very good.
 +
 +Tighten the tolerances and measure again:
 +
 +  gnucap> opt reltol=.00001 trtol=1
 +  gnucap> tran 10.01 .001 trace all >z
 +  gnucap> measure t2=cross("v(e2)", cross=7, rise, last)
 +  t2= Inf
 +
 +Error ....  we already went past 10.01 seconds ..  Move ahead and try again.
 +
 +  gnucap> tran 10.03 .001 trace all >z
 +  gnucap> !gwave z &
 +  gnucap> measure t2=cross("v(e2)", cross=7, rise, last)
 +  t2= 10.02911
 +  gnucap> measure t1=cross("v(e2)", cross=7, rise, last, before=t2)
 +  t1= 10.02747
 +  gnucap> eval frequency/2
 +  (frequency / 2)= 304.878048780472
 +  gnucap> eval frequency
 +  frequency= 609.756097560944
 +  gnucap> fourier 0 10k 304.878048780472
 +  #Time          v(e2)        
 +   10.029986     6.3978311    
 +   10.030012     6.1507251    
 +   10.030037     5.9090503    
 +
 +   10.033189     7.1588976    
 +   10.033215     6.9059126    
 +   10.03324      6.6531773    
 +   10.033266     6.4023893    
 +  # v(e2)     --------- actual ---------  -------- relative --------
 +  #freq       value        dB      phase  value        dB      phase
 +   0.         7.0581      16.97   90.000  2.2836       7.17 -104.675
 +   304.88     256.82u    -71.81   -1.240  83.092u    -81.61  164.086
 +   609.76     3.0908       9.80 -165.325  1.           0.00    0.000
 +   914.63     0.0011098  -59.09 -171.143  359.08u    -68.90   -5.817
 +   1.2195K    0.38362     -8.32   21.927  0.12412    -18.12 -172.748
 +   1.5244K    103.52u    -79.70  178.156  33.493u    -89.50  -16.518
 +   1.8293K    0.14832    -16.58 -177.459  0.047988   -26.38  -12.133
 +   2.1341K    357.2u     -68.94 -179.519  115.57u    -78.74  -14.193
 +   2.439K     0.079273   -22.02  -23.966  0.025648   -31.82  141.360
 +   2.7439K    132.94u    -77.53 -126.976  43.011u    -87.33   38.350
 +   3.0488K    0.049584   -26.09  126.722  0.016043   -35.89  -67.952
 +   3.3537K    168.29u    -75.48  163.828  54.45u     -85.28  -30.847
 +   3.6585K    0.033637   -29.46  -84.750  0.010883   -39.27   80.575
 +   3.9634K    163.24u    -75.74 -138.899  52.816u    -85.54   26.426
 +   4.2683K    0.024012   -32.39   63.711  0.0077689  -42.19 -130.964
 +   4.5732K    52.818u    -85.54  168.840  17.089u    -95.35  -25.834
 +   4.878K     0.018021   -34.88 -148.890  0.0058308  -44.69   16.435
 +
 +That's better.  Noise is -68 db or better.  305 Hz is -81 db.
 +
 +As I said, the oscillator isn't very good.  The second harmonic is only 18 db below the fundamental.
 +
 +Enough for now...
gnucap/manual/examples/phase_shift_oscillator.txt · Last modified: 2015/12/11 15:39 (external edit)
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Run by Debian Driven by DokuWiki