lm75a temperature conversion

ramasule

Member
Ive been reading up on readtemp12 and the threads associated with it.

http://www.picaxeforum.co.uk/showthread.php?t=8329
is the main one I found


The LM75a uses i2c and has the following

Datasheet
http://www.nxp.com/acrobat_download/datasheets/LM75A_4.pdf

Excerpt

Code:
The Temperature register (Temp) holds the digital result of temperature measurement 
or monitor at the end of each analog-to-digital conversion. This register is read-only and 
contains two 8-bit data bytes consisting of one Most Significant Byte (MSByte) and 
one Least Significant Byte (LSByte). However, only 11 bits of those two bytes are used to 
store the Temp data in 2’s complement format with the resolution of 0.125 °C. Table 9 shows the
bit arrangement of the Temp data in the data bytes.  When reading register Temp, all 16 bits of 
the two data bytes (MSByte and LSByte) are provided to the bus and must be all collected by 
the controller to complete the bus operation. However, only the 11 most significant bits should 
be used, and the 5 least significant bits of the LSByte are zero and should be ignored. 
One of the ways to calculate the Temp value in °C from the 11-bit Temp data is:
1. If the Temp data MSByte bit D10 = 0, then the temperature is positive and Temp value (°C) = +(Temp data) ´ 0.125 °C.
2. If the Temp data MSByte bit D10 = 1, then the temperature is negative and Temp value (°C) = -(2’s complement of Temp data) ´ 0.125 °C.

Can anyone point, shout, kick me in the right direction.

My check to see if its negative is
If w0 >= $7FF then negative

I am unsure of where to go from there.

Thanks,

Derek L
 
Last edited:

hippy

Ex-Staff (retired)
That's quite a handy format; the decimal point is at the boundary of the two bytes and the msb of the high byte is the sign bit, so rough and ready ( all untested ) ...

Code:
If w0 < $8000 Then
  SerTxd( "+" )
Else 
  w0 = -w0
  SerTxd( "-" )
End If
w1 = b0 / 32 * 125
SerTxd( #b1, ".", #w1, CR, LF )
If you want trailing zeroes, change the SerTxd to ...

Code:
SerTxd( #b1, ".", #w1 )
If b0 = 0 Then : SerTxd( "00" ) : End If
SerTxd( CR, LF )
If you want trailing zeroes removed ...

Code:
If w1 <> 0 Then
  Do 
    b0 = w1 // 10
    If b0 = 0 Then : w1 = w1 / 10 : End If
  Loop while b0 = 0 
End If
SerTxd( #b1, ".", #w1, CR, LF )
 
Last edited:

ramasule

Member
Thanks Hippy,

I was 99% sure b1 contained the whole decimal but was unsure what to do when i hit a negative and what to do with b0.

2 quickies

for i2c i need to loop the following for 2 units right...

main:

i2cSlave %10010000, i2cslow, i2cByte
ReadI2c 0,(b1,b0)
i2cSlave %10011000, i2cslow, i2cByte
ReadI2c 0,(b3,b1)

goto main

I was just wondering if you have to keep declaring hte i2cslave part
naturally ill be replacing the address with TempProbe1, TempProbe2, etc



Second question

Quick link / webpage for those sertxd commands like
SerTxD (#w0, 13, 10) where to find more commands like 13 left and 10 new line


Thanks again Hippy if your ever in edmonton ill take you for a beer or 5 :),

Derek L
 

ramasule

Member
Quick note

Code:
If w0 < $8000 Then
  SerTxd( "+" )
Else 
  w0 = -w0
  SerTxd( "-" )
End If
w1 = b0 / 32 * 125
SerTxd( #b1, ".", #w1, CR, LF )

Should be


Code:
If w0 [B][u]<= $3ff[/u][/B] Then
  SerTxd( "+" )
Else 
  w0 = -w0 [B][U]* 32[/U][/B]
  SerTxd( "-" )
End If
w1 = b0 / 32 * 125
SerTxd( #b1, ".", #w1, CR, LF )
 
Last edited:

ramasule

Member
Yes I just caught it this morning, I guess thats what I get for coding in tripple OT of stanley cup finals

When I was simulating values I forgot to add the *32 there

temp1word = $649 * 32

Thats where it was my mistake. I noticed this morning when I went to simulate a positive value.

your code

Code:
If w0 < $8000 Then
  SerTxd( "+" )
Else 
  w0 = -w0
  SerTxd( "-" )
End If
w1 = b0 / 32 * 125
SerTxd( #b1, ".", #w1, CR, LF )
is the correct code

Thank you again,

Derek L
 

hippy

Ex-Staff (retired)
If you want to save some program memory you can replace "w0 < $8000" with "b1 < $80" or "bit15 = 0".
 

ramasule

Member
Its alive!!!!


Code:
'============  PINS  ===================================================

symbol lcde    = 3
symbol LCDData = %00000100
symbol LCDInst = %00000000


'============ END PINS =================================================
'============ DECLARATIONS ==============================================

symbol OutByte = b0
symbol RS = b1
symbol counter = b2
symbol Temp1Byte = b3             'Temp1Byte status byte %00000000, =n,n,n,n,n,n,is zero, sign value 
symbol Temp1MSB = b5
symbol Temp1LSB = b4
symbol Temp1Word = w2
symbol Temp1Decimal = w3

'============ END DECLARATIONS  ========================================
'============ INITS  ================================================

	RS = LCDInst 'Init LCD
	for counter = 0 to 5
		lookup counter, ($33, $32, $28, $0c, $01, $06), OutByte
		gosub LCDOut
	next counter
	
	i2cSlave %10010000, i2cSlow, i2cByte

'============ END INITS  ===============================================
'============ MAIN       ===============================================

main:

	gosub i2ctemp
	gosub lcdword

goto main

'============ END MAIN   ===============================================
'============ SUBS       =============================================

i2ctemp:
	
	ReadI2c 0,(b5,b4)
	'Temp1Word = $649 * 32                 'simulate a temperature
	If Temp1LSB = 0 Then
        Temp1Byte = Temp1Byte or  %00000010  'Give "=zero" temp1byte
	Else
        Temp1Byte = Temp1Byte and %11111101  'Isolate zero value 
	End If

	If Temp1Word <= $8000 Then             
	  Temp1Byte = Temp1Byte or  %00000001  'Give Temp sign
	Else
	  Temp1Word = -Temp1Word               'Convert to Negative
	  Temp1Byte = Temp1Byte and %11111110  'Isolate Temp sign set to zero
      End If
	  Temp1Decimal = Temp1LSB / 32 * 125   'Shift 5 spaces and times by 125 (resolution)
		
	
return





lcdword:

		
	for counter = 0 to 2                        'Moves LCD cursor to line 1, char 0
		RS = LCDInst                          'SET RS to LCDInst must be in loop because RS gets changed
		lookup counter, ($80, $06), OutByte
		RS = LCDInst
		gosub LCDOut
	next counter
	

		     
	for counter = 0 to 14
		RS = LCDData                                  'Set to data mode
		lookup counter, ("Current Temp is"), OutByte
		gosub LCDOut
	next counter

	
	for counter = 0 to 2
		RS = LCDInst
		lookup counter, ($C6, $04), OutByte
		gosub LCDOut
	next counter
	
	if Temp1Byte <= 1 Then
	  do 

	      Temp1Decimal = Temp1Decimal / 10         'Isolate to 0.xx
		OutByte = Temp1Decimal // 10 + $30
		RS = LCDData
		gosub LCDOut
		
	  loop while Temp1Decimal > 10                   'Run to 0.xx if value was 0 would get 0.0x(x) missing
	else
	  for counter = 0 to 1
		RS = LCDData
		lookup counter, ("00"), OutByte
		gosub LCDOut
	  next counter
      end if

	
	RS = LCDData
	OutByte = "."
	gosub LCDOut

	do
		OutByte = temp1msb // 10 + $30
		RS = LCDData
		gosub LCDOut
		'if temp1msb = 0 then exit
		temp1msb = temp1msb / 10 
	
	loop while temp1msb > 0

	
	RS = LCDData
	If Temp1Byte = 1 or Temp1Byte = 3 then   'Temp1Byte sign value
	  Outbyte = "+"
      Else 
	  Outbyte = "-"
	Endif
	gosub LCDOut
	

	
	for counter = 0 to 2
		RS = LCDInst
		lookup counter, ($C8, $06), OutByte
		gosub LCDOut
	next counter

		
	for counter = 0 to 1
		RS = LCDData
		lookup counter, (%11011111,"C"), OutByte
		gosub LCDOut
	next counter
      
		

return

LCDOut: 
        'debug
	  RS = OutByte / 16 & 1 | RS         ; Move MSB DB4 to bit 0
        pins = OutByte & %11110000 | RS    ; Put MSB out fiRSt
        PULSOUT lcde, 1                    ; Give a 10uS pulse on E
        RS = RS & %00001100                ; Clear bits 3 and 4
        RS = OutByte & 1 | RS              ; Move LSB DB4 to bit 0
        pins = OutByte * %00010000 | RS    ; Put LSB out second
        PULSOUT lcde, 1                    ; Give a 10uS pulse on E
	  	  
          
return


'========= END SUBS =============================================

Of course my serial LCD and my 28x, 40x just showed up :p

Finally no more BS but it was good to learn because they are nice cheap lcd's for various projects

Cheers,

Derek L
 
Last edited:

hippy

Ex-Staff (retired)
when you use a statment like bit15 is that b15 of total memory.
so bit15 = w0 16 bit
bit30 = w1 15 bit

?
It's in the manual somewhere ...

b1 is MSB of w0, b0 is LSB of w0. bit15 is msb of w0 ( also msb of b1 ), bit0 is lsb of w0 ( also lsb of b0 ).

b3 is MSB of w1, b2 is LSB of w1. bit31 is msb of w1 ( also msb of b3 ), bit16 is lsb of w1 ( also lsb of b2 ) - But only for X1/X2, the rest only have bit0 to bit15.
 
Top