Beaglebone and TMP102 sensor example in python

0
228
beaglebone and TMP102 layout
beaglebone and TMP102 layout

In this article we look at the TMP102 digital sensor and we will connect it up to a Beaglebone

The TMP102 device is a digital temperature sensor ideal for NTC/PTC thermistor replacement where high accuracy is required. The device offers an accuracy of ±0.5°C without requiring calibration or external component signal conditioning. Device temperature sensors are highly linear and do not require complex calculations or lookup tables to derive the temperature. The on-chip 12-bit ADC offers resolutions down to 0.0625°C.

The TMP102 device features SMBus™, two-wire and I2C interface compatibility, and allows up to four devices on one bus. The device also features an SMBus alert function. The device is specified to operate over supply voltages from 1.4 to 3.6 V with the maximum quiescent current of 10 µA over the full operating range.

The TMP102 device is ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications. The device is specified for operation over a temperature range of –40°C to 125°C.

 

Parts List

NameLink
BeagleboneBeagleBone Black TI AM335x Cortex-A8 development BB-Black Rev.C
TMP102TMP102 Digital Temperature Sensor Breakout Board Module 12-bit 1.4V To 3.6VDC Sensor Module Temperature Module
connecting wireFree shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

Schematic/Connection

BeagleboneModule
3.3v – P9.3Vcc
Gnd – P9.1Gnd
SDA – P9.20SDA
SCL – P9.19SCL

 

beaglebone and TMP102 layout
beaglebone and TMP102 layout

Code

Modified example from https://github.com/n8many/TMP102py

import smbus
import time
 
TEMPERATURE_REG = 0x00
CONFIG_REG = 0x01
T_LOW_REG = 0x02
T_HIGH_REG = 0x03
 
ADDRESSES = [0x48, 0x49, 0x4A, 0x4B]
 
tempConvert = {
    'C': lambda x: x,
    'K': lambda x: x+273.15,
    'F': lambda x: x*9/5+32,
    'R': lambda x: (x+273.15)*9/5
}
 
tempConvertInv = {
    'C': lambda x: x,
    'K': lambda x: x-273.15,
    'F': lambda x: (x-32)*5/9,
    'R': lambda x: (x*5/9)-273.15
}
class TMP102(object):
    def __init__(self, units=None, address=0x48, busnum=2):
        units = units or 'C'
        if (address not in ADDRESSES):
            raise ValueError("Invalid Address: {0:#x}".format(address))
        self.address = address
        self.busnum = busnum
 
        self.setUnits(units)
        self.bus = smbus.SMBus(self.busnum)
        self.readTemperature()
 
    def bytesToTemp(self, data):
        # Adjustment for extended mode
        ext = self.extractConfig(1, 4, 1)
        #ext = data[1] & 0x01
        res = int((data[0] << (4+ext)) + (data[1] >> (4-ext)))
 
        if (data[0] | 0x7F is 0xFF):
            # Perform 2's complement operation (x = x-2^bits)
            res = res - 4096*(2**ext)
        # Outputs temperature in degC
        return res*0.0625
 
    def tempToBytes(self, temp):
        # Temp MUST be converted prior to input
        data = [0 , 0]
        res = int(temp/0.0625)
        ext = self.extractConfig(1, 4, 1)
        if (res < 0):
            res = res + 4096 * (2**ext)
        data[0] = (res >> (4 + ext)) & 0xFF
        data[1] = ((res & (2**(4 + ext)-1)) << (4 - ext)) | ext
        return data
 
    def extractConfig(self, num, location=0, length=0):
 
        data = self.bus.read_i2c_block_data(self.address, CONFIG_REG, 2)
        if (num == 3):
            #Full register dump
            return data
        else:
            mask = 2**length - 1
            return (data[num] >> location) & mask
 
    def injectConfig(self, setting, num, location, length):
        mask = (2**length - 1) << location
        setting = (setting << location) & mask
        data = self.bus.read_i2c_block_data(self.address, CONFIG_REG, 2)
        data[num] &= ~mask
        data[num] |= setting
        self.bus.write_i2c_block_data(self.address, CONFIG_REG, data)
 
    def readTemperature(self, units=None):
        data = self.bus.read_i2c_block_data(self.address, TEMPERATURE_REG, 2)
        tempC = self.bytesToTemp(data)
        units = units or self.units
 
        try:
            tempOut = tempConvert[units](tempC)
        except:
            raise ValueError('Invalid Units "' + self.units + '"')
        return tempOut
 
    def getUnits(self):
        return self.units
 
    def setUnits(self, units):
        if (units.upper() in 'RCKF' and len(units) == 1):
            self.units = units.upper()
        else:
            raise ValueError("Invalid Unit, must use C(elcius), K(elvin),"
                    "F(ahrenheit), or R(ankine)")
 
 
 
    def setConversionRate(self, rate):
        # 0 : 0.25 Hz
        # 1 : 1 Hz
        # 2 : 4 Hz (default)
        # 3 : 8 Hz
        self.injectConfig(rate, 1, 6, 2)
 
    def setExtendedMode(self, mode):
        # 0 : 12-bit ( -55C to 128C)
        # 1 : 13-bit ( -55C to 150C)
 
        self.injectConfig(mode, 1, 4, 1)
 
    def sleep(self):
        self.injectConfig(True, 0, 0, 1)
 
    def wakeup(self):
        self.injectConfig(False, 0, 0, 1)
 
    def setAlertPolarity(self, polarity):
        # 0 : Active Low
        # 1 : Active High
        self.injectConfig(polarity, 0, 2, 1)
 
    def alert(self):
        return extractConfig(1, 5, 1)
 
    def setFault(self, faultSetting):
        # 0 : 1 fault
        # 1 : 2 faults
        # 2 : 4 faults
        # 3 : 6 faults
        self.injectConfig(faultSetting, 0, 3, 2)
 
    def setAlertMode(self, mode):
        # 0 : Comparator Mode (Active within temp range)
        # 1 : Thermostat Mode (Active if over T_High, reset on read)
        self.injectConfig(mode, 0, 1, 1)
 
    def setBoundTemp(self, upper, temperature, units=None):
        units = units or self.units
        ext = self.extractConfig(1, 4, 1)
        try:
            temperature = tempConvertInv[units](temperature)
        except:
            raise ValueError('Invalid Units "' + self.units + '"')
        if (ext is 1 and temperature > 150):
            temperature = 150
        elif (temperature < -55):
            temperature = -55
        data = self.tempToBytes(temperature)
 
        if (upper):
            reg = T_HIGH_REG
        else:
            reg = T_LOW_REG
 
        self.bus.write_i2c_block_data(self.address, reg, data)
 
    def getBoundTemp(self, upper, units=None):
        units = units or self.units
        if (upper):
            reg = T_HIGH_REG
        else:
            reg = T_LOW_REG
        data = self.bus.read_i2c_block_data(self.address, reg, 2)
        tempC = self.bytesToTemp(data)
 
        try:
            tempOut = tempConvert[units](tempC)
        except:
            raise ValueError('Invalid Units "' + self.units + '"')
        return tempOut
 
if __name__ == "__main__": 
    tmp = TMP102('C', 0x48, 2)
 
    # Actually, lets make the temperatures Farenheit
    tmp.setUnits('F')
 
    while True:
        print "Current temp: {:.1f}degF".format(tmp.readTemperature())
        time.sleep(1)

 

Output

Run the above code. You should see something like this

debian@beaglebone:/var/lib/cloud9/$ python TMP102.py
Current temp: 71.4degF
Current temp: 71.3degF
Current temp: 71.3degF
Current temp: 71.3degF
Current temp: 74.4degF
Current temp: 77.7degF

Link

http://www.ti.com/lit/gpn/tmp102

LEAVE A REPLY

Please enter your comment!
Please enter your name here

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.