Infra red temperature sensors

Captain Haddock

Senior Member
Has anyone found a good infrared temperature sensor that works with picaxe? Preferably at a decent cost with digital output, i2c would be nice as I have thermocouple circuit using i2c which displays to a glcd so could be tagged in assuming different address.
I'm considering a project to check the temp of a rotating shaft so obviously contact type sensors like ds18b20 would be no use.
 
I now have a couple of MLX90614 sensors and can read each one seperately using the prog from PH Anderson as long as I change the slave address as I get a syntax error with the original figure of 45, I used %01010000.
But.... Try as I might using his prog for changing address I just can't get it to make any changes, I'm using a 20x2 and the codes is as follows, I've cycled the power and nothing changes, any help appreciated.

Code:
' MLX90614_3.Bas
'
' Prompts user for SlaveAddress and writes this to EEPROM address $0e.  Note that
' $00 is used as the SlaveAddress up to this point.  But the new slave address is
' used to read and display the content of location $0e.
'
' The intent is a framework for a program to modify the slave address to something
' other than $5a to allow for more than one device on the same bus.
'
' Note that after a lot of frustration, I discovered that after programming a new
' slave address, I had to recycle power to the MLX90614 for the new slave address to
' be recognized.
'
'
' PICAXE-20X2               MLX90614ESF-AAA
'
' Term 11 SCL --------------- SCL
' Term 13 SDA --------------- SDA
'
' 4.7K resistors to +5 VDC on SDA and SCL
'
' Note that this is a direct interface with the PICAXE.  The Parallax and
' Sparkfun boards are not required.
'
'
' copyright, Peter H Anderson, Baltimore, MD, Mar 15, 11

#picaxe 20x2
#Terminal 9600
#No_Table
#No_Data
#freq m4

Symbol Lo = B0
Symbol Hi = B1
Symbol PEC = B2
Symbol Status = B3

Symbol Ch = B5
Symbol Val = W3
Symbol I = B8
Symbol J = B9
Symbol K = B10
Symbol SlaveAdr_2 = B11
Symbol EEPROMLocation = B12

Symbol CRC8 = B13
Symbol X = B14
Symbol NewSlaveAdr = B15

Top:
    Pause 1000
    Hi2cSetup I2CMaster, %01010000, I2CSlow, I2CByte

TryAgn:
    SerTxD ("Enter New Slave Address: ")
    SerRxD [15000, TryAgn], #NewSlaveAdr
    SerTxD (#NewSlaveAdr, CR, LF);

    Pause 5000 ' pause to admire
        
    SlaveAdr_2 = $00 * 2   ' Use the general address for now


Again:

    EEPROMLocation = $20 + $0e
    GoSub ReadEEPROM

    If Status = 1 Then
          Val = Val & $00ff ' take the low byte
          SerTxD ("Current Slave Adr: ", #Val, CR, LF)
    Else
          SerTxD ("Current Slave Adr", "Invalid", CR, LF)
    EndIf

    Pause 5000
  
    SlaveAdr_2 = $00 * 2 

    Val = $00
    GoSub WriteEEPROM         ' erase location $0e

    Val = NewSlaveAdr         ' now program in the new slave address
    GoSub WriteEEPROM

    ' recycle power to the MLX90614 before trying to use the new slave address

    SerTxD ("Recycle power to the MLX90614.  Key in a number when done", CR, LF)
    SerRxD [45000], Ch

    SlaveAdr_2 = NewSlaveAdr  * 2
    GoSub ReadEEPROM

    If Status = 1 Then
          Val = Val & $00ff ' take the low byte
          SerTxD ("Current Slave Adr: ", #Val, CR, LF)
    Else
          SerTxD ("Current Slave Adr", "Invalid", #Val, CR, LF)
    EndIf
      

    Pause 10000

    GoTo Again

ReadEEPROM:

    Hi2cin [SlaveAdr_2], EEPROMLocation, (Lo, Hi, PEC)

    Val = Hi
    Val = Val * 256 + Lo
                              
    CRC8 = $00
    X = SlaveAdr_2
    GoSub CalcCRC8
    X = EEPROMLocation
    GoSub CalcCRC8
    X = SlaveAdr_2 + 1
    GoSub CalcCRC8
    X = Lo
    GoSub CalcCRC8
    X = Hi
    GoSub CalcCRC8
    X = PEC
    GoSub CalcCRC8

    ' SerTxD ("CRC = ", #CRC8, CR, LF)
    If CRC8 = 0 Then
       Status = 1 ' success
    Else
       Status = 0
    Endif

    SerTxD (#SlaveAdr_2, "  ", #EEPROMLocation, CR, LF)   
    Return

WriteEEPROM:

     Lo = Val     
     Hi = $00

     CRC8 = $00

     X = SlaveAdr_2
     GoSub CalcCRC8
     X = EEPROMLocation
     GoSub CalcCRC8
      
     X = Lo
     GoSub CalcCRC8
     X = Hi
     GoSub CalcCRC8
     PEC = CRC8

     Hi2cOut [SlaveAdr_2], EEPROMLocation, (Lo, Hi, PEC)
     Pause 20
 
     Return
 
CalcCRC8:

   X = X ^ CRC8
   For K = 0 to 7
      If X > 127 Then
         X = X * 2
         X = X ^ $07
      Else
         X = X * 2
      Endif
   Next
   CRC8 = X
   Return

I also tried his prog for reading the eeprom after cycling power and nothing changes.
 
Hi,

There are a couple of "oversights" in the Professor's code: Although he usually remembered to multiply the "7-bit" Slave address by 2, as required for the PICaxe, it's omitted in his Hi2cSetup command, which should NOT use 45 (decimal) but 90 (or $5A); nor the %01010000 (or 80 or $50) that you've used. Also his "... Slave Adr ", "Invalid" should include a separating space (as here).

Another potential issue is that his program initially uses a "General Call" address (00), which I believe is more a feature of the SMBus than the normal I2C Bus protocol. It appears this might NOT be supported on some of the (current) PICaxes, including the 20X2; See post #4 from technical HERE . Therefore, I recommend using the Slave Address 90 ($5A) throughout.

Another potential issue is the interpretation of the instruction to "Recycle Power". If you only open the supply connection to the MLX90614 module, there is a risk that it will remain "Phantom Powered" via the I2C bus lines (which idle High), and not actually reset. Thus you may need to briefly short-circuit the sensor supply rail (only) to ground. Or a better way might be to simply power it from a PICaxe Port pin, so that the Program can "automatically" reset the MLX90614 by pulling the pin Low. Also be aware that the SERRXD command that is used, will "automatically" send a DISCONNECT command to the PICaxe, which means that the PICaxe will require a "Hard Reset" (i.e. a Physical Power Down) when it is being re-programmed.

Cheers, Alan.
 
Last edited:
Got it to change addresses at last and can now connect both and chose via the slave address, just spotted and removed a # from SerRxd line:
Code:
TryAgn:
    SerTxD ("Enter New Slave Address: ")
    SerRxD [15000, TryAgn], #NewSlaveAdr
    SerTxD (#NewSlaveAdr, CR, LF);

Thanks for the help chaps, now I can move on a bit.
 
Sorry for the delayed update, got this working now with the following code.
Code:
'
#picaxe 08m2
#No_Data
#Terminal 4800
 
SYMBOL Lo         = B0    ' B1-B0 overmapped by W0
SYMBOL Hi         = B1
SYMBOL Temperature= W0

SYMBOL PEC         = B2
SYMBOL RamLocation= B3  ' Could be a Constant in this example

SYMBOL X          = B4
SYMBOL Tenths    = B4       
SYMBOL N          = B5
SYMBOL CRC8     = B6
SYMBOL LOG_RATE    = 1000    'Used as a pre-def for the logging rate (HZ)
SYMBOL PAUSE_TIME    = 1000/LOG_RATE
    
SYMBOL SlaveAdr = B7

Again: ' RAM location $07 is the object temperature in Kevin * 50
SlaveAdr = $32 * 2 'shift left by a bit to allow read/write bit.
Initialize:' Return to this section on error condition on I2C bus CRC
Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte
 
    RamLocation = $07
    GoSub ReadRAM
    If Temperature = 0 Then Error
        
   Temperature = Temperature+2/5       'Use for Kelvin - integer divide by 5 with Rounding
    'Temperature = Temperature - 12767 *3 /5 *3 /5  'to return Temp as xxx.xF - Armp
    
    Tenths=Temperature//10 : Temperature=Temperature/10 : Temperature=Temperature-273
    Sertxd ("Temp: ", #Temperature,".",#Tenths,CR,LF)
    Sertxd ("Plain ", #SlaveAdr,CR,LF)
    Sertxd (CR,LF)
    
    Pause LOG_RATE    ' Results in approx 1 reading per second 900
                      ' MLX90614 requires 865ms to settle
    '-------------------------------------------------------------
    
    SlaveAdr = $30 * 2 'shift left by a bit to allow read/write bit.

Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte

    RamLocation = $07
    GoSub ReadRAM
    If Temperature = 0 Then Error
        
   Temperature = Temperature+2/5       'Use for Kelvin - integer divide by 5 with Rounding
    'Temperature = Temperature - 12767 *3 /5 *3 /5  'to return Temp as xxx.xF - Armp
    
    Tenths=Temperature//10 : Temperature=Temperature/10 : Temperature=Temperature-273
    
    Sertxd ("Temp: ", #Temperature,".",#Tenths,CR,LF)
    Sertxd ("Black ", #SlaveAdr,CR,LF)
    Sertxd (CR,LF)
    
    Pause LOG_RATE    ' Results in approx 1 reading per second 900
                      ' MLX90614 requires 865ms to settle
    
 GoTo Again

ReadRAM:
    Hi2cin  RamLocation, (Lo, Hi, PEC)   
    CRC8 = $00
    X = SlaveAdr      : GoSub CalcCRC8
    X = RamLocation    : GoSub CalcCRC8
    X = SlaveAdr + 1    : GoSub CalcCRC8
    X = Lo            : GoSub CalcCRC8
    X = Hi            : GoSub CalcCRC8
      
    If CRC8 <> PEC Then
       Temperature = 0        ' Return Zero K if CRC Error
    Endif   
 
    Return

CalcCRC8:
   X = X ^ CRC8
   For N = 0 to 7
      If X > 127 Then
         X = X * 2
         X = X ^ $07
      Else
         X = X * 2
      Endif
   Next
   CRC8 = X
   Return

Error:
       Sertxd("ADDR ", #SlaveAdr, " Not valid", CR,LF)
      
       SlaveAdr = SlaveAdr + 1      'inc slave addr and re-init
      
         Goto Initialize   
  
END



Now have a version of my thermocouple prog with this grafted in to display all on a glcd display, won't find out if it works for a couple of weeks when I'm next at the boat to try it.
Thanks for all help given.
 
Back
Top