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
10 changes: 0 additions & 10 deletions adafruit_ads1x15/ads1015.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ def _data_rate_default(self) -> Literal[1600]:
"""Default data rate setting is 1600 samples per second"""
return 1600

def _comp_low_thres_default(self) -> Literal[0x8000]:
"""Value is 12-bit, 2's complement stored in 16-bit register where 4 LSBs are 0.
Defaults to 0x8000 as 16-bit hex (-2048 as 12-bit decimal)."""
return 0x8000

def _comp_high_thres_default(self) -> Literal[0x7FF0]:
"""Value is 12-bit, 2's complement stored in 16-bit register where 4 LSBs are 0.
Defaults to 0x7FF0 as 16-bit hex (2047 as 12-bit decimal)."""
return 0x7FF0

def _conversion_value(self, raw_adc: int) -> int:
value = struct.unpack(">h", raw_adc.to_bytes(2, "big"))[0]
return value
10 changes: 0 additions & 10 deletions adafruit_ads1x15/ads1115.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,6 @@ def _data_rate_default(self) -> Literal[128]:
"""Default data rate setting is 128 samples per second"""
return 128

def _comp_low_thres_default(self) -> Literal[0x8000]:
"""Value is 16-bit, 2's complement.
Defaults to 0x8000 as 16-bit hex (-32768 16-bit decimal)."""
return 0x8000

def _comp_high_thres_default(self) -> Literal[0x7FFF]:
"""Value is 16-bit, 2's complement.
Defaults to 0x7FFF as 16-bit hex (32767 16-bit decimal)."""
return 0x7FFF

def _conversion_value(self, raw_adc: int) -> int:
value = struct.unpack(">h", raw_adc.to_bytes(2, "big"))[0]
return value
52 changes: 22 additions & 30 deletions adafruit_ads1x15/ads1x15.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def __init__(
data_rate: Optional[int] = None,
mode: int = Mode.SINGLE,
comparator_queue_length: int = 0,
comparator_low_threshold: Optional[int] = None,
comparator_high_threshold: Optional[int] = None,
comparator_low_threshold: int = -32768,
comparator_high_threshold: int = 32767,
address: int = _ADS1X15_DEFAULT_ADDRESS,
):
# pylint: disable=too-many-arguments
Expand All @@ -106,16 +106,8 @@ def __init__(
self.mode = mode
self.comparator_queue_length = comparator_queue_length
self.i2c_device = I2CDevice(i2c, address)
self.comparator_low_threshold = (
self._comp_low_thres_default()
if comparator_low_threshold is None
else comparator_low_threshold
)
self.comparator_high_threshold = (
self._comp_high_thres_default()
if comparator_high_threshold is None
else comparator_high_threshold
)
self.comparator_low_threshold = comparator_low_threshold
self.comparator_high_threshold = comparator_high_threshold

@property
def bits(self) -> int:
Expand Down Expand Up @@ -198,23 +190,35 @@ def comparator_high_threshold(self) -> int:

@comparator_low_threshold.setter
def comparator_low_threshold(self, value: int) -> None:
"""Set comparator low threshold value for ADS1015 ADC
"""Set comparator low threshold value for ADS1x15 ADC

:param int value: 16-bit signed integer to write to register
"""
if value < 0 or value > 65535:
raise ValueError("Comparator Threshold value must be between 0 and 65535")
if value < -32768 or value > 32767:
raise ValueError(
"Comparator Threshold value must be between -32768 and 32767"
)

if (self.bits == 12) & (value & 0x000F > 0):
print("4 LSBs will be truncated for ADS1015 for 12-bit value")

tannewt marked this conversation as resolved.
Show resolved Hide resolved
self._comparator_low_threshold = value
self._write_register(_ADS1X15_POINTER_LO_THRES, self.comparator_low_threshold)

@comparator_high_threshold.setter
def comparator_high_threshold(self, value: int) -> None:
"""Set comparator high threshold value for ADS1015 ADC
"""Set comparator high threshold value for ADS1x15 ADC

:param int value: 16-bit signed integer to write to register
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:param int value: 16-bit signed integer to write to register
:param int value: 17-bit signed integer to write to register. The lowest bit is dropped.

"""
if value < 0 or value > 65535:
raise ValueError("Comparator Threshold value must be between 0 and 65535")
if value < -32768 or value > 32767:
raise ValueError(
"Comparator Threshold value must be between -32768 and 32767"
)

if (self.bits == 12) & (value & 0x000F > 0):
print("4 LSBs will be truncated for ADS1015 for 12-bit value")

tannewt marked this conversation as resolved.
Show resolved Hide resolved
self._comparator_high_threshold = value
self._write_register(_ADS1X15_POINTER_HI_THRES, self.comparator_high_threshold)

Expand Down Expand Up @@ -244,18 +248,6 @@ def _data_rate_default(self) -> int:
"""
raise NotImplementedError("Subclasses must implement _data_rate_default!")

def _comp_low_thres_default(self) -> int:
"""Retrieve the default comparator low threshold for this ADC (in 16-bit signed int).
Should be implemented by subclasses.
"""
raise NotImplementedError("Subclasses must implement _comp_low_thres_default!")

def _comp_high_thres_default(self) -> int:
"""Retrieve the default comparator high threshold for this ADC (in 16-bit signed int).
Should be implemented by subclasses.
"""
raise NotImplementedError("Subclasses must implement _comp_high_thres_default!")

def _conversion_value(self, raw_adc: int) -> int:
"""Subclasses should override this function that takes the 16 raw ADC
values of a conversion result and returns a signed integer value.
Expand Down
30 changes: 6 additions & 24 deletions adafruit_ads1x15/analog_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,10 @@ def voltage(self) -> float:
return volts

def convert_to_value(self, volts: float) -> int:
"""Calculates 12-bit integer for threshold registers from voltage level input"""

# Convert 2's complement of signed int if number is negative
if volts > 0:
value = round(
(volts / _ADS1X15_PGA_RANGE[self._ads.gain])
* ((1 << (self._ads.bits - 1)) - 1)
)
else:
value = round(
(volts / _ADS1X15_PGA_RANGE[self._ads.gain])
* (1 << (self._ads.bits - 1))
)
value += 1 << self._ads.bits
"""Calculates a standard 16-bit integer value for a given voltage"""

lsb = _ADS1X15_PGA_RANGE[self._ads.gain] / (1 << (self._ads.bits - 1))
value = int(volts / lsb)

# Need to bit shift if value is only 12-bits
value <<= 16 - self._ads.bits
Expand All @@ -86,18 +76,10 @@ def convert_to_value(self, volts: float) -> int:
def convert_to_voltage(self, value_int: int) -> float:
"""Calculates voltage from 16-bit ADC reading"""

if value_int & 0x8000:
# Need to convert negative number through 2's complement
value_int -= 0x10000
lsb = _ADS1X15_PGA_RANGE[self._ads.gain] / (1 << (self._ads.bits - 1))

# Need to bit shift if value is only 12-bits
value_int >>= 16 - self._ads.bits

volts = float(value_int)
volts = (
volts
* _ADS1X15_PGA_RANGE[self._ads.gain]
/ (0x7FFF >> (16 - self._ads.bits))
)
volts = value_int * lsb

return volts