4 Replies Latest reply on Mar 2, 2020 5:09 AM by MoTa_728816
      • 1. Re: Receiving data from an LM75 with PSoC 5LP
        MoTa_728816

        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] << 8) | 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

        • 2. Re: Receiving data from an LM75 with PSoC 5LP
          MoTa_728816

          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] << 8) | 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

          • 3. Re: Receiving data from an LM75 with PSoC 5LP
            PSCr_4653296

            Would it be possible to get an explanation of the bit shifting on this line: tempx256 = ((data[0] << 8) | 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) ;

                    }

            • 4. Re: Receiving data from an LM75 with PSoC 5LP
              MoTa_728816

              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] << 8) | 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?