From 023a3987be5346b2438b9f34e3207cb6c73b65e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebbe=20Ba=C3=9F?= Date: Sun, 10 Jul 2022 00:13:45 +0200 Subject: [PATCH] moisture test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ebbe Baß --- SDL_Adafruit_ADS1x15/Adafruit_I2C.py | 161 ++++ SDL_Adafruit_ADS1x15/SDL_Adafruit_ADS1x15.py | 783 ++++++++++++++++++ SDL_Adafruit_ADS1x15/ads1x15_ex_comparator.py | 30 + .../ads1x15_ex_differential.py | 27 + .../ads1x15_ex_singleended.py | 46 + test.py | 94 ++- 6 files changed, 1097 insertions(+), 44 deletions(-) create mode 100644 SDL_Adafruit_ADS1x15/Adafruit_I2C.py create mode 100644 SDL_Adafruit_ADS1x15/SDL_Adafruit_ADS1x15.py create mode 100644 SDL_Adafruit_ADS1x15/ads1x15_ex_comparator.py create mode 100644 SDL_Adafruit_ADS1x15/ads1x15_ex_differential.py create mode 100644 SDL_Adafruit_ADS1x15/ads1x15_ex_singleended.py diff --git a/SDL_Adafruit_ADS1x15/Adafruit_I2C.py b/SDL_Adafruit_ADS1x15/Adafruit_I2C.py new file mode 100644 index 0000000..eed0322 --- /dev/null +++ b/SDL_Adafruit_ADS1x15/Adafruit_I2C.py @@ -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") diff --git a/SDL_Adafruit_ADS1x15/SDL_Adafruit_ADS1x15.py b/SDL_Adafruit_ADS1x15/SDL_Adafruit_ADS1x15.py new file mode 100644 index 0000000..0a33e72 --- /dev/null +++ b/SDL_Adafruit_ADS1x15/SDL_Adafruit_ADS1x15.py @@ -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) + diff --git a/SDL_Adafruit_ADS1x15/ads1x15_ex_comparator.py b/SDL_Adafruit_ADS1x15/ads1x15_ex_comparator.py new file mode 100644 index 0000000..b6fb5fa --- /dev/null +++ b/SDL_Adafruit_ADS1x15/ads1x15_ex_comparator.py @@ -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) diff --git a/SDL_Adafruit_ADS1x15/ads1x15_ex_differential.py b/SDL_Adafruit_ADS1x15/ads1x15_ex_differential.py new file mode 100644 index 0000000..746051c --- /dev/null +++ b/SDL_Adafruit_ADS1x15/ads1x15_ex_differential.py @@ -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)) diff --git a/SDL_Adafruit_ADS1x15/ads1x15_ex_singleended.py b/SDL_Adafruit_ADS1x15/ads1x15_ex_singleended.py new file mode 100644 index 0000000..8e2c1a2 --- /dev/null +++ b/SDL_Adafruit_ADS1x15/ads1x15_ex_singleended.py @@ -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) diff --git a/test.py b/test.py index 1defddc..6f33ec2 100644 --- a/test.py +++ b/test.py @@ -1,49 +1,55 @@ -import RPi.GPIO as GPIO import time +import signal +import sys -GPIO.setmode(GPIO.BCM) +sys.path.append('./SDL_Adafruit_ADS1x15') -GPIO_TRIGGER = 18 -GPIO_ECHO = 24 +import SDL_Adafruit_ADS1x15 -GPIO.setup(GPIO_TRIGGER, GPIO.OUT) -GPIO.setup(GPIO_ECHO, GPIO.IN) +def signal_handler(signal, frame): + print( 'You pressed Ctrl+C!') + sys.exit(0) +signal.signal(signal.SIGINT, signal_handler) -def distanz(): - # setze Trigger auf HIGH - GPIO.output(GPIO_TRIGGER, True) - - # setze Trigger nach 0.01ms aus LOW - time.sleep(0.00001) - GPIO.output(GPIO_TRIGGER, False) - - StartZeit = time.time() - StopZeit = time.time() - - # speichere Startzeit - while GPIO.input(GPIO_ECHO) == 0: - StartZeit = time.time() - - # speichere Ankunftszeit - while GPIO.input(GPIO_ECHO) == 1: - StopZeit = time.time() - - # Zeit Differenz zwischen Start und Ankunft - TimeElapsed = StopZeit - StartZeit - # mit der Schallgeschwindigkeit (34300 cm/s) multiplizieren - # und durch 2 teilen, da hin und zurueck - distanz = (TimeElapsed * 34300) / 2 - - return distanz - -if __name__ == '__main__': - try: - while True: - abstand = distanz() - print ("Gemessene Entfernung = %.1f cm" % abstand) - time.sleep(1) - - # Beim Abbruch durch STRG+C resetten - except KeyboardInterrupt: - print("Messung vom User gestoppt") - GPIO.cleanup() \ No newline at end of file +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) +adc = SDL_Adafruit_ADS1x15.ADS1x15(ic=ADS1115) +while (1): + + # Read channels in single-ended mode using the settings above + + print ("--------------------") + voltsCh0 = adc.readADCSingleEnded(0, gain, sps) / 1000 + rawCh0 = adc.readRaw(0, gain, sps) + print ("Channel 0 =%.6fV raw=0x%4X dec=%d" % (voltsCh0, rawCh0, rawCh0)) + voltsCh1 = adc.readADCSingleEnded(1, gain, sps) / 1000 + rawCh1 = adc.readRaw(1, gain, sps) + print ("Channel 1 =%.6fV raw=0x%4X dec=%d" % (voltsCh1, rawCh1, rawCh1)) + voltsCh2 = adc.readADCSingleEnded(2, gain, sps) / 1000 + rawCh2 = adc.readRaw(2, gain, sps) + print ("Channel 2 =%.6fV raw=0x%4X dec=%d" % (voltsCh2, rawCh2, rawCh2)) + voltsCh3 = adc.readADCSingleEnded(3, gain, sps) / 1000 + rawCh3 = adc.readRaw(3, gain, sps) + print ("Channel 3 =%.6fV raw=0x%4X dec=%d" % (voltsCh3, rawCh3, rawCh3)) + print ("--------------------") + + time.sleep(0.5) \ No newline at end of file