Computing stuff tied to the physical world

In Software on Apr 13, 2012 at 00:01

The analog plug contains an MCP3424 4-channel ADC which has up to 18 bits of resolution and a programmable gain up to 8x. This can measure microvolts, and it works in the range of ± 2.048 V (or ± 0.256 V for 8x gain).

However, the analog_demo example sketch was a bit limited, reading out just a single fixed channel, so I’ve added a new AnalogPlug class to JeeLib to simplify using the Analog Plug hardware. An example:

This interfaces to an Analog Plug on port 1, and uses 0x69 as default I2C device address. There are a number of ways to use this, but if you want to read out multiple channels, you have to select the proper channel and then wait for at least one conversion to complete. Since conversions take time, especially at 18-bit resolution, a delay() is needed to get proper results.

Sample output:

I tied a 1.5V battery to channel 1 and left the rest of the pins unconnected. Touching both battery pins lowers the voltage briefly, as you can see.

These results are in microvolts, due to this expression in the code:

``````    long uvolts = ((adc.reading() >> 8) * 1000) / 64;
``````

Here’s the reasoning behind this formula:

• the reading() call returns 32 bits of I2C data, but we only need the first 24 bits
• of these 24 bits, the first 6 will simply be a sign-extended copy of bit 18
• the top of the measurement range is 2.047 Volts, i.e. 2047 millivolts
• but we want to report in terms of microvolts, so we multiply by 1000
• only 11 bits are needed to represent 0 .. 2047 mV, the remaining 6 bits are fractional
• so we shift right by 6 bits (i.e. divide by 64) to get the actual result

It’s a bit convoluted, but as you can see, the measured value comes out as about 1.477 Volts, with a few more digits of resolution. If you do the math, you’ll see that the actual “step” size of these measurements is 1000 / 64 = 15.625 µV – and it drops to under 2 µV when used with 8x gain!

With this sort of precision, electrical noise can easily creep in. But it’s pretty neat: 5 digits of precision for 4 channels, with nothing more than one teeny little I2C chip.

1. Indeed a good performance. The (selectable) resolution is useful in some cases e.g. tracking very small, slow changes of potential, but this should not be confused with accuracy. Measurements are against the precision of the internal reference (+/- 0.05% ≈ 1mV) and accuracy of the gain stage (+/- 0.05%-0.35% ≈ 1-7mV).

Some of this uncertainty can be calibrated out, especially the gain error term as it is likely to be a constant error multiplier that tracks temperature changes well.

But without extra work, uV digits are just noise.

2. Just wondering, is it because of JeeRev that you don’t include “uV” in the output of the sample program?

Since if it isn’t, maybe it would be a good idea to add that for clarity?