LM75A Temperature I2C

ramasule

Member
The following is a overview of the LM75A.

Picaxeforum helped me with the code so I see it only fair to put this back into picaxe forum for others.

The chip is fairly easy to use as the MSB from register 0 is the temp.

Getting Started

Datasheet:

http://www.datasheetcatalog.org/datasheet/philips/LM75A_1.pdf

=========================================================
The following code is to read a temperature via I2C at address 0 positive only:

i2cslave %10010000, i2cslow, i2cbyte ;Set ReadI2C to read from address 0

Code:
main:

  ReadI2c 0,(b1,b0)
  SerTxd ("Temperature is ", #b1,13,10)
  pause 1000

goto main
==========================================================
The following is to set a alarm temperature of 23c with a hysteresis of 21c
This will pull pin 3 of the IC down from 5v to 0v refer to datasheet
Pin 3 IC is connected to IN0 of Picaxe. Positive Only.

Code:
i2cslave %10010000, i2cslow, i2cbyte	;Set ReadI2C to read from address 0
writei2c 3,($17,00)				;Set Alarm Temperature of 23degC
writei2c 2,($15,00)				;Set Alarm Pullout temp of 21degC

main:

  ReadI2c 0,(b1,b0)				;Read register 0 to w0 (b1, b0)
  SerTxd ("Temperature is ", #b1," ")
  if pin0 = 1 then
	SerTxd ("Temp Good", 13, 10)
  else
	SerTxd ("Temp Bad :(",13,10)
  end if

  pause 1000

goto main
=========================================================
The following is to read 2 devices. Positive Only

Code:
main:

  i2cslave %10010000, i2cslow, i2cbyte  		;Address 0
  readi2c 0,(b1,b0)
  i2cslave %10011000, i2cslow, i2cbyte		;Address 1
  readi2c 0,(b3,b2)

  SerTxd("Probe 1 is ",#b1, " Probe 2 is ", #b3, 13, 10)
  
  pause 1000

goto main
========================================================
The following code is for one device negative and 3 decimal points (thanks hippy)

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 )

Complete code

Code:
i2cslave %10010000, i2cslow, i2cbyte	;Address 0

main:

  readi2c 0, (b1,b0)
  If w0 < $8000 Then				;Check for Sign Bit  (B1 bit 15)
    SerTxd( "+" )
  Else 
    w0 = -w0					
    SerTxd( "-" )
  End If
    w1 = b0 / 32 * 125				;Decimal reading, shift value and multiply by accuracy (0.125 deg)
  SerTxd( #b1, ".", #w1, 13, 10)
  
  pause 1000

goto main

========================================================
Here is my working temp reader with 18x. This uses the poor mans LCD and one LM75a.

Code:
;Documentation
;Pinout is as following:  From the Picaxe, Out0 -> LCD DB4, Out1 -> LM75A SDA Pin1
;Out2 -> LCD RS, Out3 -> LCDE, Out4 -> LM75A SCL Pin2, Out5 -> LCD DB5
;Out6 -> LCD DB6, Out7 -> LCD DB7
;
;
'============  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       ===============================================
lcdstatic:

	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, ($C8, $06), OutByte
		gosub LCDOut
	next counter

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

goto main

main:

	gosub i2ctemp
	gosub lcdtemp

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





lcdtemp:

	
	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

return

LCDOut: 
        
        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 =============================================


Enjoy,

Derek L
 
Last edited:

ramasule

Member
Serial LCDs make life so much better :)


Code:
hsersetup B9600_4, %10
hserout 0, ($fe, $2a, 125)
pause 50


hserout 0, ($fe, $01)
hserout 0, ($fe, $80, "Current Probe Temps")
hserout 0, ($fe, $c0, "Probe 1: ")
hserout 0, ($fe, $94, "Probe 2: ")


main:

  i2cslave %10010000, i2cslow, i2cbyte  		
  readi2c 0,(b1,b0)
  w1 = b0 / 32 * 125
  i2cslave %10011000, i2cslow, i2cbyte		
  readi2c 0,(b5,b4)
  w3 = b4 / 32 * 125
  
  If w0 < $8000 Then
    hserout 0, ($fe, $c9, "+")
  Else
    w0 = -w0
    hserout 0, ($fe, $c9, "-")
  End If
    hserout 0, (#b1, ".", #w1)

  If w2 < $8000 Then
    hserout 0, ($fe, $9d, "+")
  Else
     w2 = -w2
    hserout 0, ($fe, $9d, "-")
  End If
    hserout 0, (#b5, ".", #w3)

goto main
 
Last edited:
Top