diff --git a/Adafruit_ADS1x15/Adafruit_ADS1x15.py b/Adafruit_ADS1x15/Adafruit_ADS1x15.py index eb58087d..7d77bac5 100644 --- a/Adafruit_ADS1x15/Adafruit_ADS1x15.py +++ b/Adafruit_ADS1x15/Adafruit_ADS1x15.py @@ -18,709 +18,709 @@ # =========================================================================== 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 - + 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) - 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 + # 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 + } - # 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 + + # 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 + + + 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 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." + return ( (result[0] << 8) | (result[1]) )*pga/32768.0 - # 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 + + 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 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 - val = ((result[0] << 8) | (result[1] & 0xFF)) >> 4 - # (Take signed values into account as well) - if val >> 11: - val = val - 0xfff - return val*pga/2048.0 + # 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 + val = ((result[0] << 8) | (result[1] & 0xFF)) >> 4 + # (Take signed values into account as well) + if val >> 11: + val = val - 0xfff + return val*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 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) + 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 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 + 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) + - # 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 + 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) - # 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 + 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 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 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 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 + # 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 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. " + 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 - # With invalid channel return -1 - if (channel > 3): - if (self.debug): - print "ADS1x15: Invalid channel specified: %d" % channel - 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) - # Continuous mode - config = self.__ADS1015_REG_CONFIG_MODE_CONTIN + # 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 - 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 + # 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) - # 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 + # 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) - # 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 + # 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: - config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0 + return ( (result[0] << 8) | (result[1]) )*pga/32768.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)) + + 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: - 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 + return ( (result[0] << 8) | (result[1]) )*self.pga/32768.0 - 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 + 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) - # 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 + 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) - # 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) + 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/Adafruit_ADS1x15/ads1x15_ex_comparator.py b/Adafruit_ADS1x15/ads1x15_ex_comparator.py index e10eb6cb..93ae57b1 100644 --- a/Adafruit_ADS1x15/ads1x15_ex_comparator.py +++ b/Adafruit_ADS1x15/ads1x15_ex_comparator.py @@ -4,16 +4,16 @@ 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) + 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 +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! @@ -24,7 +24,7 @@ def signal_handler(signal, frame): 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) + print adc.getLastConversionResults()/1000.0 + time.sleep(0.25) #time.sleep(0.1) diff --git a/Adafruit_ADS1x15/ads1x15_ex_differential.py b/Adafruit_ADS1x15/ads1x15_ex_differential.py index 01614fdd..681ae8f1 100644 --- a/Adafruit_ADS1x15/ads1x15_ex_differential.py +++ b/Adafruit_ADS1x15/ads1x15_ex_differential.py @@ -4,8 +4,9 @@ from Adafruit_ADS1x15 import ADS1x15 def signal_handler(signal, frame): - #print 'You pressed Ctrl+C!' - sys.exit(0) + #print 'You pressed Ctrl+C!' + sys.exit(0) + signal.signal(signal.SIGINT, signal_handler) #print 'Press Ctrl+C to exit' diff --git a/Adafruit_ADS1x15/ads1x15_ex_singleended.py b/Adafruit_ADS1x15/ads1x15_ex_singleended.py index 2c4dee43..924a2895 100644 --- a/Adafruit_ADS1x15/ads1x15_ex_singleended.py +++ b/Adafruit_ADS1x15/ads1x15_ex_singleended.py @@ -4,8 +4,9 @@ from Adafruit_ADS1x15 import ADS1x15 def signal_handler(signal, frame): - print 'You pressed Ctrl+C!' - sys.exit(0) + print 'You pressed Ctrl+C!' + sys.exit(0) + signal.signal(signal.SIGINT, signal_handler) #print 'Press Ctrl+C to exit' diff --git a/Adafruit_BMP085/Adafruit_BMP085.py b/Adafruit_BMP085/Adafruit_BMP085.py index e8d0e314..066e0e12 100755 --- a/Adafruit_BMP085/Adafruit_BMP085.py +++ b/Adafruit_BMP085/Adafruit_BMP085.py @@ -8,252 +8,252 @@ # =========================================================================== class BMP085 : - i2c = None + i2c = None - # Operating Modes - __BMP085_ULTRALOWPOWER = 0 - __BMP085_STANDARD = 1 - __BMP085_HIGHRES = 2 - __BMP085_ULTRAHIGHRES = 3 + # Operating Modes + __BMP085_ULTRALOWPOWER = 0 + __BMP085_STANDARD = 1 + __BMP085_HIGHRES = 2 + __BMP085_ULTRAHIGHRES = 3 - # BMP085 Registers - __BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits) - __BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits) - __BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits) - __BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits) - __BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits) - __BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits) - __BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits) - __BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits) - __BMP085_CAL_MB = 0xBA # R Calibration data (16 bits) - __BMP085_CAL_MC = 0xBC # R Calibration data (16 bits) - __BMP085_CAL_MD = 0xBE # R Calibration data (16 bits) - __BMP085_CONTROL = 0xF4 - __BMP085_TEMPDATA = 0xF6 - __BMP085_PRESSUREDATA = 0xF6 - __BMP085_READTEMPCMD = 0x2E - __BMP085_READPRESSURECMD = 0x34 + # BMP085 Registers + __BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits) + __BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits) + __BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits) + __BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits) + __BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits) + __BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits) + __BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits) + __BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits) + __BMP085_CAL_MB = 0xBA # R Calibration data (16 bits) + __BMP085_CAL_MC = 0xBC # R Calibration data (16 bits) + __BMP085_CAL_MD = 0xBE # R Calibration data (16 bits) + __BMP085_CONTROL = 0xF4 + __BMP085_TEMPDATA = 0xF6 + __BMP085_PRESSUREDATA = 0xF6 + __BMP085_READTEMPCMD = 0x2E + __BMP085_READPRESSURECMD = 0x34 - # Private Fields - _cal_AC1 = 0 - _cal_AC2 = 0 - _cal_AC3 = 0 - _cal_AC4 = 0 - _cal_AC5 = 0 - _cal_AC6 = 0 - _cal_B1 = 0 - _cal_B2 = 0 - _cal_MB = 0 - _cal_MC = 0 - _cal_MD = 0 + # Private Fields + _cal_AC1 = 0 + _cal_AC2 = 0 + _cal_AC3 = 0 + _cal_AC4 = 0 + _cal_AC5 = 0 + _cal_AC6 = 0 + _cal_B1 = 0 + _cal_B2 = 0 + _cal_MB = 0 + _cal_MC = 0 + _cal_MD = 0 - # Constructor - def __init__(self, address=0x77, mode=1, debug=False): - self.i2c = Adafruit_I2C(address) + # Constructor + def __init__(self, address=0x77, mode=1, debug=False): + self.i2c = Adafruit_I2C(address) - self.address = address - self.debug = debug - # Make sure the specified mode is in the appropriate range - if ((mode < 0) | (mode > 3)): - if (self.debug): - print "Invalid Mode: Using STANDARD by default" - self.mode = self.__BMP085_STANDARD - else: - self.mode = mode - # Read the calibration data - self.readCalibrationData() + self.address = address + self.debug = debug + # Make sure the specified mode is in the appropriate range + if ((mode < 0) | (mode > 3)): + if (self.debug): + print "Invalid Mode: Using STANDARD by default" + self.mode = self.__BMP085_STANDARD + else: + self.mode = mode + # Read the calibration data + self.readCalibrationData() - def readS16(self, register): - "Reads a signed 16-bit value" - hi = self.i2c.readS8(register) - lo = self.i2c.readU8(register+1) - return (hi << 8) + lo + def readS16(self, register): + "Reads a signed 16-bit value" + hi = self.i2c.readS8(register) + lo = self.i2c.readU8(register+1) + return (hi << 8) + lo - def readU16(self, register): - "Reads an unsigned 16-bit value" - hi = self.i2c.readU8(register) - lo = self.i2c.readU8(register+1) - return (hi << 8) + lo + def readU16(self, register): + "Reads an unsigned 16-bit value" + hi = self.i2c.readU8(register) + lo = self.i2c.readU8(register+1) + return (hi << 8) + lo - def readCalibrationData(self): - "Reads the calibration data from the IC" - self._cal_AC1 = self.readS16(self.__BMP085_CAL_AC1) # INT16 - self._cal_AC2 = self.readS16(self.__BMP085_CAL_AC2) # INT16 - self._cal_AC3 = self.readS16(self.__BMP085_CAL_AC3) # INT16 - self._cal_AC4 = self.readU16(self.__BMP085_CAL_AC4) # UINT16 - self._cal_AC5 = self.readU16(self.__BMP085_CAL_AC5) # UINT16 - self._cal_AC6 = self.readU16(self.__BMP085_CAL_AC6) # UINT16 - self._cal_B1 = self.readS16(self.__BMP085_CAL_B1) # INT16 - self._cal_B2 = self.readS16(self.__BMP085_CAL_B2) # INT16 - self._cal_MB = self.readS16(self.__BMP085_CAL_MB) # INT16 - self._cal_MC = self.readS16(self.__BMP085_CAL_MC) # INT16 - self._cal_MD = self.readS16(self.__BMP085_CAL_MD) # INT16 - if (self.debug): - self.showCalibrationData() + def readCalibrationData(self): + "Reads the calibration data from the IC" + self._cal_AC1 = self.readS16(self.__BMP085_CAL_AC1) # INT16 + self._cal_AC2 = self.readS16(self.__BMP085_CAL_AC2) # INT16 + self._cal_AC3 = self.readS16(self.__BMP085_CAL_AC3) # INT16 + self._cal_AC4 = self.readU16(self.__BMP085_CAL_AC4) # UINT16 + self._cal_AC5 = self.readU16(self.__BMP085_CAL_AC5) # UINT16 + self._cal_AC6 = self.readU16(self.__BMP085_CAL_AC6) # UINT16 + self._cal_B1 = self.readS16(self.__BMP085_CAL_B1) # INT16 + self._cal_B2 = self.readS16(self.__BMP085_CAL_B2) # INT16 + self._cal_MB = self.readS16(self.__BMP085_CAL_MB) # INT16 + self._cal_MC = self.readS16(self.__BMP085_CAL_MC) # INT16 + self._cal_MD = self.readS16(self.__BMP085_CAL_MD) # INT16 + if (self.debug): + self.showCalibrationData() - def showCalibrationData(self): - "Displays the calibration values for debugging purposes" - print "DBG: AC1 = %6d" % (self._cal_AC1) - print "DBG: AC2 = %6d" % (self._cal_AC2) - print "DBG: AC3 = %6d" % (self._cal_AC3) - print "DBG: AC4 = %6d" % (self._cal_AC4) - print "DBG: AC5 = %6d" % (self._cal_AC5) - print "DBG: AC6 = %6d" % (self._cal_AC6) - print "DBG: B1 = %6d" % (self._cal_B1) - print "DBG: B2 = %6d" % (self._cal_B2) - print "DBG: MB = %6d" % (self._cal_MB) - print "DBG: MC = %6d" % (self._cal_MC) - print "DBG: MD = %6d" % (self._cal_MD) + def showCalibrationData(self): + "Displays the calibration values for debugging purposes" + print "DBG: AC1 = %6d" % (self._cal_AC1) + print "DBG: AC2 = %6d" % (self._cal_AC2) + print "DBG: AC3 = %6d" % (self._cal_AC3) + print "DBG: AC4 = %6d" % (self._cal_AC4) + print "DBG: AC5 = %6d" % (self._cal_AC5) + print "DBG: AC6 = %6d" % (self._cal_AC6) + print "DBG: B1 = %6d" % (self._cal_B1) + print "DBG: B2 = %6d" % (self._cal_B2) + print "DBG: MB = %6d" % (self._cal_MB) + print "DBG: MC = %6d" % (self._cal_MC) + print "DBG: MD = %6d" % (self._cal_MD) - def readRawTemp(self): - "Reads the raw (uncompensated) temperature from the sensor" - self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READTEMPCMD) - time.sleep(0.005) # Wait 5ms - raw = self.readU16(self.__BMP085_TEMPDATA) - if (self.debug): - print "DBG: Raw Temp: 0x%04X (%d)" % (raw & 0xFFFF, raw) - return raw + def readRawTemp(self): + "Reads the raw (uncompensated) temperature from the sensor" + self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READTEMPCMD) + time.sleep(0.005) # Wait 5ms + raw = self.readU16(self.__BMP085_TEMPDATA) + if (self.debug): + print "DBG: Raw Temp: 0x%04X (%d)" % (raw & 0xFFFF, raw) + return raw - def readRawPressure(self): - "Reads the raw (uncompensated) pressure level from the sensor" - self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READPRESSURECMD + (self.mode << 6)) - if (self.mode == self.__BMP085_ULTRALOWPOWER): - time.sleep(0.005) - elif (self.mode == self.__BMP085_HIGHRES): - time.sleep(0.014) - elif (self.mode == self.__BMP085_ULTRAHIGHRES): - time.sleep(0.026) - else: - time.sleep(0.008) - msb = self.i2c.readU8(self.__BMP085_PRESSUREDATA) - lsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+1) - xlsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+2) - raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.mode) - if (self.debug): - print "DBG: Raw Pressure: 0x%04X (%d)" % (raw & 0xFFFF, raw) - return raw + def readRawPressure(self): + "Reads the raw (uncompensated) pressure level from the sensor" + self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READPRESSURECMD + (self.mode << 6)) + if (self.mode == self.__BMP085_ULTRALOWPOWER): + time.sleep(0.005) + elif (self.mode == self.__BMP085_HIGHRES): + time.sleep(0.014) + elif (self.mode == self.__BMP085_ULTRAHIGHRES): + time.sleep(0.026) + else: + time.sleep(0.008) + msb = self.i2c.readU8(self.__BMP085_PRESSUREDATA) + lsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+1) + xlsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+2) + raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.mode) + if (self.debug): + print "DBG: Raw Pressure: 0x%04X (%d)" % (raw & 0xFFFF, raw) + return raw - def readTemperature(self): - "Gets the compensated temperature in degrees celcius" - UT = 0 - X1 = 0 - X2 = 0 - B5 = 0 - temp = 0.0 + def readTemperature(self): + "Gets the compensated temperature in degrees celcius" + UT = 0 + X1 = 0 + X2 = 0 + B5 = 0 + temp = 0.0 - # Read raw temp before aligning it with the calibration values - UT = self.readRawTemp() - X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 - X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) - B5 = X1 + X2 - temp = ((B5 + 8) >> 4) / 10.0 - if (self.debug): - print "DBG: Calibrated temperature = %f C" % temp - return temp + # Read raw temp before aligning it with the calibration values + UT = self.readRawTemp() + X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 + X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) + B5 = X1 + X2 + temp = ((B5 + 8) >> 4) / 10.0 + if (self.debug): + print "DBG: Calibrated temperature = %f C" % temp + return temp - def readPressure(self): - "Gets the compensated pressure in pascal" - UT = 0 - UP = 0 - B3 = 0 - B5 = 0 - B6 = 0 - X1 = 0 - X2 = 0 - X3 = 0 - p = 0 - B4 = 0 - B7 = 0 + def readPressure(self): + "Gets the compensated pressure in pascal" + UT = 0 + UP = 0 + B3 = 0 + B5 = 0 + B6 = 0 + X1 = 0 + X2 = 0 + X3 = 0 + p = 0 + B4 = 0 + B7 = 0 - UT = self.readRawTemp() - UP = self.readRawPressure() + UT = self.readRawTemp() + UP = self.readRawPressure() - # You can use the datasheet values to test the conversion results - # dsValues = True - dsValues = False + # You can use the datasheet values to test the conversion results + # dsValues = True + dsValues = False - if (dsValues): - UT = 27898 - UP = 23843 - self._cal_AC6 = 23153 - self._cal_AC5 = 32757 - self._cal_MB = -32768; - self._cal_MC = -8711 - self._cal_MD = 2868 - self._cal_B1 = 6190 - self._cal_B2 = 4 - self._cal_AC3 = -14383 - self._cal_AC2 = -72 - self._cal_AC1 = 408 - self._cal_AC4 = 32741 - self.mode = self.__BMP085_ULTRALOWPOWER - if (self.debug): - self.showCalibrationData() + if (dsValues): + UT = 27898 + UP = 23843 + self._cal_AC6 = 23153 + self._cal_AC5 = 32757 + self._cal_MB = -32768; + self._cal_MC = -8711 + self._cal_MD = 2868 + self._cal_B1 = 6190 + self._cal_B2 = 4 + self._cal_AC3 = -14383 + self._cal_AC2 = -72 + self._cal_AC1 = 408 + self._cal_AC4 = 32741 + self.mode = self.__BMP085_ULTRALOWPOWER + if (self.debug): + self.showCalibrationData() - # True Temperature Calculations - X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 - X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) - B5 = X1 + X2 - if (self.debug): - print "DBG: X1 = %d" % (X1) - print "DBG: X2 = %d" % (X2) - print "DBG: B5 = %d" % (B5) - print "DBG: True Temperature = %.2f C" % (((B5 + 8) >> 4) / 10.0) + # True Temperature Calculations + X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 + X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) + B5 = X1 + X2 + if (self.debug): + print "DBG: X1 = %d" % (X1) + print "DBG: X2 = %d" % (X2) + print "DBG: B5 = %d" % (B5) + print "DBG: True Temperature = %.2f C" % (((B5 + 8) >> 4) / 10.0) - # Pressure Calculations - B6 = B5 - 4000 - X1 = (self._cal_B2 * (B6 * B6) >> 12) >> 11 - X2 = (self._cal_AC2 * B6) >> 11 - X3 = X1 + X2 - B3 = (((self._cal_AC1 * 4 + X3) << self.mode) + 2) / 4 - if (self.debug): - print "DBG: B6 = %d" % (B6) - print "DBG: X1 = %d" % (X1) - print "DBG: X2 = %d" % (X2) - print "DBG: X3 = %d" % (X3) - print "DBG: B3 = %d" % (B3) + # Pressure Calculations + B6 = B5 - 4000 + X1 = (self._cal_B2 * (B6 * B6) >> 12) >> 11 + X2 = (self._cal_AC2 * B6) >> 11 + X3 = X1 + X2 + B3 = (((self._cal_AC1 * 4 + X3) << self.mode) + 2) / 4 + if (self.debug): + print "DBG: B6 = %d" % (B6) + print "DBG: X1 = %d" % (X1) + print "DBG: X2 = %d" % (X2) + print "DBG: X3 = %d" % (X3) + print "DBG: B3 = %d" % (B3) - X1 = (self._cal_AC3 * B6) >> 13 - X2 = (self._cal_B1 * ((B6 * B6) >> 12)) >> 16 - X3 = ((X1 + X2) + 2) >> 2 - B4 = (self._cal_AC4 * (X3 + 32768)) >> 15 - B7 = (UP - B3) * (50000 >> self.mode) - if (self.debug): - print "DBG: X1 = %d" % (X1) - print "DBG: X2 = %d" % (X2) - print "DBG: X3 = %d" % (X3) - print "DBG: B4 = %d" % (B4) - print "DBG: B7 = %d" % (B7) + X1 = (self._cal_AC3 * B6) >> 13 + X2 = (self._cal_B1 * ((B6 * B6) >> 12)) >> 16 + X3 = ((X1 + X2) + 2) >> 2 + B4 = (self._cal_AC4 * (X3 + 32768)) >> 15 + B7 = (UP - B3) * (50000 >> self.mode) + if (self.debug): + print "DBG: X1 = %d" % (X1) + print "DBG: X2 = %d" % (X2) + print "DBG: X3 = %d" % (X3) + print "DBG: B4 = %d" % (B4) + print "DBG: B7 = %d" % (B7) - if (B7 < 0x80000000): - p = (B7 * 2) / B4 - else: - p = (B7 / B4) * 2 + if (B7 < 0x80000000): + p = (B7 * 2) / B4 + else: + p = (B7 / B4) * 2 - if (self.debug): - print "DBG: X1 = %d" % (X1) - - X1 = (p >> 8) * (p >> 8) - X1 = (X1 * 3038) >> 16 - X2 = (-7357 * p) >> 16 - if (self.debug): - print "DBG: p = %d" % (p) - print "DBG: X1 = %d" % (X1) - print "DBG: X2 = %d" % (X2) + if (self.debug): + print "DBG: X1 = %d" % (X1) + + X1 = (p >> 8) * (p >> 8) + X1 = (X1 * 3038) >> 16 + X2 = (-7357 * p) >> 16 + if (self.debug): + print "DBG: p = %d" % (p) + print "DBG: X1 = %d" % (X1) + print "DBG: X2 = %d" % (X2) - p = p + ((X1 + X2 + 3791) >> 4) - if (self.debug): - print "DBG: Pressure = %d Pa" % (p) + p = p + ((X1 + X2 + 3791) >> 4) + if (self.debug): + print "DBG: Pressure = %d Pa" % (p) - return p + return p - def readAltitude(self, seaLevelPressure=101325): - "Calculates the altitude in meters" - altitude = 0.0 - pressure = float(self.readPressure()) - altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903)) - if (self.debug): - print "DBG: Altitude = %d" % (altitude) - return altitude + def readAltitude(self, seaLevelPressure=101325): + "Calculates the altitude in meters" + altitude = 0.0 + pressure = float(self.readPressure()) + altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903)) + if (self.debug): + print "DBG: Altitude = %d" % (altitude) + return altitude - return 0 + return 0 diff --git a/Adafruit_BMP085/Adafruit_BMP085_googledocs_ex.py b/Adafruit_BMP085/Adafruit_BMP085_googledocs_ex.py index 4d62cd0b..d2edade4 100755 --- a/Adafruit_BMP085/Adafruit_BMP085_googledocs_ex.py +++ b/Adafruit_BMP085/Adafruit_BMP085_googledocs_ex.py @@ -31,39 +31,39 @@ # Login with your Google account try: - gc = gspread.login(email, password) + gc = gspread.login(email, password) except: - print "Unable to log in. Check your email address/password" - sys.exit() + print "Unable to log in. Check your email address/password" + sys.exit() # Open a worksheet from your spreadsheet using the filename try: - worksheet = gc.open(spreadsheet).sheet1 - # Alternatively, open a spreadsheet using the spreadsheet's key - # worksheet = gc.open_by_key('0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE') + worksheet = gc.open(spreadsheet).sheet1 + # Alternatively, open a spreadsheet using the spreadsheet's key + # worksheet = gc.open_by_key('0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE') except: - print "Unable to open the spreadsheet. Check your filename: %s" % spreadsheet - sys.exit() + print "Unable to open the spreadsheet. Check your filename: %s" % spreadsheet + sys.exit() # Continuously append data while(True): - temp = bmp.readTemperature() - pressure = bmp.readPressure() - altitude = bmp.readAltitude() + temp = bmp.readTemperature() + pressure = bmp.readPressure() + altitude = bmp.readAltitude() - print "Temperature: %.2f C" % temp - print "Pressure: %.2f hPa" % (pressure / 100.0) - print "Altitude: %.2f" % altitude + print "Temperature: %.2f C" % temp + print "Pressure: %.2f hPa" % (pressure / 100.0) + print "Altitude: %.2f" % altitude - # Append the data in the spreadsheet, including a timestamp - try: - values = [datetime.datetime.now(), temp, pressure, altitude] - worksheet.append_row(values) - except: - print "Unable to append data. Check your connection?" - sys.exit() + # Append the data in the spreadsheet, including a timestamp + try: + values = [datetime.datetime.now(), temp, pressure, altitude] + worksheet.append_row(values) + except: + print "Unable to append data. Check your connection?" + sys.exit() - # Wait 5 seconds before continuing - print "Wrote a row to %s" % spreadsheet - time.sleep(5) + # Wait 5 seconds before continuing + print "Wrote a row to %s" % spreadsheet + time.sleep(5) diff --git a/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py b/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py index 9c9f6318..a4918990 100755 --- a/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py +++ b/Adafruit_DHT_Driver/Adafruit_DHT_googledocs.ex.py @@ -23,50 +23,50 @@ # Login with your Google account try: - gc = gspread.login(email, password) + gc = gspread.login(email, password) except: - print "Unable to log in. Check your email address/password" - sys.exit() + print "Unable to log in. Check your email address/password" + sys.exit() # Open a worksheet from your spreadsheet using the filename try: - worksheet = gc.open(spreadsheet).sheet1 - # Alternatively, open a spreadsheet using the spreadsheet's key - # worksheet = gc.open_by_key('0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE').sheet1 + worksheet = gc.open(spreadsheet).sheet1 + # Alternatively, open a spreadsheet using the spreadsheet's key + # worksheet = gc.open_by_key('0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE').sheet1 except: - print "Unable to open the spreadsheet. Check your filename: %s" % spreadsheet - sys.exit() + print "Unable to open the spreadsheet. Check your filename: %s" % spreadsheet + sys.exit() # Continuously append data while(True): - # Run the DHT program to get the humidity and temperature readings! + # Run the DHT program to get the humidity and temperature readings! - output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]); - print output - matches = re.search("Temp =\s+([0-9.]+)", output) - if (not matches): - time.sleep(3) - continue - temp = float(matches.group(1)) - - # search for humidity printout - matches = re.search("Hum =\s+([0-9.]+)", output) - if (not matches): - time.sleep(3) - continue - humidity = float(matches.group(1)) + output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]); + print output + matches = re.search("Temp =\s+([0-9.]+)", output) + if (not matches): + time.sleep(3) + continue + temp = float(matches.group(1)) + + # search for humidity printout + matches = re.search("Hum =\s+([0-9.]+)", output) + if (not matches): + time.sleep(3) + continue + humidity = float(matches.group(1)) - print "Temperature: %.1f C" % temp - print "Humidity: %.1f %%" % humidity + print "Temperature: %.1f C" % temp + print "Humidity: %.1f %%" % humidity - # Append the data in the spreadsheet, including a timestamp - try: - values = [datetime.datetime.now(), temp, humidity] - worksheet.append_row(values) - except: - print "Unable to append data. Check your connection?" - sys.exit() + # Append the data in the spreadsheet, including a timestamp + try: + values = [datetime.datetime.now(), temp, humidity] + worksheet.append_row(values) + except: + print "Unable to append data. Check your connection?" + sys.exit() - # Wait 30 seconds before continuing - print "Wrote a row to %s" % spreadsheet - time.sleep(30) + # Wait 30 seconds before continuing + print "Wrote a row to %s" % spreadsheet + time.sleep(30) diff --git a/Adafruit_I2C/Adafruit_I2C.py b/Adafruit_I2C/Adafruit_I2C.py index 2b24b67f..f5e363d5 100755 --- a/Adafruit_I2C/Adafruit_I2C.py +++ b/Adafruit_I2C/Adafruit_I2C.py @@ -1,161 +1,206 @@ #!/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, 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, 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, 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, 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, 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, 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, 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, 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, err: - return self.errMsg() + +# On Edison, we're looking for mraa +try: + import mraa + PLATFORM = 'EDISON' +except ImportError: + mraa = False + import smbus + + +class AdafruitI2C(object): + """ Adafruit I2C bus object + """ + + @staticmethod + def is_edison(): + """ Determine if this is an edison board """ + with open('/proc/version', 'r') as infile: + for line in infile: + match = re.match('^.*([Ee]dison).*$', line) + if match: + return True + + return False + + + @staticmethod + def get_pi_revision(): + """ Gets the version number of the Raspberry Pi board + http://elinux.org/RPi_HardwareHistory#Board_Revision_History + + :return: int + """ + 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 + + @staticmethod + def get_pi_i2c_bus_number(): + # Gets the I2C bus number /dev/i2c# + return 1 if AdafruitI2C.get_pi_revision() > 1 else 0 + + @staticmethod + def reverse_byte_order(self, data): + "Reverses the byte order of an int (16-bit) or long (32-bit) value" + # Courtesy Vishal Sapre + byte_count = len(hex(data)[2:].replace('L', '')[::2]) + val = 0 + for i in range(byte_count): + val = (val << 8) | (data & 0xff) + data >>= 8 + return val + + def __init__(self, address, bus_num=-1, debug=False): + self.address = address + + if self.is_edison(): + self.bus = mraa.I2c(bus_num) + + else: + # 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(bus_num if bus_num >= 0 else AdafruitI2C.get_pi_i2c_bus_number()) + + self.debug = debug + + def err_msg(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, err: + return self.err_msg() + + 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, err: + return self.err_msg() + + def write_raw8(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, err: + return self.err_msg() + + def write_list(self, reg, w_list): + """ Writes an array of bytes using I2C format + :param reg: register + :param w_list: things to write + :return: + """ + try: + if self.debug: + print "I2C: Writing list to register 0x%02X:" % reg + print w_list + self.bus.write_i2c_block_data(self.address, reg, w_list) + except IOError, err: + return self.err_msg() + + def read_list(self, reg, length): + """ Read a list of bytes from the I2C device + :param reg: register address + :param length: + :return: + """ + 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, err: + return self.err_msg() + + def read_u8(self, reg): + """ Read an unsigned byte from the I2C device + :param reg: + :return: + """ + 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, err: + return self.err_msg() + + def read_s8(self, reg): + """ Reads a signed byte from the I2C device + :param reg: + :return: + """ + 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, err: + return self.err_msg() + + def read_u16(self, reg, little_endian=True): + """ Reads an unsigned 16-bit value from the I2C device + :param reg: + :param little_endian: + :return: + """ + 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, err: + return self.err_msg() + + def read_s16(self, reg, little_endian=True): + """ Reads a signed 16-bit value from the I2C device + :param reg: register + :param little_endian: binary + :return: + """ + try: + result = self.read_u16(reg,little_endian) + if result > 32767: result -= 65536 + return result + except IOError, err: + return self.err_msg() if __name__ == '__main__': - try: - bus = Adafruit_I2C(address=0) + bus = AdafruitI2C(address=0) print "Default I2C bus is accessible" - except: - print "Error accessing default I2C bus" diff --git a/Adafruit_LEDBackpack/ex_7segment_clock.py b/Adafruit_LEDBackpack/ex_7segment_clock.py index 99f00ab1..3fc8a5d4 100644 --- a/Adafruit_LEDBackpack/ex_7segment_clock.py +++ b/Adafruit_LEDBackpack/ex_7segment_clock.py @@ -13,17 +13,17 @@ # Continually update the time on a 4 char, 7-segment display while(True): - now = datetime.datetime.now() - hour = now.hour - minute = now.minute - second = now.second - # Set hours - segment.writeDigit(0, int(hour / 10)) # Tens - segment.writeDigit(1, hour % 10) # Ones - # Set minutes - segment.writeDigit(3, int(minute / 10)) # Tens - segment.writeDigit(4, minute % 10) # Ones - # Toggle colon - segment.setColon(second % 2) # Toggle colon at 1Hz - # Wait one second - time.sleep(1) + now = datetime.datetime.now() + hour = now.hour + minute = now.minute + second = now.second + # Set hours + segment.writeDigit(0, int(hour / 10)) # Tens + segment.writeDigit(1, hour % 10) # Ones + # Set minutes + segment.writeDigit(3, int(minute / 10)) # Tens + segment.writeDigit(4, minute % 10) # Ones + # Toggle colon + segment.setColon(second % 2) # Toggle colon at 1Hz + # Wait one second + time.sleep(1) diff --git a/Adafruit_LEDBackpack/ex_8x8_color_pixels.py b/Adafruit_LEDBackpack/ex_8x8_color_pixels.py index 978db826..eee582f6 100644 --- a/Adafruit_LEDBackpack/ex_8x8_color_pixels.py +++ b/Adafruit_LEDBackpack/ex_8x8_color_pixels.py @@ -15,9 +15,9 @@ # Continually update the 8x8 display one pixel at a time while(True): - iter += 1 + iter += 1 - for x in range(0, 8): - for y in range(0, 8): - grid.setPixel(x, y, iter % 4 ) - time.sleep(0.02) + for x in range(0, 8): + for y in range(0, 8): + grid.setPixel(x, y, iter % 4 ) + time.sleep(0.02) diff --git a/Adafruit_LEDBackpack/ex_8x8_pixels.py b/Adafruit_LEDBackpack/ex_8x8_pixels.py index 4a396ee3..d7f3b2fd 100644 --- a/Adafruit_LEDBackpack/ex_8x8_pixels.py +++ b/Adafruit_LEDBackpack/ex_8x8_pixels.py @@ -13,10 +13,10 @@ # Continually update the 8x8 display one pixel at a time while(True): - for x in range(0, 8): - for y in range(0, 8): - grid.setPixel(x, y) - time.sleep(0.05) - time.sleep(0.5) - grid.clear() - time.sleep(0.5) + for x in range(0, 8): + for y in range(0, 8): + grid.setPixel(x, y) + time.sleep(0.05) + time.sleep(0.5) + grid.clear() + time.sleep(0.5) diff --git a/Adafruit_LEDBackpack/ex_bargraph.py b/Adafruit_LEDBackpack/ex_bargraph.py index 1fa0a31e..73619cd5 100644 --- a/Adafruit_LEDBackpack/ex_bargraph.py +++ b/Adafruit_LEDBackpack/ex_bargraph.py @@ -12,8 +12,8 @@ print "Press CTRL+C to exit" while(True): - for color in range(1, 4): - for i in range(24): - print i - bargraph.setLed(i, color) - time.sleep(0.05) + for color in range(1, 4): + for i in range(24): + print i + bargraph.setLed(i, color) + time.sleep(0.05) diff --git a/Adafruit_LEDpixels/Adafruit_LEDpixels.py b/Adafruit_LEDpixels/Adafruit_LEDpixels.py index 07e1a953..22c4d4e8 100644 --- a/Adafruit_LEDpixels/Adafruit_LEDpixels.py +++ b/Adafruit_LEDpixels/Adafruit_LEDpixels.py @@ -8,16 +8,16 @@ GPIO.setmode(GPIO.BCM) def slowspiwrite(clockpin, datapin, byteout): - GPIO.setup(clockpin, GPIO.OUT) - GPIO.setup(datapin, GPIO.OUT) - for i in range(8): - if (byteout & 0x80): - GPIO.output(datapin, True) - else: - GPIO.output(clockpin, False) - byteout <<= 1 - GPIO.output(clockpin, True) - GPIO.output(clockpin, False) + GPIO.setup(clockpin, GPIO.OUT) + GPIO.setup(datapin, GPIO.OUT) + for i in range(8): + if (byteout & 0x80): + GPIO.output(datapin, True) + else: + GPIO.output(clockpin, False) + byteout <<= 1 + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) SPICLK = 18 @@ -26,56 +26,56 @@ def slowspiwrite(clockpin, datapin, byteout): ledpixels = [0] * 25 def writestrip(pixels): - spidev = file("/dev/spidev0.0", "w") - for i in range(len(pixels)): - spidev.write(chr((pixels[i]>>16) & 0xFF)) - spidev.write(chr((pixels[i]>>8) & 0xFF)) - spidev.write(chr(pixels[i] & 0xFF)) - spidev.close() - time.sleep(0.002) + spidev = file("/dev/spidev0.0", "w") + for i in range(len(pixels)): + spidev.write(chr((pixels[i]>>16) & 0xFF)) + spidev.write(chr((pixels[i]>>8) & 0xFF)) + spidev.write(chr(pixels[i] & 0xFF)) + spidev.close() + time.sleep(0.002) def Color(r, g, b): - return ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) + return ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) def setpixelcolor(pixels, n, r, g, b): - if (n >= len(pixels)): - return - pixels[n] = Color(r,g,b) + if (n >= len(pixels)): + return + pixels[n] = Color(r,g,b) def setpixelcolor(pixels, n, c): - if (n >= len(pixels)): - return - pixels[n] = c + if (n >= len(pixels)): + return + pixels[n] = c def colorwipe(pixels, c, delay): - for i in range(len(pixels)): - setpixelcolor(pixels, i, c) - writestrip(pixels) - time.sleep(delay) + for i in range(len(pixels)): + setpixelcolor(pixels, i, c) + writestrip(pixels) + time.sleep(delay) def Wheel(WheelPos): - if (WheelPos < 85): - return Color(WheelPos * 3, 255 - WheelPos * 3, 0) - elif (WheelPos < 170): - WheelPos -= 85; - return Color(255 - WheelPos * 3, 0, WheelPos * 3) - else: - WheelPos -= 170; - return Color(0, WheelPos * 3, 255 - WheelPos * 3) + if (WheelPos < 85): + return Color(WheelPos * 3, 255 - WheelPos * 3, 0) + elif (WheelPos < 170): + WheelPos -= 85; + return Color(255 - WheelPos * 3, 0, WheelPos * 3) + else: + WheelPos -= 170; + return Color(0, WheelPos * 3, 255 - WheelPos * 3) def rainbowCycle(pixels, wait): - for j in range(256): # one cycle of all 256 colors in the wheel - for i in range(len(pixels)): + for j in range(256): # one cycle of all 256 colors in the wheel + for i in range(len(pixels)): # tricky math! we use each pixel as a fraction of the full 96-color wheel # (thats the i / strip.numPixels() part) # Then add in j which makes the colors go around per pixel # the % 96 is to make the wheel cycle around - setpixelcolor(pixels, i, Wheel( ((i * 256 / len(pixels)) + j) % 256) ) - writestrip(pixels) - time.sleep(wait) + setpixelcolor(pixels, i, Wheel( ((i * 256 / len(pixels)) + j) % 256) ) + writestrip(pixels) + time.sleep(wait) colorwipe(ledpixels, Color(255, 0, 0), 0.05) colorwipe(ledpixels, Color(0, 255, 0), 0.05) colorwipe(ledpixels, Color(0, 0, 255), 0.05) while True: - rainbowCycle(ledpixels, 0.00) + rainbowCycle(ledpixels, 0.00) diff --git a/Adafruit_MCP3002/MCP3002.py b/Adafruit_MCP3002/MCP3002.py index 5b0b68b5..46e0c5f0 100644 --- a/Adafruit_MCP3002/MCP3002.py +++ b/Adafruit_MCP3002/MCP3002.py @@ -9,29 +9,29 @@ # this function is not used, its for future reference! def slowspiwrite(clockpin, datapin, byteout): - GPIO.setup(clockpin, GPIO.OUT) - GPIO.setup(datapin, GPIO.OUT) - for i in range(8): - if (byteout & 0x80): - GPIO.output(datapin, True) - else: - GPIO.output(datapin, False) - byteout <<= 1 - GPIO.output(clockpin, True) - GPIO.output(clockpin, False) + GPIO.setup(clockpin, GPIO.OUT) + GPIO.setup(datapin, GPIO.OUT) + for i in range(8): + if (byteout & 0x80): + GPIO.output(datapin, True) + else: + GPIO.output(datapin, False) + byteout <<= 1 + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) # this function is not used, its for future reference! def slowspiread(clockpin, datapin): - GPIO.setup(clockpin, GPIO.OUT) - GPIO.setup(datapin, GPIO.IN) - byteout = 0 - for i in range(8): - GPIO.output(clockpin, False) - GPIO.output(clockpin, True) - byteout <<= 1 - if (GPIO.input(datapin)): - byteout = byteout | 0x1 - return byteout + GPIO.setup(clockpin, GPIO.OUT) + GPIO.setup(datapin, GPIO.IN) + byteout = 0 + for i in range(8): + GPIO.output(clockpin, False) + GPIO.output(clockpin, True) + byteout <<= 1 + if (GPIO.input(datapin)): + byteout = byteout | 0x1 + return byteout # read SPI data from MCP3002 chip, 2 possible adc's (0 thru 1) def readadc(adcnum, clockpin, mosipin, misopin, cspin): @@ -87,8 +87,8 @@ def readadc(adcnum, clockpin, mosipin, misopin, cspin): print "| #0 \t #1|" print "-----------------------------------------------------------------" while True: - print "|", - for adcnum in range(2): - ret = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) - print ret,"\t", - print "|" + print "|", + for adcnum in range(2): + ret = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) + print ret,"\t", + print "|" diff --git a/Adafruit_MCP3008/mcp3008.py b/Adafruit_MCP3008/mcp3008.py index 73dcd7dd..f08cd67c 100644 --- a/Adafruit_MCP3008/mcp3008.py +++ b/Adafruit_MCP3008/mcp3008.py @@ -9,94 +9,94 @@ # this function is not used, its for future reference! def slowspiwrite(clockpin, datapin, byteout): - GPIO.setup(clockpin, GPIO.OUT) - GPIO.setup(datapin, GPIO.OUT) - for i in range(8): - if (byteout & 0x80): - GPIO.output(datapin, True) - else: - GPIO.output(datapin, False) - byteout <<= 1 - GPIO.output(clockpin, True) - GPIO.output(clockpin, False) + GPIO.setup(clockpin, GPIO.OUT) + GPIO.setup(datapin, GPIO.OUT) + for i in range(8): + if (byteout & 0x80): + GPIO.output(datapin, True) + else: + GPIO.output(datapin, False) + byteout <<= 1 + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) # this function is not used, its for future reference! def slowspiread(clockpin, datapin): - GPIO.setup(clockpin, GPIO.OUT) - GPIO.setup(datapin, GPIO.IN) - byteout = 0 - for i in range(8): - GPIO.output(clockpin, False) - GPIO.output(clockpin, True) - byteout <<= 1 - if (GPIO.input(datapin)): - byteout = byteout | 0x1 - return byteout + GPIO.setup(clockpin, GPIO.OUT) + GPIO.setup(datapin, GPIO.IN) + byteout = 0 + for i in range(8): + GPIO.output(clockpin, False) + GPIO.output(clockpin, True) + byteout <<= 1 + if (GPIO.input(datapin)): + byteout = byteout | 0x1 + return byteout # read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7) def readadc(adcnum, clockpin, mosipin, misopin, cspin): - if ((adcnum > 7) or (adcnum < 0)): - return -1 - GPIO.output(cspin, True) - - GPIO.output(clockpin, False) # start clock low - GPIO.output(cspin, False) # bring CS low - - commandout = adcnum - commandout |= 0x18 # start bit + single-ended bit - commandout <<= 3 # we only need to send 5 bits here - for i in range(5): - if (commandout & 0x80): - GPIO.output(mosipin, True) - else: - GPIO.output(mosipin, False) - commandout <<= 1 - GPIO.output(clockpin, True) - GPIO.output(clockpin, False) - - adcout = 0 - # read in one empty bit, one null bit and 10 ADC bits - for i in range(12): - GPIO.output(clockpin, True) - GPIO.output(clockpin, False) - adcout <<= 1 - if (GPIO.input(misopin)): - adcout |= 0x1 - - GPIO.output(cspin, True) - - adcout /= 2 # first bit is 'null' so drop it - return adcout - + if ((adcnum > 7) or (adcnum < 0)): + return -1 + GPIO.output(cspin, True) + + GPIO.output(clockpin, False) # start clock low + GPIO.output(cspin, False) # bring CS low + + commandout = adcnum + commandout |= 0x18 # start bit + single-ended bit + commandout <<= 3 # we only need to send 5 bits here + for i in range(5): + if (commandout & 0x80): + GPIO.output(mosipin, True) + else: + GPIO.output(mosipin, False) + commandout <<= 1 + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) + + adcout = 0 + # read in one empty bit, one null bit and 10 ADC bits + for i in range(12): + GPIO.output(clockpin, True) + GPIO.output(clockpin, False) + adcout <<= 1 + if (GPIO.input(misopin)): + adcout |= 0x1 + + GPIO.output(cspin, True) + + adcout /= 2 # first bit is 'null' so drop it + return adcout + if __name__=='__main__': - try: - # change these as desired - SPICLK = 18 - SPIMISO = 21 - SPIMOSI = 17 - SPICS = 22 - - # set up the SPI interface pins - GPIO.setup(SPICLK, GPIO.OUT) - GPIO.setup(SPIMISO, GPIO.IN) - GPIO.setup(SPIMOSI, GPIO.OUT) - GPIO.setup(SPICS, GPIO.OUT) - - # Note that bitbanging SPI is incredibly slow on the Pi as its not - # a RTOS - reading the ADC takes about 30 ms (~30 samples per second) - # which is awful for a microcontroller but better-than-nothing for Linux - - print "| #0 \t #1 \t #2 \t #3 \t #4 \t #5 \t #6 \t #7\t|" - print "-----------------------------------------------------------------" - while True: - print "|", - for adcnum in range(8): - ret = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) - print ret,"\t", - print "|" - - except KeyboardInterrupt: - pass - - GPIO.cleanup() + try: + # change these as desired + SPICLK = 18 + SPIMISO = 21 + SPIMOSI = 17 + SPICS = 22 + + # set up the SPI interface pins + GPIO.setup(SPICLK, GPIO.OUT) + GPIO.setup(SPIMISO, GPIO.IN) + GPIO.setup(SPIMOSI, GPIO.OUT) + GPIO.setup(SPICS, GPIO.OUT) + + # Note that bitbanging SPI is incredibly slow on the Pi as its not + # a RTOS - reading the ADC takes about 30 ms (~30 samples per second) + # which is awful for a microcontroller but better-than-nothing for Linux + + print "| #0 \t #1 \t #2 \t #3 \t #4 \t #5 \t #6 \t #7\t|" + print "-----------------------------------------------------------------" + while True: + print "|", + for adcnum in range(8): + ret = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) + print ret,"\t", + print "|" + + except KeyboardInterrupt: + pass + + GPIO.cleanup() diff --git a/Adafruit_MCP4725/Adafruit_MCP4725.py b/Adafruit_MCP4725/Adafruit_MCP4725.py index 0cd66b20..5936ca34 100755 --- a/Adafruit_MCP4725/Adafruit_MCP4725.py +++ b/Adafruit_MCP4725/Adafruit_MCP4725.py @@ -7,29 +7,29 @@ # ============================================================================ class MCP4725 : - i2c = None - - # Registers - __REG_WRITEDAC = 0x40 - __REG_WRITEDACEEPROM = 0x60 + i2c = None + + # Registers + __REG_WRITEDAC = 0x40 + __REG_WRITEDACEEPROM = 0x60 - # Constructor - def __init__(self, address=0x62, debug=False): - self.i2c = Adafruit_I2C(address) - self.address = address - self.debug = debug + # Constructor + def __init__(self, address=0x62, debug=False): + self.i2c = Adafruit_I2C(address) + self.address = address + self.debug = debug - def setVoltage(self, voltage, persist=False): - "Sets the output voltage to the specified value" - if (voltage > 4095): - voltage = 4095 - if (voltage < 0): - voltage = 0 - if (self.debug): - print "Setting voltage to %04d" % voltage - # Value needs to be left-shifted four bytes for the MCP4725 - bytes = [(voltage >> 4) & 0xFF, (voltage << 4) & 0xFF] - if (persist): - self.i2c.writeList(self.__REG_WRITEDACEEPROM, bytes) - else: - self.i2c.writeList(self.__REG_WRITEDAC, bytes) + def setVoltage(self, voltage, persist=False): + "Sets the output voltage to the specified value" + if (voltage > 4095): + voltage = 4095 + if (voltage < 0): + voltage = 0 + if (self.debug): + print "Setting voltage to %04d" % voltage + # Value needs to be left-shifted four bytes for the MCP4725 + bytes = [(voltage >> 4) & 0xFF, (voltage << 4) & 0xFF] + if (persist): + self.i2c.writeList(self.__REG_WRITEDACEEPROM, bytes) + else: + self.i2c.writeList(self.__REG_WRITEDAC, bytes) diff --git a/Adafruit_MCP4725/sinewave.py b/Adafruit_MCP4725/sinewave.py index 11928251..eadf243b 100755 --- a/Adafruit_MCP4725/sinewave.py +++ b/Adafruit_MCP4725/sinewave.py @@ -7,166 +7,166 @@ DAC_RESOLUTION = 9 # 9-Bit Lookup Table (512 values) -DACLookup_FullSine_9Bit = \ -[ 2048, 2073, 2098, 2123, 2148, 2174, 2199, 2224, - 2249, 2274, 2299, 2324, 2349, 2373, 2398, 2423, - 2448, 2472, 2497, 2521, 2546, 2570, 2594, 2618, - 2643, 2667, 2690, 2714, 2738, 2762, 2785, 2808, - 2832, 2855, 2878, 2901, 2924, 2946, 2969, 2991, - 3013, 3036, 3057, 3079, 3101, 3122, 3144, 3165, - 3186, 3207, 3227, 3248, 3268, 3288, 3308, 3328, - 3347, 3367, 3386, 3405, 3423, 3442, 3460, 3478, - 3496, 3514, 3531, 3548, 3565, 3582, 3599, 3615, - 3631, 3647, 3663, 3678, 3693, 3708, 3722, 3737, - 3751, 3765, 3778, 3792, 3805, 3817, 3830, 3842, - 3854, 3866, 3877, 3888, 3899, 3910, 3920, 3930, - 3940, 3950, 3959, 3968, 3976, 3985, 3993, 4000, - 4008, 4015, 4022, 4028, 4035, 4041, 4046, 4052, - 4057, 4061, 4066, 4070, 4074, 4077, 4081, 4084, - 4086, 4088, 4090, 4092, 4094, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4094, 4092, 4090, 4088, - 4086, 4084, 4081, 4077, 4074, 4070, 4066, 4061, - 4057, 4052, 4046, 4041, 4035, 4028, 4022, 4015, - 4008, 4000, 3993, 3985, 3976, 3968, 3959, 3950, - 3940, 3930, 3920, 3910, 3899, 3888, 3877, 3866, - 3854, 3842, 3830, 3817, 3805, 3792, 3778, 3765, - 3751, 3737, 3722, 3708, 3693, 3678, 3663, 3647, - 3631, 3615, 3599, 3582, 3565, 3548, 3531, 3514, - 3496, 3478, 3460, 3442, 3423, 3405, 3386, 3367, - 3347, 3328, 3308, 3288, 3268, 3248, 3227, 3207, - 3186, 3165, 3144, 3122, 3101, 3079, 3057, 3036, - 3013, 2991, 2969, 2946, 2924, 2901, 2878, 2855, - 2832, 2808, 2785, 2762, 2738, 2714, 2690, 2667, - 2643, 2618, 2594, 2570, 2546, 2521, 2497, 2472, - 2448, 2423, 2398, 2373, 2349, 2324, 2299, 2274, - 2249, 2224, 2199, 2174, 2148, 2123, 2098, 2073, - 2048, 2023, 1998, 1973, 1948, 1922, 1897, 1872, - 1847, 1822, 1797, 1772, 1747, 1723, 1698, 1673, - 1648, 1624, 1599, 1575, 1550, 1526, 1502, 1478, - 1453, 1429, 1406, 1382, 1358, 1334, 1311, 1288, - 1264, 1241, 1218, 1195, 1172, 1150, 1127, 1105, - 1083, 1060, 1039, 1017, 995, 974, 952, 931, - 910, 889, 869, 848, 828, 808, 788, 768, - 749, 729, 710, 691, 673, 654, 636, 618, - 600, 582, 565, 548, 531, 514, 497, 481, - 465, 449, 433, 418, 403, 388, 374, 359, - 345, 331, 318, 304, 291, 279, 266, 254, - 242, 230, 219, 208, 197, 186, 176, 166, - 156, 146, 137, 128, 120, 111, 103, 96, +DACLookup_FullSine_9Bit = [ + 2048, 2073, 2098, 2123, 2148, 2174, 2199, 2224, + 2249, 2274, 2299, 2324, 2349, 2373, 2398, 2423, + 2448, 2472, 2497, 2521, 2546, 2570, 2594, 2618, + 2643, 2667, 2690, 2714, 2738, 2762, 2785, 2808, + 2832, 2855, 2878, 2901, 2924, 2946, 2969, 2991, + 3013, 3036, 3057, 3079, 3101, 3122, 3144, 3165, + 3186, 3207, 3227, 3248, 3268, 3288, 3308, 3328, + 3347, 3367, 3386, 3405, 3423, 3442, 3460, 3478, + 3496, 3514, 3531, 3548, 3565, 3582, 3599, 3615, + 3631, 3647, 3663, 3678, 3693, 3708, 3722, 3737, + 3751, 3765, 3778, 3792, 3805, 3817, 3830, 3842, + 3854, 3866, 3877, 3888, 3899, 3910, 3920, 3930, + 3940, 3950, 3959, 3968, 3976, 3985, 3993, 4000, + 4008, 4015, 4022, 4028, 4035, 4041, 4046, 4052, + 4057, 4061, 4066, 4070, 4074, 4077, 4081, 4084, + 4086, 4088, 4090, 4092, 4094, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4094, 4092, 4090, 4088, + 4086, 4084, 4081, 4077, 4074, 4070, 4066, 4061, + 4057, 4052, 4046, 4041, 4035, 4028, 4022, 4015, + 4008, 4000, 3993, 3985, 3976, 3968, 3959, 3950, + 3940, 3930, 3920, 3910, 3899, 3888, 3877, 3866, + 3854, 3842, 3830, 3817, 3805, 3792, 3778, 3765, + 3751, 3737, 3722, 3708, 3693, 3678, 3663, 3647, + 3631, 3615, 3599, 3582, 3565, 3548, 3531, 3514, + 3496, 3478, 3460, 3442, 3423, 3405, 3386, 3367, + 3347, 3328, 3308, 3288, 3268, 3248, 3227, 3207, + 3186, 3165, 3144, 3122, 3101, 3079, 3057, 3036, + 3013, 2991, 2969, 2946, 2924, 2901, 2878, 2855, + 2832, 2808, 2785, 2762, 2738, 2714, 2690, 2667, + 2643, 2618, 2594, 2570, 2546, 2521, 2497, 2472, + 2448, 2423, 2398, 2373, 2349, 2324, 2299, 2274, + 2249, 2224, 2199, 2174, 2148, 2123, 2098, 2073, + 2048, 2023, 1998, 1973, 1948, 1922, 1897, 1872, + 1847, 1822, 1797, 1772, 1747, 1723, 1698, 1673, + 1648, 1624, 1599, 1575, 1550, 1526, 1502, 1478, + 1453, 1429, 1406, 1382, 1358, 1334, 1311, 1288, + 1264, 1241, 1218, 1195, 1172, 1150, 1127, 1105, + 1083, 1060, 1039, 1017, 995, 974, 952, 931, + 910, 889, 869, 848, 828, 808, 788, 768, + 749, 729, 710, 691, 673, 654, 636, 618, + 600, 582, 565, 548, 531, 514, 497, 481, + 465, 449, 433, 418, 403, 388, 374, 359, + 345, 331, 318, 304, 291, 279, 266, 254, + 242, 230, 219, 208, 197, 186, 176, 166, + 156, 146, 137, 128, 120, 111, 103, 96, 88, 81, 74, 68, 61, 55, 50, 44, 39, 35, 30, 26, 22, 19, 15, 12, 10, 8, 6, 4, 2, 1, 1, 0, - 0, 0, 1, 1, 2, 4, 6, 8, + 0, 0, 1, 1, 2, 4, 6, 8, 10, 12, 15, 19, 22, 26, 30, 35, 39, 44, 50, 55, 61, 68, 74, 81, 88, 96, 103, 111, 120, 128, 137, 146, - 156, 166, 176, 186, 197, 208, 219, 230, - 242, 254, 266, 279, 291, 304, 318, 331, - 345, 359, 374, 388, 403, 418, 433, 449, - 465, 481, 497, 514, 531, 548, 565, 582, - 600, 618, 636, 654, 673, 691, 710, 729, - 749, 768, 788, 808, 828, 848, 869, 889, - 910, 931, 952, 974, 995, 1017, 1039, 1060, - 1083, 1105, 1127, 1150, 1172, 1195, 1218, 1241, - 1264, 1288, 1311, 1334, 1358, 1382, 1406, 1429, - 1453, 1478, 1502, 1526, 1550, 1575, 1599, 1624, - 1648, 1673, 1698, 1723, 1747, 1772, 1797, 1822, - 1847, 1872, 1897, 1922, 1948, 1973, 1998, 2023 ] + 156, 166, 176, 186, 197, 208, 219, 230, + 242, 254, 266, 279, 291, 304, 318, 331, + 345, 359, 374, 388, 403, 418, 433, 449, + 465, 481, 497, 514, 531, 548, 565, 582, + 600, 618, 636, 654, 673, 691, 710, 729, + 749, 768, 788, 808, 828, 848, 869, 889, + 910, 931, 952, 974, 995, 1017, 1039, 1060, + 1083, 1105, 1127, 1150, 1172, 1195, 1218, 1241, + 1264, 1288, 1311, 1334, 1358, 1382, 1406, 1429, + 1453, 1478, 1502, 1526, 1550, 1575, 1599, 1624, + 1648, 1673, 1698, 1723, 1747, 1772, 1797, 1822, + 1847, 1872, 1897, 1922, 1948, 1973, 1998, 2023 ] # 8-bit Lookup Table (256 values) -DACLookup_FullSine_8Bit = \ -[ 2048, 2098, 2148, 2198, 2248, 2298, 2348, 2398, - 2447, 2496, 2545, 2594, 2642, 2690, 2737, 2784, - 2831, 2877, 2923, 2968, 3013, 3057, 3100, 3143, - 3185, 3226, 3267, 3307, 3346, 3385, 3423, 3459, - 3495, 3530, 3565, 3598, 3630, 3662, 3692, 3722, - 3750, 3777, 3804, 3829, 3853, 3876, 3898, 3919, - 3939, 3958, 3975, 3992, 4007, 4021, 4034, 4045, - 4056, 4065, 4073, 4080, 4085, 4089, 4093, 4094, - 4095, 4094, 4093, 4089, 4085, 4080, 4073, 4065, - 4056, 4045, 4034, 4021, 4007, 3992, 3975, 3958, - 3939, 3919, 3898, 3876, 3853, 3829, 3804, 3777, - 3750, 3722, 3692, 3662, 3630, 3598, 3565, 3530, - 3495, 3459, 3423, 3385, 3346, 3307, 3267, 3226, - 3185, 3143, 3100, 3057, 3013, 2968, 2923, 2877, - 2831, 2784, 2737, 2690, 2642, 2594, 2545, 2496, - 2447, 2398, 2348, 2298, 2248, 2198, 2148, 2098, - 2048, 1997, 1947, 1897, 1847, 1797, 1747, 1697, - 1648, 1599, 1550, 1501, 1453, 1405, 1358, 1311, - 1264, 1218, 1172, 1127, 1082, 1038, 995, 952, - 910, 869, 828, 788, 749, 710, 672, 636, - 600, 565, 530, 497, 465, 433, 403, 373, - 345, 318, 291, 266, 242, 219, 197, 176, - 156, 137, 120, 103, 88, 74, 61, 50, +DACLookup_FullSine_8Bit = [ + 2048, 2098, 2148, 2198, 2248, 2298, 2348, 2398, + 2447, 2496, 2545, 2594, 2642, 2690, 2737, 2784, + 2831, 2877, 2923, 2968, 3013, 3057, 3100, 3143, + 3185, 3226, 3267, 3307, 3346, 3385, 3423, 3459, + 3495, 3530, 3565, 3598, 3630, 3662, 3692, 3722, + 3750, 3777, 3804, 3829, 3853, 3876, 3898, 3919, + 3939, 3958, 3975, 3992, 4007, 4021, 4034, 4045, + 4056, 4065, 4073, 4080, 4085, 4089, 4093, 4094, + 4095, 4094, 4093, 4089, 4085, 4080, 4073, 4065, + 4056, 4045, 4034, 4021, 4007, 3992, 3975, 3958, + 3939, 3919, 3898, 3876, 3853, 3829, 3804, 3777, + 3750, 3722, 3692, 3662, 3630, 3598, 3565, 3530, + 3495, 3459, 3423, 3385, 3346, 3307, 3267, 3226, + 3185, 3143, 3100, 3057, 3013, 2968, 2923, 2877, + 2831, 2784, 2737, 2690, 2642, 2594, 2545, 2496, + 2447, 2398, 2348, 2298, 2248, 2198, 2148, 2098, + 2048, 1997, 1947, 1897, 1847, 1797, 1747, 1697, + 1648, 1599, 1550, 1501, 1453, 1405, 1358, 1311, + 1264, 1218, 1172, 1127, 1082, 1038, 995, 952, + 910, 869, 828, 788, 749, 710, 672, 636, + 600, 565, 530, 497, 465, 433, 403, 373, + 345, 318, 291, 266, 242, 219, 197, 176, + 156, 137, 120, 103, 88, 74, 61, 50, 39, 30, 22, 15, 10, 6, 2, 1, - 0, 1, 2, 6, 10, 15, 22, 30, + 0, 1, 2, 6, 10, 15, 22, 30, 39, 50, 61, 74, 88, 103, 120, 137, - 156, 176, 197, 219, 242, 266, 291, 318, - 345, 373, 403, 433, 465, 497, 530, 565, - 600, 636, 672, 710, 749, 788, 828, 869, - 910, 952, 995, 1038, 1082, 1127, 1172, 1218, - 1264, 1311, 1358, 1405, 1453, 1501, 1550, 1599, - 1648, 1697, 1747, 1797, 1847, 1897, 1947, 1997 ] + 156, 176, 197, 219, 242, 266, 291, 318, + 345, 373, 403, 433, 465, 497, 530, 565, + 600, 636, 672, 710, 749, 788, 828, 869, + 910, 952, 995, 1038, 1082, 1127, 1172, 1218, + 1264, 1311, 1358, 1405, 1453, 1501, 1550, 1599, + 1648, 1697, 1747, 1797, 1847, 1897, 1947, 1997 ] # 7-bit Lookup Table (128 values) -DACLookup_FullSine_7Bit = \ -[ 2048, 2148, 2248, 2348, 2447, 2545, 2642, 2737, - 2831, 2923, 3013, 3100, 3185, 3267, 3346, 3423, - 3495, 3565, 3630, 3692, 3750, 3804, 3853, 3898, - 3939, 3975, 4007, 4034, 4056, 4073, 4085, 4093, - 4095, 4093, 4085, 4073, 4056, 4034, 4007, 3975, - 3939, 3898, 3853, 3804, 3750, 3692, 3630, 3565, - 3495, 3423, 3346, 3267, 3185, 3100, 3013, 2923, - 2831, 2737, 2642, 2545, 2447, 2348, 2248, 2148, - 2048, 1947, 1847, 1747, 1648, 1550, 1453, 1358, - 1264, 1172, 1082, 995, 910, 828, 749, 672, - 600, 530, 465, 403, 345, 291, 242, 197, - 156, 120, 88, 61, 39, 22, 10, 2, - 0, 2, 10, 22, 39, 61, 88, 120, - 156, 197, 242, 291, 345, 403, 465, 530, - 600, 672, 749, 828, 910, 995, 1082, 1172, - 1264, 1358, 1453, 1550, 1648, 1747, 1847, 1947 ] +DACLookup_FullSine_7Bit = [ + 2048, 2148, 2248, 2348, 2447, 2545, 2642, 2737, + 2831, 2923, 3013, 3100, 3185, 3267, 3346, 3423, + 3495, 3565, 3630, 3692, 3750, 3804, 3853, 3898, + 3939, 3975, 4007, 4034, 4056, 4073, 4085, 4093, + 4095, 4093, 4085, 4073, 4056, 4034, 4007, 3975, + 3939, 3898, 3853, 3804, 3750, 3692, 3630, 3565, + 3495, 3423, 3346, 3267, 3185, 3100, 3013, 2923, + 2831, 2737, 2642, 2545, 2447, 2348, 2248, 2148, + 2048, 1947, 1847, 1747, 1648, 1550, 1453, 1358, + 1264, 1172, 1082, 995, 910, 828, 749, 672, + 600, 530, 465, 403, 345, 291, 242, 197, + 156, 120, 88, 61, 39, 22, 10, 2, + 0, 2, 10, 22, 39, 61, 88, 120, + 156, 197, 242, 291, 345, 403, 465, 530, + 600, 672, 749, 828, 910, 995, 1082, 1172, + 1264, 1358, 1453, 1550, 1648, 1747, 1847, 1947 ] # 6-bit Lookup Table (64 values) -DACLookup_FullSine_6Bit = \ -[ 2048, 2248, 2447, 2642, 2831, 3013, 3185, 3346, - 3495, 3630, 3750, 3853, 3939, 4007, 4056, 4085, - 4095, 4085, 4056, 4007, 3939, 3853, 3750, 3630, - 3495, 3346, 3185, 3013, 2831, 2642, 2447, 2248, - 2048, 1847, 1648, 1453, 1264, 1082, 910, 749, - 600, 465, 345, 242, 156, 88, 39, 10, - 0, 10, 39, 88, 156, 242, 345, 465, - 600, 749, 910, 1082, 1264, 1453, 1648, 1847 ] +DACLookup_FullSine_6Bit = [ + 2048, 2248, 2447, 2642, 2831, 3013, 3185, 3346, + 3495, 3630, 3750, 3853, 3939, 4007, 4056, 4085, + 4095, 4085, 4056, 4007, 3939, 3853, 3750, 3630, + 3495, 3346, 3185, 3013, 2831, 2642, 2447, 2248, + 2048, 1847, 1648, 1453, 1264, 1082, 910, 749, + 600, 465, 345, 242, 156, 88, 39, 10, + 0, 10, 39, 88, 156, 242, 345, 465, + 600, 749, 910, 1082, 1264, 1453, 1648, 1847 ] # 5-bit Lookup Table (32 values) -DACLookup_FullSine_5Bit = \ -[ 2048, 2447, 2831, 3185, 3495, 3750, 3939, 4056, - 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447, - 2048, 1648, 1264, 910, 600, 345, 156, 39, - 0, 39, 156, 345, 600, 910, 1264, 1648 ] +DACLookup_FullSine_5Bit = [ + 2048, 2447, 2831, 3185, 3495, 3750, 3939, 4056, + 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447, + 2048, 1648, 1264, 910, 600, 345, 156, 39, + 0, 39, 156, 345, 600, 910, 1264, 1648 ] # Initialise the DAC using the default address dac = MCP4725(0x62) if (DAC_RESOLUTION < 5) | (DAC_RESOLUTION > 9): - print "Invalid DAC resolution: Set DAC_RESOLUTION from 5..9" + print "Invalid DAC resolution: Set DAC_RESOLUTION from 5..9" else: - print "Generating a sine wave with %d-bit resolution" % DAC_RESOLUTION - print "Press CTRL+C to stop" - while(True): - if (DAC_RESOLUTION == 9): - for val in DACLookup_FullSine_9Bit: - dac.setVoltage(val) - if (DAC_RESOLUTION == 8): - for val in DACLookup_FullSine_8Bit: - dac.setVoltage(val) - if (DAC_RESOLUTION == 7): - for val in DACLookup_FullSine_7Bit: - dac.setVoltage(val) - if (DAC_RESOLUTION == 6): - for val in DACLookup_FullSine_6Bit: - dac.setVoltage(val) - if (DAC_RESOLUTION == 5): - for val in DACLookup_FullSine_5Bit: - dac.setVoltage(val) + print "Generating a sine wave with %d-bit resolution" % DAC_RESOLUTION + print "Press CTRL+C to stop" + while(True): + if (DAC_RESOLUTION == 9): + for val in DACLookup_FullSine_9Bit: + dac.setVoltage(val) + if (DAC_RESOLUTION == 8): + for val in DACLookup_FullSine_8Bit: + dac.setVoltage(val) + if (DAC_RESOLUTION == 7): + for val in DACLookup_FullSine_7Bit: + dac.setVoltage(val) + if (DAC_RESOLUTION == 6): + for val in DACLookup_FullSine_6Bit: + dac.setVoltage(val) + if (DAC_RESOLUTION == 5): + for val in DACLookup_FullSine_5Bit: + dac.setVoltage(val) diff --git a/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py b/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py index 35c993ca..e055f32b 100644 --- a/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py +++ b/Adafruit_PWM_Servo_Driver/Adafruit_PWM_Servo_Driver.py @@ -9,84 +9,84 @@ # ============================================================================ class PWM : - # Registers/etc. - __MODE1 = 0x00 - __MODE2 = 0x01 - __SUBADR1 = 0x02 - __SUBADR2 = 0x03 - __SUBADR3 = 0x04 - __PRESCALE = 0xFE - __LED0_ON_L = 0x06 - __LED0_ON_H = 0x07 - __LED0_OFF_L = 0x08 - __LED0_OFF_H = 0x09 - __ALL_LED_ON_L = 0xFA - __ALL_LED_ON_H = 0xFB - __ALL_LED_OFF_L = 0xFC - __ALL_LED_OFF_H = 0xFD + # Registers/etc. + __MODE1 = 0x00 + __MODE2 = 0x01 + __SUBADR1 = 0x02 + __SUBADR2 = 0x03 + __SUBADR3 = 0x04 + __PRESCALE = 0xFE + __LED0_ON_L = 0x06 + __LED0_ON_H = 0x07 + __LED0_OFF_L = 0x08 + __LED0_OFF_H = 0x09 + __ALL_LED_ON_L = 0xFA + __ALL_LED_ON_H = 0xFB + __ALL_LED_OFF_L = 0xFC + __ALL_LED_OFF_H = 0xFD - # Bits - __RESTART = 0x80 - __SLEEP = 0x10 - __ALLCALL = 0x01 - __INVRT = 0x10 - __OUTDRV = 0x04 + # Bits + __RESTART = 0x80 + __SLEEP = 0x10 + __ALLCALL = 0x01 + __INVRT = 0x10 + __OUTDRV = 0x04 - general_call_i2c = Adafruit_I2C(0x00) + general_call_i2c = Adafruit_I2C(0x00) - @classmethod - def softwareReset(cls): - "Sends a software reset (SWRST) command to all the servo drivers on the bus" - cls.general_call_i2c.writeRaw8(0x06) # SWRST + @classmethod + def softwareReset(cls): + "Sends a software reset (SWRST) command to all the servo drivers on the bus" + cls.general_call_i2c.writeRaw8(0x06) # SWRST - def __init__(self, address=0x40, debug=False): - self.i2c = Adafruit_I2C(address) - self.i2c.debug = debug - self.address = address - self.debug = debug - if (self.debug): - print "Reseting PCA9685 MODE1 (without SLEEP) and MODE2" - self.setAllPWM(0, 0) - self.i2c.write8(self.__MODE2, self.__OUTDRV) - self.i2c.write8(self.__MODE1, self.__ALLCALL) - time.sleep(0.005) # wait for oscillator - - mode1 = self.i2c.readU8(self.__MODE1) - mode1 = mode1 & ~self.__SLEEP # wake up (reset sleep) - self.i2c.write8(self.__MODE1, mode1) - time.sleep(0.005) # wait for oscillator + def __init__(self, address=0x40, debug=False): + self.i2c = Adafruit_I2C(address) + self.i2c.debug = debug + self.address = address + self.debug = debug + if (self.debug): + print "Reseting PCA9685 MODE1 (without SLEEP) and MODE2" + self.setAllPWM(0, 0) + self.i2c.write8(self.__MODE2, self.__OUTDRV) + self.i2c.write8(self.__MODE1, self.__ALLCALL) + time.sleep(0.005) # wait for oscillator + + mode1 = self.i2c.readU8(self.__MODE1) + mode1 = mode1 & ~self.__SLEEP # wake up (reset sleep) + self.i2c.write8(self.__MODE1, mode1) + time.sleep(0.005) # wait for oscillator - def setPWMFreq(self, freq): - "Sets the PWM frequency" - prescaleval = 25000000.0 # 25MHz - prescaleval /= 4096.0 # 12-bit - prescaleval /= float(freq) - prescaleval -= 1.0 - if (self.debug): - print "Setting PWM frequency to %d Hz" % freq - print "Estimated pre-scale: %d" % prescaleval - prescale = math.floor(prescaleval + 0.5) - if (self.debug): - print "Final pre-scale: %d" % prescale + def setPWMFreq(self, freq): + "Sets the PWM frequency" + prescaleval = 25000000.0 # 25MHz + prescaleval /= 4096.0 # 12-bit + prescaleval /= float(freq) + prescaleval -= 1.0 + if (self.debug): + print "Setting PWM frequency to %d Hz" % freq + print "Estimated pre-scale: %d" % prescaleval + prescale = math.floor(prescaleval + 0.5) + if (self.debug): + print "Final pre-scale: %d" % prescale - oldmode = self.i2c.readU8(self.__MODE1); - newmode = (oldmode & 0x7F) | 0x10 # sleep - self.i2c.write8(self.__MODE1, newmode) # go to sleep - self.i2c.write8(self.__PRESCALE, int(math.floor(prescale))) - self.i2c.write8(self.__MODE1, oldmode) - time.sleep(0.005) - self.i2c.write8(self.__MODE1, oldmode | 0x80) + oldmode = self.i2c.readU8(self.__MODE1); + newmode = (oldmode & 0x7F) | 0x10 # sleep + self.i2c.write8(self.__MODE1, newmode) # go to sleep + self.i2c.write8(self.__PRESCALE, int(math.floor(prescale))) + self.i2c.write8(self.__MODE1, oldmode) + time.sleep(0.005) + self.i2c.write8(self.__MODE1, oldmode | 0x80) - def setPWM(self, channel, on, off): - "Sets a single PWM channel" - self.i2c.write8(self.__LED0_ON_L+4*channel, on & 0xFF) - self.i2c.write8(self.__LED0_ON_H+4*channel, on >> 8) - self.i2c.write8(self.__LED0_OFF_L+4*channel, off & 0xFF) - self.i2c.write8(self.__LED0_OFF_H+4*channel, off >> 8) + def setPWM(self, channel, on, off): + "Sets a single PWM channel" + self.i2c.write8(self.__LED0_ON_L+4*channel, on & 0xFF) + self.i2c.write8(self.__LED0_ON_H+4*channel, on >> 8) + self.i2c.write8(self.__LED0_OFF_L+4*channel, off & 0xFF) + self.i2c.write8(self.__LED0_OFF_H+4*channel, off >> 8) - def setAllPWM(self, on, off): - "Sets a all PWM channels" - self.i2c.write8(self.__ALL_LED_ON_L, on & 0xFF) - self.i2c.write8(self.__ALL_LED_ON_H, on >> 8) - self.i2c.write8(self.__ALL_LED_OFF_L, off & 0xFF) - self.i2c.write8(self.__ALL_LED_OFF_H, off >> 8) + def setAllPWM(self, on, off): + "Sets a all PWM channels" + self.i2c.write8(self.__ALL_LED_ON_L, on & 0xFF) + self.i2c.write8(self.__ALL_LED_ON_H, on >> 8) + self.i2c.write8(self.__ALL_LED_OFF_L, off & 0xFF) + self.i2c.write8(self.__ALL_LED_OFF_H, off >> 8) diff --git a/Adafruit_PWM_Servo_Driver/Servo_Example.py b/Adafruit_PWM_Servo_Driver/Servo_Example.py index 66a0d7fa..0e7baa4a 100644 --- a/Adafruit_PWM_Servo_Driver/Servo_Example.py +++ b/Adafruit_PWM_Servo_Driver/Servo_Example.py @@ -16,22 +16,19 @@ servoMax = 600 # Max pulse length out of 4096 def setServoPulse(channel, pulse): - pulseLength = 1000000 # 1,000,000 us per second - pulseLength /= 60 # 60 Hz - print "%d us per period" % pulseLength - pulseLength /= 4096 # 12 bits of resolution - print "%d us per bit" % pulseLength - pulse *= 1000 - pulse /= pulseLength - pwm.setPWM(channel, 0, pulse) + pulseLength = 1000000 # 1,000,000 us per second + pulseLength /= 60 # 60 Hz + print "%d us per period" % pulseLength + pulseLength /= 4096 # 12 bits of resolution + print "%d us per bit" % pulseLength + pulse *= 1000 + pulse /= pulseLength + pwm.setPWM(channel, 0, pulse) pwm.setPWMFreq(60) # Set frequency to 60 Hz while (True): - # Change speed of continuous servo on channel O - pwm.setPWM(0, 0, servoMin) - time.sleep(1) - pwm.setPWM(0, 0, servoMax) - time.sleep(1) - - - + # Change speed of continuous servo on channel O + pwm.setPWM(0, 0, servoMin) + time.sleep(1) + pwm.setPWM(0, 0, servoMax) + time.sleep(1) diff --git a/Adafruit_TCS34725/Adafruit_I2C.py b/Adafruit_TCS34725/Adafruit_I2C.py index 3423461d..fd1f058c 100644 --- a/Adafruit_TCS34725/Adafruit_I2C.py +++ b/Adafruit_TCS34725/Adafruit_I2C.py @@ -8,163 +8,163 @@ class Adafruit_I2C : - @staticmethod - def getPiRevision(): - "Gets the version number of the Raspberry Pi board" - # Courtesy quick2wire-python-api - # https://github.com/quick2wire/quick2wire-python-api - try: - with open('/proc/cpuinfo','r') as f: - for line in f: - if line.startswith('Revision'): - return 1 if line.rstrip()[-1] in ['1','2'] else 2 - except: - return 0 - - @staticmethod - def getPiI2CBusNumber(): - # Gets the I2C bus number /dev/i2c# - return 1 if Adafruit_I2C.getPiRevision() > 1 else 0 + @staticmethod + def getPiRevision(): + "Gets the version number of the Raspberry Pi board" + # Courtesy quick2wire-python-api + # https://github.com/quick2wire/quick2wire-python-api + try: + with open('/proc/cpuinfo','r') as f: + for line in f: + if line.startswith('Revision'): + return 1 if line.rstrip()[-1] in ['1','2'] else 2 + 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, 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, 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, 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, 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, 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, err: - return self.errMsg() - - def readU16(self, reg): - "Reads an unsigned 16-bit value from the I2C device" - try: - hibyte = self.readU8(reg) - lobyte = self.readU8(reg+1) - result = (hibyte << 8) + lobyte - if (self.debug): - print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) - return result - except IOError, err: - return self.errMsg() - - def readS16(self, reg): - "Reads a signed 16-bit value from the I2C device" - try: - hibyte = self.readS8(reg) - lobyte = self.readU8(reg+1) - result = (hibyte << 8) + lobyte - if (self.debug): - print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) - return result - except IOError, err: - return self.errMsg() - - def readU16Rev(self, reg): - "Reads an unsigned 16-bit value from the I2C device with rev byte order" - try: - lobyte = self.readU8(reg) - hibyte = self.readU8(reg+1) - result = (hibyte << 8) + lobyte - if (self.debug): - print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) - return result - except IOError, err: - return self.errMsg() - - def readS16Rev(self, reg): - "Reads a signed 16-bit value from the I2C device with rev byte order" - try: - lobyte = self.readS8(reg) - hibyte = self.readU8(reg+1) - result = (hibyte << 8) + lobyte - if (self.debug): - print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) - return result - except IOError, err: - return self.errMsg() + 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, 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, 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, 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, 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, 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, err: + return self.errMsg() + + def readU16(self, reg): + "Reads an unsigned 16-bit value from the I2C device" + try: + hibyte = self.readU8(reg) + lobyte = self.readU8(reg+1) + result = (hibyte << 8) + lobyte + if (self.debug): + print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) + return result + except IOError, err: + return self.errMsg() + + def readS16(self, reg): + "Reads a signed 16-bit value from the I2C device" + try: + hibyte = self.readS8(reg) + lobyte = self.readU8(reg+1) + result = (hibyte << 8) + lobyte + if (self.debug): + print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) + return result + except IOError, err: + return self.errMsg() + + def readU16Rev(self, reg): + "Reads an unsigned 16-bit value from the I2C device with rev byte order" + try: + lobyte = self.readU8(reg) + hibyte = self.readU8(reg+1) + result = (hibyte << 8) + lobyte + if (self.debug): + print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) + return result + except IOError, err: + return self.errMsg() + + def readS16Rev(self, reg): + "Reads a signed 16-bit value from the I2C device with rev byte order" + try: + lobyte = self.readS8(reg) + hibyte = self.readU8(reg+1) + result = (hibyte << 8) + lobyte + if (self.debug): + print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg) + return result + except IOError, 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" + try: + bus = Adafruit_I2C(address=0) + print "Default I2C bus is accessible" + except: + print "Error accessing default I2C bus" diff --git a/Adafruit_VCNL4000/Adafruit_VCNL4000.py b/Adafruit_VCNL4000/Adafruit_VCNL4000.py index 4d307536..2c764490 100755 --- a/Adafruit_VCNL4000/Adafruit_VCNL4000.py +++ b/Adafruit_VCNL4000/Adafruit_VCNL4000.py @@ -31,31 +31,31 @@ VCNL4000_PROXIMITYREADY = 0x20 class VCNL4000 : - i2c = None - - # Constructor - def __init__(self, address=0x13): - self.i2c = Adafruit_I2C(address) - - self.address = address - - # Write proximity adjustement register - self.i2c.write8(VCNL4000_PROXINITYADJUST, 0x81); - - # Read data from proximity sensor - def read_proximity(self): - self.i2c.write8(VCNL4000_COMMAND, VCNL4000_MEASUREPROXIMITY) - while True: - result = self.i2c.readU8(VCNL4000_COMMAND) - if (result and VCNL4000_PROXIMITYREADY): - return self.i2c.readU16(VCNL4000_PROXIMITYDATA) - time.sleep(0.001) - - # Read data from ambient sensor - def read_ambient(self): - self.i2c.write8(VCNL4000_COMMAND, VCNL4000_MEASUREAMBIENT) - while True: - result = self.i2c.readU8(VCNL4000_COMMAND) - if (result and VCNL4000_AMBIENTREADY): - return self.i2c.readU16(VCNL4000_AMBIENTDATA) - time.sleep(0.001) + i2c = None + + # Constructor + def __init__(self, address=0x13): + self.i2c = Adafruit_I2C(address) + + self.address = address + + # Write proximity adjustement register + self.i2c.write8(VCNL4000_PROXINITYADJUST, 0x81); + + # Read data from proximity sensor + def read_proximity(self): + self.i2c.write8(VCNL4000_COMMAND, VCNL4000_MEASUREPROXIMITY) + while True: + result = self.i2c.readU8(VCNL4000_COMMAND) + if (result and VCNL4000_PROXIMITYREADY): + return self.i2c.readU16(VCNL4000_PROXIMITYDATA) + time.sleep(0.001) + + # Read data from ambient sensor + def read_ambient(self): + self.i2c.write8(VCNL4000_COMMAND, VCNL4000_MEASUREAMBIENT) + while True: + result = self.i2c.readU8(VCNL4000_COMMAND) + if (result and VCNL4000_AMBIENTREADY): + return self.i2c.readU16(VCNL4000_AMBIENTDATA) + time.sleep(0.001) diff --git a/Adafruit_VCNL4000/Adafruit_VCNL4000_example.py b/Adafruit_VCNL4000/Adafruit_VCNL4000_example.py index 36baa422..028434a0 100755 --- a/Adafruit_VCNL4000/Adafruit_VCNL4000_example.py +++ b/Adafruit_VCNL4000/Adafruit_VCNL4000_example.py @@ -12,6 +12,6 @@ # Print proximity sensor data every 100 ms while True: - - print "Data from proximity sensor", vcnl.read_proximity() - time.sleep(0.1) + + print "Data from proximity sensor", vcnl.read_proximity() + time.sleep(0.1)