The CLUE and Circuit Playground Bluefruit boards both use the nRF52840 System on a Chip (SoC). This includes an analogue-to-digital converter (ADC) using the successive approximation design. This is used in this project to measure the voltage across a capacitor. CircuitPython configures this ADC in 12bit mode making each bit equivalent to 0.806mV.
This page explores the consistency of the ADC and the distribution of noise to determine if an average value (arithmetic mean) over a certain number of samples is a valid approach to calculate an accurate voltage.
The graph below shows 1000 successive samples from the same function used in the program.
The samples are shown as dots which grow in size and are coloured relative to their distance from a fitted (straight) line. This visualisation appears useful in confirming:
- most values are near the line,
- the distribution looks fairly even above and below the line(s),
- a few values are significantly above or below the line but these also look reasonably evenly distributed either side for this number of samples.
A second weighted line is also shown - this is a refinement created by weighting the points based on their distance from the first line on a scale of 4 to 1. This reduces the large effect that outliers have using the least squares approach to line fitting. There's only a 0.2mV difference between this potentially more accurate line's arithmetic mean value and the samples suggesting a basic, quick-to-calculate mean value gives a voltage with good accuracy. If the sampling was reduced to, say 50 samples (over 2.4ms), then this looks more risky for an outlier having a pronounced, adverse effect on the calculated mean voltage.
The curve fitting is an unnecessary leftover from when this graphing analysis code was used previously on a capacitor discharging. In this case the capacitor is charging and discharging at a 400kHz rate. The samples here have been gathered over ~47ms which covers over 18 thousand charge cycles. This means the voltage will be largely constant with a miniscule amount of ripple.
In this case, it's possible these outliers are genuine but it seems unlikely that the voltage is really jumping around because the:
- difference is so great,
- there's not an obvious "trail" of dots joining the spikes and
- there's a capacitor involved.
The use of weighting for this analysis means they are not ignored, just downplayed based on the previous justification. Statistics by Jim has a useful guide on distinguishing outliers and deciding what to do with them. Discarding inconvenient results is not a good justification!
This is a zoomed-in look at the lines. The scale exaggerates the tiny gradient. The discrete ADC levels from 12bit sampling can be see with the clearly defined rows of samples.
The histogram here is more of a bar chart as it's carefully aligned with the quantized sample values. Only the central portion of values is shown on this bar chart. This could show any ADC peculiarities particularly with more graphs of samples. There's nothing that jumps out as concerning here.
The choice of bucket size (width) for a histogram can have a large effect on the visual representation of the data. If the data is quantised in some way then this effect can be more pronounced. Checking and presenting varying bucket sizes is one way to avoid creating misleading charts. The animated graph below shows different bucket sizes across the full range of sample values (voltages) with the data presented with the mean subtracted making the central voltage 0mV.
A steady voltage reference source like a battery is a better test to look at the ADC. The results for two 1000 sample runs against an old alkaline AAA battery are very similar to the graphs above.
These tests were all conducted with the CLUE board powered by USB power from a desktop computer. Some further testing would be useful, like:
- Powering the CLUE from battery power with USB power removed to examine any adverse effects on the ADC from noise on the power supply.
- Comparing multiple CLUE boards and other boards based on the nRF52840.
- Checking the distribution on the samples when measuring GND and 3.3V.
- Checking different ADC acquisition times - this requires use of C++/Arduino.
- Comparing software over-sampling with nRF52840 hardware over-sampling - this requires use of C++/Arduino.
- Looking at the sample data in the frequency domain to look for any periodic peculiarities. This will be imperfect as the code in CircuitPython is not taking samples at a precise rate and the jitter will muddy everything except the very low frequencies.