# Getting rid of jitter when measuring voltage

• Just a quick question - maybe someone knows a better way: My custom pH-meter has a voltmeter which returns values which are jumping around a bit. Now, this may be because the whole thing currently resides on a breadboard and thus may be subject to outside influence, but still.

Calculating the mean is still jittery but the median is at least somewhat stable.

Current setup: Take 100 measurements (i.e. `float`) in one second, calculate the median and output the value. However, there's still some jitter and, knowing my pupils, they'll be confused if they have to decide whether to jot down 0.13 V, 0.15 V, 0.16 V or 0.18 V.

Before you say: "Simply use more data!" I'd like to point towards my use of an Arduino Nano which is a bit limited in RAM for dynamic variables. Which means that 200 `float` data points are pushing it.

So, any ideas on how to further stabilize the value? First instinct would be to build the average of several medians but that feels wrong somehow.

• @rhywden I've forgot the name of the approach, but you can average out the values by doing a weighted average of the previous output and the current input.

`Vnext = ɑ * Vin + (1 - ɑ) * Vprev`

• Maybe attach a capacitor to the voltage source and let it charge until it is in equilibrium, then measure the voltage on the capacitor.

• I've forgot the name of the approach, but you can average out the values by doing a weighted average of the previous output and the current input.

`Vnext = ɑ * Vin + (1 - ɑ) * Vprev`

Maybe attach a capacitor to the voltage source and let it charge until it is in equilibrium, then measure the voltage on the capacitor.

I love the fact that the first two responses said basically to do the same thing, but one of them described how to do it in software and the other one described how to do it in hardware.

• @benoni I'm not sure that one is applicable - I only have one dimension. Kalman seems to need at least two.

Of course I could create a differential from two data points. Not sure how valid that would be.

• First, if you are calculating average, us a moving average (rolling average).
Second, consider putting in a median filter first... https://embeddedgurus.com/stack-overflow/2010/10/median-filtering/

Edit, third, since you are taking readings from an ADC and using an 8-bit micro without floating point unit. The readings from the ADC would be a integer or a long before they get calculated into floating point, therefore do your averaging in integer.

• @Rhywden You have position and velocity. That's two dimensions, if you really need it. Filtering voltage is one of the simplest canonical cases for Kalman filters. This page has a reasonable explanation of how to do it with a single dimension: http://bilgin.esme.org/BitsAndBytes/KalmanFilterforDummies

• 200 float data points

floats are only precise to about 0.0000001, so depending on how precise your readings are in the first place, that might be causing the jitter. A double would bring that to around 0.0000000000000002, and with 200 of them, that's only an extra 800 bytes. If that's too much, going to 100 doubles might improve your data's stability instead of 200 floats.

• 200 float data points

floats are only precise to about 0.0000001, so depending on how precise your readings are in the first place, that might be causing the jitter. A double would bring that to around 0.0000000000000002, and with 200 of them, that's only an extra 800 bytes. If that's too much, going to 100 doubles might improve your data's stability instead of 200 floats.

Naw, I only have about 3 significant digits.

Anyway, I just tested the one-dimensional Kalman filter. It stabilizes the values nicely but takes quite some time to get there - we're talking about roughly ten to fifteen seconds (with one measurement every 10 ms). Also, for some reason my whole setup works for neutral solutions (yields -0.13 V) and acidic solutions ( > -0.8 V), but my basic solution seems to have triggered some bug and and only yields 0.0 V, whatever I do.

It doesn't help that the Arduino doesn't have a proper debugger. Maybe I'll connect the setup to an RPi - that has an I2C interface as well, after all. And using Python instead of C might reveal if it's a software or a hardware problem somehow.

• @rhywden What voltage are you expecting for the basic? Based on the other two you quoted, it should be about +0.54 volts - but at least 0 is in the right place on the continuum (higher than neutral, which is higher than acidic), so maybe it just scales weird.

• @rhywden What voltage are you expecting for the basic? Based on the other two you quoted, it should be about +0.54 volts - but at least 0 is in the right place on the continuum (higher than neutral, which is higher than acidic), so maybe it just scales weird.

It should indeed be a moderately positive number - roughly around 0.7 V. But the result is a constant 0.0000 - absolutely no jitter there (not even in the last significant digit).

• a constant 0.0000

Usually a maths issue will overflow a number and start wrapping...
Is the ADC able to measure positive voltages or run out of range? Can you post schematic of the voltage measurement end?

• an 8-bit micro without floating point unit

Fixed-point math. Fun!

• a constant 0.0000
Usually a maths issue will overflow a number and start wrapping...
Is the ADC able to measure positive voltages or run out of range? Can you post schematic of the voltage measurement end?

The ADC measures voltages in both directions just fine - that's why I'm using it in the first place. I think I'll connect my oscilloscope to various places to see what's what.

Might take some time, from today on I have two weeks of holidays

• @rhywden I've forgot the name of the approach, but you can average out the values by doing a weighted average of the previous output and the current input.

`Vnext = ɑ * Vin + (1 - ɑ) * Vprev`

Classic Single Pole Low Pass Filter...

VERY similar to the hardware solution of adding a capacitor, but NOT mathematically identical (hint: there is no such thing as "pure" capacitance)

• @TheCPUWizard
Another key difference I suspect is that while that code is subject to the measuring interval, a capacitor is not, allowing the capacitor to stabilise its value more quickly.

There may be benefit in combining the approaches.

• VERY similar to the hardware solution of adding a capacitor, but NOT mathematically identical (hint: there is no such thing as "pure" capacitance)

VERY similar to a normal human being's response, but ACTUALLY a pedantic dickweed response (hint: fucking unclench)

• @TheCPUWizard
Another key difference I suspect is that while that code is subject to the measuring interval, a capacitor is not, allowing the capacitor to stabilise its value more quickly.

There may be benefit in combining the approaches.

And another is that the jitter might actually be random noise from inside the ADC, in which case a capacitor would stabilize the voltage before the jitter got added -- in other words, if the jitter is from the ADC itself, you'd need a software filter to remove it. (Or a better ADC.)

• And another is that the jitter might actually be random noise from inside the ADC, in which case a capacitor would stabilize the voltage before the jitter got added -- in other words, if the jitter is from the ADC itself, you'd need a software filter to remove it. (Or a better ADC.)

@Rhywden already mentioned attacking the problem with an oscilloscope — that should be able to answer that problem.

• VERY similar to the hardware solution of adding a capacitor, but NOT mathematically identical

The `Vnext = ɑ Vin + (1 - ɑ) Vprev` recursive function, when the input voltage changes from V0 to V1 at t = 1, is equivalent to:

And with parameters {V0 = 0, V1 = 1, ɑ = 1%}, it looks like:

The rate of charge on a capacitor depends on a time constant, RC, and if you assume an initial charge of V0 and a charging voltage of V1, the function describing its charge would be:

It's basically the same function. The capacitance, C, takes the place of the discrete sampling rate of the software-based function, and the resistance, R, takes the place of the ɑ constant... both of them affect how quickly the function converges to a new input voltage (V1).

• @rhywden One of my science fair projects way back when was a homemade pH measuring device that attached to an Atari-style joystick port. It worked by shining an LED through a vial with the test solution (liquid whatever + litmus powder) and onto a photoresistor. I wrote software for my Commodore 64 to read the input from one of the paddle lines and interpret the results.

Jitter wasn't much of an issue given the limited range of input values and similarly limited range of pH values it could measure. So I guess I'd suggest you get older tools?

(Yeah, this doesn't help at all, but it was neat to see a similar project.)

• Since the details are debated, I should add to my solution with the capacitor:
Measuring the voltage discharches the capacitor, so to be even more precise, measure the voltage over time (as it discharges) and fit a falling exponential function to it to find the voltage at time=0.

• Anyway, I just tested the one-dimensional Kalman filter. It stabilizes the values nicely but takes quite some time to get there - we're talking about roughly ten to fifteen seconds (with one measurement every 10 ms).

1000 measurements? Ouch. Using a better estimate for the noise should improve that. Ideally it should be R=σ², which you can precompute from a number of samples.

• @rhywden

But clearly it doesn't, it gets stuck at 0

• art wrapping...
Is the ADC able to measure positive voltages or run out

how can a oscilloscope tell us what is in your schematic?

• how can a oscilloscope tell us what is in your schematic?

It can answer the question of whether the input to the ADC is meaningful. If it is, the problem is in the software side (or a bust ADC :() and may be with overflow or underflow, or int/float problems. It is a bit too easy to make such mistakes and software tells us about it by giving unexpected results…

• Measuring the voltage discharches the capacitor

Not significantly, if the voltage meter is any good. The effective resistance of the volt meter is virtually infinite, so almost no current flows through it. If a significant amount of current did flow through the volt meter, it would change the voltage drop across the element or portion of the circuit that you're trying to measure.

• @dkf
How do you know the meaningful range of the ADC without details such as any voltage divider or amplifier, source and input resistance, value of Vref etc

• @TheCPUWizard
Another key difference I suspect is that while that code is subject to the measuring interval, a capacitor is not, allowing the capacitor to stabilise its value more quickly.

There may be benefit in combining the approaches.

I think the capacitor will do just fine. Order a selection from Amazon, eBay or any other supplier and try it out. This is exactly what they are made for.

• Measuring the voltage discharches the capacitor

Not significantly, if the voltage meter is any good. The effective resistance of the volt meter is virtually infinite, so almost no current flows through it. If a significant amount of current did flow through the volt meter, it would change the voltage drop across the element or portion of the circuit that you're trying to measure.

The ADC on an Arduino is 100M ohm. For the purposes of these measurements it is effectively infinite.

• @TheCPUWizard
Another key difference I suspect is that while that code is subject to the measuring interval, a capacitor is not, allowing the capacitor to stabilise its value more quickly.

There may be benefit in combining the approaches.

And another is that the jitter might actually be random noise from inside the ADC, in which case a capacitor would stabilize the voltage before the jitter got added -- in other words, if the jitter is from the ADC itself, you'd need a software filter to remove it. (Or a better ADC.)

It could also be noise from the voltage source. We need a schematic for how the pH meter is designed to really tell anything meaningful.

• How do you know the meaningful range of the ADC without details such as any voltage divider or amplifier, source and input resistance, value of Vref etc

Measure? Data sheet?

• @dkf
How do you know the meaningful range of the ADC without details such as any voltage divider or amplifier, source and input resistance, value of Vref etc