Skip to main content
Associate II
July 20, 2024
Solved

TMP102 Configuration Register Read/Write fail

  • July 20, 2024
  • 6 replies
  • 1178 views

I need help to setup TMP102 alarm function. My board is NUCLEO-F439ZI

Reading the temperature is working fine.

uint8_t TMP102_ADDR = 0x48 << 1;

uint8_t REG_TEMP = 0x00;

uint8_t buf[12];

buf[0] = REG_TEMP;

ret = HAL_I2C_Master_Transmit(&hi2c2, 0x90, buf, 1, 10);    // OK

ret = HAL_I2C_Master_Transmit(&hi2c2, 0x90, 0x00, 1, 10);   //OK

ret = HAL_I2C_Master_Receive(&hi2c2, 0x90, buf, 2 , 10);    //OK

reads the temperature correctly. Buf[0] and buf[1]has correct temperature data.

 

I am trying to setup the alarm function. Reading/writing the Limit registers are failing.

Datasheet states that Thigh=80C, and Tlow=70C. After Reset.

I am reading the Thigh registers, with the following code:

uint8_t reghi = 0x03;

ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, reghi, 1, 10); // fail

is sending 0x00 on reghi. I verified by scope.

ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, 0x03, 1, 10);  //fail     

it is sending 0x00 to configuration register.

The only way to send the right value accomplished by:

Unit8_t reghi = 0x03;

buf[0] = reghigh;

ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, buf, 1, 10); OK.

Sending 0x03 to select the Thigh register. Verified by scope.

 

Now I want to read the value of Thigh.

ret = HAL_I2C_Master_Receive(&hi2c2, TMP102_ADDR, buf, 2 , 100);

The value in buf[0] = 0x00;

The value in buf{1] = 0x00;

I verified it in Debug mode.

 

The same problem when I write two bytes to Thigh and read it back

It gives 0x00 for both bytes.

If anybody tried to set the alarm successfully in TMp102, please help.

Thanks,

Rasem

    Best answer by padawan

    Hi Rasem

    try this:

    change 

     

     

    temphi[0] = 0x1A;
    
    temphi[1] = 0x00; // set high temp alarm at 26C.
    to 
    temphi[1] = 0x1A;
    
    temphi[0] = 0x00; // set high temp alarm at 26C.

     

    better

     

     

    uint8_t temphi[3]= {0};
    temphi[0] = 0x03; // register
    temphi[1] = 0x00; // HiByte
    temphi[2] = 0x1A; // LowByte
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, temphi,3, 100);

     

     

    Hint: An array is always passed as an address.

     

    hth

    padawan

     

    6 replies

    Tesla DeLorean
    Guru
    July 20, 2024

    Yeah, because it want a POINTER, the address of variable, and not the number/constant itself..

    uint8_t reghi = 0x03;
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, reghi, 1, 10); // fail
    
    is sending 0x00 on reghi. I verified by scope.
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, 0x03, 1, 10); //fail 
    
    it is sending 0x00 to configuration register.
    
    The only way to send the right value accomplished by:

     

    uint8_t reghi = 0x03;
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, (void *)&reghi, 1, 10); // pass via pointer
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    rasemAuthor
    Associate II
    July 21, 2024

    Hi Tesla DeLorean,

    Thank you very much for your quick reply. It was great. I am able to read the High Temperature setting of

    80C correctly.

    I still need your help setting my own limits:

    The following did not work.

    uint8_t reghi = 0x03;

    uint8_t  temphi[2];

    uint8_t lowlimit [2];

    temphi[0] = 0x1A;

    temphi[1] = 0x00; // set high temp alarm at 26C.

     

    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, (void *)&reghi, 1, 10); //OK

    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, (void*)&temphi,2, 100);

    ret = HAL_I2C_Master_Receive(&hi2c2, TMP102_ADDR, lowlimit, 2 , 100);

    // reads lowlimit[0]=0x00, lowlimit[1]=0x00

     

    Coffee on it's way.Thanks.

    Rasem

     

     

     

     

    padawan
    padawanBest answer
    Senior
    July 23, 2024

    Hi Rasem

    try this:

    change 

     

     

    temphi[0] = 0x1A;
    
    temphi[1] = 0x00; // set high temp alarm at 26C.
    to 
    temphi[1] = 0x1A;
    
    temphi[0] = 0x00; // set high temp alarm at 26C.

     

    better

     

     

    uint8_t temphi[3]= {0};
    temphi[0] = 0x03; // register
    temphi[1] = 0x00; // HiByte
    temphi[2] = 0x1A; // LowByte
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, temphi,3, 100);

     

     

    Hint: An array is always passed as an address.

     

    hth

    padawan

     

    rasemAuthor
    Associate II
    July 30, 2024

    Hi Padawan.

    Great solution. It is working now after sending 3 bytes togther.

    Thank you very much.

    Rasem

     

    Visitor II
    December 21, 2025

    Hi ,

    Can some explain the below please ?

    uint8_t temphi[3]= {0};
    temphi[0] = 0x03; // register
    temphi[1] = 0x00; // HiByte
    temphi[2] = 0x1A; // LowByte
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, temphi,3, 100);

    Not sure why these 3 registers are transmitted at the same time ? in my understanding should we just Transmit 0x03 and then use the _Receive function to read 2 registers. Do any one have sample code please ?

    thanks

    padawan
    Senior
    December 22, 2025

    Hi GOB,

    The code snipped shows how to write the registers.

    The "ret" is the HAL Stat (HAL_OK)

    if you want to read the Resiter you are right.

    uint8_t temphi_reg[1]= {0};
    uint8_t temphi[2]= {0};
    uint16_t temphi_val = 0xFFFF; // If the I²c fails 
    
    temphi_reg[0] = 0x03; // register
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, TMP102_ADDR, temphi_reg,1, 100);
    if (ret== HAL_OK)
    {
     ret= HAL_I2C_Master_Receive (&hi2c2, TMP102_ADDR,temphi,2 ,100);
    }
    // in temphi the val of the reg
    if (ret== HAL_OK)
    {
     temphi_val= (temphi[0]<<8)+ temphi[1];
    }

     padawan

    Visitor II
    January 1, 2026

    Thankyou Padawan,

    ref datasheet "The temperature limits are stored in the T(LOW) and T(HIGH) registers in the same format as the temperature result, and the values are compared to the temperature result on every conversion." 

    Does this mean only 12 bits carry useful data ?

    in this case should we use the below:

    // Combine the bytes

    value = ((int16_t)temphi[0] << 4) | (temphi[1] >> 4);

    // Convert the float value temperature value to Celcious, then to decimal format

    value_THigh_C = value * 0.0625 * 100;

    sprintf((char*)buf, "%u.%02u C\r\n", ((unsigned int)value_THigh_C), ((unsigned int)value_THigh_C % 100));

     

    but i am getting 8000.00 C instead of 80.00C

    Then i tried 

    temphi_val= (temphi[0]<<8)+ temphi[1];

    its giving me 80.80 C

    any help is much appreciated please ?

    padawan
    Senior
    January 7, 2026

    HI GOB,

    your are right. 

    I don't have access to the sensor, so my code is more theoretical.

    After checking the data sheet again, it should work as described below. As I said, in theory.

    int16_t temp_val= (((temphi[0])<<8)+ temphi[1]);
    int16_t temp_val12 = temp_val / 16
    float temp = (temp_val12 *0.0625);

    We shift the Highbyte to the upper byte of the 16Bit val, Add the low byte and dived by 16 (12Bit).

    so we are care about negativ values

     theoretical ;)

    This shows the 12Bit conversion.  

    hth

    padawan