Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Comparator functionality #98

Merged
merged 12 commits into from
Aug 6, 2024
78 changes: 76 additions & 2 deletions adafruit_ads1x15/ads1x15.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2018 Carter Nelson for Adafruit Industries

Check failure on line 1 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

reformatted
#
# SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -33,9 +33,17 @@
_ADS1X15_DEFAULT_ADDRESS = const(0x48)
_ADS1X15_POINTER_CONVERSION = const(0x00)
_ADS1X15_POINTER_CONFIG = const(0x01)
_ADS1X15_POINTER_LO_THRES = const(0x02)
_ADS1X15_POINTER_HI_THRES = const(0x03)

_ADS1X15_CONFIG_OS_SINGLE = const(0x8000)
_ADS1X15_CONFIG_MUX_OFFSET = const(12)
_ADS1X15_CONFIG_COMP_QUE_DISABLE = const(0x0003)
_ADS1X15_CONFIG_COMP_QUEUE = {
0: 0x0003,
1: 0x0000,
2: 0x0001,
4: 0x0002,
}
_ADS1X15_CONFIG_GAIN = {
2 / 3: 0x0000,
1: 0x0200,
Expand All @@ -58,7 +66,7 @@
"""Single-Shot Mode"""


class ADS1x15:

Check failure on line 69 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

Too many instance attributes (15/11)
"""Base functionality for ADS1x15 analog to digital converters.

:param ~busio.I2C i2c: The I2C bus the device is connected to.
Expand All @@ -66,6 +74,9 @@
:param int data_rate: The data rate for ADC conversion in samples per second.
Default value depends on the device.
:param Mode mode: The conversion mode, defaults to `Mode.SINGLE`.
:param int comparator_queue_length: The number of successive conversions exceeding the comparator threshold before asserting ALERT/RDY pin, defaults to 0 (comparator function disabled).

Check failure on line 77 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

Line too long (189/100)
:param int comparator_low_thres: Voltage limit under which comparator de-asserts ALERT/RDY pin. Must be lower than high threshold to use comparator function. Defaults to 0x800.

Check failure on line 78 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

Line too long (180/100)
tannewt marked this conversation as resolved.
Show resolved Hide resolved
:param int comparator_high_thres: Voltage limit over which comparator asserts ALERT/RDY pin. Must be higher than low threshold to use comparator function. Defaults to 0x7FF.

Check failure on line 79 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

Line too long (177/100)
:param int address: The I2C address of the device.
"""

Expand All @@ -75,6 +86,9 @@
gain: float = 1,
data_rate: Optional[int] = None,
mode: int = Mode.SINGLE,
comparator_queue_length: int = 0,
comparator_low_thres: int = 0x8000,
comparator_high_thres: int = 0x7FF0,
address: int = _ADS1X15_DEFAULT_ADDRESS,
):
# pylint: disable=too-many-arguments
Expand All @@ -83,6 +97,9 @@
self.gain = gain
self.data_rate = self._data_rate_default() if data_rate is None else data_rate
self.mode = mode
self.comparator_queue_length = comparator_queue_length
self.comparator_low_thres: comparator_low_thres
self.comparator_high_thres: comparator_high_thres
self.i2c_device = I2CDevice(i2c, address)

@property
Expand Down Expand Up @@ -131,6 +148,49 @@
g.sort()
return g

@property
def comparator_queue_length(self) -> int:
"""The ADC Comparator Queue."""
tannewt marked this conversation as resolved.
Show resolved Hide resolved
return self._comparator_queue_length

@comparator_queue_length.setter
def comparator_queue_length(self, comparator_queue_length: int) -> None:
possible_comparator_queue_lengths = self.comparator_queue_lengths

Check failure on line 158 in adafruit_ads1x15/ads1x15.py

View workflow job for this annotation

GitHub Actions / test

Variable name "possible_comparator_queue_lengths" doesn't conform to '(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$' pattern
if comparator_queue_length not in possible_comparator_queue_lengths:
raise ValueError("Comparator Queue must be one of: {}".format(possible_comparator_queue_lengths))
self._comparator_queue_length = comparator_queue_length

@property
def comparator_queue_lengths(self) -> List[int]:
"""Possible comparator queue length settings."""
g = list(_ADS1X15_CONFIG_COMP_QUEUE.keys())
g.sort()
return g

@property
def comparator_low_thres(self) -> int:
"""The ADC Comparator Lower Limit Threshold."""
return self._comparator_low_thres

@comparator_low_thres.setter
def comparator_low_thres(self, comparator_low_thres: int) -> None:
"""Sets 12-bit threshold in 16-bit register in unsigned format."""
if comparator_low_thres < 0 or comparator_low_thres > 65535:
raise ValueError("Comparator Low Threshold must be unsigned 16-bit integer between 0 and 65535")
self._comparator_low_thres = comparator_low_thres

@property
def comparator_high_thres(self) -> int:
"""The ADC Comparator Higher Limit Threshold."""
return self._comparator_high_thres

@comparator_high_thres.setter
def comparator_high_thres(self, comparator_high_thres: int) -> None:
"""Sets 12-bit threshold in 16-bit register in unsigned format."""
if comparator_high_thres < 0 or comparator_high_thres > 65535:
raise ValueError("Comparator High Threshold must be unsigned 16-bit integer between 0 and 65535")
self._comparator_high_thres = comparator_high_thres

@property
def mode(self) -> int:
"""The ADC conversion mode."""
Expand Down Expand Up @@ -183,7 +243,7 @@
config |= _ADS1X15_CONFIG_GAIN[self.gain]
config |= self.mode
config |= self.rate_config[self.data_rate]
config |= _ADS1X15_CONFIG_COMP_QUE_DISABLE
config |= _ADS1X15_CONFIG_COMP_QUEUE[self.comparator_queue_length]
self._write_register(_ADS1X15_POINTER_CONFIG, config)

# Wait for conversion to complete
Expand Down Expand Up @@ -222,6 +282,20 @@
with self.i2c_device as i2c:
i2c.write(self.buf)

def write_comparator_thresholds(self):
tannewt marked this conversation as resolved.
Show resolved Hide resolved
"""Write 16 bit values to Comparator Low and High Threshold registers."""
self.buf[0] = _ADS1X15_POINTER_LO_THRES
self.buf[1] = (self._comparator_low_thres >> 8) & 0xFF
self.buf[2] = self._comparator_low_thres & 0xFF
with self.i2c_device as i2c:
i2c.write(self.buf)

self.buf[0] = _ADS1X15_POINTER_HI_THRES
self.buf[1] = (self._comparator_high_thres >> 8) & 0xFF
self.buf[2] = self._comparator_high_thres & 0xFF
with self.i2c_device as i2c:
i2c.write(self.buf)

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.
Expand Down
14 changes: 14 additions & 0 deletions adafruit_ads1x15/analog_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,19 @@
@property
def voltage(self) -> float:
"""Returns the voltage from the ADC pin as a floating point value."""
volts = self.convert_to_voltage(self.value)
return volts

def convert_to_value(self, volts: float) -> int:
"""Calculates integer for threshold registers from voltage level input"""
value = round((volts * 32767) / _ADS1X15_PGA_RANGE[self._ads.gain])
if value < 0:
value = 65536 + value
return value

def convert_to_voltage(self, value: int) -> float:

Check failure on line 75 in adafruit_ads1x15/analog_in.py

View workflow job for this annotation

GitHub Actions / test

Unused argument 'value'
"""Calculates integer for threshold registers from voltage level input"""
volts = self.value * _ADS1X15_PGA_RANGE[self._ads.gain] / 32767
if volts > _ADS1X15_PGA_RANGE[self._ads.gain]:
volts = _ADS1X15_PGA_RANGE[self._ads.gain] - volts
return volts
44 changes: 44 additions & 0 deletions examples/ads1x15_comparator_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries

Check failure on line 1 in examples/ads1x15_comparator_example.py

View workflow job for this annotation

GitHub Actions / test

reformatted
# SPDX-License-Identifier: MIT

import time
import board
import busio
import countio

import adafruit_ads1x15.ads1015 as ADS
# import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)

# Create the ADS object
ads = ADS.ADS1015(i2c)
# ads = ADS.ADS1115(i2c)

# Create a single-ended channel on Pin 0
# Max counts for ADS1015 = 2047
# ADS1115 = 32767
chan = AnalogIn(ads, ADS.P0)

# Create Interrupt-driven input to track comparator changes
int_pin = countio.Counter(board.GP9, edge=countio.Edge.RISE)

# Set comparator to assert after 1 ADC conversion
ads.comparator_queue_length = 1

# Set comparator low threshold to 2V
ads.comparator_low_thres = chan.convert_to_value(2.000)
# Set comparator high threshold to 2.002V. High threshold must be above low threshold
ads.comparator_high_thres = chan.convert_to_value(2.002)
# Write comparator values to the chip registers
ads.write_comparator_thresholds()

count = 0
while True:
print(chan.value, chan.voltage) #This initiates new ADC reading
if int_pin.count > count:
print("Comparator Triggered")
count = int_pin.count
time.sleep(2)
Loading