Here is an external pretty nice I2C 16 bit A/D converter, it's based on the TI ADS1115 chip. It can be run as either two differential channels or four single ended analog input. Can be run at 5vdc and is breadboard friendly. So far my check out of the device is very favorable, I can detect a 1 microvolt change at the highest gain setting of +/- .256 vdc full range, but can still read 0-5vdc at it's lowest gain setting, but still getting .000187 volts per step resolution. Seems very stable and the large number of programmable range options can save needing to use external op-amps for interfacing things like strain gages and other Wheatstone bridge type sensors.
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=230619695873&ssPageName=STRK:MEWAX:IT
Datasheet: http://www.ti.com/lit/ds/sbas444b/sbas444b.pdf
Here is a sketch I wrote this weekend to check out the device:
/* Basic testing and check out sketch for a TI ADS1115 4 channel,16 bit, I2C, analog to digital converter chip
Leftyretro 08/06/11
*/
#include <Wire.h>
int topofScale; // made global to use adc range value to display millivolt reading conversion
void setup()
{
Wire.begin(); // join I2C bus
Serial.begin(38400); // initialize serial communication
setConfiguration(); // configure ADS1115 chip for range and channel desired
}
void loop() {
int rawValue; // holds 16 bit result read from A/D device
int scaledValue; // to convert to millivolts
byte userKeys;
Serial.print("Analog input #1 counts = ");
rawValue = getadcReading(); // read current A/D value
Serial.print(rawValue);
Serial.print(" Millvolts = ");
scaledValue = map(rawValue, 0, 32767, 0, topofScale);
Serial.print(scaledValue);
Serial.println(" Hit any key to continue");
while(Serial.available() < 1) {} // wait for user keystroke
while(Serial.available() > 0) {userKeys = Serial.read();} //read keystrokes then back to loop
}
int getadcReading()
{
int data;
int deviceAdd = 0x48; //ADS1115 address with address pin grounded
Wire.beginTransmission(deviceAdd); // transmit to I2c device address
Wire.send(0x00); // point to device register 0
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(deviceAdd, 2); // request 2 bytes from slave device #2
while(Wire.available()) // need two bytes, MSB and LSB of converstion value
{
data = Wire.receive(); //get MSB of reading
data = data << 8; // shift it to high byte of data
data = data + Wire.receive(); // add LSB to data
}
return data;
}
void setConfiguration()
{
int deviceAdd = 0x48; //ADS1115 address with address pin grounded
//uncomment desired voltage input range
int confWord= 0x0000; topofScale = 6144; // 0- 0-6.144 vdc range
//int confWord= 0x0200; topofScale = 4096; // 1= 0-4.096 vdc range
//int confWord= 0x0400; topofScale = 2048; // 2= 0-2.048 vdc range
//int confWord= 0x0600; topofScale = 1024; // 3= 0-1.024 vdc range
//int confWord= 0x0800; topofScale = 512; // 4= 0-.512 vdc range
//int confWord= 0x0A00; topofScale = 256; // 5= 0-.256 vdc range
//uncomment desired channel input
// Also this sets sample rate to 860 SPS, disables comparitor,
// and turns on continous conversion mode.
confWord = confWord | 0x00E3; // 0= input wired to + AIN0 - AIN1, diff
//confWord = confWord | 0x30E3; // 3= input wired to + AIN2 - AIN3, diff
//confWord = confWord | 0x40E3; // 4= input wired to + AIN0 - gnd, single ended
//confWord = confWord | 0x50E3; // 5= input wired to + AIN1 - gnd, single ended
//confWord = confWord | 0x60E3; // 6= input wired to + AIN2 - gnd, single ended
//confWord = confWord | 0x70E3 ; // 7= input wired to + AIN3 - gnd, single ended
Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
Wire.send(0x01); // point to configuration register
Wire.send(highByte(confWord)); // sends MSB of configuration word
Wire.send(lowByte(confWord)); // sends LSB of configuration word
Wire.endTransmission(); // stop transmitting
}
Lefty