kevinjwalters · GitHub

Starting in CONTINUOUS mode makes it possible to change to SINGLE mode but a subsequent change back to CONTINUOUS mode then gives bogus values.

Measuring a DAC's output as an example set to about 5.000V (using a Cytron Maker Nano 2040 running 10.2.1).

>>> ads1115 = ADS1115(i2c, data_rate=128, mode=ads1x15.Mode.CONTINUOUS, gain=2/3) ; ads1115_chan = ADSAnalogIn(ads1115, ADS1115_PIN)
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
5.001
5.001188
5.001188 26673
>>> ads1115.mode = ads1x15.Mode.SINGLE
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
4.980562
4.98
4.980188 26561
>>> ads1115.mode = ads1x15.Mode.CONTINUOUS
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
3.096563
3.096563
3.096563 16515

Also happens if you start out in SINGLE mode.

>>> ads1115 = ADS1115(i2c, data_rate=128, mode=ads1x15.Mode.SINGLE, gain=2/3) ; ads1115_chan = ADSAnalogIn(ads1115, ADS1115_PIN)
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
4.980374
4.98
4.980188 26560
>>> ads1115.mode = ads1x15.Mode.CONTINUOUS
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
3.096563
3.096563
3.096563 16515

I can drop voltage to near 0.000V and the value lingers on.

>>> dac_chan.raw_value = 0
>>> print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage) ; time.sleep(0.1) ; print(ads1115_chan.voltage, ads1115_chan.value)
3.096563
3.096563
3.096563 16515

Perhaps this is something to with the fast=True code path in _read_register() and the ADS1115 hardware register (address) no longer being correct?

def _read_register(self, reg: int, fast: bool = False) -> int:
"""Read 16 bit register value. If fast is True, the pointer register
is not updated.
"""
with self.i2c_device as i2c:
if fast:
i2c.readinto(self.buf, end=2)
else:
i2c.write_then_readinto(bytearray([reg]), self.buf, in_end=2)
return self.buf[0] << 8 | self.buf[1]

Read the original on github.com ↗