nodepower/bin/tmp102.py
b98e8b95
 #!/usr/bin/python2
8623d74e
 #
 # Module: tmp102.py
 #
 # Description: This module acts as an interface between the TMP102 sensor
 # and downstream applications that use the data.  Class methods get
 # temperature data from the TMP102 sensor. It acts as a library module that
 # can be imported into and called from other Python programs.
 #
 # Copyright 2021 Jeff Owrey
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see http://www.gnu.org/license.
 #
 # Revision History
 #   * v10 released 01 June 2021 by J L Owrey; first release
 #
 #2345678901234567890123456789012345678901234567890123456789012345678901234567890
 
 # Import the I2C interface library
 import smbus
 import time
 
 # Define constants
b98e8b95
 DEGSYM = u'\xB0'
8623d74e
 
 # Define TMP102 Device Registers
 CONFIG_REG = 0x1
 TEMP_REG = 0x0
 
b98e8b95
 # Define default sm bus address.
 DEFAULT_BUS_ADDRESS = 0x48
 DEFAULT_BUS_NUMBER = 1
 
 # Define the default sensor configuration.  See the TMP102 data sheet
 # for meaning of each bit.  The following bytes are written to the
 # configuration register
 #     byte 1: 01100000
 #     byte 2: 10100000
 DEFAULT_CONFIG = 0x60A0
 
8623d74e
 class tmp102:
 
     # Initialize the TMP102 sensor at the supplied address (default
     # address is 0x48), and supplied bus (default is 1).  Creates
     # a new SMBus object for each instance of this class.  Writes
     # configuration data (two bytes) to the TMP102 configuration
     # register.
b98e8b95
     def __init__(self, sAddr=DEFAULT_BUS_ADDRESS,
                  sbus=DEFAULT_BUS_NUMBER,
3e66b3fa
                  config=DEFAULT_CONFIG,
                  debug=False): 
8623d74e
         # Instantiate a smbus object
         self.sensorAddr = sAddr
         self.bus = smbus.SMBus(sbus)
3e66b3fa
         self.debugMode = debug
  
b98e8b95
         # Initialize TMP102 sensor.  
         initData = [(config >> 8), (config & 0x00FF)]
8623d74e
         self.bus.write_i2c_block_data(self.sensorAddr, CONFIG_REG, initData)
3e66b3fa
 
         if self.debugMode:
             # Read the TMP102 configuration register.
             data = self.getInfo()
cd727c58
             print(self)
3e66b3fa
             print("configuration register: %s %s\n" % data)
8623d74e
     ## end def
 
     # Reads the configuration register (two bytes).
3e66b3fa
     def getInfo(self):
8623d74e
         # Read configuration data
         config = self.bus.read_i2c_block_data(self.sensorAddr, CONFIG_REG, 2)
         configB1 = format(config[0], "08b")
         configB2 = format(config[1], "08b")
         return (configB1, configB2)
     ## end def
 
d65ec281
     def getTempReg(self):
         # Read temperature register and return raw binary data for test
         # and debug.
         data = self.bus.read_i2c_block_data(self.sensorAddr, TEMP_REG, 2)
         dataB1 = format(data[0], "08b")
         dataB2 = format(data[1], "08b")
         return (dataB1, dataB2)
     ## end def
 
8623d74e
     # Gets the temperature in binary format and converts to degrees
     # Celsius.
     def getTempC(self):
         # Get temperature data from the sensor.
         # TMP102 returns the data in two bytes formatted as follows
         #        -------------------------------------------------
         #    bit | b7  | b6  | b5  | b4  | b3  | b2  | b1  | b0  |
         #        -------------------------------------------------
         # byte 1 | d11 | d10 | d9  | d8  | d7  | d6  | d5  | d4  |
         #        -------------------------------------------------
         # byte 2 | d3  | d2  | d1  | d0  | 0   |  0  |  0  |  0  |
         #        -------------------------------------------------
         # The temperature is returned in d11-d0, a two's complement,
         # 12 bit number.  This means that d11 is the sign bit.
         data=self.bus.read_i2c_block_data(self.sensorAddr, TEMP_REG, 2)
3e66b3fa
 
         if self.debugMode:
             dataB1 = format(data[0], "08b")
             dataB2 = format(data[1], "08b")
             print("Temperature Reg: %s %s" % (dataB1, dataB2))
 
8623d74e
         # Format into a 12 bit word.
         bData = ( data[0] << 8 | data[1] ) >> 4
         # Convert from two's complement to integer.
         # If d11 is 1, the the number is a negative two's complement
         # number.  The absolute value is 2^12 - 1 minus the value
b98e8b95
         # of d11-d0 taken as a positive number.
8623d74e
         if bData > 0x7FF:  # all greater values are negative numbers
             bData = -(0xFFF - bData)  # 0xFFF is 2^12 - 1
         # convert integer data to Celsius
         tempC = bData * 0.0625 # LSB is 0.0625 deg Celsius
         return tempC
     ## end def
 
     def getTempF(self):
         # Convert Celsius to Fahrenheit using standard formula.
         tempF = (9./5.) * self.getTempC() + 32.
         return tempF
     ## end def
 ## end class
 
 def testclass():
     # Initialize the smbus and TMP102 sensor.
3e66b3fa
     ts1 = tmp102(0x48, 1, debug=True)
8623d74e
     # Print out sensor values.
     bAl = False
     while True:
         tempC = ts1.getTempC()
         tempF = ts1.getTempF()
         if bAl:
             bAl = False
3e66b3fa
             print("\033[42;30m%6.2f%sC  %6.2f%sF                 \033[m" % \
b98e8b95
                   (tempC, DEGSYM, tempF, DEGSYM))
8623d74e
         else:
             bAl = True
b98e8b95
             print("%6.2f%sC  %6.2f%sF" % \
                   (tempC, DEGSYM, tempF, DEGSYM))
8623d74e
         time.sleep(2)
     ## end while
 ## end def
 
 if __name__ == '__main__':
     testclass()