Trouble Interfacing ADS 7817 with Arduino

Hey All,

I'm rather new to the Arduino community and am understanding very quickly I have a lot to learn. XD I appreciate any time or thought towards my issue:

I am trying to interface a TI ADS7817 12-Bit serial ADC to an Arduino. My circuit is rather complex at the moment but the portion I'm working with resembles the attached. I have tried several things with my code, but I only seem to get a constant output of ~1268 (out of a total 4096) from the converter regardless of input. I have reviewed my circuit and determined that everything is connected correctly (to the best of my knowledge) and that the clock is cycling like it should.

If anyone has any input I'm all ears. My code is below. Thanks.

#define CS 10 //Chip selection pin
#define DATAPIN 12 //Data pin
#define CLOCK 13 //ADS 7817 clock

int readvalue;

void setup() {

//Set up pin modes
pinMode(CS, OUTPUT);
pinMode(DATAPIN, INPUT);
pinMode(CLOCK, OUTPUT);

//Ensure ADS7817 is powered off to start
digitalWrite(CS, HIGH); //Pin needs to be high for shutdown mode
digitalWrite(CLOCK, LOW);

Serial.begin(9600); //Initialize serial for debugging
}

int readADS7817() {

int adcvalue=0;
digitalWrite(CS, LOW); //Select the ADS7817

//Cycle clock to ignore two null bits of data transferred
digitalWrite(CLOCK, HIGH);
delay(50);
digitalWrite(CLOCK, LOW);
delay(50);
digitalWrite(CLOCK, HIGH);
delay(50);
digitalWrite(CLOCK, LOW);
delay(50);

//Read the 12 data bits from ADS 7817
for (int i=11; i>=0; i--) {
adcvalue+=digitalRead(DATAPIN)<<i;
//Serial.println(adcvalue, DEC);
//Cycle clock
digitalWrite(CLOCK, HIGH);
digitalWrite(CLOCK, LOW);
}
digitalWrite(CS, HIGH); //Power down ADS7817
return adcvalue;
}

void loop() {

readvalue = readADS7817();

Serial.println("");
Serial.println(readvalue, DEC);
delay(250); //Delay between data sampling streams
}

Doc1.pdf (140 KB)

Figured it out. Having some issues with the converter's range and the voltage reference, but the converter puts out the desired values. Code below:

#define CS 10    //Chip selection pin    
#define DATAPIN 12    //Data pin
#define CLOCK 13  //ADS 7817 clock

int readvalue;

void setup()  {                

  //Set up pin modes
  pinMode(CS, OUTPUT);
  pinMode(DATAPIN, INPUT);
  pinMode(CLOCK, OUTPUT);
  
  //Ensure ADS7817 is powered off to start
  digitalWrite(CS, HIGH);  //Pin needs to be high for shutdown mode
  //digitalWrite(DATAOUT, LOW);   //May not be needed
  digitalWrite(CLOCK, LOW);
  
  Serial.begin(9600);  //Initialize serial for debugging
}

int readADS7817()  {
  
  int adcvalue=0;
  digitalWrite(CS, LOW);  //Select the ADS7817
  
  //Cycle clock to ignore two null bits of data transferred
  digitalWrite(CLOCK, HIGH);
  delay(500); 
  digitalWrite(CLOCK, LOW);
  delay(500); 
  digitalWrite(CLOCK, HIGH);
  delay(500); 
  digitalWrite(CLOCK, LOW);
  delay(500); 
  
  //Read the 12 data bits from ADS 7817 
  for (int i=11; i>=0; i--) {
    adcvalue+=digitalRead(DATAPIN)<<i;//???
    Serial.println(adcvalue, DEC);
    //Cycle clock
    digitalWrite(CLOCK, HIGH);
    digitalWrite(CLOCK, LOW);
  }
  digitalWrite(CS, HIGH);  //Power down ADS7817
  return adcvalue;
}
  
void loop()  {
  
  readvalue = readADS7817();
 
  Serial.println("");
  Serial.println(readvalue, DEC);
  delay(250);  //Delay between data sampling streams
}

Figured it out. Having some issues with the converter's range and the voltage reference, but the converter puts out the desired values.

Good for you. I also recently worked on interfacing to one of TI's newer ADC chip the ADS1115. It uses I2C rather then SPI, but it comes with many more features then the older one you are using. Build in voltage reference, works at 3.3v or 5v, is a 16 bit A/D with programmable gains and a built in voltage comparitor function. In many cases this chip can be wired directly to a Wheatstone bridge sensor circuit without requiring any external op-amp voltage amplification when using the +/- .256 full scale gain setting.

Datasheet: http://www.ti.com/lit/ds/symlink/ads1115.pdf

Avalible breakout module: http://www.ebay.com/itm/230619695873?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

Lefty

Looking at the ADS1115 spec. sheet, it looks like a lot of external circuitry is eliminated (as compared to the ADS7817). In your experience with this chip, has noise been an issue? Also, is there information regarding interfacing this with an Arduino available?

Thanks.

toughsled:
Looking at the ADS1115 spec. sheet, it looks like a lot of external circuitry is eliminated (as compared to the ADS7817). In your experience with this chip, has noise been an issue? Also, is there information regarding interfacing this with an Arduino available?

Thanks.

So far I have been very impressed with it. It is a $6 chip so expectations should be pretty high. It was very easy to get running and is heads and shoulders above the arduion build in ADC.

Here is the sketch I developed to test out it's operation and options. I'm not software experianced enough to
make it into a nice library code, but have condensed it down to three simple functions.

/* Basic testing and check out sketch for a TI ADS1115 4 channel 16 bit I2C analog to digital converter chip.
 Reads voltage at desired range on desired channel and displays it on serial monitor. Also allows comparitor
 to output a active low signal pin if enabled. Comparitor output pin appears to be a open-drain output pin,
 requiring an external pull-up resistor. Note that 16 bit ADC applies to only differential mode, in the form of
 a twos complements integer. if using single ended input mode, results are a 15 bit positive integer result.
 Chip will work at any Vcc from 2-5vdc, which also sets the maximum input voltage that can be applied to the
 input pins. For differential input the channel numbers are 0 and 1, for single ended, 0,1,2,3.
 Data sheet at http://www.ti.com/lit/ds/symlink/ads1115.pdf
 
 On most Arduino boards, I2C SDA (data line) is on analog input pin 4, and I2C SCL (clock line) is on analog input pin 5.
 On the Arduino Mega, SDA is digital pin 20 and SCL is 21.
 
 Leftyretro 08/23/11
 */
#include <Wire.h>  //Arduino supplied library performs the low level I2C commands
const int I2Caddress = 0x48;         // ADS1115 7 bit I2C address with ADDR pin grounded,
                                     // 0x49,0x4A,0x4B avalible with other ADDR wiring options
    /* uncomment one desired voltage input ranges */
const int rangeSelect= 0x0000; const int topofScale = 6144;  // +/-6.144 vdc range, electrical limit = Vcc applies
//const int rangeSelect= 0x0200; const int topofScale = 4096;  // +/-4.096 vdc range, electrical limit = Vcc applies
//const int rangeSelect= 0x0400; const int topofScale = 2048;  // +/-2.048 vdc range
//const int rangeSelect= 0x0600; const int topofScale = 1024;  // +/-1.024 vdc range
//const int rangeSelect= 0x0800; const int topofScale =  512;  // +/-.512 vdc range
//const int rangeSelect= 0x0A00; const int topofScale =  256;  // +/-.256 vdc range

    /*  uncomment one desired channel input options
        This also sets sample rate to 860 SPS and turns on continous conversion mode. */
const int channelSelect = 0x00E0; byte channel = 0;  //input wired to + AIN0 - AIN1, diff +/- max range
//const int channelSelect = 0x30E0; byte channel = 1;  //input wired to + AIN2 - AIN3, diff +/- max range
//const int channelSelect = 0x40E0; byte channel = 0;  //input wired to + AIN0 - gnd, single ended, 0 to +max range
//const int channelSelect = 0x50E0; byte channel = 1;  //input wired to + AIN1 - gnd, single ended, 0 to +max range
//const int channelSelect = 0x60E0; byte channel = 2;  //input wired to + AIN2 - gnd, single ended, 0 to +max range
//const int channelSelect = 0x70E0; byte channel = 3;  //input wired to + AIN3 - gnd, single ended, 0 to +max range

    /* uncomment one desired comparator options
       active low ready pin, window mode = input voltage is inside high and low limit values
       active low ready pin, traditional = input voltage passed above high limit or fell below low limit values */
//const int comparatorMode = 0x0003;    //disable comparitor
//const int comparatorMode = 0x0008;    //enable comparitor in traditional comparator mode
const int comparatorMode = 0x0018;    //enable comparitor in window comparator mode

    /* set values for comparitor high and low limit values */
const int highCompare = 17000;   // high count value for comparitor threshold value, must be higher then lowCompare, 32767 max +
const int lowCompare  = 11000;   // low  count value for comparitor threshold value, must be lower then highCompare, -32768 max -

void setup() 
 {
   Wire.begin();           // join I2C bus
   Serial.begin(38400);    // initialize serial communication
     /* configure ADS1115 chip for range, channel input, comparitor mode */
   adcConfig(I2Caddress,rangeSelect | channelSelect | comparatorMode);
     if (comparatorMode != 0x0003)  // set limit values if comparator mode enabled
       {
        configLimits(I2Caddress,lowCompare, highCompare);
       }
 }

void loop()
 {
   int rawValue = adcRead(I2Caddress);  // read current A/D value
   int scaledValue = map(rawValue, 0, 32767, 0, topofScale);  //convert raw adc counts to millivolts
   Serial.print("Analog input #");
   Serial.print(channel,DEC);
   Serial.print("   counts =  ");
   Serial.print(rawValue);
   Serial.print("  Millvolts =  ");
   Serial.print(scaledValue);
   Serial.println("     Hit any key to continue");
   while(Serial.available() < 1) { }   // wait for user keystroke
   while(Serial.available() > 0) {byte userKeys = Serial.read();} //read keystrokes 
 }


//Function to read ADC conversion data from device 
int adcRead(int deviceAdd)             // read and return 16 bit analog voltage reading
  {
    int data;
    Wire.beginTransmission(deviceAdd); // transmit to I2c device address
    Wire.send(0x00);                   // point to device register 0, 16 bit ADC conversion results 
    Wire.endTransmission();            // stop transmitting

    Wire.requestFrom(deviceAdd, 2);    // request 2 bytes from slave device
    while(Wire.available())            // need two bytes, MSB and LSB of converstion result value
     { 
      data =  Wire.receive() << 8;     // get MSB of reading and shift it to high byte
      data += Wire.receive();          // add in LSB to data
     }
    return data;
  }

  //Function to configure the ADC device for desire channel, voltage range, compare mode
void adcConfig(int deviceAdd, int confWord)
 {
     //send configuration word to device
  Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
  Wire.send(0x01);                   // point to device configuration 16 bit register
  Wire.send(highByte(confWord));     // send MSB of configuration word
  Wire.send(lowByte(confWord));      // send LSB of configuration word
  Wire.endTransmission();            // stop transmitting  
 }
  
  //Function to load high and low limit values for comparator
void configLimits(int deviceAdd, int loCompare, int hiCompare)
 {
     //send low threshold compair value word to device
  Wire.beginTransmission(deviceAdd);  // transmit to ADS1115 device
  Wire.send(0x02);                    // point to device low threshold 16 bit register
  Wire.send(highByte(loCompare));     // send MSB of low threshold word
  Wire.send(lowByte(loCompare));      // send LSB of low threshold word
  Wire.endTransmission();             // stop transmitting

  //send high threshold compair value word to device
  Wire.beginTransmission(deviceAdd);  // transmit to ADS1115 device
  Wire.send(0x03);                    // point to device high threshold 16 bit register
  Wire.send(highByte(hiCompare));     // sends MSB of high threshold word
  Wire.send(lowByte(hiCompare));      // sends LSB of high threshold word
  Wire.endTransmission();             // stop transmitting
 }

As far as noise readings, I have the breakout module on a small solderless breadboard. If I short the + and - through a 6" jumper I see a maximum +1 or -1 one count variation on the +/- 6.144 voltage range, so a + or - 188uv variation. At the maximum gain setting, +/- .256vdc, I see a +/- 3 count variation representing +/- 24uv variation or so. That seems pretty good to me.

Lefty

Lefty,

Thanks for all the help. I had no idea there was a $6-7 chip out there that could do all that.

-toughsled