- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
schematic
pins
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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) ;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
According to the NXP LM75B Datasheet, LM75B returns 2 bytes data.
> 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?