I have been looking for a simple solution to this problem for about a year. I have found a part that is accurate and very simple to use. The part is a Delta-Sigma ADC system from Microchip. I have used it on an Adafruit Proto Shield and have connected it directly to a GPS Shield to log sensor data. See below for directions for using it.
I have compared the accuracy of several of these parts with a Fluke (0.09% DC V) meter. The results agree to about 1 part in a 1000 with no calibration of the ADC for measurements in the one to two volt range.
Here are the main features of this part:
High accuracy 18-bit Delta-Sigma ADC with differential inputs.
MCP3424 14-pin SOIC with 4 channel or MCP3422 8-pin SOIC with 2 channel MUX.
Digi-Key prices MCP3422 $3.14, MCP3424 $4.26.
On-board Voltage Reference (VREF) 2.048V ± 0.05%
On-board Programmable Gain Amplifier (PGA) with gains of 1, 2, 4 or 8.
Differential input full-scale range: -VREF to +VREF
Self calibration of internal offset and gain for each conversion.
Conversion bit resolution options: 12, 14, 16, or 18 bits.
Conversion rate:3.75 SPS (18 bits), 15 SPS (16 bits), 60 SPS (14 bits), 240 SPS (12 bits).
Detectable input signal level is 2 micro-volts for LSB in 18-bit mode with PGA = 8.
High input impedance, 2.25 M ohm at gain of 1.
One-shot or continuous conversion option.
On-board oscillator.
2-wire Interface allows up to eight chips with 32 channels to be connected to one Arduino using just the two I2C pins.
How to make it:
Solder the part on to the SOIC area of an Adafruit Proto Shield or SOIC breakout board.
Connect VSS pin to ground.
Connect VDD pin to +5V.
Connect SDA pin to Arduino SDA (Analog pin 4)
Connect SCL pin to Arduino SCL (Analog pin 5)
Connect input channels to your sensor.
That’s it, no other parts required.
Here is a photo of the 14-pin part soldered on a Proto Shield (upper left SOIC area) for experiments and logging of sensor data. And a break-out board (above Proto Shield) that shows how the 8-pin part can be used as an 8-pin DIP or if the pins are replaced by wires it can be directly connected to a GPS Shield or bare Arduino. Simple test program that reads channel one in 12-bit mode (default mode at power on). Output is the voltage in mv, no calibration required.
Code: Select all
#include <Wire.h>
#define MCP3422_ADDRESS 0X68
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
Wire.requestFrom(MCP3422_ADDRESS, 3);
if (Wire.available() != 3) {
Serial.println("Wire.available failed");
while(1);
}
int16_t v = (Wire.receive() << 8);
v |= Wire.receive();
// read but ignore status
uint8_t s = Wire.receive();
//print voltage from channel one in millivolts
Serial.print(v);Serial.println(" mv");
delay(500);
}