Monday, April 30, 2012

TMP102 temperature sensor integration with TelosB mote

Here is a very simple NesC code for getting temperature value from TMP102 digital Temperature sensor with Telosb mote.

Connection
 
TMP102 GND   -> TELOSB 9 pin
TMP102 VCC    -> TELOSB 1 pin
TMP102 ADD0  -> TELOSB 9 pin
TMP102 SDA    -> TELOSB 8 pin 
TMP102 SCL    -> TELOSB 6 pin  

Apart from this connect pull-up resistor(10 KOhm) from SDA &SCL to VCC.

Program

Program has  three main files Accelerometer345AppC.nc, Accelerometer345C.nc and Makefile.

TMP102AppC.nc
configuration TMP102AppC {
}

implementation {
  components MainC, TMP102C as App;
  App.Boot -> MainC;

  components LedsC;
  App.Leds -> LedsC;
  
  components new TimerMilliC() as TimerTemp;
  App.TimerTemp -> TimerTemp;

  components new SimpleTMP102C();
  App.Temp -> SimpleTMP102C.Read;
}

TMP102C.nc
#include "printf.h"

module TMP102C {
  uses {
    interface Boot;
    interface Leds;
    interface Timer as TimerTemp;
    interface Read as Temp;
  }
}

implementation {

  event void Boot.booted() {
    printf("Temperature sensor starting..\n\n");
    call TimerTemp.startPeriodic(1000);
  }

  event void TimerTemp.fired() {
    call Leds.led0On();
    call Temp.read();
  }  

  event void Temp.readDone(error_t result, uint16_t temp) {
    temp=temp*0.0625;
    if (result == SUCCESS) printf("Temperature = %d \n", temp);
    else printf("Error..\n");
    printfflush();
    call Leds.led0Off();
  }
}

Makefile
COMPONENT=TMP102AppC
CFLAGS += -I$(TOSDIR)/lib/printf
CFLAGS += -I$(TOSDIR)/chips/tmp102

include $(MAKERULES)



Files SimpleTMP102C and SimpleTMP102P can be downloaded from TinyOS trunk or use these files given below.

SimpleTMP102C
generic configuration SimpleTMP102C() {
  provides interface Read;
}
implementation {
  components SimpleTMP102P;
  Read = SimpleTMP102P;

  components new TimerMilliC() as TimerSensor;
  SimpleTMP102P.TimerSensor -> TimerSensor;

  components new TimerMilliC() as TimerFail;
  SimpleTMP102P.TimerFail -> TimerFail;

  components new Msp430I2CC();
  SimpleTMP102P.Resource -> Msp430I2CC;
  SimpleTMP102P.ResourceRequested -> Msp430I2CC;
  SimpleTMP102P.I2CBasicAddr -> Msp430I2CC;     
}

SimpleTMP102C 
#include "TMP102.h"

module SimpleTMP102P {
   provides interface Read;
   uses {
    interface Timer as TimerSensor;
    interface Timer as TimerFail;
    interface Resource;
    interface ResourceRequested;
    interface I2CPacket as I2CBasicAddr;        
  }
}

implementation {
  
  uint16_t temp;
  uint8_t pointer;
  uint8_t temperaturebuff[2];
  uint16_t tmpaddr;
  
  norace uint8_t tempcmd;
    
  task void calculateTemp(){
    uint16_t tmp = temp;
    signal Read.readDone(SUCCESS, tmp);
  }
  
  command error_t Read.read(){
 call TimerSensor.startOneShot(100);
 return SUCCESS;
  }

  event void TimerSensor.fired() {
 call Resource.request();  
  }
  
  event void TimerFail.fired() {
   signal Read.readDone(SUCCESS, 0);
  }

  event void Resource.granted(){
    error_t error;
    pointer = TMP102_TEMPREG;
    tempcmd = TMP_READ_TMP;
    error= call I2CBasicAddr.write((I2C_START | I2C_STOP), TMP102_ADDRESS, 1, &pointer); 
    if(error){
      call Resource.release();
      signal Read.readDone(error, 0);
    }
  }
  
  async event void I2CBasicAddr.readDone(error_t error, uint16_t addr, uint8_t length, uint8_t *data){
    if(call Resource.isOwner()) {
 uint16_t tmp;
 for(tmp=0;tmp<0xffff;tmp++); //delay
 call Resource.release();
        printf("\nMSB = %d  ",data[0]);
        printf("LSB = %d\n",data[1]);
 tmp = data[0];
 tmp = tmp << 8;
 tmp = tmp + data[1];
 tmp = tmp >> 4;
 atomic temp = tmp;
 post calculateTemp();
 }
  }

  async event void I2CBasicAddr.writeDone(error_t error, uint16_t addr, uint8_t length, uint8_t *data){
    if(call Resource.isOwner()){
      error_t e;
      e = call I2CBasicAddr.read((I2C_START | I2C_STOP),  TMP102_ADDRESS, 2, temperaturebuff);
      if(e){
        call Resource.release();
        signal Read.readDone(error, 0);
       }
     }
  }   
  
  async event void ResourceRequested.requested(){ }
  async event void ResourceRequested.immediateRequested(){ }   
  
}

TMP102.h
#ifndef TMP102_H
#define TMP102_H
#define TMP102_ADDRESS          0x48
#define TMP102_TEMPREG          0x00
#define TMP102_CONFREG          0x01
#define TMP_READ_TMP    1

#endif

6 comments:

  1. hi;
    how can I a test (if temperature > 40) then send paquet
    thanks

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Hi Saadia,
      In TMP102C.nc after this line "temp=temp*0.0625;"
      check if the temperature is above 40 using a if condition
      if true use "call AMControl.start();" to start transmission.

      This is the procedure. But for starting transmission again you have to use corresponding components. If u need further details plz feel free to contact "prasanthhere@gmail.com"

      Delete
  2. hi prasanth,

    i am working on a project being my final year project.. i am stuck in a situation where i cant access the temperature. i have a BlinkToRadioC.nc file and BlinkToRadioApp.nc file in which i want a slight modification and want to show sensed Temperature.

    I am using 2 TelosB motes, one is having BaseStation App and the other is having the BlinkToRadio App.

    Your urgent reply would be highly appreciated.

    Thanks n Regards

    Salma

    ReplyDelete
  3. Hi Iam using Contiki and new to it, can you post programme for integrating SHT75 (humidity and temperature sensor) with telosB mote.

    ReplyDelete
  4. Hello,
    I am trying to connect a DHT21 (AM2301) sensor on a TelosB mote. This sensor is considered compatible with Sensirion SHT11 driver, but the one I have has 3 cables instead of 4. In other words it uses one cable for data communication sending both temperature and humidity readings through it. Have you ever had the chance to implement anything custom on SHT11 driver? Any suggestions?
    Thank you in advance.

    ReplyDelete