diff --git a/adafruit_ads7830.py b/adafruit_ads7830.py deleted file mode 100644 index 0d80dfa..0000000 --- a/adafruit_ads7830.py +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries -# SPDX-FileCopyrightText: Copyright (c) 2023 Liz Clark for Adafruit Industries -# -# SPDX-License-Identifier: MIT -""" -`adafruit_ads7830` -================================================================================ - -CircuitPython driver for the ADS7830 analog to digital converter - - -* Author(s): Liz Clark - -Implementation Notes --------------------- - -**Hardware:** - -* `Adafruit ADS7830 8-Channel 8-Bit ADC with I2C `_ - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://circuitpython.org/downloads - -* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice -""" - -# imports - -__version__ = "0.0.0+auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ADS7830.git" diff --git a/adafruit_ads7830/ads7830.py b/adafruit_ads7830/ads7830.py new file mode 100644 index 0000000..4676ba7 --- /dev/null +++ b/adafruit_ads7830/ads7830.py @@ -0,0 +1,119 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT +""" +:py:class:`~adafruit_ads7830.ads7830.ADS7830` +================================================================================ + +CircuitPython driver for the ADS7830 analog to digital converter + + +* Author(s): Liz Clark + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit ADS7830 8-Channel 8-Bit ADC with I2C `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + +* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice +""" + +from adafruit_bus_device.i2c_device import I2CDevice +from micropython import const + +try: + import typing # pylint: disable=unused-import + from busio import I2C +except ImportError: + pass + +__version__ = "0.0.0+auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ADS7830.git" + +_I2C_ADDR = const(0x48) + + +class ADS7830: + """Adafruit ADS7830 ADC driver""" + + # Single channel selection list + _CHANNEL_SELECTION = [ + 0x08, # SINGLE_CH0 + 0x0C, # SINGLE_CH1 + 0x09, # SINGLE_CH2 + 0x0D, # SINGLE_CH3 + 0x0A, # SINGLE_CH4 + 0x0E, # SINGLE_CH5 + 0x0B, # SINGLE_CH6 + 0x0F, # SINGLE_CH7 + ] + # Differential channel selection list + _DIFF_CHANNEL_SELECTION = [ + 0x00, # DIFF_CH0_CH1 + 0x04, # DIFF_CH1_CH0 + 0x01, # DIFF_CH2_CH3 + 0x05, # DIFF_CH3_CH2 + 0x02, # DIFF_CH4_CH5 + 0x06, # DIFF_CH5_CH4 + 0x03, # DIFF_CH6_CH7 + 0x07, # DIFF_CH7_CH6 + ] + + # pylint: disable=too-many-arguments + def __init__( + self, + i2c: I2C, + address: int = _I2C_ADDR, + differential_mode: bool = False, + int_ref_power_down: bool = False, + adc_power_down: bool = False, + ) -> None: + """Initialization over I2C + + :param int address: I2C address (default 0x48) + :param bool differential_mode: Select differential vs. single mode + :param bool int_ref_power_down: Power down internal reference after sampling + :param bool adc_power_down: Power down ADC after sampling + """ + self.i2c_device = I2CDevice(i2c, address) + _pd = 0 + if not int_ref_power_down: + _pd |= 2 + if not adc_power_down: + _pd |= 1 + self.power_down = _pd + self.differential_mode = differential_mode + + def read(self, channel: int) -> int: + """ADC value + Scales the 8-bit ADC value to a 16-bit value + + :param int channel: Channel (0-7) + :return: Scaled ADC value or raise an exception if read failed + :rtype: int + """ + if channel > 7: + raise ValueError("Invalid channel: must be 0-7") + if self.differential_mode: + command_byte = self._DIFF_CHANNEL_SELECTION[channel // 2] + else: + command_byte = self._CHANNEL_SELECTION[channel] + command_byte <<= 4 + command_byte |= self.power_down << 2 + + with self.i2c_device as i2c: + try: + # Buffer to store the read ADC value + adc_value = bytearray(1) + i2c.write_then_readinto(bytearray([command_byte]), adc_value) + # Scale the 8-bit value to 16-bit + return adc_value[0] << 8 + except Exception as error: + raise RuntimeError(f"Failed to read value: {error}") from error diff --git a/adafruit_ads7830/analog_in.py b/adafruit_ads7830/analog_in.py new file mode 100644 index 0000000..bb01e4a --- /dev/null +++ b/adafruit_ads7830/analog_in.py @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +:py:class:`~adafruit_ads7830.analog_in.AnalogIn` +====================================================== +AnalogIn for ADC readings. + +* Author(s): Liz Clark + +""" + +from adafruit_ads7830.ads7830 import ADS7830 + + +class AnalogIn: + """AnalogIn Mock Implementation for ADC Reads. + + :param ADS7830 adc: The ADC object. + :param int pin: Required pin for reading. + """ + + def __init__(self, adc: ADS7830, pin: int) -> None: + if not isinstance(adc, ADS7830): + raise ValueError("ADC object is from the ADS7830 class.") + self._adc = adc + self._pin = pin + + @property + def value(self) -> int: + """Returns the value of an ADC pin as an integer in the range [0, 65535].""" + result = self._adc.read(self._pin) + return result diff --git a/docs/api.rst b/docs/api.rst index 499eddb..3e71d40 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,5 +4,8 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" -.. automodule:: adafruit_ads7830 +.. automodule:: adafruit_ads7830.ads7830 + :members: + +.. automodule:: adafruit_ads7830.analog_in :members: diff --git a/docs/conf.py b/docs/conf.py index 2d7dd9b..a5c1fa2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,18 +23,18 @@ "sphinx.ext.todo", ] -# TODO: Please Read! -# Uncomment the below if you use native CircuitPython modules such as -# digitalio, micropython and busio. List the modules you use. Without it, the -# autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["board", "busio", "micropython"] +autodoc_mock_imports = [ + "micropython", + "busio", + "adafruit_bus_device", +] autodoc_preserve_defaults = True intersphinx_mapping = { - "python": ("https://docs.python.org/3", None),"BusDevice": ("https://docs.circuitpython.org/projects/busdevice/en/latest/", None), - "Register": ("https://docs.circuitpython.org/projects/register/en/latest/", None), + "python": ("https://docs.python.org/3", None), + "BusDevice": ("https://docs.circuitpython.org/projects/busdevice/en/latest/", None), "CircuitPython": ("https://docs.circuitpython.org/en/latest/", None), } diff --git a/examples/ads7830_simpletest.py b/examples/ads7830_simpletest.py index 9ed95d2..3c0936b 100644 --- a/examples/ads7830_simpletest.py +++ b/examples/ads7830_simpletest.py @@ -1,4 +1,19 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries -# SPDX-FileCopyrightText: Copyright (c) 2023 Liz Clark for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense +# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries +# SPDX-License-Identifier: MIT + +# Simple demo to read analog input on channel 0 + +import time +import board +import adafruit_ads7830.ads7830 as ADC +from adafruit_ads7830.analog_in import AnalogIn + +i2c = board.I2C() + +# Initialize ADS7830 +adc = ADC.ADS7830(i2c) +chan = AnalogIn(adc, 0) + +while True: + print(f"ADC channel 0 = {chan.value}") + time.sleep(0.1) diff --git a/pyproject.toml b/pyproject.toml index cf20e74..c62bfd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dynamic = ["dependencies", "optional-dependencies"] [tool.setuptools] # TODO: IF LIBRARY FILES ARE A PACKAGE FOLDER, # CHANGE `py_modules = ['...']` TO `packages = ['...']` -py-modules = ["adafruit_ads7830"] +packages = ["adafruit_ads7830"] [tool.setuptools.dynamic] dependencies = {file = ["requirements.txt"]}