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

Adding library and example #1

Merged
merged 9 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
redo API with analog_in
  • Loading branch information
BlitzCityDIY committed Nov 7, 2023
commit f80fc15e435f08f39c786c1ce572c6cc6747a3f2
99 changes: 37 additions & 62 deletions adafruit_ads7830.py → adafruit_ads7830/ads7830.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: MIT
"""
`adafruit_ads7830`
:py:class:`~adafruit_ads7830.ads7830.ADS7830`
================================================================================

CircuitPython driver for the ADS7830 analog to digital converter
Expand Down Expand Up @@ -40,16 +40,21 @@
_I2C_ADDR = const(0x48)


class Adafruit_ADS7830:
class ADS7830:
"""Adafruit ADS7830 ADC driver"""

# Power-down modes
_POWER_DOWN_MODES = [
0x00, # POWER_DOWN_BETWEEN_CONVERSIONS
0x01, # INTERNAL_REF_OFF_ADC_ON
0x02, # INTERNAL_REF_ON_ADC_OFF
0x03, # INTERNAL_REF_ON_ADC_ON (default)
POWER_DOWN_MODES = [
0x00,
0x01,
0x02,
0x03,
]
"""Power down modes

:param int 0: power down between conversions
:param int 1: internal reference off, ADC on
:param int 2: internal reference on, ADC off
:param int 3: internal reference on, ADC on (default)"""
# Single channel selection list
_CHANNEL_SELECTION = [
0x08, # SINGLE_CH0
Expand All @@ -73,50 +78,42 @@ class Adafruit_ADS7830:
0x07, # DIFF_CH7_CH6
]

def __init__(self, i2c: I2C, address: int = _I2C_ADDR) -> None:
self.i2c_device = I2CDevice(i2c, address)

def _single_channel(self, channel: int, pd_mode: int = 3) -> int:
"""ADC value in single-ended mode
Scales the 8-bit ADC value to a 16-bit value

:param int channel: Channel (0-7)
:param int pd_mode: Power-down mode
:return: Scaled ADC value or raise an exception if read failed
:rtype: int
def __init__(
self,
i2c: I2C,
address: int = _I2C_ADDR,
diff_mode: bool = False,
pd_mode: int = 3,
) -> None:
"""Initialization over I2C

:param int address: I2C address (default 0x48)
:param bool diff_mode: Select differential vs. single mode
:param int pd_mode: Select power down mode (default internal reference on, ADC on)
"""
if channel > 7:
raise ValueError("Invalid channel: must be 0-7")

command_byte = self._CHANNEL_SELECTION[channel]
command_byte <<= 4
command_byte |= self._POWER_DOWN_MODES[pd_mode] << 2
self.i2c_device = I2CDevice(i2c, address)
self.power = self.POWER_DOWN_MODES[pd_mode]
self.differential_mode = diff_mode

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
def read(self, channel: int) -> int:
"""ADC value

def _differential_channel(self, channel: int, pd_mode: int = 3) -> int:
"""ADC value in differential mode
Scales the 8-bit ADC value to a 16-bit value

:param int channel: Positive channel for differential reading (0-7)
:param int channel: Channel (0-7)
:param int pd_mode: Power-down mode
:param bool diff: Differential vs. single read mode
:return: Scaled ADC value or raise an exception if read failed
:rtype: int
"""
if channel > 7:
raise ValueError("Invalid channel: must be 0-7")

command_byte = self._DIFF_CHANNEL_SELECTION[channel // 2]
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_MODES[pd_mode] << 2
command_byte |= self.power << 2

with self.i2c_device as i2c:
try:
Expand All @@ -127,25 +124,3 @@ def _differential_channel(self, channel: int, pd_mode: int = 3) -> int:
return adc_value[0] << 8
except Exception as error:
raise RuntimeError(f"Failed to read value: {error}") from error

@property
def value(self) -> typing.List[int]:
"""Single-ended mode ADC values for all channels

:rtype: List[int]"""
values = []
for i in range(8):
single_value = self._single_channel(i)
values.append(single_value)
return values

@property
def differential_value(self) -> typing.List[int]:
"""Differential ADC values for all channel pairs

:rtype: List[int]"""
values = []
for i in range(0, 8, 2): # Iterate over channel pairs
diff_value = self._differential_channel(i)
values.append(diff_value)
return values
34 changes: 34 additions & 0 deletions adafruit_ads7830/analog_in.py
Original file line number Diff line number Diff line change
@@ -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
5 changes: 4 additions & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:
12 changes: 6 additions & 6 deletions examples/ads7830_simpletest.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple demo to read 8 analog inputs
# from ADS7830 ADC
# Simple demo to read analog input on channel 0

import time
import board
import adafruit_ads7830
import adafruit_ads7830.ads7830 as ADC
from adafruit_ads7830.analog_in import AnalogIn

i2c = board.I2C()

# Initialize ADS7830
adc = adafruit_ads7830.Adafruit_ADS7830(i2c)
adc = ADC.ADS7830(i2c)
chan = AnalogIn(adc, 0)

while True:
for i in range(8):
print(f"ADC channel {i} = {adc.value[i]}")
print(f"ADC channel {0} = {chan.value}")
time.sleep(0.1)