Receiving data from an LM75

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
PSCr_4653296
Level 1
Level 1
First like given

[deleted]

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Oops!

I made a mistake about the negative temperature calculation. >_<

The main() should have been

===============

int main(void)

{

    uint8_t data[0] ;

    int16_t tempx256 ;

    float ftemp ;

    uint8_t addr = 0 ; /* temp pointer */

   

    init_hardware() ;

    splash() ;

    

    for(;;)

    {      

        myI2C_Read2Bytes(addr, data) ;

        tempx256 = ((data[0] << 😎 | data[1]) ;

        ftemp = (float)tempx256 / 256.0 ;

        if (tempx256 >= 0.0) {

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        } else {

            ftemp *= -1.0 ;

            sprintf(str, "-%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        }

        print(str) ;

        CyDelay(1000) ;

    }

}

===============

moto

View solution in original post

0 Likes
4 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I recently wrote a similar sample of CY8CKIT-059 and LM75B at

CY8CKIT-059 I2C pins P12_0 and P12_1

But it was reading only the integer part of temp.

So today I modified it for 11bit float version

Tera Term log

000-TeraTerm-log.JPG

schematic

001-schematic.JPG

pins

002-pins.JPG

main.c

=================

#include "project.h"

#include "stdio.h"

#define LM75B_I2C_SLAVE_ADDR (0x48)

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_PutString(str) ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    sprintf(str, "PSoC 5LPI2C I2C (LM75B) Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    UART_Start() ;   

    splash() ;

    I2C_Start() ; 

}

uint8_t myI2C_Read2Bytes(uint8_t reg_addr, uint8_t data[])

{

    uint8_t status ;

    uint8_t value = 0 ;

   

    I2C_MasterClearStatus();

    status = I2C_MasterSendStart(LM75B_I2C_SLAVE_ADDR, I2C_WRITE_XFER_MODE) ;

   

    if (I2C_MSTR_NO_ERROR == status) {

        I2C_MasterWriteByte(reg_addr);

        status = I2C_MasterSendRestart(LM75B_I2C_SLAVE_ADDR, I2C_READ_XFER_MODE); 

    }

   

    if (I2C_MSTR_NO_ERROR == status) {  

        data[0] = I2C_MasterReadByte(I2C_ACK_DATA); // read int part

        data[1] = I2C_MasterReadByte(I2C_NAK_DATA); // read frac part

    }

       

    I2C_MasterSendStop(); 

   

    return(status) ;

}

int main(void)

{

    uint8_t data[0] ;

    int16_t tempx8 ;

    float ftemp ;

    uint8_t addr = 0 ; /* temp pointer */

   

    init_hardware() ;

    splash() ;

    

    for(;;)

    {      

        myI2C_Read2Bytes(addr, data) ;

        tempx8 = ((data[0] << 😎 | data[1]) >> 5 ;

        ftemp = (float)tempx8 * 0.125 ;

        if (ftemp >= 0.0) {

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        } else {

            ftemp *= -1.0 ;

            sprintf(str, "-%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        }

        print(str) ;

        CyDelay(1000) ;

    }

}

=================

moto

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Oops!

I made a mistake about the negative temperature calculation. >_<

The main() should have been

===============

int main(void)

{

    uint8_t data[0] ;

    int16_t tempx256 ;

    float ftemp ;

    uint8_t addr = 0 ; /* temp pointer */

   

    init_hardware() ;

    splash() ;

    

    for(;;)

    {      

        myI2C_Read2Bytes(addr, data) ;

        tempx256 = ((data[0] << 😎 | data[1]) ;

        ftemp = (float)tempx256 / 256.0 ;

        if (tempx256 >= 0.0) {

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        } else {

            ftemp *= -1.0 ;

            sprintf(str, "-%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        }

        print(str) ;

        CyDelay(1000) ;

    }

}

===============

moto

0 Likes

Would it be possible to get an explanation of the bit shifting on this line: tempx256 = ((data[0] << 😎 | data[1]) ;

Also what is happening here?:

if (tempx256 >= 0.0) {

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        } else {

            ftemp *= -1.0 ;

            sprintf(str, "-%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        }

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

According to the NXP LM75B Datasheet, LM75B returns 2 bytes data.

010-7_4_3_temperatur_register.JPG

011-7_4_3_temp_cont.JPG

>         tempx256 = ((data[0] << 😎 | data[1]) ;

So at first I got 2 bytes from the sensor via I2C, data[0] and data[1].

data[0] holds D10 - D3, which is the integer part of the temperature.

and

data[1] holds D2 - D0, which is the fractional part of the temperature.

So I shifted data[0] by 8bit  and make or with data[1] making a 16bit integer value tempx256.

| data[0]                                           |   data[1]                                 |

| D10, D9, D8, D7, D6, D5, D4, D3 | D2, D1, D0, xx, xx, xx, xx, xx |

Since there is an imaginary decimal point between D3 and D2

tempx256 is actually the temperature multiplied by 256.

then I assigned tempx256 divided by 256.0 to a float value ftemp.

>        ftemp = (float)tempx256 / 256.0 ;

If I did not mind using "%f", I could have written

     sprintf(str, "%.2f", ftemp) ;

But to save some memory and avoid dealing with float format I used following format

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

where

(int)ftemp is the integer part of the temperature formatted to "%d" decimal

(int)(ftemp * 100) is ftemp multiplied by 100

and

(int)(ftemp * 100) % 100 extracts the fractional part as a decimal number

and to correctly show the place, I used "%02d" so that the value 1 will be 01.

I did up to this point at the first reply, but then I remembered that the temp can be a negative value!

So

        if (tempx256 >= 0.0) { /* if temp is a positive value do the above */

            sprintf(str, "%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ;

        } else {                         /* but in case the temp is a negative value */

            ftemp *= -1.0 ;          /* at first make it a positive value of its absolute value */

            sprintf(str, "-%d.%02d\n", (int)ftemp, (int)(ftemp * 100)%100) ; /* then added '-' at the beginning */

        }

Last not but least, I'm regretting that I should have written as below to use snprintf() instead of sprintf()

#define STR_LEN 128

char str[STR_LEN] ;

void print(char *str)

...

snprintf(str, STR_LEN, ...)

Well, may be next time I will..

moto

P.S. Could I make sense?