[Particle Photon] Reading wrong voltage ADC values from ADS 7828 through I2C

I am reading wrong Voltage ADC values from the ADS 7828 board in the particle PHOTONH through I2C channel.

Even I haven’t given any input to AD0 & COM0 lines, I am reading random voltage values between 3.1 - 3.9. Actually, it should return zero values because I haven’t attached any input. Please refer below pics for more details. Actually, I don’t understand why I am reading wrong values through I2C. Please refer below source code and detail explanation of my input. If you guys have any idea on this issue, please provide your suggestions.

NOTE: we found reference of this source from the github community and modified it based our need.

// ADS7828 I2C address:- A0 = 0x49(73) & A1 = 0x4A(74) 
#define Addr 0x49

int raw_adc = 0;
double Current = 0;

void setup()
{
  // Set variable
  Particle.variable("Current", Current);
  
  // Initialize I2C communication as MASTER
  Wire.begin();

  // Initialize serial communication, set baud rate = 9600
  Serial.begin(9600);
  delay(300);
}

void loop()
{
  byte data[2];
  
  // Start I2C Transmission
  Wire.beginTransmission(Addr);

  // Send command byte
  // Single Ended inputs
  // Channel: 0 (zero) selected
  // Internal Reference ON and A/D Converter ON
  Wire.write(0x9C);

  // Stop I2C transmission
  Wire.endTransmission();
  
  // Request 2 bytes of data
  Wire.requestFrom(Addr, 2);
   //Particle.publish("Digital: ", "read two bytes");
  
  // Read 2 bytes of data
  // raw_adc msb, raw_adc lsb
  if(Wire.available() == 2)
  {
    Particle.publish("Digital: ", "after two bytes read");
    data[0] = Wire.read();
    data[1] = Wire.read();
    
    // Output data to dashboard
    Particle.publish("data D0: ", String(data[0]));
    Particle.publish("data D1: ", String(data[1]));

    // Converting the data to 12 bits
    int raw_adc = ((data[0] & 0x0F) * 256) + data[1];
    double Voltage = raw_adc * 0.0012207;
    Particle.publish("Digital: ", String(Voltage));

    // 1 sec delay
    delay(1000);
  }
  else
    Particle.publish("Digital: ", "Not available");
}

I2C READ (AD0 & COM0) or (ADx & COMx)

Output: 3.2 - 3.8 voltage values

========================================================================
1) CHANNEL SELECTION CONTROL
SD C2 C1 C0 CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 COM
-----------------------------------------------
1 0 0 0 +IN - - - - - - - –IN

2) POWER DOWN SELECTION
PD1 PD0 DESCRIPTION
— --- ---------------
0 1 Internal Reference OFF and A/D Converter ON (When Power input from I2C)
1 1 Internal Reference ON and A/D Converter ON (When power src from external 12V pwr supply)

NOTE: I used both options but I am getting wrong values/

3) DEVICE ID SELECTION
A1 A0
-----
0 1 -> device ID ‘01’

This is what’s commonly called a floating input and they will typically produce floating readings :wink:

If you have no signal to measure you are virtually measuring stray charges around your system.

Actually, I have tried to read voltage data both these ways, with 3.3v input from the particle and without any input to AD0 & COM0 but I am getting same floating numbers.

Is my jumper settings are wrong on ADS 7828?

Floating is never a good idea.

To check the readings you should try 3.3V, GND and a known voltage divider to get a set of readings for each of them and then see where these readings fall and what deviation you see between them.

Where is that 0.0012207 constant coming from?

I cannot really see whether the pull-up jumpers are set correctly or rotated 90 degrees (which would be wrong).
However, the pull-ups need to be enabled.

BTW, have you tried running an I2C scanner app to see whether the sensor can be found at all?

As @ScruffR pointed out the ADC inputs are going to float if nothing is connected to them. You can use simple 10K resistors to pull the inputs low which should give you a continuous 0 reading.

If you are not certain you have valid communication between the Photon module and the ADS7828 try flashing this I2C Scan firmware on the photon and monitor the Photon’s output:
https://go.particle.io/shared_apps/5ce853938bb3850010b71ccd
This will tell you if the ADS7828 ICs are on the bus and what their addresses are, then you can validate that against the code you are currently running.

2 Likes

Hi Travis & ScruffR,

Thank you so for your suggestions!!

Actually, I have tried all your suggestions but didn’t work any of them. Let me describe you in detail what I have tried.

  1. I have used the code @Travis has suggested to find out that what device IDs are enabled for communication.
    I found two devices are active for the communication:
    - A0=0x49 (73)
    - A1=0x4A (74)
  2. AD0 & COM0 of 0x49 device, I have used to verify value with 10K resister, but still I am receiving floating values.
    • I have checked values of all ADC channels of both 0x49 & 0x4A pannels. Please refer my below code and floating output.
    • One more stuff, even if I gave input (3.3v | 5.0v) or not (0v) to AD0, I was getting similar floating values.

Output of below source code - Make sure I haven’t given any input to AD0 & COM0 so it should show zero values instead of floating number (voltage)


`
3) I have tried all combinations of PD1 & PD0, but there is no change in values.
PD1 PD0 DESCRIPTION
---------------------------------------
0 0 Power Down Between A/D Converter Conversions
0 1 Internal Reference OFF and A/D Converter ON
1 0 Internal Reference ON and A/D Converter OFF
1 1 Internal Reference ON and A/D Converter ON

  1. I have tried both external power source (12V) and BUS power source (I2C 5+V) using power src jumper but there is not change in values.

  2. About the pull up jumper, as CE (ControlEverthing) guys have suggested that if we are using slave CE device (ADS7828) with master CE device (Screw Terminal Breakout Board for Particle Photon) we do not need to use pull jumper. So pull up jumper is not an issue here.

    • @Travis please correct me I am wrong here then.

I really need your help to get it work. So if you have any other suggestion or I have missed anything then please feel free to let me know.

#include <application.h>
#include <spark_wiring_i2c.h>

int raw_adc = 0;
double Current = 0;
void setup()
{
    // Set variable
    Particle.variable("i2cdevice", "ADS7828");
    Particle.variable("raw_adc", raw_adc);
    Particle.variable("Voltage", Voltage);
  
    // Initialize I2C communication as MASTER
    Wire.begin();

    // Initialize serial communication, set baud rate = 9600
    Serial.begin(9600);
    delay(300);
}

void loop()
{
    byte data[2];
    String newDevices = " ";

    // ADS7828 I2C address is 0x49(73): 0100 1001
    // ADS7828 I2C address is 0x4A(74): 0100 1010
    for(int add=0x49; add<=0x4A; add++)
    {
        newDevices = " ";
    
        for (int i=0; i<8; i++)
        {
            // Start I2C Transmission
            Wire.beginTransmission(add);

            byte tmp = i << 4;
            tmp = 0x84 | tmp;
            Wire.write(tmp);
            
            // Stop I2C transmission
            Wire.endTransmission();

            // Request 2 bytes of data
            Wire.requestFrom(Addr, 2);
          
            // Read 2 bytes of data
            // raw_adc msb, raw_adc lsb
            if(Wire.available() == 2)
            {
                //Particle.publish("Digital: ", "after two bytes read");
                data[0] = Wire.read();
                data[1] = Wire.read();

                // Converting the data to 12 bits
                int raw_adc = ((data[0] & 0x0F) * 256) + data[1];
                double Voltage= raw_adc * 0.0012207;

                char datasct[4];
                snprintf(datasct, sizeof(datasct), "%d: ",i);
                newDevices.concat(String(datasct));
                newDevices.concat(String(Voltage));
                newDevices.concat(", ");
            }
            else
                Particle.publish("Digital: ", "Not available");

            delay(100);
        }

        Particle.publish("Data;;", String(newDevices));
    }

}

The image you posted after this shows 7 very constant numbers that seem pretty close to 3.3V to me. I cannot see any variation/floating whatsoever. :confused:

@ScruffR

It seems constant on all 7 channels but I haven’t connected any input (0v) to all those channels. So it should show us zero voltage value, correct?. One more point I want you clear that, if I have connected 10K resister to AD0 channel input then it should shows us different output value, than the other channels (AD1-AD7), right? But it doesn’t show up that difference.

Let me know if you want more information then. By mistake, I added a image with exact same value but, I will show you an example with different values by EOD.

Also, make sure I removed pull-up resister jumper caps and put them besides. So no one has a confusion for that.

@ScruffR
0.0012207 value, which I am multiplying with raw_adc value to get actual voltage value.
In my case, I am using input voltage from 0v to 5v & ADS7828 has a range from 0-4096 (4k = 2^12 => 12-bits ADC board) to represent readings in digital form. So I am using below equation to convert digital raw ADC data to voltage:

Multiplier = (Vin_max - Vin_min)/(ADC_max - ADC_min)

Multiplier = (5 - 0)/ (4096 - 0) = 5/4096 = 0.0012207.

I see - but it should actually be 0…4095, although that won’t make that much of a difference :wink:

Hi,
could you please flash with this:
https://go.particle.io/shared_apps/5eff67e556a45e0025e0ca2e
and see if is any difference ?
The original code is from here, just modified a little to fit in Photon.
As suggested by @ScruffR could you double check with multi meter if your
Pull-ups jumpers are for sure OK on PR33-6 board ?

in your code above is some glitch i’m not sure but…

  1. you iterate over add in for loop and then Wire.requestFrom(Addr, 2);
    (this shouldn’t even compile as Addr is not defined )

  2. delay(100); looks like is to small during Particle.Publish require ad least 1s between publishes

I hope this helps
Regards