parent
6d6ae46a2e
commit
e731810cfd
11 changed files with 753 additions and 1 deletions
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@adafruit.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Carter Nelson for Adafruit Industries
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1 +0,0 @@
|
|||
just a blank repo to get the ball rolling...
|
||||
74
README.rst
Normal file
74
README.rst
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. image:: https://readthedocs.org/projects/adafruit-circuitpython-CircuitPython_ADS1x15/badge/?version=latest
|
||||
:target: https://circuitpython.readthedocs.io/projects/CircuitPython_ADS1x15/en/latest/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image :: https://badges.gitter.im/adafruit/circuitpython.svg
|
||||
:target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
||||
:alt: Gitter
|
||||
|
||||
Support for the ADS1x15 series of analog-to-digital converters. Available in 12-bit (ADS1015)
|
||||
and 16-bit (ADS1115) versions.
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
This driver depends on:
|
||||
|
||||
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
||||
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
||||
|
||||
Please ensure all dependencies are available on the CircuitPython filesystem.
|
||||
This is easily achieved by downloading
|
||||
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
Single Ended
|
||||
------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import board
|
||||
import busio
|
||||
from adafruit_ads1x15.single_ended import ADS1015
|
||||
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
adc = ADS1015(i2c)
|
||||
while True:
|
||||
# channel 0
|
||||
print(adc[0].value, adc[0].volts)
|
||||
|
||||
Differential
|
||||
------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import board
|
||||
import busio
|
||||
from adafruit_ads1x15.differential import ADS1015
|
||||
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
adc = ADS1015(i2c)
|
||||
while True:
|
||||
# channel 0 - channel 1
|
||||
print(adc[(0,1)].value, adc[(0,1)].volts)
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome! Please read our `Code of Conduct
|
||||
<https://github.com/adafruit/Adafruit_CircuitPython_CircuitPython_ADS1x15/blob/master/CODE_OF_CONDUCT.md>`_
|
||||
before contributing to help this project stay welcoming.
|
||||
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
||||
219
adafruit_ads1x15/adafruit_ads1x15.py
Normal file
219
adafruit_ads1x15/adafruit_ads1x15.py
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Carter Nelson for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`adafruit__ads1x15`
|
||||
====================================================
|
||||
|
||||
CircuitPython driver for ADS1015/1115 ADCs.
|
||||
|
||||
* Author(s): Carter Nelson
|
||||
"""
|
||||
import time
|
||||
from micropython import const
|
||||
from adafruit_bus_device.i2c_device import I2CDevice
|
||||
|
||||
# Register and other configuration values:
|
||||
ADS1x15_DEFAULT_ADDRESS = const(0x48)
|
||||
ADS1x15_POINTER_CONVERSION = const(0x00)
|
||||
ADS1x15_POINTER_CONFIG = const(0x01)
|
||||
ADS1x15_POINTER_LOW_THRESHOLD = const(0x02)
|
||||
ADS1x15_POINTER_HIGH_THRESHOLD = const(0x03)
|
||||
ADS1x15_CONFIG_OS_SINGLE = const(0x8000)
|
||||
ADS1x15_CONFIG_MUX_OFFSET = const(12)
|
||||
# Maping of gain values to config register values.
|
||||
ADS1x15_CONFIG_GAIN = {
|
||||
2/3: 0x0000,
|
||||
1: 0x0200,
|
||||
2: 0x0400,
|
||||
4: 0x0600,
|
||||
8: 0x0800,
|
||||
16: 0x0A00
|
||||
}
|
||||
ADS1x15_PGA_RANGE = {
|
||||
2/3: 6.144,
|
||||
1: 4.096,
|
||||
2: 2.048,
|
||||
4: 1.024,
|
||||
8: 0.512,
|
||||
16: 0.256
|
||||
}
|
||||
ADS1x15_CONFIG_MODE_CONTINUOUS = const(0x0000)
|
||||
ADS1x15_CONFIG_MODE_SINGLE = const(0x0100)
|
||||
# Mapping of data/sample rate to config register values for ADS1015 (faster).
|
||||
ADS1015_CONFIG_DR = {
|
||||
128: 0x0000,
|
||||
250: 0x0020,
|
||||
490: 0x0040,
|
||||
920: 0x0060,
|
||||
1600: 0x0080,
|
||||
2400: 0x00A0,
|
||||
3300: 0x00C0
|
||||
}
|
||||
# Mapping of data/sample rate to config register values for ADS1115 (slower).
|
||||
ADS1115_CONFIG_DR = {
|
||||
8: 0x0000,
|
||||
16: 0x0020,
|
||||
32: 0x0040,
|
||||
64: 0x0060,
|
||||
128: 0x0080,
|
||||
250: 0x00A0,
|
||||
475: 0x00C0,
|
||||
860: 0x00E0
|
||||
}
|
||||
ADS1x15_CONFIG_COMP_WINDOW = const(0x0010)
|
||||
ADS1x15_CONFIG_COMP_ACTIVE_HIGH = const(0x0008)
|
||||
ADS1x15_CONFIG_COMP_LATCHING = const(0x0004)
|
||||
ADS1x15_CONFIG_COMP_QUE = {
|
||||
1: 0x0000,
|
||||
2: 0x0001,
|
||||
4: 0x0002
|
||||
}
|
||||
ADS1x15_CONFIG_COMP_QUE_DISABLE = const(0x0003)
|
||||
ADS1x15_DIFF_CHANNELS = {
|
||||
(0,1): 0,
|
||||
(0,3): 1,
|
||||
(1,3): 2,
|
||||
(2,3): 3
|
||||
}
|
||||
|
||||
class ADC_Channel(object):
|
||||
"""Provides per channel access to ADC readings."""
|
||||
|
||||
def __init__(self, adc, channel):
|
||||
self._adc = adc
|
||||
self._channel = channel
|
||||
|
||||
@property
|
||||
def value(self, ):
|
||||
"""ADC reading in raw counts."""
|
||||
return self._adc._read_channel(self._channel)
|
||||
|
||||
@property
|
||||
def volts(self, ):
|
||||
"""ADC reading in volts."""
|
||||
return self._adc._read_channel_volts(self._channel)
|
||||
|
||||
|
||||
class ADS1x15(object):
|
||||
"""Base functionality for ADS1x15 analog to digital converters."""
|
||||
|
||||
def __init__(self, i2c, address=ADS1x15_DEFAULT_ADDRESS, **kwargs):
|
||||
self.buf = bytearray(3)
|
||||
self.i2c_device = I2CDevice(i2c, address)
|
||||
self.bits = None
|
||||
self._channels = [ADC_Channel(self, 0),
|
||||
ADC_Channel(self, 1),
|
||||
ADC_Channel(self, 2),
|
||||
ADC_Channel(self, 3)]
|
||||
|
||||
def _data_rate_default(self):
|
||||
"""Retrieve the default data rate for this ADC (in samples per second).
|
||||
Should be implemented by subclasses.
|
||||
"""
|
||||
raise NotImplementedError('Subclasses must implement _data_rate_default!')
|
||||
|
||||
def _data_rate_config(self, data_rate):
|
||||
"""Subclasses should override this function and return a 16-bit value
|
||||
that can be OR'ed with the config register to set the specified
|
||||
data rate. If a value of None is specified then a default data_rate
|
||||
setting should be returned. If an invalid or unsupported data_rate is
|
||||
provided then an exception should be thrown.
|
||||
"""
|
||||
raise NotImplementedError('Subclass must implement _data_rate_config function!')
|
||||
|
||||
def _conversion_value(self, low, high):
|
||||
"""Subclasses should override this function that takes the low and high
|
||||
byte of a conversion result and returns a signed integer value.
|
||||
"""
|
||||
raise NotImplementedError('Subclass must implement _conversion_value function!')
|
||||
|
||||
def _read_channel(self, channel):
|
||||
"""Subclasses should override this function to return a value for the
|
||||
requested channels as a signed integer value.
|
||||
"""
|
||||
raise NotImplementedError('Subclass must implement _read_channel function!')
|
||||
|
||||
def _read_channel_volts(self, channel):
|
||||
"""Subclasses should override this function to return a value for the
|
||||
requested channels as a float value.
|
||||
"""
|
||||
raise NotImplementedError('Subclass must implement _read_channel_volts function!')
|
||||
|
||||
def _read(self, mux, gain, data_rate, mode):
|
||||
"""Perform an ADC read with the provided mux, gain, data_rate, and mode
|
||||
values. Returns the signed integer result of the read.
|
||||
"""
|
||||
config = ADS1x15_CONFIG_OS_SINGLE # Go out of power-down mode for conversion.
|
||||
# Specify mux value.
|
||||
config |= (mux & 0x07) << ADS1x15_CONFIG_MUX_OFFSET
|
||||
# Validate the passed in gain and then set it in the config.
|
||||
if gain not in ADS1x15_CONFIG_GAIN:
|
||||
raise ValueError('Gain must be one of: 2/3, 1, 2, 4, 8, 16')
|
||||
config |= ADS1x15_CONFIG_GAIN[gain]
|
||||
# Set the mode (continuous or single shot).
|
||||
config |= mode
|
||||
# Get the default data rate if none is specified (default differs between
|
||||
# ADS1015 and ADS1115).
|
||||
if data_rate is None:
|
||||
data_rate = self._data_rate_default()
|
||||
# Set the data rate (this is controlled by the subclass as it differs
|
||||
# between ADS1015 and ADS1115).
|
||||
config |= self._data_rate_config(data_rate)
|
||||
config |= ADS1x15_CONFIG_COMP_QUE_DISABLE # Disble comparator mode.
|
||||
# Send the config value to start the ADC conversion.
|
||||
# Explicitly break the 16-bit value down to a big endian pair of bytes.
|
||||
self.buf[0] = ADS1x15_POINTER_CONFIG
|
||||
self.buf[1] = (config >> 8) & 0xFF
|
||||
self.buf[2] = config & 0xFF
|
||||
with self.i2c_device as i2c:
|
||||
i2c.write(self.buf)
|
||||
# Wait for the ADC sample to finish based on the sample rate plus a
|
||||
# small offset to be sure (0.1 millisecond).
|
||||
time.sleep(1.0/data_rate+0.0001)
|
||||
# Retrieve the result.
|
||||
self.buf[0] = ADS1x15_POINTER_CONVERSION
|
||||
i2c.write(self.buf, end=1, stop=False)
|
||||
i2c.read_into(self.buf, start=1)
|
||||
return self._conversion_value(self.buf[2], self.buf[1])
|
||||
|
||||
def stop_adc(self):
|
||||
"""Stop all continuous ADC conversions (either normal or difference mode).
|
||||
"""
|
||||
# Set the config register to its default value of 0x8583 to stop
|
||||
# continuous conversions.
|
||||
self.buf[0] = ADS1x15_POINTER_CONFIG
|
||||
self.buf[1] = 0x85
|
||||
self.buf[2] = 0x83
|
||||
with self.i2c_device as i2c:
|
||||
i2c.write(self.buf)
|
||||
|
||||
def get_last_result(self):
|
||||
"""Read the last conversion result when in continuous conversion mode.
|
||||
Will return a signed integer value.
|
||||
"""
|
||||
# Retrieve the conversion register value, convert to a signed int, and
|
||||
# return it.
|
||||
self.buf[0] = ADS1x15_POINTER_CONVERSION
|
||||
with self.i2c_device as i2c:
|
||||
i2c.write(self.buf, end=1, stop=False)
|
||||
i2c.read_into(self.buf, start=1)
|
||||
return self._conversion_value(self.buf[2], self.buf[1])
|
||||
111
adafruit_ads1x15/differential.py
Normal file
111
adafruit_ads1x15/differential.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
from .adafruit_ads1x15 import *
|
||||
|
||||
class ADS1x15_Differential(ADS1x15):
|
||||
"""Base functionality for ADS1x15 analog to digital converters operating
|
||||
in differential mode."""
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._channels[ADS1x15_DIFF_CHANNELS[key]]
|
||||
|
||||
def read_adc_difference(self, differential, gain=1, data_rate=None):
|
||||
"""Read the difference between two ADC channels and return the ADC value
|
||||
as a signed integer result. Differential must be one of:
|
||||
- 0 = Channel 0 minus channel 1
|
||||
- 1 = Channel 0 minus channel 3
|
||||
- 2 = Channel 1 minus channel 3
|
||||
- 3 = Channel 2 minus channel 3
|
||||
"""
|
||||
assert 0 <= differential <= 3, 'Differential must be a value within 0-3!'
|
||||
# Perform a single shot read using the provided differential value
|
||||
# as the mux value (which will enable differential mode).
|
||||
return self._read(differential, gain, data_rate, ADS1x15_CONFIG_MODE_SINGLE)
|
||||
|
||||
def read_volts_difference(self, differential, gain=1, data_rate=None):
|
||||
"""Read the difference between two ADC channels and return the voltage value
|
||||
as a floating point result. Differential must be one of:
|
||||
- 0 = Channel 0 minus channel 1
|
||||
- 1 = Channel 0 minus channel 3
|
||||
- 2 = Channel 1 minus channel 3
|
||||
- 3 = Channel 2 minus channel 3
|
||||
"""
|
||||
assert 0 <= differential <= 3, 'Differential must be a value within 0-3!'
|
||||
raw = self.read_adc_difference(differential, gain, data_rate)
|
||||
volts = raw * (ADS1x15_PGA_RANGE[gain] / (2**(self.bits-1) - 1))
|
||||
return volts
|
||||
|
||||
def start_adc_difference(self, differential, gain=1, data_rate=None):
|
||||
"""Start continuous ADC conversions between two ADC channels. Differential
|
||||
must be one of:
|
||||
- 0 = Channel 0 minus channel 1
|
||||
- 1 = Channel 0 minus channel 3
|
||||
- 2 = Channel 1 minus channel 3
|
||||
- 3 = Channel 2 minus channel 3
|
||||
Will return an initial conversion result, then call the get_last_result()
|
||||
function continuously to read the most recent conversion result. Call
|
||||
stop_adc() to stop conversions.
|
||||
"""
|
||||
assert 0 <= differential <= 3, 'Differential must be a value within 0-3!'
|
||||
# Perform a single shot read using the provided differential value
|
||||
# as the mux value (which will enable differential mode).
|
||||
return self._read(differential, gain, data_rate, ADS1x15_CONFIG_MODE_CONTINUOUS)
|
||||
|
||||
class ADS1015(ADS1x15_Differential):
|
||||
"""ADS1015 12-bit differential analog to digital converter instance."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ADS1015, self).__init__(*args, **kwargs)
|
||||
self.bits = 12
|
||||
|
||||
def _data_rate_default(self):
|
||||
# Default from datasheet page 19, config register DR bit default.
|
||||
return 1600
|
||||
|
||||
def _data_rate_config(self, data_rate):
|
||||
if data_rate not in ADS1015_CONFIG_DR:
|
||||
raise ValueError('Data rate must be one of: 128, 250, 490, 920, 1600, 2400, 3300')
|
||||
return ADS1015_CONFIG_DR[data_rate]
|
||||
|
||||
def _conversion_value(self, low, high):
|
||||
# Convert to 12-bit signed value.
|
||||
value = ((high & 0xFF) << 4) | ((low & 0xFF) >> 4)
|
||||
# Check for sign bit and turn into a negative value if set.
|
||||
if value & 0x800 != 0:
|
||||
value -= 1 << 12
|
||||
return value
|
||||
|
||||
def _read_channel(self, channel):
|
||||
return self.read_adc_difference(channel)
|
||||
|
||||
def _read_channel_volts(self, channel):
|
||||
return self.read_volts_difference(channel)
|
||||
|
||||
|
||||
class ADS1115(ADS1x15_Differential):
|
||||
"""ADS1115 16-bit differential analog to digital converter instance."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ADS1115, self).__init__(*args, **kwargs)
|
||||
self.bits = 16
|
||||
|
||||
def _data_rate_default(self):
|
||||
# Default from datasheet page 16, config register DR bit default.
|
||||
return 128
|
||||
|
||||
def _data_rate_config(self, data_rate):
|
||||
if data_rate not in ADS1115_CONFIG_DR:
|
||||
raise ValueError('Data rate must be one of: 8, 16, 32, 64, 128, 250, 475, 860')
|
||||
return ADS1115_CONFIG_DR[data_rate]
|
||||
|
||||
def _conversion_value(self, low, high):
|
||||
# Convert to 16-bit signed value.
|
||||
value = ((high & 0xFF) << 8) | (low & 0xFF)
|
||||
# Check for sign bit and turn into a negative value if set.
|
||||
if value & 0x8000 != 0:
|
||||
value -= 1 << 16
|
||||
return value
|
||||
|
||||
def _read_channel(self, channel):
|
||||
return self.read_adc_difference(channel)
|
||||
|
||||
def _read_channel_volts(self, channel):
|
||||
return self.read_volts_difference(channel)
|
||||
98
adafruit_ads1x15/single_ended.py
Normal file
98
adafruit_ads1x15/single_ended.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
from .adafruit_ads1x15 import *
|
||||
|
||||
class ADS1x15_SingleEnded(ADS1x15):
|
||||
"""Base functionality for ADS1x15 analog to digital converters operating
|
||||
in single ended mode."""
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._channels[key]
|
||||
|
||||
def read_adc(self, channel, gain=1, data_rate=None):
|
||||
"""Read a single ADC channel and return the ADC value as a signed integer
|
||||
result. Channel must be a value within 0-3.
|
||||
"""
|
||||
assert 0 <= channel <= 3, 'Channel must be a value within 0-3!'
|
||||
# Perform a single shot read and set the mux value to the channel plus
|
||||
# the highest bit (bit 3) set.
|
||||
return self._read(channel + 0x04, gain, data_rate, ADS1x15_CONFIG_MODE_SINGLE)
|
||||
|
||||
def read_volts(self, channel, gain=1, data_rate=None):
|
||||
"""Read a single ADC channel and return the voltage value as a floating point
|
||||
result. Channel must be a value within 0-3.
|
||||
"""
|
||||
assert 0 <= channel <= 3, 'Channel must be a value within 0-3!'
|
||||
raw = self.read_adc(channel, gain, data_rate)
|
||||
volts = raw * (ADS1x15_PGA_RANGE[gain] / (2**(self.bits-1) - 1))
|
||||
return volts
|
||||
|
||||
def start_adc(self, channel, gain=1, data_rate=None):
|
||||
"""Start continuous ADC conversions on the specified channel (0-3). Will
|
||||
return an initial conversion result, then call the get_last_result()
|
||||
function to read the most recent conversion result. Call stop_adc() to
|
||||
stop conversions.
|
||||
"""
|
||||
assert 0 <= channel <= 3, 'Channel must be a value within 0-3!'
|
||||
# Start continuous reads and set the mux value to the channel plus
|
||||
# the highest bit (bit 3) set.
|
||||
return self._read(channel + 0x04, gain, data_rate, ADS1x15_CONFIG_MODE_CONTINUOUS)
|
||||
|
||||
class ADS1015(ADS1x15_SingleEnded):
|
||||
"""ADS1015 12-bit single ended analog to digital converter instance."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ADS1015, self).__init__(*args, **kwargs)
|
||||
self.bits = 12
|
||||
|
||||
def _data_rate_default(self):
|
||||
# Default from datasheet page 19, config register DR bit default.
|
||||
return 1600
|
||||
|
||||
def _data_rate_config(self, data_rate):
|
||||
if data_rate not in ADS1015_CONFIG_DR:
|
||||
raise ValueError('Data rate must be one of: 128, 250, 490, 920, 1600, 2400, 3300')
|
||||
return ADS1015_CONFIG_DR[data_rate]
|
||||
|
||||
def _conversion_value(self, low, high):
|
||||
# Convert to 12-bit signed value.
|
||||
value = ((high & 0xFF) << 4) | ((low & 0xFF) >> 4)
|
||||
# Check for sign bit and turn into a negative value if set.
|
||||
if value & 0x800 != 0:
|
||||
value -= 1 << 12
|
||||
return value
|
||||
|
||||
def _read_channel(self, channel):
|
||||
return self.read_adc(channel)
|
||||
|
||||
def _read_channel_volts(self, channel):
|
||||
return self.read_volts(channel)
|
||||
|
||||
|
||||
class ADS1115(ADS1x15_SingleEnded):
|
||||
"""ADS1115 16-bit single ended analog to digital converter instance."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ADS1115, self).__init__(*args, **kwargs)
|
||||
self.bits = 16
|
||||
|
||||
def _data_rate_default(self):
|
||||
# Default from datasheet page 16, config register DR bit default.
|
||||
return 128
|
||||
|
||||
def _data_rate_config(self, data_rate):
|
||||
if data_rate not in ADS1115_CONFIG_DR:
|
||||
raise ValueError('Data rate must be one of: 8, 16, 32, 64, 128, 250, 475, 860')
|
||||
return ADS1115_CONFIG_DR[data_rate]
|
||||
|
||||
def _conversion_value(self, low, high):
|
||||
# Convert to 16-bit signed value.
|
||||
value = ((high & 0xFF) << 8) | (low & 0xFF)
|
||||
# Check for sign bit and turn into a negative value if set.
|
||||
if value & 0x8000 != 0:
|
||||
value -= 1 << 16
|
||||
return value
|
||||
|
||||
def _read_channel(self, channel):
|
||||
return self.read_adc(channel)
|
||||
|
||||
def _read_channel_volts(self, channel):
|
||||
return self.read_volts(channel)
|
||||
11
api.rst
Normal file
11
api.rst
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
.. If you created a package, create one automodule per module in the package.
|
||||
|
||||
.. automodule:: adafruit_ads1x15
|
||||
:members:
|
||||
|
||||
.. automodule:: differential
|
||||
:members:
|
||||
|
||||
.. automodule:: single_ended
|
||||
:members:
|
||||
142
conf.py
Normal file
142
conf.py
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'BusDevice': ('https://circuitpython.readthedocs.io/projects/bus_device/en/latest/', None),'Register': ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'README'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Adafruit CIRCUITPYTHON_ADS1X15 Library'
|
||||
copyright = u'2017 Carter Nelson'
|
||||
author = u'Carter Nelson'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#
|
||||
default_role = "any"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#
|
||||
add_function_parentheses = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'AdafruitCIRCUITPYTHON_ADS1X15Librarydoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'AdafruitCIRCUITPYTHON_ADS1X15Library.tex', u'Adafruit CIRCUITPYTHON_ADS1X15 Library Documentation',
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'adafruitCIRCUITPYTHON_ADS1X15library', u'Adafruit CIRCUITPYTHON_ADS1X15 Library Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'AdafruitCIRCUITPYTHON_ADS1X15Library', u'Adafruit CIRCUITPYTHON_ADS1X15 Library Documentation',
|
||||
author, 'AdafruitCIRCUITPYTHON_ADS1X15Library', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
2
readthedocs.yml
Normal file
2
readthedocs.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
requirements_file: requirements.txt
|
||||
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
adafruit-circuitpython-bus-device
|
||||
Loading…
Reference in a new issue