Wien Bridge Oscillator

A Wien bridge oscillator is a type of electronic oscillator that generates sine waves. See https://en.wikipedia.org/wiki/Wien_bridge_oscillator.

Design calculations for Wien Bridge Oscillator. See page 21-1 of Handbook of Operational Amplifier Circuit Design, by David F. Stout and edited by Milton Kaufman. Reference designators match figure 21.1.

The Opamp used in the implementation is a LM324, from the TI datasheet:

Input bias current: 20nA
output offset voltage: 1.4 volts due to 20nA input bias current.  1.4 volts in the test condition measured under open loop conditions. 
unity gain frequency: 1.2 MHz

Notes:

  • The output offset voltage in the datasheet didn't seem to make sense when looking at the reference design, which used 0.1 volts as the output offset voltage.
  • The design equations suggest a value for R6 of 100 times R2. The reference design has this part as a pot. A value of 4.5 times R2 makes the spice simulation work better.
In [1]:
from math import *
In [2]:
# opamp parameters
Ib1 = 20.0e-9 #input bias current of A1
dVo_max = 0.1   #output offset due to bias current of A1
fu2 = 1.2e6  #unity gain cross over freuqncy of A1

#frequency of oscillation
fo = 1.0  #design frequency at mid band
In [3]:
# step 1: compute a value for R1_max
R1_max = dVo_max/Ib1
print('R1_max = {:.2f}'.format(R1_max))
R1_max = 5000000.00
In [4]:
#step 2: determine other resistor values
R2 = sqrt(R1_max)
R4 = R2
R5 = R2
R6 = R2
R3 = 1.1*R2
R6 = 4.5*R3    # 100.0*R3
# display resistor values
#print('R1 = {:.2f}'.format(R1))
print('R2 = {:.2f}'.format(R2))
print('R3 = {:.2f}'.format(R3))
print('R4 = {:.2f}'.format(R4))
print('R5 = {:.2f}'.format(R5))
print('R6 = {:.2f}'.format(R6))
R2 = 2236.07
R3 = 2459.67
R4 = 2236.07
R5 = 2236.07
R6 = 11068.54
In [5]:
#step 3: determine nominal values for C1 and C2
C1 = 1.0/(2.0*pi*fo*R2)
C2 = C1
#display capacitor values
print('C1 = {:.3e}'.format(C1))
print('C2 = {:.3e}'.format(C2))
C1 = 7.118e-05
C2 = 7.118e-05
In [6]:
#step 4: compute fixed portion of R1
R1_min = (R4**2.0/(4.0*pi**2.0*R2*C1*C2*fu2**2.0))**0.3333
print('R1_min = {:.2f}'.format(R1_min))
R1_min = 0.20
In [7]:
#step 5: compute frequency limits
fo_max = (fu2/(4.0*pi**2.0*R2*R4*C1*C2))**0.333
fo_min = (1/(2.0*pi))*(Ib1/(R2*C1*C2*dVo_max))**0.5
print('fo_min = {:f}'.format(fo_min))
print('fo_max = {:f}'.format(fo_max))
fo_min = 0.021147
fo_max = 105.771181
In [8]:
#step 6, oscillator frequency is recalculated
fo_min = 1/((2*pi)*(R1_max*R2*C1*C2)**0.5)
print('fo_min = {:f}'.format(fo_min))
R1_nom = R2
fo_nom = 1/((2*pi)*(R1_nom*R2*C1*C2)**0.5)
print('fo_nom = {:f}'.format(fo_nom))
R1_mid = (R1_min+R1_max)/2.0  #set R1 to be the mid point between min and max values of R1
fo_mid = 1/((2*pi)*(R1_mid*R2*C1*C2)**0.5)
print('fo_mid = {:f}'.format(fo_mid))
fo_max = 1/((2*pi)*(R1_min*R2*C1*C2)**0.5)
print('fo_max = {:f}'.format(fo_max))
fo_min = 0.021147
fo_nom = 1.000000
fo_mid = 0.029907
fo_max = 106.257253
In [ ]: