parent
60ab07dbc6
commit
023a3987be
|
@ -0,0 +1,161 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import re
|
||||||
|
import smbus
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Adafruit_I2C Class
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
class Adafruit_I2C(object):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getPiRevision():
|
||||||
|
"Gets the version number of the Raspberry Pi board"
|
||||||
|
# Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
|
||||||
|
try:
|
||||||
|
with open('/proc/cpuinfo', 'r') as infile:
|
||||||
|
for line in infile:
|
||||||
|
# Match a line of the form "Revision : 0002" while ignoring extra
|
||||||
|
# info in front of the revsion (like 1000 when the Pi was over-volted).
|
||||||
|
match = re.match('Revision\s+:\s+.*(\w{4})$', line)
|
||||||
|
if match and match.group(1) in ['0000', '0002', '0003']:
|
||||||
|
# Return revision 1 if revision ends with 0000, 0002 or 0003.
|
||||||
|
return 1
|
||||||
|
elif match:
|
||||||
|
# Assume revision 2 if revision ends with any other 4 chars.
|
||||||
|
return 2
|
||||||
|
# Couldn't find the revision, assume revision 0 like older code for compatibility.
|
||||||
|
return 0
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getPiI2CBusNumber():
|
||||||
|
# Gets the I2C bus number /dev/i2c#
|
||||||
|
return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
|
||||||
|
|
||||||
|
def __init__(self, address, busnum=-1, debug=False):
|
||||||
|
self.address = address
|
||||||
|
# By default, the correct I2C bus is auto-detected using /proc/cpuinfo
|
||||||
|
# Alternatively, you can hard-code the bus version below:
|
||||||
|
# self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
|
||||||
|
# self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
|
||||||
|
self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
|
||||||
|
self.debug = debug
|
||||||
|
|
||||||
|
def reverseByteOrder(self, data):
|
||||||
|
"Reverses the byte order of an int (16-bit) or long (32-bit) value"
|
||||||
|
# Courtesy Vishal Sapre
|
||||||
|
byteCount = len(hex(data)[2:].replace('L','')[::2])
|
||||||
|
val = 0
|
||||||
|
for i in range(byteCount):
|
||||||
|
val = (val << 8) | (data & 0xff)
|
||||||
|
data >>= 8
|
||||||
|
return val
|
||||||
|
|
||||||
|
def errMsg(self):
|
||||||
|
print ("Error accessing 0x%02X: Check your I2C address" % self.address)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def write8(self, reg, value):
|
||||||
|
"Writes an 8-bit value to the specified register/address"
|
||||||
|
try:
|
||||||
|
self.bus.write_byte_data(self.address, reg, value)
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def write16(self, reg, value):
|
||||||
|
"Writes a 16-bit value to the specified register/address pair"
|
||||||
|
try:
|
||||||
|
self.bus.write_word_data(self.address, reg, value)
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
|
||||||
|
(value, reg, reg+1))
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def writeRaw8(self, value):
|
||||||
|
"Writes an 8-bit value on the bus"
|
||||||
|
try:
|
||||||
|
self.bus.write_byte(self.address, value)
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Wrote 0x%02X" % value)
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def writeList(self, reg, list):
|
||||||
|
"Writes an array of bytes using I2C format"
|
||||||
|
try:
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Writing list to register 0x%02X:" % reg)
|
||||||
|
print (list)
|
||||||
|
self.bus.write_i2c_block_data(self.address, reg, list)
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def readList(self, reg, length):
|
||||||
|
"Read a list of bytes from the I2C device"
|
||||||
|
try:
|
||||||
|
results = self.bus.read_i2c_block_data(self.address, reg, length)
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
|
||||||
|
(self.address, reg))
|
||||||
|
print (results)
|
||||||
|
return results
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def readU8(self, reg):
|
||||||
|
"Read an unsigned byte from the I2C device"
|
||||||
|
try:
|
||||||
|
result = self.bus.read_byte_data(self.address, reg)
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
|
||||||
|
(self.address, result & 0xFF, reg))
|
||||||
|
return result
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def readS8(self, reg):
|
||||||
|
"Reads a signed byte from the I2C device"
|
||||||
|
try:
|
||||||
|
result = self.bus.read_byte_data(self.address, reg)
|
||||||
|
if result > 127: result -= 256
|
||||||
|
if self.debug:
|
||||||
|
print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
|
||||||
|
(self.address, result & 0xFF, reg))
|
||||||
|
return result
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def readU16(self, reg, little_endian=True):
|
||||||
|
"Reads an unsigned 16-bit value from the I2C device"
|
||||||
|
try:
|
||||||
|
result = self.bus.read_word_data(self.address,reg)
|
||||||
|
# Swap bytes if using big endian because read_word_data assumes little
|
||||||
|
# endian on ARM (little endian) systems.
|
||||||
|
if not little_endian:
|
||||||
|
result = ((result << 8) & 0xFF00) + (result >> 8)
|
||||||
|
if (self.debug):
|
||||||
|
print ("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
|
||||||
|
return result
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
def readS16(self, reg, little_endian=True):
|
||||||
|
"Reads a signed 16-bit value from the I2C device"
|
||||||
|
try:
|
||||||
|
result = self.readU16(reg,little_endian)
|
||||||
|
if result > 32767: result -= 65536
|
||||||
|
return result
|
||||||
|
except IOError as err:
|
||||||
|
return self.errMsg()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
bus = Adafruit_I2C(address=0)
|
||||||
|
print ("Default I2C bus is accessible")
|
||||||
|
except:
|
||||||
|
print ("Error accessing default I2C bus")
|
|
@ -0,0 +1,783 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
#mods SwitchDoc Labs May 2016
|
||||||
|
import time
|
||||||
|
import smbus
|
||||||
|
from Adafruit_I2C import Adafruit_I2C
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# ADS1x15 Class
|
||||||
|
#
|
||||||
|
# Originally written by K. Townsend, Adafruit (https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/tree/master/Adafruit_ADS1x15)
|
||||||
|
# Updates and new functions implementation by Pedro Villanueva, 03/2013.
|
||||||
|
# The only error in the original code was in line 57:
|
||||||
|
# __ADS1015_REG_CONFIG_DR_920SPS = 0x0050
|
||||||
|
# should be
|
||||||
|
# __ADS1015_REG_CONFIG_DR_920SPS = 0x0060
|
||||||
|
#
|
||||||
|
# NOT IMPLEMENTED: Conversion ready pin, page 15 datasheet.
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
class ADS1x15:
|
||||||
|
i2c = None
|
||||||
|
|
||||||
|
# IC Identifiers
|
||||||
|
__IC_ADS1015 = 0x00
|
||||||
|
__IC_ADS1115 = 0x01
|
||||||
|
|
||||||
|
# Pointer Register
|
||||||
|
__ADS1015_REG_POINTER_MASK = 0x03
|
||||||
|
__ADS1015_REG_POINTER_CONVERT = 0x00
|
||||||
|
__ADS1015_REG_POINTER_CONFIG = 0x01
|
||||||
|
__ADS1015_REG_POINTER_LOWTHRESH = 0x02
|
||||||
|
__ADS1015_REG_POINTER_HITHRESH = 0x03
|
||||||
|
|
||||||
|
# Config Register
|
||||||
|
__ADS1015_REG_CONFIG_OS_MASK = 0x8000
|
||||||
|
__ADS1015_REG_CONFIG_OS_SINGLE = 0x8000 # Write: Set to start a single-conversion
|
||||||
|
__ADS1015_REG_CONFIG_OS_BUSY = 0x0000 # Read: Bit = 0 when conversion is in progress
|
||||||
|
__ADS1015_REG_CONFIG_OS_NOTBUSY = 0x8000 # Read: Bit = 1 when device is not performing a conversion
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_MUX_MASK = 0x7000
|
||||||
|
__ADS1015_REG_CONFIG_MUX_DIFF_0_1 = 0x0000 # Differential P = AIN0, N = AIN1 (default)
|
||||||
|
__ADS1015_REG_CONFIG_MUX_DIFF_0_3 = 0x1000 # Differential P = AIN0, N = AIN3
|
||||||
|
__ADS1015_REG_CONFIG_MUX_DIFF_1_3 = 0x2000 # Differential P = AIN1, N = AIN3
|
||||||
|
__ADS1015_REG_CONFIG_MUX_DIFF_2_3 = 0x3000 # Differential P = AIN2, N = AIN3
|
||||||
|
__ADS1015_REG_CONFIG_MUX_SINGLE_0 = 0x4000 # Single-ended AIN0
|
||||||
|
__ADS1015_REG_CONFIG_MUX_SINGLE_1 = 0x5000 # Single-ended AIN1
|
||||||
|
__ADS1015_REG_CONFIG_MUX_SINGLE_2 = 0x6000 # Single-ended AIN2
|
||||||
|
__ADS1015_REG_CONFIG_MUX_SINGLE_3 = 0x7000 # Single-ended AIN3
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_PGA_MASK = 0x0E00
|
||||||
|
__ADS1015_REG_CONFIG_PGA_6_144V = 0x0000 # +/-6.144V range
|
||||||
|
__ADS1015_REG_CONFIG_PGA_4_096V = 0x0200 # +/-4.096V range
|
||||||
|
__ADS1015_REG_CONFIG_PGA_2_048V = 0x0400 # +/-2.048V range (default)
|
||||||
|
__ADS1015_REG_CONFIG_PGA_1_024V = 0x0600 # +/-1.024V range
|
||||||
|
__ADS1015_REG_CONFIG_PGA_0_512V = 0x0800 # +/-0.512V range
|
||||||
|
__ADS1015_REG_CONFIG_PGA_0_256V = 0x0A00 # +/-0.256V range
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_MODE_MASK = 0x0100
|
||||||
|
__ADS1015_REG_CONFIG_MODE_CONTIN = 0x0000 # Continuous conversion mode
|
||||||
|
__ADS1015_REG_CONFIG_MODE_SINGLE = 0x0100 # Power-down single-shot mode (default)
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_DR_MASK = 0x00E0
|
||||||
|
__ADS1015_REG_CONFIG_DR_128SPS = 0x0000 # 128 samples per second
|
||||||
|
__ADS1015_REG_CONFIG_DR_250SPS = 0x0020 # 250 samples per second
|
||||||
|
__ADS1015_REG_CONFIG_DR_490SPS = 0x0040 # 490 samples per second
|
||||||
|
__ADS1015_REG_CONFIG_DR_920SPS = 0x0060 # 920 samples per second
|
||||||
|
__ADS1015_REG_CONFIG_DR_1600SPS = 0x0080 # 1600 samples per second (default)
|
||||||
|
__ADS1015_REG_CONFIG_DR_2400SPS = 0x00A0 # 2400 samples per second
|
||||||
|
__ADS1015_REG_CONFIG_DR_3300SPS = 0x00C0 # 3300 samples per second (also 0x00E0)
|
||||||
|
|
||||||
|
__ADS1115_REG_CONFIG_DR_8SPS = 0x0000 # 8 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_16SPS = 0x0020 # 16 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_32SPS = 0x0040 # 32 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_64SPS = 0x0060 # 64 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_128SPS = 0x0080 # 128 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_250SPS = 0x00A0 # 250 samples per second (default)
|
||||||
|
__ADS1115_REG_CONFIG_DR_475SPS = 0x00C0 # 475 samples per second
|
||||||
|
__ADS1115_REG_CONFIG_DR_860SPS = 0x00E0 # 860 samples per second
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_CMODE_MASK = 0x0010
|
||||||
|
__ADS1015_REG_CONFIG_CMODE_TRAD = 0x0000 # Traditional comparator with hysteresis (default)
|
||||||
|
__ADS1015_REG_CONFIG_CMODE_WINDOW = 0x0010 # Window comparator
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_CPOL_MASK = 0x0008
|
||||||
|
__ADS1015_REG_CONFIG_CPOL_ACTVLOW = 0x0000 # ALERT/RDY pin is low when active (default)
|
||||||
|
__ADS1015_REG_CONFIG_CPOL_ACTVHI = 0x0008 # ALERT/RDY pin is high when active
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_CLAT_MASK = 0x0004 # Determines if ALERT/RDY pin latches once asserted
|
||||||
|
__ADS1015_REG_CONFIG_CLAT_NONLAT = 0x0000 # Non-latching comparator (default)
|
||||||
|
__ADS1015_REG_CONFIG_CLAT_LATCH = 0x0004 # Latching comparator
|
||||||
|
|
||||||
|
__ADS1015_REG_CONFIG_CQUE_MASK = 0x0003
|
||||||
|
__ADS1015_REG_CONFIG_CQUE_1CONV = 0x0000 # Assert ALERT/RDY after one conversions
|
||||||
|
__ADS1015_REG_CONFIG_CQUE_2CONV = 0x0001 # Assert ALERT/RDY after two conversions
|
||||||
|
__ADS1015_REG_CONFIG_CQUE_4CONV = 0x0002 # Assert ALERT/RDY after four conversions
|
||||||
|
__ADS1015_REG_CONFIG_CQUE_NONE = 0x0003 # Disable the comparator and put ALERT/RDY in high state (default)
|
||||||
|
|
||||||
|
|
||||||
|
# Dictionaries with the sampling speed values
|
||||||
|
# These simplify and clean the code (avoid the abuse of if/elif/else clauses)
|
||||||
|
spsADS1115 = {
|
||||||
|
8:__ADS1115_REG_CONFIG_DR_8SPS,
|
||||||
|
16:__ADS1115_REG_CONFIG_DR_16SPS,
|
||||||
|
32:__ADS1115_REG_CONFIG_DR_32SPS,
|
||||||
|
64:__ADS1115_REG_CONFIG_DR_64SPS,
|
||||||
|
128:__ADS1115_REG_CONFIG_DR_128SPS,
|
||||||
|
250:__ADS1115_REG_CONFIG_DR_250SPS,
|
||||||
|
475:__ADS1115_REG_CONFIG_DR_475SPS,
|
||||||
|
860:__ADS1115_REG_CONFIG_DR_860SPS
|
||||||
|
}
|
||||||
|
spsADS1015 = {
|
||||||
|
128:__ADS1015_REG_CONFIG_DR_128SPS,
|
||||||
|
250:__ADS1015_REG_CONFIG_DR_250SPS,
|
||||||
|
490:__ADS1015_REG_CONFIG_DR_490SPS,
|
||||||
|
920:__ADS1015_REG_CONFIG_DR_920SPS,
|
||||||
|
1600:__ADS1015_REG_CONFIG_DR_1600SPS,
|
||||||
|
2400:__ADS1015_REG_CONFIG_DR_2400SPS,
|
||||||
|
3300:__ADS1015_REG_CONFIG_DR_3300SPS
|
||||||
|
}
|
||||||
|
# Dictionariy with the programable gains
|
||||||
|
pgaADS1x15 = {
|
||||||
|
6144:__ADS1015_REG_CONFIG_PGA_6_144V,
|
||||||
|
4096:__ADS1015_REG_CONFIG_PGA_4_096V,
|
||||||
|
2048:__ADS1015_REG_CONFIG_PGA_2_048V,
|
||||||
|
1024:__ADS1015_REG_CONFIG_PGA_1_024V,
|
||||||
|
512:__ADS1015_REG_CONFIG_PGA_0_512V,
|
||||||
|
256:__ADS1015_REG_CONFIG_PGA_0_256V
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Constructor
|
||||||
|
def __init__(self, address=0x48, ic=__IC_ADS1015, debug=False):
|
||||||
|
# Depending on if you have an old or a new Raspberry Pi, you
|
||||||
|
# may need to change the I2C bus. Older Pis use SMBus 0,
|
||||||
|
# whereas new Pis use SMBus 1. If you see an error like:
|
||||||
|
# 'Error accessing 0x48: Check your I2C address '
|
||||||
|
# change the SMBus number in the initializer below!
|
||||||
|
self.i2c = Adafruit_I2C(address)
|
||||||
|
self.address = address
|
||||||
|
self.debug = debug
|
||||||
|
# Make sure the IC specified is valid
|
||||||
|
if ((ic < self.__IC_ADS1015) | (ic > self.__IC_ADS1115)):
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid IC specfied: %h" % ic)
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
self.ic = ic
|
||||||
|
|
||||||
|
# Set pga value, so that getLastConversionResult() can use it,
|
||||||
|
# any function that accepts a pga value must update this.
|
||||||
|
self.pga = 6144
|
||||||
|
|
||||||
|
# SwitchDoc Labs Mod - added readRaw
|
||||||
|
def readRaw(self, channel=0, pga=6144, sps=250):
|
||||||
|
|
||||||
|
# return raw AD Value
|
||||||
|
# With invalid channel return -1
|
||||||
|
if (channel > 3):
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channel specified: %d" % channel)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Disable comparator, Non-latching, Alert/Rdy active low
|
||||||
|
# traditional comparator, single-shot mode
|
||||||
|
config = self.__ADS1015_REG_CONFIG_CQUE_NONE | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CLAT_NONLAT | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CMODE_TRAD | \
|
||||||
|
self.__ADS1015_REG_CONFIG_MODE_SINGLE
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps)
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps)
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set the channel to be converted
|
||||||
|
if channel == 3:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
|
||||||
|
elif channel == 2:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
|
||||||
|
elif channel == 1:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
# Wait for the ADC conversion to complete
|
||||||
|
# The minimum delay depends on the sps: delay >= 1/sps
|
||||||
|
# We add 0.1ms to be sure
|
||||||
|
delay = 1.0/sps+0.0001
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
return ( (result[0] << 8) | (result[1]) )
|
||||||
|
|
||||||
|
|
||||||
|
def readADCSingleEnded(self, channel=0, pga=6144, sps=250):
|
||||||
|
"Gets a single-ended ADC reading from the specified channel in mV. \
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see datasheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
|
||||||
|
# With invalid channel return -1
|
||||||
|
if (channel > 3):
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channel specified: %d" % channel)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Disable comparator, Non-latching, Alert/Rdy active low
|
||||||
|
# traditional comparator, single-shot mode
|
||||||
|
config = self.__ADS1015_REG_CONFIG_CQUE_NONE | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CLAT_NONLAT | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CMODE_TRAD | \
|
||||||
|
self.__ADS1015_REG_CONFIG_MODE_SINGLE
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set the channel to be converted
|
||||||
|
if channel == 3:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
|
||||||
|
elif channel == 2:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
|
||||||
|
elif channel == 1:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
# Wait for the ADC conversion to complete
|
||||||
|
# The minimum delay depends on the sps: delay >= 1/sps
|
||||||
|
# We add 0.1ms to be sure
|
||||||
|
delay = 1.0/sps+0.0001
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
# Shift right 4 bits for the 12-bit ADS1015 and convert to mV
|
||||||
|
return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
|
||||||
|
else:
|
||||||
|
# Return a mV value for the ADS1115
|
||||||
|
# (Take signed values into account as well)
|
||||||
|
val = (result[0] << 8) | (result[1])
|
||||||
|
if val > 0x7FFF:
|
||||||
|
return (val - 0xFFFF)*pga/32768.0
|
||||||
|
else:
|
||||||
|
return ( (result[0] << 8) | (result[1]) )*pga/32768.0
|
||||||
|
|
||||||
|
|
||||||
|
def readADCDifferential(self, chP=0, chN=1, pga=6144, sps=250):
|
||||||
|
"Gets a differential ADC reading from channels chP and chN in mV. \
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see data sheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
|
||||||
|
# Disable comparator, Non-latching, Alert/Rdy active low
|
||||||
|
# traditional comparator, single-shot mode
|
||||||
|
config = self.__ADS1015_REG_CONFIG_CQUE_NONE | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CLAT_NONLAT | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CMODE_TRAD | \
|
||||||
|
self.__ADS1015_REG_CONFIG_MODE_SINGLE
|
||||||
|
|
||||||
|
# Set channels
|
||||||
|
if ( (chP == 0) & (chN == 1) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
|
||||||
|
elif ( (chP == 0) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
|
||||||
|
elif ( (chP == 2) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
|
||||||
|
elif ( (chP == 1) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3
|
||||||
|
else:
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channels specified: %d, %d" % (chP, chN))
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init()) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps)
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
# Wait for the ADC conversion to complete
|
||||||
|
# The minimum delay depends on the sps: delay >= 1/sps
|
||||||
|
# We add 0.1ms to be sure
|
||||||
|
delay = 1.0/sps+0.0001
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
# Shift right 4 bits for the 12-bit ADS1015 and convert to mV
|
||||||
|
return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
|
||||||
|
else:
|
||||||
|
# Return a mV value for the ADS1115
|
||||||
|
# (Take signed values into account as well)
|
||||||
|
val = (result[0] << 8) | (result[1])
|
||||||
|
if val > 0x7FFF:
|
||||||
|
return (val - 0xFFFF)*pga/32768.0
|
||||||
|
else:
|
||||||
|
return ( (result[0] << 8) | (result[1]) )*pga/32768.0
|
||||||
|
|
||||||
|
|
||||||
|
def readADCDifferential01(self, pga=6144, sps=250):
|
||||||
|
"Gets a differential ADC reading from channels 0 and 1 in mV\
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see data sheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
return self.readADCDifferential(0, 1, pga, sps)
|
||||||
|
|
||||||
|
|
||||||
|
def readADCDifferential03(self, pga=6144, sps=250):
|
||||||
|
"Gets a differential ADC reading from channels 0 and 3 in mV \
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see data sheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
return self.readADCDifferential(0, 3, pga, sps)
|
||||||
|
|
||||||
|
|
||||||
|
def readADCDifferential13(self, pga=6144, sps=250):
|
||||||
|
"Gets a differential ADC reading from channels 1 and 3 in mV \
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see data sheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
return self.__readADCDifferential(1, 3, pga, sps)
|
||||||
|
|
||||||
|
|
||||||
|
def readADCDifferential23(self, pga=6144, sps=250):
|
||||||
|
"Gets a differential ADC reading from channels 2 and 3 in mV \
|
||||||
|
The sample rate for this mode (single-shot) can be used to lower the noise \
|
||||||
|
(low sps) or to lower the power consumption (high sps) by duty cycling, \
|
||||||
|
see data sheet page 14 for more info. \
|
||||||
|
The pga must be given in mV, see page 13 for the supported values."
|
||||||
|
return self.readADCDifferential(2, 3, pga, sps)
|
||||||
|
|
||||||
|
|
||||||
|
def startContinuousConversion(self, channel=0, pga=6144, sps=250):
|
||||||
|
"Starts the continuous conversion mode and returns the first ADC reading \
|
||||||
|
in mV from the specified channel. \
|
||||||
|
The sps controls the sample rate. \
|
||||||
|
The pga must be given in mV, see datasheet page 13 for the supported values. \
|
||||||
|
Use getLastConversionResults() to read the next values and \
|
||||||
|
stopContinuousConversion() to stop converting."
|
||||||
|
|
||||||
|
# Default to channel 0 with invalid channel, or return -1?
|
||||||
|
if (channel > 3):
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channel specified: %d" % channel)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Disable comparator, Non-latching, Alert/Rdy active low
|
||||||
|
# traditional comparator, continuous mode
|
||||||
|
# The last flag is the only change we need, page 11 datasheet
|
||||||
|
config = self.__ADS1015_REG_CONFIG_CQUE_NONE | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CLAT_NONLAT | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CMODE_TRAD | \
|
||||||
|
self.__ADS1015_REG_CONFIG_MODE_CONTIN
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init()) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set the channel to be converted
|
||||||
|
if channel == 3:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
|
||||||
|
elif channel == 2:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
|
||||||
|
elif channel == 1:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit to begin conversions
|
||||||
|
# No need to change this for continuous mode!
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
# Once we write the ADC will convert continously
|
||||||
|
# we can read the next values using getLastConversionResult
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
# Wait for the ADC conversion to complete
|
||||||
|
# The minimum delay depends on the sps: delay >= 1/sps
|
||||||
|
# We add 0.5ms to be sure
|
||||||
|
delay = 1.0/sps+0.0005
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
# Shift right 4 bits for the 12-bit ADS1015 and convert to mV
|
||||||
|
return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
|
||||||
|
else:
|
||||||
|
# Return a mV value for the ADS1115
|
||||||
|
# (Take signed values into account as well)
|
||||||
|
val = (result[0] << 8) | (result[1])
|
||||||
|
if val > 0x7FFF:
|
||||||
|
return (val - 0xFFFF)*pga/32768.0
|
||||||
|
else:
|
||||||
|
return ( (result[0] << 8) | (result[1]) )*pga/32768.0
|
||||||
|
|
||||||
|
def startContinuousDifferentialConversion(self, chP=0, chN=1, pga=6144, sps=250):
|
||||||
|
"Starts the continuous differential conversion mode and returns the first ADC reading \
|
||||||
|
in mV as the difference from the specified channels. \
|
||||||
|
The sps controls the sample rate. \
|
||||||
|
The pga must be given in mV, see datasheet page 13 for the supported values. \
|
||||||
|
Use getLastConversionResults() to read the next values and \
|
||||||
|
stopContinuousConversion() to stop converting."
|
||||||
|
|
||||||
|
# Disable comparator, Non-latching, Alert/Rdy active low
|
||||||
|
# traditional comparator, continuous mode
|
||||||
|
# The last flag is the only change we need, page 11 datasheet
|
||||||
|
config = self.__ADS1015_REG_CONFIG_CQUE_NONE | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CLAT_NONLAT | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
|
||||||
|
self.__ADS1015_REG_CONFIG_CMODE_TRAD | \
|
||||||
|
self.__ADS1015_REG_CONFIG_MODE_CONTIN
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init()) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % sps )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set channels
|
||||||
|
if ( (chP == 0) & (chN == 1) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
|
||||||
|
elif ( (chP == 0) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
|
||||||
|
elif ( (chP == 2) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
|
||||||
|
elif ( (chP == 1) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3
|
||||||
|
else:
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channels specified: %d, %d" % (chP, chN))
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit to begin conversions
|
||||||
|
# No need to change this for continuous mode!
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
# Once we write the ADC will convert continously
|
||||||
|
# we can read the next values using getLastConversionResult
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
# Wait for the ADC conversion to complete
|
||||||
|
# The minimum delay depends on the sps: delay >= 1/sps
|
||||||
|
# We add 0.5ms to be sure
|
||||||
|
delay = 1.0/sps+0.0005
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
# Shift right 4 bits for the 12-bit ADS1015 and convert to mV
|
||||||
|
return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
|
||||||
|
else:
|
||||||
|
# Return a mV value for the ADS1115
|
||||||
|
# (Take signed values into account as well)
|
||||||
|
val = (result[0] << 8) | (result[1])
|
||||||
|
if val > 0x7FFF:
|
||||||
|
return (val - 0xFFFF)*pga/32768.0
|
||||||
|
else:
|
||||||
|
return ( (result[0] << 8) | (result[1]) )*pga/32768.0
|
||||||
|
|
||||||
|
|
||||||
|
def stopContinuousConversion(self):
|
||||||
|
"Stops the ADC's conversions when in continuous mode \
|
||||||
|
and resets the configuration to its default value."
|
||||||
|
# Write the default config register to the ADC
|
||||||
|
# Once we write, the ADC will do a single conversion and
|
||||||
|
# enter power-off mode.
|
||||||
|
config = 0x8583 # Page 18 datasheet.
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getLastConversionResults(self):
|
||||||
|
"Returns the last ADC conversion result in mV"
|
||||||
|
# Read the conversion results
|
||||||
|
result = self.i2c.readList(self.__ADS1015_REG_POINTER_CONVERT, 2)
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
# Shift right 4 bits for the 12-bit ADS1015 and convert to mV
|
||||||
|
return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*self.pga/2048.0
|
||||||
|
else:
|
||||||
|
# Return a mV value for the ADS1115
|
||||||
|
# (Take signed values into account as well)
|
||||||
|
val = (result[0] << 8) | (result[1])
|
||||||
|
if val > 0x7FFF:
|
||||||
|
return (val - 0xFFFF)*self.pga/32768.0
|
||||||
|
else:
|
||||||
|
return ( (result[0] << 8) | (result[1]) )*self.pga/32768.0
|
||||||
|
|
||||||
|
|
||||||
|
def startSingleEndedComparator(self, channel, thresholdHigh, thresholdLow, \
|
||||||
|
pga=6144, sps=250, \
|
||||||
|
activeLow=True, traditionalMode=True, latching=False, \
|
||||||
|
numReadings=1):
|
||||||
|
"Starts the comparator mode on the specified channel, see datasheet pg. 15. \
|
||||||
|
In traditional mode it alerts (ALERT pin will go low) when voltage exceeds \
|
||||||
|
thresholdHigh until it falls below thresholdLow (both given in mV). \
|
||||||
|
In window mode (traditionalMode=False) it alerts when voltage doesn't lie\
|
||||||
|
between both thresholds.\
|
||||||
|
In latching mode the alert will continue until the conversion value is read. \
|
||||||
|
numReadings controls how many readings are necessary to trigger an alert: 1, 2 or 4.\
|
||||||
|
Use getLastConversionResults() to read the current value (which may differ \
|
||||||
|
from the one that triggered the alert) and clear the alert pin in latching mode. \
|
||||||
|
This function starts the continuous conversion mode. The sps controls \
|
||||||
|
the sample rate and the pga the gain, see datasheet page 13. "
|
||||||
|
|
||||||
|
# With invalid channel return -1
|
||||||
|
if (channel > 3):
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channel specified: %d" % channel)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Continuous mode
|
||||||
|
config = self.__ADS1015_REG_CONFIG_MODE_CONTIN
|
||||||
|
|
||||||
|
if (activeLow==False):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVHI
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW
|
||||||
|
|
||||||
|
if (traditionalMode==False):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CMODE_WINDOW
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CMODE_TRAD
|
||||||
|
|
||||||
|
if (latching==True):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CLAT_LATCH
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CLAT_NONLAT
|
||||||
|
|
||||||
|
if (numReadings==4):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_4CONV
|
||||||
|
elif (numReadings==2):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_2CONV
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_1CONV
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init()) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
if ( (sps not in self.spsADS1015) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid sps specified: %d, using 1600sps" % sps )
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid sps specified: %d, using 250sps" % sps )
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % pga )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set the channel to be converted
|
||||||
|
if channel == 3:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
|
||||||
|
elif channel == 2:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
|
||||||
|
elif channel == 1:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit to begin conversions
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write threshold high and low registers to the ADC
|
||||||
|
# V_digital = (2^(n-1)-1)/pga*V_analog
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
thresholdHighWORD = int(thresholdHigh*(2048.0/pga))
|
||||||
|
else:
|
||||||
|
thresholdHighWORD = int(thresholdHigh*(32767.0/pga))
|
||||||
|
bytes = [(thresholdHighWORD >> 8) & 0xFF, thresholdHighWORD & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_HITHRESH, bytes)
|
||||||
|
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
thresholdLowWORD = int(thresholdLow*(2048.0/pga))
|
||||||
|
else:
|
||||||
|
thresholdLowWORD = int(thresholdLow*(32767.0/pga))
|
||||||
|
bytes = [(thresholdLowWORD >> 8) & 0xFF, thresholdLowWORD & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_LOWTHRESH, bytes)
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
# Once we write the ADC will convert continously and alert when things happen,
|
||||||
|
# we can read the converted values using getLastConversionResult
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
||||||
|
|
||||||
|
def startDifferentialComparator(self, chP, chN, thresholdHigh, thresholdLow, \
|
||||||
|
pga=6144, sps=250, \
|
||||||
|
activeLow=True, traditionalMode=True, latching=False, \
|
||||||
|
numReadings=1):
|
||||||
|
"Starts the comparator mode on the specified channel, see datasheet pg. 15. \
|
||||||
|
In traditional mode it alerts (ALERT pin will go low) when voltage exceeds \
|
||||||
|
thresholdHigh until it falls below thresholdLow (both given in mV). \
|
||||||
|
In window mode (traditionalMode=False) it alerts when voltage doesn't lie\
|
||||||
|
between both thresholds.\
|
||||||
|
In latching mode the alert will continue until the conversion value is read. \
|
||||||
|
numReadings controls how many readings are necessary to trigger an alert: 1, 2 or 4.\
|
||||||
|
Use getLastConversionResults() to read the current value (which may differ \
|
||||||
|
from the one that triggered the alert) and clear the alert pin in latching mode. \
|
||||||
|
This function starts the continuous conversion mode. The sps controls \
|
||||||
|
the sample rate and the pga the gain, see datasheet page 13. "
|
||||||
|
|
||||||
|
# Continuous mode
|
||||||
|
config = self.__ADS1015_REG_CONFIG_MODE_CONTIN
|
||||||
|
|
||||||
|
if (activeLow==False):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVHI
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW
|
||||||
|
|
||||||
|
if (traditionalMode==False):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CMODE_WINDOW
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CMODE_TRAD
|
||||||
|
|
||||||
|
if (latching==True):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CLAT_LATCH
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CLAT_NONLAT
|
||||||
|
|
||||||
|
if (numReadings==4):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_4CONV
|
||||||
|
elif (numReadings==2):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_2CONV
|
||||||
|
else:
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_CQUE_1CONV
|
||||||
|
|
||||||
|
# Set sample per seconds, defaults to 250sps
|
||||||
|
# If sps is in the dictionary (defined in init()) it returns the value of the constant
|
||||||
|
# othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
if ( (sps not in self.spsADS1015) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid sps specified: %d, using 1600sps" % sps )
|
||||||
|
config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
|
||||||
|
else:
|
||||||
|
if ( (sps not in self.spsADS1115) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid sps specified: %d, using 250sps" % sps )
|
||||||
|
config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
|
||||||
|
|
||||||
|
# Set PGA/voltage range, defaults to +-6.144V
|
||||||
|
if ( (pga not in self.pgaADS1x15) & self.debug):
|
||||||
|
print ("ADS1x15: Invalid pga specified: %d, using 6144mV" % pga )
|
||||||
|
config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
|
||||||
|
self.pga = pga
|
||||||
|
|
||||||
|
# Set channels
|
||||||
|
if ( (chP == 0) & (chN == 1) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
|
||||||
|
elif ( (chP == 0) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
|
||||||
|
elif ( (chP == 2) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
|
||||||
|
elif ( (chP == 1) & (chN == 3) ):
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3
|
||||||
|
else:
|
||||||
|
if (self.debug):
|
||||||
|
print ("ADS1x15: Invalid channels specified: %d, %d" % (chP, chN))
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Set 'start single-conversion' bit to begin conversions
|
||||||
|
config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
|
||||||
|
|
||||||
|
# Write threshold high and low registers to the ADC
|
||||||
|
# V_digital = (2^(n-1)-1)/pga*V_analog
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
thresholdHighWORD = int(thresholdHigh*(2048.0/pga))
|
||||||
|
else:
|
||||||
|
thresholdHighWORD = int(thresholdHigh*(32767.0/pga))
|
||||||
|
bytes = [(thresholdHighWORD >> 8) & 0xFF, thresholdHighWORD & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_HITHRESH, bytes)
|
||||||
|
|
||||||
|
if (self.ic == self.__IC_ADS1015):
|
||||||
|
thresholdLowWORD = int(thresholdLow*(2048.0/pga))
|
||||||
|
else:
|
||||||
|
thresholdLowWORD = int(thresholdLow*(32767.0/pga))
|
||||||
|
bytes = [(thresholdLowWORD >> 8) & 0xFF, thresholdLowWORD & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_LOWTHRESH, bytes)
|
||||||
|
|
||||||
|
# Write config register to the ADC
|
||||||
|
# Once we write the ADC will convert continously and alert when things happen,
|
||||||
|
# we can read the converted values using getLastConversionResult
|
||||||
|
bytes = [(config >> 8) & 0xFF, config & 0xFF]
|
||||||
|
self.i2c.writeList(self.__ADS1015_REG_POINTER_CONFIG, bytes)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import time, signal, sys
|
||||||
|
from Adafruit_ADS1x15 import ADS1x15
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
print ('You pressed Ctrl+C!')
|
||||||
|
print (adc.getLastConversionResults()/1000.0)
|
||||||
|
adc.stopContinuousConversion()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
# Print 'Press Ctrl+C to exit'
|
||||||
|
|
||||||
|
ADS1015 = 0x00 # 12-bit ADC
|
||||||
|
ADS1115 = 0x01 # 16-bit ADC
|
||||||
|
|
||||||
|
# Initialise the ADC using the default mode (use default I2C address)
|
||||||
|
# Set this to ADS1015 or ADS1115 depending on the ADC you are using!
|
||||||
|
adc = ADS1x15(ic=ADS1115)
|
||||||
|
|
||||||
|
# start comparator on channel 2 with a thresholdHigh=200mV and low=100mV
|
||||||
|
# in traditional mode, non-latching, +/-1.024V and 250sps
|
||||||
|
adc.startSingleEndedComparator(2, 200, 100, pga=1024, sps=250, activeLow=True, traditionalMode=True, latching=False, numReadings=1)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print (adc.getLastConversionResults()/1000.0)
|
||||||
|
time.sleep(0.25)
|
||||||
|
|
||||||
|
#time.sleep(0.1)
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import time, signal, sys
|
||||||
|
from Adafruit_ADS1x15 import ADS1x15
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
#print 'You pressed Ctrl+C!'
|
||||||
|
sys.exit(0)
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
#print 'Press Ctrl+C to exit'
|
||||||
|
|
||||||
|
ADS1015 = 0x00 # 12-bit ADC
|
||||||
|
ADS1115 = 0x01 # 16-bit ADC
|
||||||
|
|
||||||
|
# Initialise the ADC using the default mode (use default I2C address)
|
||||||
|
# Set this to ADS1015 or ADS1115 depending on the ADC you are using!
|
||||||
|
adc = ADS1x15(ic=ADS1115)
|
||||||
|
|
||||||
|
# Read channels 2 and 3 in single-ended mode, at +/-4.096V and 250sps
|
||||||
|
volts2 = adc.readADCSingleEnded(2, 4096, 250)/1000.0
|
||||||
|
volts3 = adc.readADCSingleEnded(3, 4096, 250)/1000.0
|
||||||
|
|
||||||
|
# Now do a differential reading of channels 2 and 3
|
||||||
|
voltsdiff = adc.readADCDifferential23(4096, 250)/1000.0
|
||||||
|
|
||||||
|
# Display the two different reading for comparison purposes
|
||||||
|
print ("%.8f %.8f %.8f %.8f" % (volts2, volts3, volts3-volts2, -voltsdiff))
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import time, signal, sys
|
||||||
|
from Adafruit_ADS1x15 import ADS1x15
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
print ('You pressed Ctrl+C!')
|
||||||
|
sys.exit(0)
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
#print 'Press Ctrl+C to exit'
|
||||||
|
|
||||||
|
ADS1015 = 0x00 # 12-bit ADC
|
||||||
|
ADS1115 = 0x01 # 16-bit ADC
|
||||||
|
|
||||||
|
# Select the gain
|
||||||
|
# gain = 6144 # +/- 6.144V
|
||||||
|
gain = 4096 # +/- 4.096V
|
||||||
|
# gain = 2048 # +/- 2.048V
|
||||||
|
# gain = 1024 # +/- 1.024V
|
||||||
|
# gain = 512 # +/- 0.512V
|
||||||
|
# gain = 256 # +/- 0.256V
|
||||||
|
|
||||||
|
# Select the sample rate
|
||||||
|
# sps = 8 # 8 samples per second
|
||||||
|
# sps = 16 # 16 samples per second
|
||||||
|
# sps = 32 # 32 samples per second
|
||||||
|
# sps = 64 # 64 samples per second
|
||||||
|
# sps = 128 # 128 samples per second
|
||||||
|
sps = 250 # 250 samples per second
|
||||||
|
# sps = 475 # 475 samples per second
|
||||||
|
# sps = 860 # 860 samples per second
|
||||||
|
|
||||||
|
# Initialise the ADC using the default mode (use default I2C address)
|
||||||
|
# Set this to ADS1015 or ADS1115 depending on the ADC you are using!
|
||||||
|
adc = ADS1x15(ic=ADS1115)
|
||||||
|
while (1):
|
||||||
|
|
||||||
|
# Read channel 1 in single-ended mode using the settings above
|
||||||
|
|
||||||
|
volts = adc.readADCSingleEnded(1, gain, sps) / 1000
|
||||||
|
|
||||||
|
# To read channel 3 in single-ended mode, +/- 1.024V, 860 sps use:
|
||||||
|
# volts = adc.readADCSingleEnded(3, 1024, 860)
|
||||||
|
|
||||||
|
print ("%.6f" % (volts))
|
||||||
|
time.sleep(0.5)
|
94
test.py
94
test.py
|
@ -1,49 +1,55 @@
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import time
|
import time
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
sys.path.append('./SDL_Adafruit_ADS1x15')
|
||||||
|
|
||||||
GPIO_TRIGGER = 18
|
import SDL_Adafruit_ADS1x15
|
||||||
GPIO_ECHO = 24
|
|
||||||
|
|
||||||
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
|
def signal_handler(signal, frame):
|
||||||
GPIO.setup(GPIO_ECHO, GPIO.IN)
|
print( 'You pressed Ctrl+C!')
|
||||||
|
sys.exit(0)
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
def distanz():
|
ADS1115 = 0x01 # 16-bit ADC
|
||||||
# setze Trigger auf HIGH
|
|
||||||
GPIO.output(GPIO_TRIGGER, True)
|
# Select the gain
|
||||||
|
# gain = 6144 # +/- 6.144V
|
||||||
# setze Trigger nach 0.01ms aus LOW
|
gain = 4096 # +/- 4.096V
|
||||||
time.sleep(0.00001)
|
# gain = 2048 # +/- 2.048V
|
||||||
GPIO.output(GPIO_TRIGGER, False)
|
# gain = 1024 # +/- 1.024V
|
||||||
|
# gain = 512 # +/- 0.512V
|
||||||
StartZeit = time.time()
|
# gain = 256 # +/- 0.256V
|
||||||
StopZeit = time.time()
|
|
||||||
|
# Select the sample rate
|
||||||
# speichere Startzeit
|
# sps = 8 # 8 samples per second
|
||||||
while GPIO.input(GPIO_ECHO) == 0:
|
# sps = 16 # 16 samples per second
|
||||||
StartZeit = time.time()
|
# sps = 32 # 32 samples per second
|
||||||
|
# sps = 64 # 64 samples per second
|
||||||
# speichere Ankunftszeit
|
# sps = 128 # 128 samples per second
|
||||||
while GPIO.input(GPIO_ECHO) == 1:
|
sps = 250 # 250 samples per second
|
||||||
StopZeit = time.time()
|
# sps = 475 # 475 samples per second
|
||||||
|
# sps = 860 # 860 samples per second
|
||||||
# Zeit Differenz zwischen Start und Ankunft
|
|
||||||
TimeElapsed = StopZeit - StartZeit
|
# Initialise the ADC using the default mode (use default I2C address)
|
||||||
# mit der Schallgeschwindigkeit (34300 cm/s) multiplizieren
|
adc = SDL_Adafruit_ADS1x15.ADS1x15(ic=ADS1115)
|
||||||
# und durch 2 teilen, da hin und zurueck
|
while (1):
|
||||||
distanz = (TimeElapsed * 34300) / 2
|
|
||||||
|
# Read channels in single-ended mode using the settings above
|
||||||
return distanz
|
|
||||||
|
print ("--------------------")
|
||||||
if __name__ == '__main__':
|
voltsCh0 = adc.readADCSingleEnded(0, gain, sps) / 1000
|
||||||
try:
|
rawCh0 = adc.readRaw(0, gain, sps)
|
||||||
while True:
|
print ("Channel 0 =%.6fV raw=0x%4X dec=%d" % (voltsCh0, rawCh0, rawCh0))
|
||||||
abstand = distanz()
|
voltsCh1 = adc.readADCSingleEnded(1, gain, sps) / 1000
|
||||||
print ("Gemessene Entfernung = %.1f cm" % abstand)
|
rawCh1 = adc.readRaw(1, gain, sps)
|
||||||
time.sleep(1)
|
print ("Channel 1 =%.6fV raw=0x%4X dec=%d" % (voltsCh1, rawCh1, rawCh1))
|
||||||
|
voltsCh2 = adc.readADCSingleEnded(2, gain, sps) / 1000
|
||||||
# Beim Abbruch durch STRG+C resetten
|
rawCh2 = adc.readRaw(2, gain, sps)
|
||||||
except KeyboardInterrupt:
|
print ("Channel 2 =%.6fV raw=0x%4X dec=%d" % (voltsCh2, rawCh2, rawCh2))
|
||||||
print("Messung vom User gestoppt")
|
voltsCh3 = adc.readADCSingleEnded(3, gain, sps) / 1000
|
||||||
GPIO.cleanup()
|
rawCh3 = adc.readRaw(3, gain, sps)
|
||||||
|
print ("Channel 3 =%.6fV raw=0x%4X dec=%d" % (voltsCh3, rawCh3, rawCh3))
|
||||||
|
print ("--------------------")
|
||||||
|
|
||||||
|
time.sleep(0.5)
|
Loading…
Reference in New Issue