.. _hp5065_c_driver2: C-field driver - again ======================= After some work I have designed at this C-field driver: .. image:: A15_cfld.svg The main change since :ref:`first version ` a couple of extra resistors supply the stable current for the buried zener in the LM399 voltage reference. I've run a monte-carlo analysis for the tempco of the components over a ±10 {K} temperature range. VCC & R4 -------- VCC is the +20V regulated supply, which I allowed to vary ±0.5 {V} If R4 is 1M with 100 {ppm/K} tempco, the frequency noise is 6.5e-17 {s/s}. If R4 is 100k with 100 {ppm/K} tempco, the frequency noise is 5.7e-16 {s/s}. I have not checked how small R4 needs to be to ensure startup, but given the low offset voltage of U1, I don't expect problems. R2 & R3 ------- The voltage over these is the same (± U1's Vos) and their ratio sets the U2 zener current relative to the C-field current. With 50 {ppm/K} each of them contributes 6.7e-17 {s/s} frequency noise. U1 -- LT1007 has a guaranteed max drift with temperature of 0.6 {µV/K}, which contributes 1.1e-15 {s/s} frequency noise. There is no need to trim the offset of U1. R1 & U2 ------- R1 is a Vishay Z201 with a *typical* tempco of ±0.2 {ppm/K} U2 is a LM399 (without -A suffix) with a *typical* tempco 0.3 {ppm/K} If we use these typical tempcos, the frequency noise is 4.3e-15 {s/s} If we use the max tempco, 2 {ppm/K}, for the LM399 and the typical for R1, the noise rises to 2.4e-14 which is above my 1e-14 {s/s} goal. There is no max tempco specified for the Z201, and the datasheet doesn't give me high confidence that the typical is very typical after all. Temperature ----------- The limiting factor is R1 and U2, and all in all there is about 1.5 {ppm/K} tempco to share between them. Of course ±10 {K} is a pretty brutal condition for a device which presumably lives in a somewhat civilized laboratory. If we can keep the excursions to ±2{K}, then R1 can have 3 {ppm/K} tempco and still stay below target. Tunable C-field current ----------------------- Mechanical trimmers have two digit tempcos, and since they would go between U2 and U1, math isn't even necessary. A digital solution *may* be possible, there are special DACs for driving 4-20 {mA} industrial circuits, for instance Analog's AD5422, which could possibly be beaten into submission, given a good external reference. That would be neat, since it would open the way for a GPS discipline implementation, but that is a project for another day. Right now I just want to get the Fluke 732A and the long wire out of the picture. Monte-Carlo Code ---------------- Here is my monte-carlo simulation in python:: #!/usr/bin/env python # # # VCC # | # | # R4 # | |\ # *--------------| \ # | | >--- L1 --+ # | +--| / | # | | |/ | # | | | # *---- R3 -------+-----------+ # | | | # | | R2 # | | | # D1 +---* # | | # | R1 # | | # GND GND # from __future__ import print_function import random import math def calc(comp): d = dict(comp) for i in range(5): d["vr1"] = d["D1"] + d["U1"] d["ir1"] = d["vr1"] / d["R1"] d["vr2"] = d["ir1"] * d["R2"] d["vl1"] = d["ir1"] * d["L1"] d["vout"] = d["vl1"] + d["vr2"] + d["vr1"] d["vr3"] = d["vr1"] + d["vr2"] - d["D1"] d["ir3"] = d["vr3"] / d["R3"] d["ir4"] = (d["VCC"] - d["D1"]) / d["R4"] d["id1"] = d["ir3"] + d["ir4"] d["D1"] = comp["D1"] + d["id1"] * .66 return d def show(d): l = d.keys() l.sort() for i in l: print("%s\t%17.9f" % (i, d[i])) def ppm(n): r = random.uniform(-n, n) r *= 1e-6 r += 1.0 return r comp0 = { "R1": 5000./3, # Ohm #"R1": 1000., # Ohm "R2": 500, # Ohm "R3": 2000, # Ohm "R4": 1e5, # Ohm "D1": 6.9, # Volt "L1": 12.0, # Ohm "U1": 0.0, # Volt "VCC": 20.0, # Volt } d = calc(comp0) show(d) iref = d["ir1"] sy = 0.0 syy = 0.0 n = 0.0 for i in range(1000): x = dict(comp0) dt = 10 # 2.4e-15 @ 2ppm (LM399), +/- 10K x["D1"] *= ppm(2 * dt) # 2.5e-15 @ .2ppm (Z201 TYP!), +/- 10K x["R1"] *= ppm(3.0 * dt) # 1.1e-15 @ .6PPM/K (LT1007A), +/- 10K x["U1"] = 1e-6 * random.uniform(-.6 * dt, .6 * dt) # 6.7e-17 @ 50pmm, +/- 10K x["R3"] *= ppm(50 * dt) # 6.7e-17 @ 50ppm, +/- 10K x["R2"] *= ppm(50 * dt) # 6.5e-17 @ 100ppm, +/- 10K, 19.5-20.5 VCC x["VCC"] = random.uniform(19.5, 20.5) x["R4"] *= ppm(100 * dt) d = calc(x) df = (d["ir1"] - iref) * 5e-7 sy += df syy += df * df n += 1.0 avg = sy / n stddev = math.sqrt((syy - sy * sy / n) / (n - 1)) print("%.1e" % stddev) *phk*