adafruit / Adafruit_CircuitPython_ADS1x15

CircuitPython drivers for the ADS1x15 series of ADCs.
MIT License
133 stars 58 forks source link

SINGLE and CONTINUOUS mode have different voltage value #81

Closed Yingliangzhe closed 2 years ago

Yingliangzhe commented 2 years ago

Hello everyone, I am a little bit confused by the SINGLE and CONTINUOUS mode of ads1115. I use the following code to test.

import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.ads1x15 import Mode
from adafruit_ads1x15.analog_in import AnalogIn

i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.mode = Mode.CONTINUOUS
#ads.mode = Mode.SINGLE
ads.gain = 1
voltage_divider = 0.4

chan1 = AnalogIn(ads, ADS.P0)
chan2 = AnalogIn(ads, ADS.P1)
chan3 = AnalogIn(ads, ADS.P2)
chan4 = AnalogIn(ads, ADS.P3)

while True:
  #chan1 = AnalogIn(ads, ADS.P0)
  #print(ADS.P0)
  print(f'0. channel value is: {chan1.value}, channel voltage is: {chan1.voltage/voltage_divider}')

  #chan2 = AnalogIn(ads, ADS.P1)
  print(f'1. channel value is: {chan2.value}, channel voltage is: {chan2.voltage/voltage_divider}')

  #chan3 = AnalogIn(ads, ADS.P2)
  print(f'2. channel value is: {chan3.value}, channel voltage is: {chan3.voltage/voltage_divider}')

  #chan4 = AnalogIn(ads, ADS.P3)
  print(f'3. channel value is: {chan4.value}, channel voltage is: {chan4.voltage/voltage_divider}')

  print('\n')

  time.sleep(1)

If I use the CONTINUOUS mode, the output is like this:

0. channel value is: 8638, channel voltage is: 5.321099887081515
1. channel value is: 8679, channel voltage is: 6.601138950773644
2. channel value is: 8908, channel voltage is: 7.881178014465774
3. channel value is: 8742, channel voltage is: 9.161217078157902

0. channel value is: 8638, channel voltage is: 5.321099887081515
1. channel value is: 8680, channel voltage is: 6.601138950773644
2. channel value is: 8907, channel voltage is: 7.881178014465774
3. channel value is: 8742, channel voltage is: 9.161217078157902

0. channel value is: 8638, channel voltage is: 5.321099887081515
1. channel value is: 8679, channel voltage is: 6.601138950773644
2. channel value is: 8908, channel voltage is: 7.881178014465774
3. channel value is: 8741, channel voltage is: 9.161217078157902

0. channel value is: 8634, channel voltage is: 5.321099887081515
1. channel value is: 8679, channel voltage is: 6.601138950773644
2. channel value is: 8908, channel voltage is: 7.881178014465774
3. channel value is: 8742, channel voltage is: 9.161217078157902

If I switch the mode the SINGLE, it gives me the following:

0. channel value is: 8741, channel voltage is: 2.6994573809015163
1. channel value is: 8742, channel voltage is: 2.712270271919919
2. channel value is: 8679, channel voltage is: 2.7838349559007534
3. channel value is: 8742, channel voltage is: 2.7319583727530747

0. channel value is: 8679, channel voltage is: 2.6994573809015163
1. channel value is: 8679, channel voltage is: 2.710707724234748
2. channel value is: 8908, channel voltage is: 2.782897427289651
3. channel value is: 8742, channel voltage is: 2.7319583727530747

0. channel value is: 8638, channel voltage is: 2.6994573809015163
1. channel value is: 8679, channel voltage is: 2.712270271919919
2. channel value is: 8908, channel voltage is: 2.7838349559007534
3. channel value is: 8741, channel voltage is: 2.7316458632160403

0. channel value is: 8741, channel voltage is: 2.698519852290414
1. channel value is: 8679, channel voltage is: 2.712270271919919
2. channel value is: 8908, channel voltage is: 2.7838349559007534
3. channel value is: 8739, channel voltage is: 2.7316458632160403

The measurement values from SINGLE mode are actually right. Does someone know, what is the problem?

Thank you!

caternuson commented 2 years ago

The raw count values generally agree between the two outputs. Are you able to vary the input voltage? If so, try that and see if the raw values track as expected - that is, see if you get the same readings in terms of ADC counts with both SINGLE and CONTINUOUS with some new input voltage.

Yingliangzhe commented 2 years ago

@caternuson Hello, Yes the raw count values are almost identical. As you can see from the output from different mode. The channel values(counts) are almost the same. But the conversion calculation for CONTINUOUS mode seems not correct.

The ADC is now connected with 4 temperature sensors, it should measure like 25°C, about 2.7V. I can't change the voltage. I connect a Raspberry Pi with ADC remotely. At the analog input side, there is a data logger, which is also measuring the voltages. It output also 2.7V.

Yingliangzhe commented 2 years ago

@caternuson I actually expect some noise from the each measurement. But it seems the same. So I thought, if I should use CONTINUOUS mode.

caternuson commented 2 years ago

OK, try changing your loop code to this:

while True:
  #chan1 = AnalogIn(ads, ADS.P0)
  #print(ADS.P0)
  print(f'0. channel value is: {chan1.value}')

  #chan2 = AnalogIn(ads, ADS.P1)
  print(f'1. channel value is: {chan2.value}')

  #chan3 = AnalogIn(ads, ADS.P2)
  print(f'2. channel value is: {chan3.value}')

  #chan4 = AnalogIn(ads, ADS.P3)
  print(f'3. channel value is: {chan4.value}')

  print('\n')

  #chan1 = AnalogIn(ads, ADS.P0)
  #print(ADS.P0)
  print(f'0. channel voltage is: {chan1.voltage/voltage_divider}')

  #chan2 = AnalogIn(ads, ADS.P1)
  print(f'1. channel voltage is: {chan2.voltage/voltage_divider}')

  #chan3 = AnalogIn(ads, ADS.P2)
  print(f'2. channel voltage is: {chan3.voltage/voltage_divider}')

  #chan4 = AnalogIn(ads, ADS.P3)
  print(f'3. channel voltage is: {chan4.voltage/voltage_divider}')

  print('\n')

  time.sleep(1)
sgrobler commented 2 years ago

I ran your code on my ads1115/raspberry pi but I don't seem to get the same issue.

Yingliangzhe commented 2 years ago

The output of CONTINUOUS mode is almost the same as that of SINGLE mode.

Just because of changing the place of printing voltage?

Yingliangzhe commented 2 years ago

I ran your code on my ads1115/raspberry pi but I don't seem to get the same issue.

But I still have the problem, if I print the voltage just after the raw counts.

caternuson commented 2 years ago

I think this has something to do with the simple optimization that's in place to help speed up continuous reads: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/5d4068c9ff8528fcefb6d1f8f006ae9bb500f125/adafruit_ads1x15/ads1x15.py#L159-L162

The voltage reading directly after the raw reading would be seen as same channel. The changed code alters the order so no back-to-back same channel reads occur.

So seems like something is breaking there. Will need to investigate this.

Just to make sure - you're using the latest library release?

Yingliangzhe commented 2 years ago

pip freeze tells me: adafruit-circuitpython-ads1x15==2.2.12 Maybe not the latest version.

OK. Thank you for helping.

caternuson commented 2 years ago

Thanks. That's latest enough. It has the latest code, for the code that matters.

@sgrobler What's your setup? Curious why you did not see the issue.

caternuson commented 2 years ago

@Yingliangzhe I can't recreate this issue. I get the same results using your example for both CONTINUOUS and SINGLE:

CONTINUOUS:

0. channel value is: 18142, channel voltage is: 2.2678192083498643
1. channel value is: 18143, channel voltage is: 2.267569200720237
2. channel value is: 18143, channel voltage is: 2.267944212164678
3. channel value is: 18142, channel voltage is: 2.2678192083498643

0. channel value is: 18142, channel voltage is: 2.2678192083498643
1. channel value is: 18143, channel voltage is: 2.267569200720237
2. channel value is: 18143, channel voltage is: 2.267944212164678
3. channel value is: 18146, channel voltage is: 2.268319223609119

0. channel value is: 18148, channel voltage is: 2.268569231238746
1. channel value is: 18148, channel voltage is: 2.268319223609119
2. channel value is: 18148, channel voltage is: 2.268569231238746
3. channel value is: 18147, channel voltage is: 2.2684442274239327

SINGLE:

0. channel value is: 18149, channel voltage is: 2.2684442274239327
1. channel value is: 18148, channel voltage is: 2.268569231238746
2. channel value is: 18147, channel voltage is: 2.26869423505356
3. channel value is: 18149, channel voltage is: 2.26869423505356

0. channel value is: 18150, channel voltage is: 2.268819238868374
1. channel value is: 18150, channel voltage is: 2.268819238868374
2. channel value is: 18150, channel voltage is: 2.26869423505356
3. channel value is: 18147, channel voltage is: 2.268319223609119

0. channel value is: 18144, channel voltage is: 2.267944212164678
1. channel value is: 18145, channel voltage is: 2.2680692159794917
2. channel value is: 18145, channel voltage is: 2.267944212164678
3. channel value is: 18143, channel voltage is: 2.2680692159794917

The only change I made was:

voltage_divider = 1

since I have no additional voltage dividing in my setup.

Why do you need the voltage_divider in your code? What about your specific setup necessitates that?

Yingliangzhe commented 2 years ago

@caternuson OK. I am just a little bit admired, why the order of printing matters. I think if I just use the voltage of a channel should be fine.

The Voltage_divider is for the conversion from my measurement to the real value. Because there are 2 resistors (15k + 10k) in a series connection. I only measure the voltage of 10k.

sgrobler commented 2 years ago

@sgrobler What's your setup? Curious why you did not see the issue.

@caternuson I have an old Rpi Model B r2 + ads1115 adafruit-circuitpython-ads1x15 v2.2.13 adafruit-circuitpython-busdevice v5.1.8

caternuson commented 2 years ago

The fact that changing the order of printing changed the results on your setup is possibly relating to something happening. But I am not able to recreate that same behavior. So it is currently unknown what is happening.

The voltage divider and the scaling math being done with voltage_divider should not matter.

Are you able to repeat the behavior on your setup? The original code that reads like this:

  print(f'0. channel value is: {chan1.value}, channel voltage is: {chan1.voltage/voltage_divider}')

still behaves differently with the only change being CONTINUOUS vs. SINGLE for mode?

Yingliangzhe commented 2 years ago

Hello @caternuson, sorry for the late repsonse. I couldn't connect to the rpi during these days. Now I have tested it again, following are the ouputs:

CONTINUOUS

0. channel value is: 8926, channel voltage is: 2.7894601275673696
1. channel value is: 8926, channel voltage is: 2.7894601275673696
2. channel value is: 9157, channel voltage is: 2.8616498306222726
3. channel value is: 9117, channel voltage is: 2.849149449140904

0. channel value is: 8926, channel voltage is: 2.7894601275673696
1. channel value is: 8926, channel voltage is: 2.7894601275673696
2. channel value is: 8926, channel voltage is: 2.7894601275673696
3. channel value is: 8926, channel voltage is: 2.7894601275673696
SINGLE

0. channel value is: 8927, channel voltage is: 2.8260237434003725
1. channel value is: 8927, channel voltage is: 2.789772637104403
2. channel value is: 9157, channel voltage is: 2.861962340159306
3. channel value is: 9116, channel voltage is: 2.849149449140904

0. channel value is: 8926, channel voltage is: 2.8260237434003725
1. channel value is: 8927, channel voltage is: 2.789772637104403
2. channel value is: 9158, channel voltage is: 2.8616498306222726
3. channel value is: 9117, channel voltage is: 2.849149449140904

So both modes provide almost the same output. Don't know what happened before. :(

caternuson commented 2 years ago

OK, no worries. Will close this for now. If it happens again and issue can be recreated, can reopen and take another look.