Source code for qwiic_tmp102

"""
qwiic_tmp102
============
Python module for the [SparkFun Qwiic TMP102 Sensor](https://www.sparkfun.com/products/16304)

This python package is a port of the existing [SparkFun Qwiic TMP102 Sensor Arduino Examples](https://github.com/sparkfun/SparkFun_TMP102_Arduino_Library/tree/master/examples)

This package can be used in conjunction with the overall [SparkFun qwiic Python Package](https://github.com/sparkfun/Qwiic_Py)

New to qwiic? Take a look at the entire [SparkFun qwiic ecosystem](https://www.sparkfun.com/qwiic).

"""
from __future__ import print_function, division

import qwiic_i2c

#======================================================================
# Basic setup of I2C commands and available I2C Addresses
#
#
# The name of this device - note this is private
_DEFAULT_NAME = "Qwiic TMP102 Sensor"

# Command addresses. These can be found on page 23 of the datasheet
TEMPERATURE_REGISTER = 0x00
CONFIG_REGISTER = 0x01
T_LOW_REGISTER = 0x02
T_HIGH_REGISTER = 0x03
TMP102_DEFAULT_ADDRESS = 0x48


TMP102_RESOLUTION = 0.0625                   # Resolution of the device, found on (page 1 of datasheet)

#Address can only be 0x48 (GND), 
#	0x49 (V+), 0x4A (SDA), and 0x4B (SCL)
_AVAILABLE_I2C_ADDRESS = [0x48, 0x49, 0x4A, 0x4B]

###############################################################################
###############################################################################
# Some devices have multiple available addresses - this is a list of these addresses.
# NOTE: The first address in this list is considered the default I2C address for the
# device.
[docs]class QwiicTmp102Sensor(object): """ QwiicTmp102Sensor :param address: The I2C address to use for the device. If not provided, the default address is used. :param i2c_driver: An existing i2c driver object. If not provided a driver object is created. :return: The TMP102 Sensor device object. :rtype: Object """ device_name = _DEFAULT_NAME available_addresses = _AVAILABLE_I2C_ADDRESS # Constructor def __init__(self, address=None, i2c_driver=None): # Did the user specify an I2C address? self.address = self.available_addresses[0] if address is None else address # load the I2C driver if one isn't provided if i2c_driver is None: self._i2c = qwiic_i2c.getI2CDriver() if self._i2c is None: print("Unable to load I2C driver for this platform.") return else: self._i2c = i2c_driver # ---------------------------------- # is_connected() # # Is an actual board connected to our system?
[docs] def is_connected(self): """ Determine if a Soil MoistureSensor device is conntected to the system.. :return: True if the device is connected, otherwise False. :rtype: bool """ return qwiic_i2c.isDeviceConnected(self.address)
connected = property(is_connected) # ---------------------------------- # begin() # # Initialize the system/validate the board.
[docs] def begin(self): """ Initialize the operation of the Soil Moisture Sensor module :return: Returns true of the initialization was successful, otherwise False. :rtype: bool """ # Set variables self.tempC = 0 self.tempF = 0 # Basically return True if we are connected... return self.is_connected()
#****************************************************************************# # # Sensor functions # # ****************************************************************************#
[docs] def get_address(self): """ Returns the device address """ return self.address
[docs] def read_temp_c(self): """ Reads the results from the sensor :rtype: integer """ data = self._i2c.readBlock(self.address, TEMPERATURE_REGISTER, 2) if (data[0] == 0xFF and data[1] == 0xFF): return NaN if(data[1]&0x01): # 13 bit mode baseRead = ((data[0]) << 5) | (data[1] >> 3) if(baseRead > 0xFFF): baseRead |= 0xE000 else: #Combine bytes to create a signed int baseRead = ((data[0]) << 4) | (data[1] >> 4) #Temperature data can be + or -, if it should be negative, #convert 12 bit to 16 bit and use the 2s compliment. if(baseRead > 0x7FF): baseRead |= 0xF000 self.tempC = baseRead * 0.0625 return self.tempC
[docs] def read_temp_f(self): """ Reads the results from the sensor :rtype: integer """ self.tempF = self.read_temp_c() * 9.0 / 5.0 + 32.0 return self.tempF
[docs] def set_conversion_rate(self, rate): """ // Set the conversion rate (0-3) // 0 - 0.25 Hz // 1 - 1 Hz // 2 - 4 Hz (default) // 3 - 8 Hz """ configByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) rate = rate&0x03 # Load new conversion rate configByte[1] &= 0x3F # Clear CR0/1 (bit 6 and 7 of second byte) configByte[1] |= rate<<6 # Shift in new conversion rate self._i2c.writeBlock(self.address, CONFIG_REGISTER, configByte)
[docs] def set_extended_mode(self, mode): """ Enable or disable extended mode 0 - disabled (-55C to +128C) 1 - enabled (-55C to +150C) """ configByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) # Load new value for extention mode configByte[1] &= 0xEF # Clear EM (bit 4 of second byte) configByte[1] |= mode<<4 # Shift in new exentended mode bit self._i2c.writeBlock(self.address, CONFIG_REGISTER, configByte)
[docs] def sleep(self): """ Switch sensor to low power mode """ sleepValue = self._i2c.readByte(self.address, CONFIG_REGISTER) sleepValue |= 0x01 # Set SD (bit 0 of first byte) self._i2c.writeByte(self.address, CONFIG_REGISTER, sleepValue)
[docs] def wakeup(self): """ Wakeup and start running in normal power mode """ wakeValue = self._i2c.readByte(self.address, CONFIG_REGISTER) wakeValue &= 0xFE # Clear SD (bit 0 of first byte) self._i2c.writeByte(self.address, CONFIG_REGISTER, wakeValue)
[docs] def set_alert_polarity(self, polarity): """ Set the polarity of Alert 0 - Active LOW 1 - Active HIGH """ configByte = self._i2c.readByte(self.address, CONFIG_REGISTER) # Load new value for polarity configByte &= 0xFB # Clear POL (bit 2 of registerByte) configByte |= polarity<<2 # Shift in new POL bit self._i2c.writeByte(self.address, CONFIG_REGISTER, configByte)
[docs] def alert(self): """ Returns state of Alert register """ alert = self._i2c.readByte(self.address, CONFIG_REGISTER) alert &= 0x20 #Clear everything but the alert bit (bit 5) return alert>>5
[docs] def one_shot(self, setOneShot = 0): """ Sets the SingleShot Register. Returns 1 after the conversion is complete """ registerByte = self._i2c.readByte(self.address, CONFIG_REGISTER) if(setOneShot == 1): registerByte |= (1<<7) self._i2c.writeByte(self.address, CONFIG_REGISTER, registerByte) return 0 else: registerByte &= (1<<7) return (registerByte>>7)
[docs] def set_low_temp_c(self, temperature): """ Sets T_LOW (degrees C) alert threshold """ if(temperature > 150.0): temperature = 150.0 if(temperature < -55.0): temperature = -55.0 registerByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) #Check if temperature should be 12 or 13 bits # 0 - temp data will be 12 bits # 1 - temp data will be 13 bits extendedMode = (registerByte[1]&0x10) >> 4 #Convert analog temperature to digital value temperature = temperature/0.0625 if(extendedMode): #13-bit mode registerByte[0] = int(temperature)>>5 registerByte[1] = (int(temperature)<<3) else: registerByte[0] = int(temperature)>>4 registerByte[1] = int(temperature)<<4 self._i2c.writeBlock(self.address, T_LOW_REGISTER, registerByte)
[docs] def set_high_temp_c(self, temperature): """ Sets T_LOW (degrees C) alert threshold """ if(temperature > 150.0): temperature = 150.0 if(temperature < -55.0): temperature = -55.0 registerByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) #Check if temperature should be 12 or 13 bits # 0 - temp data will be 12 bits # 1 - temp data will be 13 bits extendedMode = (registerByte[1]&0x10) >> 4 #Convert analog temperature to digital value temperature = temperature/0.0625 if(extendedMode): #13-bit mode registerByte[0] = int(temperature)>>5 registerByte[1] = (int(temperature)<<3) else: registerByte[0] = int(temperature)>>4 registerByte[1] = int(temperature)<<4 self._i2c.writeBlock(self.address, T_HIGH_REGISTER, registerByte)
[docs] def set_low_temp_f(self, temperature): """ Sets T_LOW (degrees F) alert threshold """ new_temp = (temperature - 32)*5/9 # Convert temperature to C self.set_low_temp_c(new_temp) # Set T_LOW
[docs] def set_high_temp_f(self, temperature): """ Sets T_HIGH (degrees F) alert threshold """ new_temp = (temperature - 32)*5/9 # Convert temperature to C self.set_high_temp_c(new_temp) # Set T_HIGH
[docs] def read_low_temp_c(self): """ Gets T_LOW (degrees C) alert threshold """ configByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) # 0 - temp data will be 12 bits # 1 - temp data will be 13 bits extendedMode = (configByte[1]&0x10)>>4 lowTempByte = self._i2c.readBlock(self.address, T_LOW_REGISTER, 2) if(lowTempByte[0] == 0xFF and lowTempByte[1] == 0xFF): return NAN if (extendedMode): digitalTemp = ((lowTempByte[0]) << 5) | (lowTempByte[1] >> 3) if(digitalTemp > 0xFFF): digitalTemp |= 0xE000 else: digitalTemp = ((lowTempByte[0]) << 4) | (lowTempByte[1] >> 4) if(digitalTemp > 0x7FF): digitalTemp |= 0xF000 return digitalTemp*0.0625
[docs] def read_high_temp_c(self): """ Gets T_HIGH (degrees C) alert threshold """ configByte = self._i2c.readBlock(self.address, CONFIG_REGISTER, 2) # 0 - temp data will be 12 bits # 1 - temp data will be 13 bits extendedMode = (configByte[1]&0x10)>>4 highTempByte = self._i2c.readBlock(self.address, T_HIGH_REGISTER, 2) if(highTempByte[0] == 0xFF and highTempByte[1] == 0xFF): return NAN if (extendedMode): digitalTemp = ((highTempByte[0]) << 5) | (highTempByte[1] >> 3) if(digitalTemp > 0xFFF): digitalTemp |= 0xE000 else: digitalTemp = ((highTempByte[0]) << 4) | (highTempByte[1] >> 4) if(digitalTemp > 0x7FF): digitalTemp |= 0xF000 return digitalTemp*0.0625
[docs] def read_low_temp_f(self): """ Reads T_LOW register in F """ return self.read_low_temp_c()*9.0/5.0 + 32.0
[docs] def read_high_temp_f(self): """ Reads T_HIGH register in F """ return self.read_high_temp_c()*9.0/5.0 + 32.0
[docs] def set_fault(self, faultSetting): """ Set the number of consecutive faults 0 - 1 fault 1 - 2 faults 2 - 4 faults 3 - 6 faults """ faultSetting = faultSetting&3 #Make sure rate is not set higher than 3. configByte = self._i2c.readByte(self.address, CONFIG_REGISTER) #Load new conversion rate configByte &= 0xE7 # Clear F0/1 (bit 3 and 4 of first byte) configByte |= faultSetting<<3 # Shift new fault setting self._i2c.writeByte(self.address, CONFIG_REGISTER, configByte)
[docs] def set_alert_mode(self, mode): """ // Set Alert type // 0 - Comparator Mode: Active from temp > T_HIGH until temp < T_LOW // 1 - Thermostat Mode: Active when temp > T_HIGH until any read operation occurs """ configByte = self._i2c.readByte(self.address, CONFIG_REGISTER) #Load new conversion rate configByte &= 0xFD # Clear old TM bit (bit 1 of first byte) configByte |= mode<<1 # Shift in new TM bit self._i2c.writeByte(self.address, CONFIG_REGISTER, configByte)