Weird "frequency to voltage converter"

July 2016, Author: Adrian Colomitchi

WTH topic

Somebody sent me a link to a capacitive soil moisture sensor the other day (July 12 2016 to be more precise) and was curious to see how it works.
The DFRobots seem to be nice enough to provide their schematics online starting from their wiki page - you see, they pride themselves in being open hardware. For the purpose of analysis (fair use, folks), I copied it here and started to look over it.

First thing, where's the capacitive probe in this schematics? The only one that fits the bill seems to be `C_5` - a plausible value and connected as the capacitor of a NE555 astable circuit.
So far, so good... astable, using a LMC555 (a CMOS equiv of NE555, able to go to 2MHz), will form a train of pulses... yes, OK... they say their sensor will output an analog value - which, of course, will need calibration, here's an example of values one may encounter.
So they'll need to convert the frequency to voltage somehow... umm-hmm... hang on, I'll let aside that `C_3` (the one that's supposed to provide the output signal as voltage) is 'naked' if connected to anything but a huge impedance, but what's the group I circled in red supposed to do?

It's not a low-pass filter (the `D_1` diode would stop the discharge of the `C_3` by the 555), it's not a peak-detector (what would `R_1` do in a peak detector?).
Looks like an integrative circuit with losses - the astable's pulses would be integrated by the `C_3` through `R_2`, while `C_3` will slowly discharge all the time through `R_1`. Perhaps this is meant to smooth/average the output voltage?

But that's not all... the plot thickens... the astable will be pumping pulses like crazy - with the values on the schema, the pulse period will be `ln(2) * (R_3+2*R_4) * C_5 = 1.15μs`. That's close to 900kHz guys.

Meanwhile, the `R_2` and `R_1` have quite disproportionate values, so `C_3` will charge quickly through `R_2` and diiissschaaaarge sloooowlyyy through `R_1` (`D_1` blocks the discharge by the 555 through `R_2`).
It's likely that `C_3` will be close to the max value unless the astable's duty cycle would drop low enough to allow a significant discharge. But... but... the astable's duty cycle is already fixed by the `R_3` and `R_4`, so what gives?

And this is the WTH topic to be examined here


The stage is set, let me try to derive the output voltage as a function of the probe capacitance, maybe my intuition is wrong and the maths will provide the correction.

Evolution of the output voltage in the "up" phase of the astable cycle

a. the "up" part of the cycle - `C_3` charges through `R_2`
So, on the left, the "mistery circuit", during the "up" part of the astable's cycle. (the `D_1` and `R_1` are reversed but that's not modifying in any way the functionality of the circuit - they are in a series connection)

Start your Maxima and describe the equations of the circuit for the "up" part of the cycle:

e1: i(t)=i1(t)+i2(t);
e2: Vs=R2*i(t)+Vx(t);
e3: Vx(t)=R1*i1(t);
e4: 'diff(Vx(t),t)=i2(t)/C3; 
then solve the system:

After a bit of massaging, the solution for the output voltage becomes:
`V_x(t) = R_1/(R_1+R_2) * V_s*(1-e^(-((R_1+R_2)*t)/(R_1*R_2*C_3))) + V_x(0)*e^(-((R_1+R_2)*t)/(R_1*R_2*C_3))`
With the self-explanatory notation of: `R_1∥R_2 = (R_1*R_2)/(R_1+R_2)`, the expression becomes:

  1. `V_x(t) = R_1/(R_1+R_2) * V_s*(1-e^(-t/(R_1∥R_2*C_3))) + V_x(0)*e^(-t/(R_1∥R_2*C_3))`
which tells the simple story of the output voltage during the "up" phase of the astable, which is the sum between:
  1. first term - the source asymptotically pushing the voltage in `C_3` through the `R_1∥R_2` combination towards the value given by the voltage divider made for the two resistors; and
  2. the second term - the asymptotically decaying initial voltage on the `C_3` through the same `R_1` and `R_2` parallel combination

(before you jump on my throat telling "that's no way `C_3` can use `R2` to discharge because `D_1`, so something must be wrong": no, it's nothing wrong, that's the mathematical expression as a superposition of two terms of the DE - that's "differential equations". In reality, the already existing charge/voltage on `C_3` will cause a slower current caused by the `V_s`, which is equivalent with a "charge" current as if `C_3` would be empty minus a "discharge" current as if `V_s` would be 0)

Evolution of the output voltage in the "down" phase of the astable cycle

b. the "down" part of the cycle - `C_3` discharges through `R_1`
This has to be simple, right? It's an exponential decay cause by the charge on `C_3` draining slooowly through `R_1`, starting with the value where the "up" stage of the astable left it. Reseting the time origin into `t_1`, it becomes:
  1. `V_x(t)=V_x(t_1)*e^(-t/(R_1*C_3))`

Output voltage after one full "up/down" astable cycle

Putting together the two evolution expressions (for up and down), the output voltage after one full astable cycle becomes:

`V_x(t_1+t_2)=V_x(t_1)*e^(- t_2/(R_1*C_3))=(V_s* R_1/(R_1+R_2) * (1-e^(-t_1/(R_1∥R_2*C_3))) + V_x(0)*e^(-t_1/(R_1∥R_2*C_3)))*e^(-t_2/(R_1*C_3))`

Let massage it a bit to put into evidence the contribution of the initial voltage separately from the contribution of the charge injected during the "up" stage of the astable.

  1. `V_x(t_1+t_2) =V_s* R_1/(R_1+R_2) * (1-e^(-t_1/(R_1∥R_2*C_3)))*e^(-t_2/(R_1*C_3)) + V_x(0)*e^(- (t_1/(R_1∥R_2*C_3)+t_2/(R_1*C_3)))`

Output voltage after N full "up/down" cycles

To simplify a bit the computations, let's introduce some notations in the full-cycle output voltage above:
  1. `\mathbf(A) = R_1/(R_1+R_2) * (1-e^(-t_1 / {R_1∥R_2*C_3}))*e^(-t_2/(R_1*C_3))` and
  2. `\mathbf(B) = e^(- (t_1/(R_1∥R_2*C_3)+t_2/(R_1*C_3)))`

With the note that both of them are subunitary (be my guest, check), the output voltage after a full cycle becomes:

  1. `V_x(t_1+t_2) = \mathbf(A) * V_s + mathbf(B) * V_x(0)`
where `V_x(0)` is the voltage on `C_3` at the beginning of the cycle.

Right! So, what after 2 such cycles? Well simple:

  1. `V_x(2*(t_1+t_2)) = \mathbf(A) * V_s + mathbf(B) * V_x(t_1+t_2)`; or

    `V_x(2*(t_1+t_2))=\mathbf(A) * V_s +mathbf(B) * (\mathbf(A) * V_s + mathbf(B) * V_x(0))`

`V_x(2*(t_1+t_2))=\mathbf(A) * V_s ( 1 + mathbf(B))+ mathbf(B)^2 * V_x(0)`

After 3 complete cycles? Well, of course

  1. `V_x(3*(t_1+t_2))`
    1. `= \mathbf(A) * V_s + mathbf(B) * V_x(2*(t_1+t_2))`
    2. `=\mathbf(A) * V_s ( 1 + mathbf(B) + mathbf(B)^2)+ mathbf(B)^3 * V_x(0)`

After n complete cycles? Elementary, my dear, high school stuff:

  1. `V_x(n*(t_1+t_2))`
    1. `= \mathbf(A) * V_s + mathbf(B) * V_x((n-1)*(t_1+t_2))`
    2. `= \mathbf(A) * V_s * ( 1 + mathbf(B))+ mathbf(B)^2 * V_x((n-2)*(t_1+t_2))`
    3. `= \mathbf(A) * V_s * ( 1 + mathbf(B) + mathbf(B)^2)+ mathbf(B)^3 * V_x((n-3)*(t_1+t_2))`
    4. `= \mathbf(A) * V_s * ( 1 + mathbf(B) + mathbf(B)^2+…+ mathbf(B)^(n-1)) + mathbf(B)^n * V_x(0)`

So, after n cycles, the output voltage becomes:

  1. `V_x(n*(t_1+t_2)) = \mathbf(A) * V_s * ((1 - mathbf(B)^n) / (1 - mathbf(B))) + mathbf(B)^n * V_x(0)`

After a sufficient number of cycles (big n), because `mathbf(B)` is subunitary, the output voltage becomes:

  1. `lim_(n \to ∞) V_x(n*(t_1+t_2)) = \mathbf(A) * V_s * (1/ (1 - mathbf(B)))`

The output voltage as a function of probe capacitance

Good, so the steady output voltage of the circuit (after enough "up/down" cycles) is:

  1. `V_(output) = V_s * (\mathbf(A) / (1 - mathbf(B)))`
  1. `\mathbf(A) = R_1/(R_1+R_2) * (1-e^(-t_1/(R_1∥R_2*C_3)))*e^(-t_2/(R_1*C_3))` and
  2. `\mathbf(B) = e^{- (t_1/(R_1∥R_2*C_3)+t_2/(R_1*C_3))}`

Before replacing the `\mathbf(A)` and `\mathbf(B)` constants, let's try to substitute the `t_1` (duration of the "up" stage of the astable) and `t_2` (duration of the "up" stage).
The astable is a 555 classic so, using the component references of the original schematic, one gets

  1. `t_1 = ln(2)*(R_3+R_4) * C_5` and
  2. `t_2 = ln(2)*R_4*C_5`
With those values, we get:
  1. `\mathbf(A) = R_1/(R_1+R_2) * (e^(- ln(2) * C_5/C_3*R_4/R_1)-e^(- ln(2)*C_5/C_3*((R_3+R_4)/(R_1∥R_2)+R_4/R_1)))`
  2. `1-\mathbf(B) = 1 - e^(- ln(2)*C_5/C_3*((R_3+R_4)/(R_1∥R_2)+R_4/R_1))`
Quick replace these into (8) and...

... finally, the glorious formula for the output voltage of the "mistery circuit" as a function of the probe capacitance (`C_5`):

  1. `V_(output) = V_s * R_1/(R_1+R_2) * (e^(- ln(2) * C_5/C_3*R_4/R_1)-e^(- ln(2)*C_5/C_3*((R_3+R_4)/(R_1∥R_2)+R_4/R_1)))/(1 - e^(- ln(2)*C_5/C_3*((R_3+R_4)/(R_1∥R_2)+R_4/R_1)))`

Consideration over the output voltage as a function of the moisture probe capacitance

Well, just look at the ginormous fraction with exponetial functions... scary, isn't it? Actually, it's pretty easy to see something peculiar. That fraction has the form of
  1. `(X - Y)/(1-Y)`
which immediately tells you that: as long as `X` is well different to `1`, we are going to see something, otherwise that fraction will be pretty close to 'saturation'

As it stands though, with the values specified by the schematics ( `C_5 = 470`pF, `C_3 = 10`μF, `R_4=1.6`K, `R_1=1`M), the `e^(- ln(2) * C_5/C_3*R_4/R_1)` is so close to `1` somebody would need an electron microscope to discerne between them (the value is `0.999999479`).

Which confirms my intuition: due to the `D_1` diode, the `C_3` capacitor can only discharge through `R_1`, which is so humongous that one would never see anything but saturation, no matter how the capacitance of the soil moisture probe would vary.

Actually, the capacitance of the soil moisture probe would need to be in the order of `R_1/R_4 * C_3` for the circuit as presented by the schematic to 'feel' something. Let me translate this: the moisture probe capacitance would need to be somewhere in the region of 10 to 100μF for the circuit to feel something different than saturation

Finally, to prove this, fire up Maxima and let's examine `vout = V_(output)/V_s` as a function of `x = C_5/C_3` with the values specified by the schematics:


plot2d(vout(1e6,1e4,330,1600,x), [x,1e-5,1200],
   [label, ["C5/C3", 800, 0.1], ["Vout/Vs", 100, 0.9]]);

And there you have it: until the `x = C_5/C_3` doesn't step into the 10-100 range, the `V_(output)/V_s` will stick pretty close to `1`. Actually one will need...(let me see)

find_root(vout(1e6,1e4,330,1600,x)=0.5,x,1e-5, 1200);
... yeap, `x = C_5/C_3 = 616.0279` to have `V_(output)/V_s = 0.5`. That means a capacitance of the moisture probe to a value of 616μF. If somebody actually manages to do this with a coplanar capacitor etched from a 25 x 100mm (or 1" x 4") get that person a Nobel award: the energy storage solution of the future is here and cheap


Important - don't try to DIY the circuit with the values presented in the schematic: it will not work. In spite of their pretention of "open source hardware", the DFRobot guys seems to be sloppy (and I'm considering "honest mistake" circumstances here) and put up a wrong schematics.

Yes, of course, there is the possiblibity that I made a mistake in the computations above - I don't think so but, if you find an error, please drop me an email on, thanks

Also important (for me at least): yes, that part may work as a poor's man "frequency to voltage converter", but not with the values as presented by the schematic.
Use the (8) formula group to get the output voltage as a function of frequency and duty cycle.