1

I have a ADS1115 breakout board from adafruit connected to my RPi 3B connected via I2C. It is powered via the RPi 3.3V pin. The A0 input to the ADC is connected to a sensor that will produce out-voltages varying wildly between 0 and 3.3V. For outputs around ~1V I have made some experiments and checked that the ADC readings are good - at least on the order of magntude, but I am now looking into the lower range, on the order of mV.

Running the below code in Python 3.5

import Adafruit_ADS1x15 # pip3 install git+https://github.com/adafruit/Adafruit_Python_ADS1x15.git
from statistics import mean, stdev
from math import sqrt

adc = Adafruit_ADS1x15.ADS1115()
max_val = 2**15 # signed 16 bit number is read
gain_levels =[ # according to the library
    (2/3,6.144), 
    (1  ,4.096), 
    (2  ,2.048), 
    (4  ,1.024),
    (8  ,0.512),
    (16 ,0.256),
]

n_samples = 20
for gain,max_volts in gain_levels:
    readings = [adc.read_adc(channel=0,gain=gain,data_rate=8) for _ in range(n_samples)]
    readings_in_volt = [max_volts * (reading / max_val) for reading in readings ]
    avg = mean(readings_in_volt)
    sem = stdev(readings_in_volt)/sqrt(n_samples)
    res= "{gain:5.2f} {avg_mv:.2f} mV +- {ci_mv:.2f} mV".format(
        gain=gain,
        avg_mv=avg*1000,
        ci_mv=1.96*sem*1000
        )
    print(res)

produces the following

 0.67 54.00 mV +- 4.02 mV
 1.00 56.70 mV +- 4.03 mV
 2.00 52.25 mV +- 3.91 mV
 4.00 64.30 mV +- 3.71 mV
 8.00 29.26 mV +- 3.31 mV
16.00 29.13 mV +- 3.50 mV

Taking a reading with a multimeter gives 40.0 mV. As you can see, it seems that there is bias in the readings, and that the bias is gain dependant. I am very new to I2C communication and working with bit manpulation, so I am a little worried there is something off in either my own calculations, or in the gain settings in the library.

How would I go about to troubleshoot these inconsistent readings? Am I doing something strange converting the integer reading from the device to a voltage-value?

-- EDIT I think that my problem was a hardware problem on my part, and not a programming issue. Possible causes are:

  1. Frying the ADC chip some time earlier on
  2. Not providing the 0.000150 A current draw that the ADC needs.
  3. Using a different ground in the multimeter reading and the ADC reading. I dont have the original setup anymore, and cannot troubleshoot.

I will keep this question here, becuase of the good answer, even though I think my resolution was something different.

2
  • 3
    You use the gain appropriate for the voltage range you expect. I'm not sure what you want us to do.
    – joan
    Apr 18, 2021 at 21:13
  • I suggest using the new ADS1x15 library: github.com/adafruit/Adafruit_CircuitPython_ADS1x15 - it is less likely to have bugs, and has voltage conversion built in. Try this change, and see if you get the same results. This means we could rule out the software. Apr 24, 2021 at 15:12

1 Answer 1

1

Well, if for 1V range, everything seems to go well, then it is very likely your I2C hardware, software, binary results to decimal software etc are OK.

Now if the problem only appears in the lower mV range, I think it is the full scale range not set properly. Please see my datasheet summary on full scale range setting etc in the appendices below.

There are other troubleshooting tricks to consider:

  1. Keep I2C connecting wiring shorter then 30cm.

  2. Use a low I2C speed, say 100kHz, or even down to 50kHz.

  3. Use single shot conversion, instead of continuous conversion mode.

  4. Use differential mode, instead of common/single end mode.

  5. Connect unused input channel input pins to ground.

  6. Do not load too many I2C devices, preferably only one, the ADS1115 on the bus.

  7. Remove the ADS1115's onboard 4k7/10k pullups. You don't need them, because Rpi3/4's I2C pins already have strong 1k8 pullups on board. Removing all the I2C devices' on board pull ups keep the total (device + wiring) impedance within the I2C spec's limit of 400pF, for more reliable performance.


References

(1) ADS1115 I2C, 860-SPS, 16-Bit ADC datasheet - TI


Appendices

Appendix A - ADS1115 Full scale range setting and single conversion mode setting.

9.3.3 Full-Scale Range (FSR) and LSB Size

FSR Setting

A programmable gain amplifier (PGA) is implemented before the ΔΣ ADC of the ADS1114 and ADS1115. The full-scale range is configured by bits PGA[2:0] in the Config register and can be set to:

±6.144 V, ±4.096 V, ±2.048 V, ±1.024 V, ±0.512 V, ±0.256 V.

Table 3 shows the FSR together with the corresponding LSB size. ...


9.4.2.1 Single-Shot Mode

When the MODE bit in the Config register is set to 1, the ADS111x enter a power-down state, and operate in single-shot mode.

This power-down state is the default state for the ADS111x when power is first applied.

Although powered down, the devices still respond to commands. The ADS111x remain in this power-down state until a 1 is written to the operational status (OS) bit in the Config register.

When the OS bit is asserted, the device powers up in approximately 25 μs, resets the OS bit to 0, and starts a single conversion.

.END

2
  • 1
    Thank you. Some of the points I had already started to consider, and some I had not. I consider this a good answer to "How would I go about to troubleshoot these inconsistent readings?"
    – LudvigH
    Apr 19, 2021 at 7:57
  • 1
    @Ludvigh, It is my pleasure to troubleshoot with you your ADC problem. I think your proposed question title much better reflects you situation then mine. So I have taken liberty to change the question title again. I agree that the ΔΣ ADS1115 is a sophisticated lady and we need to go slowly to get to know her. Happy learning. Cheers..
    – tlfong01
    Apr 19, 2021 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.