nodepower/bin/tmp102.py
8623d74e
 #!/usr/bin/python
 #
 # 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
 DEGSYM = u'\xb0'
 
 # Define TMP102 Device Registers
 CONFIG_REG = 0x1
 TEMP_REG = 0x0
 
 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.
     def __init__(self, sAddr=0x48, sbus=1): 
         # Instantiate a smbus object
         self.sensorAddr = sAddr
         self.bus = smbus.SMBus(sbus)
         # Initialize TMP102 sensor.  See the data sheet for meaning of
         # each bit.  The following bytes are written to the configuration
         # register
         #     byte 1: 01100000
         #     byte 2: 10100000
         initData = [0x60, 0xA0]
         self.bus.write_i2c_block_data(self.sensorAddr, CONFIG_REG, initData)
     ## end def
 
     # Reads the configuration register (two bytes).
     def status(self):
         # 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
 
     # 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)
         # 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
         # of d10-d0 taken as a positive number.
         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.
     ts1 = tmp102(0x48, 1)
     # Read the TMP102 configuration register.
     data = ts1.status()
     print "configuration register: %s %s\n" % data
     # Print out sensor values.
     bAl = False
     while True:
         tempC = ts1.getTempC()
         tempF = ts1.getTempF()
         if bAl:
             bAl = False
             print "\033[42;30m%6.2f%sC  %6.2f%sF\033[m" % \
                   (tempC, DEGSYM, tempF, DEGSYM)
         else:
             bAl = True
             print "%6.2f%sC  %6.2f%sF" % \
                   (tempC, DEGSYM, tempF, DEGSYM)
         time.sleep(2)
     ## end while
 ## end def
 
 if __name__ == '__main__':
     testclass()