Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LM75 Help please

Status
Not open for further replies.

AtomSoft

Well-Known Member
need some help :(

i got a LM75(BD) and can only get so far.. its I2C and so far i can read from it i think heh

Im using the below code to split the 2 byte data (temperature) into 1 byte then into 3 bytes...

Code:
     temp3 = ReadLM75BD();                    //get 2 bytes (int)
    temp4 = temp3 >> 8;                      // erase the LSByte (the LSBit is not important i assume)
    tH = (temp4 / 100) + 0x30;               // divide by 100 to get hundreds #
    tT = ((temp4 % 100) / 10) + 0x30;        // divide by 100 and use remainder to divide by 10  to get tens #
    tO = (((temp4 % 100) % 10) % 10) + 0x30; //use remainder on of temp4/100 then divide that byt 10 and with that remainder divide it by ten and use last remainder  as ones...

and code to get info:
Code:
unsigned int ReadLM75BD(void){
unsigned int tmp;
char result;

    i2c_start(); //Send Start
    i2c_write(RAdd); //Send our Device Address with the Write BIT

    result = i2c_ack2(); //Test for ACK

    tmp = i2c_read(); //Read 1 Byte from device and save in tmp
    result = i2c_ack2(); //Test for ACK

    tmp = tmp << 8;
    tmp |= i2c_read(); //Read 1 Byte from device and save in tmp

    result = i2c_ack(); //Test for NACK
    i2c_stop(); //Send Stop
    return tmp;
}

My entire code is quite long. Not sure if i should post it heh... the I2C is in my PDF cheat sheet and worked before so i assume its not the code for that or the hardware since i get a int like 0x02FF and such...

I assume it the way i convert the stuff or something or read the bytes in..

EDIT:

Here is some valuable info which i dont understand much:
"
quote-jpg.34335
"
temper-jpg.34334
 
Last edited:

AtomSoft

Well-Known Member
I get a steady reading of 0x01 or 0x00 and it increases with my finger on it.

It says the default register is TEMP so i assume thats what im reading.

Im reading D15 to D8 as my temperature but heh its unlikely the temperature is 0-1C here heh...

I must be doing something wrong... when i first start the program i get a reading of about 25C
 

AtomSoft

Well-Known Member
decided to use the built in i2c stuff:
Code:
unsigned char ReadLM(void){
unsigned char tmpC;
unsigned char result;

    StartI2C();

    WriteI2C(WAdd);
    AckI2C();

    WriteI2C(0x00);
    AckI2C();

    RestartI2C();

    WriteI2C(RAdd);
    AckI2C();

    tmpC = ReadI2C();
    //AckI2C();

    //result = getcI2C();
    NotAckI2C();

    StopI2C();

    return tmpC;
    
}

Still no good. I get a steady 127 (0x7F)
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
Jason,

You need to make your variables signed.

Code:
[COLOR="red"]signed[/COLOR] int ReadLM75BD(void){
[COLOR="Red"]signed[/COLOR] int tmp;
char result;

    i2c_start(); //Send Start
    i2c_write(RAdd); //Send our Device Address with the Write BIT

    result = i2c_ack2(); //Test for ACK

    tmp = i2c_read(); //Read 1 Byte from device and save in tmp
    result = i2c_ack2(); //Test for ACK

    tmp = tmp << 8;
    tmp |= i2c_read(); //Read 1 Byte from device and save in tmp

    result = i2c_ack(); //Test for NACK
    i2c_stop(); //Send Stop
    return ([COLOR="red"]tmp>>7[/COLOR]);
}

The function will then return a signed value that is twice the actual temperature. To display it you would do,
Code:
signed int temp;        //must be signed
    temp=ReadLM75BD();  //get temperature
    if(temp<0){         //if negative
        PutLCD('-');    //put minus sign
        temp=-temp;     //and negate temperature
    }
    else{               //else
        PutLCD(' ');    //put a space
    }
    PutNumber(temp/2);  //put the 3 digit number
    PutLCD('.')         //put decimal point
    if(temp&1)          //if there was a half degree
        PutLCD('5');    //display it
    else
        PutLCD('0');    //or dont

You could do it all unsigned but it makes more sense signed. If you prefer unsigned let me know.

Mike.
 

Pommie

Well-Known Member
Most Helpful Member
If you have read a single byte as in your last code you may have hung the I2C bus. Power your circuit down and try again.

Mike.
 

AtomSoft

Well-Known Member
thanks guys BUT.... no luck... after a power off (complete no power) then power on and code alterations i have this code
Code:
	while(1){

    LCD_LINE(2);
    LCD_STR((unsigned rom char*)"Temp: ");

    temp=ReadLM75BD();      //get temperature
    if(temp<0){             //if negative
        LCD_DATA('-',1);    //put minus sign
        temp=-temp;         //and negate temperature
    } else {                //else
        LCD_DATA(' ',1);    //put a space
    }

    tH = ((temp/2) / 100) + 0x30;
    tT = (((temp/2) % 100) / 10) + 0x30;
    tO = ((temp/2) % 10) + 0x30;

    LCD_DATA(tH,1);
    LCD_DATA(tT,1);
    LCD_DATA(tO,1);

    LCD_DATA('.',1);        //put decimal point
    if(temp&1)              //if there was a half degree
         LCD_DATA('5',1);   //display it
    else
         LCD_DATA('0',1);   //or dont

	}

MY LCD shows 127.5
 

Pommie

Well-Known Member
Most Helpful Member
The LM75 is returning 0x00ff and so I guess it's not working. Can you go back to the code that returned 25C?

Mike.
 

AtomSoft

Well-Known Member
Code:
while(1){

    LCD_LINE(2);
    LCD_STR((unsigned rom char*)"Temp: ");

    temp = 0;
    temp=ReadLM75BD();      //get temperature
    if(temp<0){             //if negative
        LCD_DATA('-',1);    //put minus sign
        temp=-temp;         //and negate temperature
    } else {                //else
        LCD_DATA(' ',1);    //put a space
    }

    temp = 1.8*temp+32;

    tH = ((temp/2) / 100) + 0x30;
    tT = (((temp/2) % 100) / 10) + 0x30;
    tO = ((temp/2) % 10) + 0x30;

    LCD_DATA(tH,1);
    LCD_DATA(tT,1);
    LCD_DATA(tO,1);

    LCD_DATA('.',1);        //put decimal point
    if(temp&1)              //if there was a half degree
         LCD_DATA('5',1);   //display it
    else
         LCD_DATA('0',1);    //or dont

     LCD_DATA('F',1);    //or dont

    DelayMS(250);
    DelayMS(250);
    DelayMS(250);
    DelayMS(250);
}

The above shows me the degrees in fahrenheit . Which seems to be correct heh.
 

DirtyLude

Well-Known Member
I can't really follow what you are doing. I have to assume the I2C functions are doing more than just a basic write and read. This is my function for returning the temp bytes from the LM75 using bit banged code on the MSP430. I'll just post the read function and maybe you can figure out what it's doing differently.

Code:
unsigned int get_temp( void)
{
	unsigned char buf[2];
	volatile unsigned int temp;

	i2cm_start( );
	
	if( i2cm_out( 0x90 | device ) ) //send write control byte
		return 9999;
	
	else if( i2cm_out( 0x00 ) )//send config command byte
		return 9999;
	
	i2cm_start( );//device wants start again to read
	
	if( i2cm_out( 0x91 | device ) ) //send read control byte
		return 9999;
	
	i2cm_in( buf, 2 ); //input the config byte to 'buf'

	i2cm_stop( );
	//device was not busy or failed...
	//set sucsess flag if needed before return

	temp = buf[0] << 8 | buf[1];
	temp >>= 5;
	return temp;
}
 

DirtyLude

Well-Known Member
I guess I sat on my message too long. Is it possibly the device address? If you have the address select pins grounded, that might be affected by taking away ground.

EDIT: Are you sure its correct? 27.5 Celsius is really pretty hot for indoors.
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
This line,
Code:
    temp = 1.8*temp+32;
needs to be,
Code:
    temp = 1.8*temp+[COLOR="Red"]64[/COLOR];
As the temperature is times 2. But this would make your room temperature around 80F:eek: so I suspect something is still wrong.

A better way would be,
Code:
    temp*=9;
    temp/=5;
    temp+=64;
Using 1.8 may make the compiler use floating point!!

Mike.
 

Pommie

Well-Known Member
Most Helpful Member
Yes, to do the conversion you add 32 but your value is twice as big as it should be and so you have to add 64.

Consider 20C, the chip will return 40 which gets divided by 2 and so 20 is displayed. When you multiply the 40 by 9, divide by 5 and add 64 you get 136 which will be displayed as 68F. Doing it without it being doubled, 20*9/5+32=68 which is correct.

Mike.
 

DirtyLude

Well-Known Member
Is this an LM75 or LM75A? I was wondering why you were shifting 7 bits and your calcs were different until I realized I was using the 11bit return from the LM75A.
 

Pommie

Well-Known Member
Most Helpful Member
Is this an LM75 or LM75A? I was wondering why you were shifting 7 bits and your calcs were different until I realized I was using the 11bit return from the LM75A.

Interesting question. I'd assumed the A as that is what Jason posted information from but in the text he states the bd which returns 11 bits. However, the code should work with either as the LSBs will get shifted out.

The code is a little lazy, it shifts the MSB left 8 so the sign bit is in the correct position and then shifts right 7 to preserve the sign.

Mike.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top