Page 1 of 1

Measure temperature with a TI TMP102 using I2C

Posted: Mon Jun 18, 2012 2:07 pm
by cfbsoftware

Code: Select all

MODULE Temperature;
(* =========================================================================  
    Example Cortex-M3 Oberon I2C Temperature Measurement Program  
 
   Description:
     Monitors the current temperature every second and writes it to output
     whenever it changes  
      
   Target: 
     LPC17xx systems with a TI TMP102 Digital Temperature Sensor
     connected to the I2C1 bus

   Tested with:
     TMP102: SparkFun SEN-09418: TI Digital Temperature Sensor Breakout +
     Embedded Artists LPCXpresso LPC1769 Board 

   Refs: 
     NXP LPC17xx User Manual UM10360
     TI TMP102 Datasheet
     Oberon for Cortex-M3 Microcontrollers
   
   (c) 2010-2012 CFB Software   
   http://www.astrobe.com  
   
   ========================================================================= *)

IMPORT I2C, Main, Out, SYSTEM, Timer;

PROCEDURE Progress(msg: ARRAY OF CHAR; status: INTEGER);
BEGIN
  Out.String(msg); 
  IF status = I2C.OK THEN 
    Out.String(" OK ")
  ELSE 
    Out.String(" Error ");
    Out.Int(status, 0)
  END;
  Out.Ln()
END Progress;


PROCEDURE DataToDegrees(data: ARRAY OF SYSTEM.BYTE): REAL;
VAR
  degrees: INTEGER;
BEGIN
  (* Ref: TMP102 *)
  (* 12-bit value *)
  degrees := (ORD(data[0]) * 256 + ORD(data[1])) DIV 16;
  (* Sign-extend to a 32-bit integer *)
  degrees := ASR(LSL(degrees, 20), 20);
  RETURN FLT(degrees) * 0.0625
END DataToDegrees;


PROCEDURE OutDegrees(degrees: REAL);
(* Output with single digit after the decimal point *)
VAR
  deg10: INTEGER;
BEGIN
  (* Scale and round *)
  deg10 := FLOOR((degrees * 10.0) + 5.0);
  Out.Int(deg10 DIV 10, 0); Out.Char("."); Out.Int(deg10 MOD 10, 0);
  Out.String(" degrees"); Out.Ln()
END OutDegrees;
  

PROCEDURE Run;
CONST
  I2CBus = 1;
  freq = 400000;
  (* A0, A1 & A2 pins are connected to ground *)
  (* 7-bit Slave address. Ref: TMP102 *)
  ThermAddr = 048H;
VAR
  command: CHAR;
  reading: ARRAY 2 OF SYSTEM.BYTE;
  degrees, lastValue: REAL; 
  status: INTEGER;
BEGIN
  I2C.Init(I2CBus, freq);
  Out.String("I2C Temperature"); Out.Ln();
  status := I2C.OK;
  Progress("Init", status);
  command := 0X;
  lastValue := 9999.0;
  WHILE TRUE DO 
    status := I2C.Read(ThermAddr, command, reading);
    IF status = I2C.OK THEN 
      degrees := DataToDegrees(reading);
      IF degrees # lastValue THEN 
        OutDegrees(degrees);
        lastValue := degrees
      END 
    ELSE
      Progress("Read", status)
    END;
    Timer.MSecDelay(1000)
  END
END Run;


BEGIN
  Run()
END Temperature.