IR temp sensor

jlangholzj

New Member
Alright guys, Just got my hands on a picaxe. They seemed like a pretty cool little unit and can do a lot when I don't need the umpf of a ARM core processor.

Little background:

Not a complete hardware idiot but embedded design is def. one of my weak points. I can code up and down all day in multiple languages but getting ports set up and some of the intricies of protocols can trip me up sometimes.


What I'm working with:
MLX90615 IR temp sensor
picaxe 18m2+
Data Sheet for the IR temp

The good:
Pic is working great, made lights go blinky....programs great...etc

NOW onto my problem.....

The IR sensor is smbus which from my understanding is compatible with i2c at rates lower than 100k. I've also found some documentation around the intertubes that guys have in fact got the sensor to work with something like an 08 or 20 pic.

I'm not getting anything that really makes sense with my code (down there at the bottom). I'm not entirely sure though about the i2c protocols and my scope isn't giving me something that makes sense. Mainly, I'm not entirely sure if I need to wait for the ACK from the device or not....some other things.

My main question is what address exactly I'm going to want to send for various commands. The object temp is at address $07 but in order to access rom the command needs to be 0010 aaaa based on the datasheet, giving me a $27 for the address. I'm ASSUMING that this is the address that I need to use for the hi2cin command instead of the slave address (default is something like $B4)

Which leads me to my next question, since you can have multiple devices on the buss...that would lend itself to wanting to access the slave address ($B4) instead of the ROM address command ($27). Soooo......So i need to write first, then read on the i2c buss? write to tell it the instruction at the given slave address and then read for the response that the slave is sending?

sorry if this doesn't make a whole lot of sense....lets see if this can fijure it out.

Code:
'Program to read from IR sensor
'SDSU FSAE
'Written by John Langholz
'MLX90615
init:

'symbols and defines
symbol ir_lo = b0
symbol ir_hi = b1
symbol ir_pec = b2
symbol slave_addr = b3
symbol temp = w2		;b4 and b5


'initialize i2c communications
slave_addr = $B4							;standard is $B4 but all respond to $00
hi2csetup i2cmaster, slave_addr, i2cslow, i2cbyte	;Set up the i2c protocols 10110100

main:

hi2cin $27, (ir_lo, ir_hi, ir_pec)				;read out of ram at location $07
temp = ir_hi*255 + ir_lo					;shift and add for the full word
temp = temp*2 - 27315						;convert into *C

SerTxD ("Temp = ", #temp, 13, 10)				;temp output shifted 2 dec left

pause	10								;wait to update temp set at 100Hz logging rate

goto main
 

ThierryP

New Member
By googling "mlx90614 mlx90615 difference" the resulting pdf doc reveals only minor differences between mlx90614 and mlx90615, so I expect the Picaxe software from Peter Anderson will work OK.
I used it successfully on my mlx90614, just need to find a good application for it.
I was triggered by this thermal imaging app, I got the mlx90614 and a 10W RGB LED plus ULN2003 driver, now I just need to find the time to play with it.

Thierry
 

jlangholzj

New Member
Page 7 of the data sheet says the address is $5B, did you try that?
tried that with the address....but again,Trying to sort out if its the way I'm going about trying to access the sensor, or something else.

By googling "mlx90614 mlx90615 difference" the resulting pdf doc reveals only minor differences between mlx90614 and mlx90615, so I expect the Picaxe software from Peter Anderson will work OK.
I used it successfully on my mlx90614, just need to find a good application for it.
I was triggered by this thermal imaging app, I got the mlx90614 and a 10W RGB LED plus ULN2003 driver, now I just need to find the time to play with it.

Thierry
tried a copy-paste with that guy. the 18m2+ doesn't support the extended addressing so I'm back to where I started. I'll try and dink around a bit more with that code and see if i can get anywhere.
 

Armp

Senior Member
This code is for the MLX90614 and I've run it on 08M2, 20M2 and 20M2 so I think it should work for you.
Used with mrburnettes permission.
Many thanks to Pete Anderson and mrburnette!

Code:
' MLX90614_08M2.Bas	
' (c)2011 by MR Burnette for all rights not reserved by PH Anderson
' Modified for M2 chips by Armp - Thanks Peter and Ray 1/12/13
'
' 20M2 - Straight Drop In Replacement for 20X2,
' 08M2 - Connect 20X2 socket Pin 11 to Pin 17, Pin 13 to Pin 18,
' 196 Bytes
'
#picaxe 20m2
#No_Data
 
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 SlaveAdr = $5A * 2 'Hi2cSetup does not allow General Call 0 address.

sertxd("Beginning data:",CR,LF)

Initialize:
' Return to this section on error condition on I2C bus CRC
Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte

Again: ' RAM location $07 is the object temperature in Kevin * 50
  
    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
    Sertxd (#Temperature,".",#Tenths,CR,LF)
     
    Pause 900	' Results in approx 1 reading per second
                  ' 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("CRC Error...", CR,LF)
     	Goto Initialize   
   
END
Edit: Differences between '614 and '615

You'll need to change
SYMBOL SlaveAdr = $5A * 2 to
SYMBOL SlaveAdr = $5B * 2

And
RamLocation = $07 to
RamLocation = $27

Edit 11/21/2014: Also known to work with 20X2, and 18M2+
The MLX90614Axx is spec'd down to 4.5v, and DOES NOT WORK reliably much below that. For other devices RTFM.
 
Last edited:

jlangholzj

New Member
This code is for the MLX90614 and I've run it on 08M2, 20M2 and 20M2 so I think it should work for you.
Used with mrburnettes permission.
Many thanks to Pete Anderson and mrburnette!

Code:
' MLX90614_08M2.Bas	
' (c)2011 by MR Burnette for all rights not reserved by PH Anderson
' Modified for M2 chips by Armp - Thanks Peter and Ray 1/12/13
'
' 20M2 - Straight Drop In Replacement for 20X2,
' 08M2 - Connect 20X2 socket Pin 11 to Pin 17, Pin 13 to Pin 18,
' 196 Bytes
'
#picaxe 20m2
#No_Data
 
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 SlaveAdr = $5A * 2 'Hi2cSetup does not allow General Call 0 address.

sertxd("Beginning data:",CR,LF)

Initialize:
' Return to this section on error condition on I2C bus CRC
Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte

Again: ' RAM location $07 is the object temperature in Kevin * 50
  
    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
    Sertxd (#Temperature,".",#Tenths,CR,LF)
     
    Pause 900	' Results in approx 1 reading per second
                  ' 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("CRC Error...", CR,LF)
     	Goto Initialize   
   
END
Edit: Differences between '614 and '615

I think you'll need to change
SYMBOL SlaveAdr = $5A * 2 to
SYMBOL SlaveAdr = $5B * 2

And
RamLocation = $07 to
RamLocation = $27
WOOHOO!

So it works. Not entirely sure why yet....but I can come back to that later.

My next question, Since all the sensors are programmed with the $5B address from factory does that mean that I need to talk to it first, change the address and then I can put multiple's on the bus and have it read correctly?
 

Armp

Senior Member
My next question, Since all the sensors are programmed with the $5B address from factory does that mean that I need to talk to it first, change the address and then I can put multiple's on the bus and have it read correctly?
Yes - you have to put them on the bus one at a time, then write a new address to EEPROM 0.
See page 9 of the '615 spec. Only need to do this once.

Let me know if you need help, or can't figure out why the above code works :rolleyes:
 
Last edited:

jlangholzj

New Member
Yes - you have to put them on the bus one at a time, then write a new address to EEPROM 0.
See page 9 of the '615 spec. Only need to do this once.

Let me know if you need help, or can't figure out why the above code works :rolleyes:

I'm starting to see how picaxe handles their i2c protocols...so its making much more sense....the only line that gets me is "$5A * 2" for the slave address. whats with the multiply by two? Does it need to be shifted for some reason....
 

nick12ab

Senior Member
Does it need to be shifted for some reason....
Yes, because on PICAXE the i2c slave address you have to specify has to include the read/write bit (but that is automatically changed by use of hi2cin/hi2cout command) but $5A is the i2c slave address not including this bit which is the least significant bit so to include it the bits must be shifted left.
 

jlangholzj

New Member
Yes, because on PICAXE the i2c slave address you have to specify has to include the read/write bit (but that is automatically changed by use of hi2cin/hi2cout command) but $5A is the i2c slave address not including this bit which is the least significant bit so to include it the bits must be shifted left.
:cool: Figured it was something like that. I'm going to do some digging around and see if I can find some more literature on how picaxe handles their protocol. All I was able to find was in the manual...which really doesn't lend a whole lot of explanation. I was wondering why their addresses never matched up :rolleyes:
 

Armp

Senior Member
I'm going to do some digging around and see if I can find some more literature on how picaxe handles their protocol. All I was able to find was in the manual...which really doesn't lend a whole lot of explanation. I was wondering why their addresses never matched up
The Manual says:
Most datasheets give the slave address in 8 bit format e.g.
1010000x - where x is don’t care (the read/write bit, PICAXE controlled)
However some datasheets use a 7 bit format. In this case the bits must be shifted
left to take account for the read/write bit.
IMHO the converse is true for most manufacturers today.
To avoid confusion I use the convention SYMBOL SlaveAdr = $5B * 2 to clearly show that I am shifting the I2C address left to comply with the requirements of Hi2cSetup.

What is %1010000x in HEX anyway? :)
 

jlangholzj

New Member
The Manual says:


IMHO the converse is true for most manufacturers today.
To avoid confusion I use the convention SYMBOL SlaveAdr = $5B * 2 to clearly show that I am shifting the I2C address left to comply with the requirements of Hi2cSetup.

What is %1010000x in HEX anyway? :)
Well I guess thats what I get for "skimming" and not "reading" :p Let me just try and pry my foot out of my mouth here quick...and last i checked its $Ax to answer...I meant the addresses in the MLX wouldn't match...They would note talking to address $5B and then send protocol of $B6. I never realized there was a bit-shift involved so it never quite dawned on me :rolleyes:
 

jlangholzj

New Member
well I finally got around to trying my hand at re-addressing this guy. Found some more of Anderson's code and modified it. Just wanted to run it your way before accidentally blasting one of my sensors. Take-look

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 18m2
#Terminal 4800

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, $5B, I2CSlow, I2CByte 

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

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


Again:

    EEPROMLocation = $10 + $00 ' 8'b0001 aaaa is the format for EEPROM access
    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
    

    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 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 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
thanks doods.
 

Armp

Senior Member
well I finally got around to trying my hand at re-addressing this guy. Found some more of Anderson's code and modified it. Just wanted to run it your way before accidentally blasting one of my sensors.
I don't think there's any danger of blasting a sensor as it looks as if your code does not make connection.

Pete's code used I2C addressing features of the X2 family that don't apply to the M2 - that's why I had to mod the code for the '614.

First he used a dummy address in hI2Csetup:

Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte

Then reads and writes to the sensor using the real address:
Code:
SlaveAdr_2 = NewSlaveAdr  * 2
....
Hi2cin [COLOR="#0000CD"][SlaveAdr_2][/COLOR], EEPROMLocation, (Lo, Hi, PEC)
....
Hi2cOut [COLOR="#0000CD"][SlaveAdr_2][/COLOR], EEPROMLocation, (Lo, Hi, PEC)
You couldn't use this as the M2 doesn't support it. So you used a dummy address of $5B.

Hi2cSetup I2CMaster, $5B, I2CSlow, I2CByte

Then your code tries to R/W from this address:
Code:
Hi2cin EEPROMLocation, (Lo, Hi, PEC)
....
Hi2cOut EEPROMLocation, (Lo, Hi, PEC)
Since there is no device at $5B these lines don't do anything. Unfortunately the PICAXE I2C Commands don't give any error messages as far as I can tell? The manual says " If the i2c hardware is incorrectly configured, or the wrong i2cslave data has been used, the value 255 ($FF) will be loaded into each variable."

You'll need to call hI2Csetup with the proper address - $5b*2 initially, then SlaveAdr_2 * 2 after you've changed the address.
 

jlangholzj

New Member
I don't think there's any danger of blasting a sensor as it looks as if your code does not make connection.

Pete's code used I2C addressing features of the X2 family that don't apply to the M2 - that's why I had to mod the code for the '614.

First he used a dummy address in hI2Csetup:

Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte

Then reads and writes to the sensor using the real address:
Code:
SlaveAdr_2 = NewSlaveAdr  * 2
....
Hi2cin [COLOR="#0000CD"][SlaveAdr_2][/COLOR], EEPROMLocation, (Lo, Hi, PEC)
....
Hi2cOut [COLOR="#0000CD"][SlaveAdr_2][/COLOR], EEPROMLocation, (Lo, Hi, PEC)
You couldn't use this as the M2 doesn't support it. So you used a dummy address of $5B.

Hi2cSetup I2CMaster, $5B, I2CSlow, I2CByte

Then your code tries to R/W from this address:
Code:
Hi2cin EEPROMLocation, (Lo, Hi, PEC)
....
Hi2cOut EEPROMLocation, (Lo, Hi, PEC)
Since there is no device at $5B these lines don't do anything. Unfortunately the PICAXE I2C Commands don't give any error messages as far as I can tell? The manual says " If the i2c hardware is incorrectly configured, or the wrong i2cslave data has been used, the value 255 ($FF) will be loaded into each variable."

You'll need to call hI2Csetup with the proper address - $5b*2 initially, then SlaveAdr_2 * 2 after you've changed the address.

This being the case, would you have to re-initialize after the "erase"? From my understanding the picaxe won't properly implement address $00...so I'm assumingthat all we'll ahve to worry about is after I sent the new address?
 

Armp

Senior Member
This being the case, would you have to re-initialize after the "erase"? From my understanding the picaxe won't properly implement address $00...so I'm assumingthat all we'll ahve to worry about is after I sent the new address?
You should never use Address $00 - it's a reserved address, used to see if there are any devices on the bus.
PICAXE doesn't implement the general call, and that's probably a good idea.

I'd try:
Fix the address error in your existing hi2csetup, then issue a write to eeprom address $00 to store a new valid address.
I'd suggest $5A maybe. I don't think you need to 'erase' the location first?
Power off/on the '615. Then reissue hi2csetup again with the new address (2*5A), and do a read of eeprom $00.
Check it's the value you just wrote $5A, and not $FF.

Others may already have working code?
 

jlangholzj

New Member
You should never use Address $00 - it's a reserved address, used to see if there are any devices on the bus.
PICAXE doesn't implement the general call, and that's probably a good idea.

I'd try:
Fix the address error in your existing hi2csetup, then issue a write to eeprom address $00 to store a new valid address.
I'd suggest $5A maybe. I don't think you need to 'erase' the location first?
Power off/on the '615. Then reissue hi2csetup again with the new address (2*5A), and do a read of eeprom $00.
Check it's the value you just wrote $5A, and not $FF.

Others may already have working code?

Current code:

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 18m2
#Terminal 4800

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

symbol slave_addr = $5B*2 'initial slave setup

Top:
    Pause 1000
    Hi2cSetup I2CMaster, slave_addr, I2CSlow, I2CByte 

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

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


Again:

    EEPROMLocation = $10 ' 8'b0001 aaaa is the format for EEPROM access
    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
    

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

    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 channel when done", CR, LF)
    SerRxD [45000], Ch

    SlaveAdr_2 = NewSlaveAdr  * 2
    
    Hi2cSetup I2CMaster, SlaveAdr_2, I2CSlow, I2CByte ' re-initialize the sensor for new address
    
    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", #Val, "Invalid", CR, LF)
    EndIf
      

    Pause 10000

    GoTo Again

ReadEEPROM:

    Hi2cin 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 ("Val from EEPROM:  ", #Val, CR, LF)
    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 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've managed to do something.....hahaha. It was reading that $5b was the correct address but it would not change the physical address at all...just kept $5b in there. Now it's giving me an "invalid address" for $5B and when i read from $10 for the EEprom I get all F's.

This would lead me to believe that I've blow away the address??
 

jlangholzj

New Member
Entered in 90 for the new slave address, Last I got anything out of it before this was "Current slave addr 5B" as if it had not changed. After a power reset was when I got the FFFF reply. Reverting back to the actual IR code gives me a CRC error as well.
 

Armp

Senior Member
Entered in 90 for the new slave address, Last I got anything out of it before this was "Current slave addr 5B" as if it had not changed. After a power reset was when I got the FFFF reply. Reverting back to the actual IR code gives me a CRC error as well.
When I enter 90 for the new slave address in the simulator I get 0 back... Must be a 'feature' of SerRxD I guess?

I'll leave it to the RevEd experts to figure out. Not sure if that's what Pete had in mind.
 

jlangholzj

New Member
When I enter 90 for the new slave address in the simulator I get 0 back... Must be a 'feature' of SerRxD I guess?

I'll leave it to the RevEd experts to figure out. Not sure if that's what Pete had in mind.
Thats what I get with the sim as wel.....kind of weird. Whenever I enter in the value it always gives me the correct decimal representation back....I'll do some more looking tonight and see what i can come up with.
 

Buzby

Senior Member
From post #16
PICAXE doesn't implement the general call, and that's probably a good idea.
I totally disagree.

General call should be implemented as a broadcast that every PICAXE slave reacts to.

The slave may reply if the broadcast includes a token it recognises, or alternatively the slave could just store the data.

General Call is part of the NXP I2C standard ( admittedly optional, but good to have ) which PICAXE slaves should adhere to, and PICAXE Masters should be able to send.

( Prompted by my project which would have benefited greatly if PICAXE did support GC. )

Cheers,

Buzby
 

Armp

Senior Member
From post #16

I totally disagree.

General call should be implemented as a broadcast that every PICAXE slave reacts to.

The slave may reply if the broadcast includes a token it recognises, or alternatively the slave could just store the data.
Point taken Jeff. But you're not a typical picaxe user. Most wouldn't know how to use a general call.
 

Armp

Senior Member
When I enter 90 for the new slave address in the simulator I get 0 back... Must be a 'feature' of SerRxD I guess?

I'll leave it to the RevEd experts to figure out. Not sure if that's what Pete had in mind.
This is what the manual says:
Reading number values

When the #variable format is used received data will be taken and converted to a number.

All characters received are ignored until the first ASCII digit character is received. A number is then determined until a non-digit character is received. The value stored in the variable will be number represented by the digit characters received. Note that the #variable will not complete until the number has been terminated by a non-digit character being received.
So if you type in 90, surely SerRxD [15000, TryAgn], #NewSlaveAdr should assign the value 90 to NewSlaveAdr?
 

jlangholzj

New Member
This is what the manual says:


So if you type in 90, surely SerRxD [15000, TryAgn], #NewSlaveAdr should assign the value 90 to NewSlaveAdr?

well i end up tying in "90d" or whatever other letter my finger decides to hit just for that reason. the SerTxd after the Rxd will read back the correct entered value however showing that NewSlaveAdr is in fact being assigned the value of 90
 

Armp

Senior Member
well i end up tying in "90d" or whatever other letter my finger decides to hit just for that reason. the SerTxd after the Rxd will read back the correct entered value however showing that NewSlaveAdr is in fact being assigned the value of 90
Yeah - I was playing earlier and discovered that "90" (90 in quotes) worked... Not sure why? And no feedback from any of the 'gurus' so far.

Pete Anderson was a smart guy, and a pleasure to do business with - but some of his code is a little confusing!

Have you tried accessing the '615 at $5A, or the original value of $5B?
 

jlangholzj

New Member
Yeah - I was playing earlier and discovered that "90" (90 in quotes) worked... Not sure why? And no feedback from any of the 'gurus' so far.

Pete Anderson was a smart guy, and a pleasure to do business with - but some of his code is a little confusing!

Have you tried accessing the '615 at $5A, or the original value of $5B?
both, with no success thus far. Both the re-addressing code and the IR temp read code. The IR read code gives a CRC...haven't gotten around to actually displaying the values yet. The re-address gives FF's for both slave addresses
 

jlangholzj

New Member
so I wrote this little chunk of code:

Code:
' MLX90614_08M2.Bas	
' (c)2011 by MR Burnette for all rights not reserved by PH Anderson
' Modified for M2 chips by Armp - Thanks Peter and Ray 1/12/13
'
' 20M2 - Straight Drop In Replacement for 20X2,
' 08M2 - Connect 20X2 socket Pin 11 to Pin 17, Pin 13 to Pin 18,
' 196 Bytes
'
' Modified by JlangholzJ and Armp for use in 18m2+
' Also modified for MLX90615
' 18M2+ - Stright drop in
'
#picaxe 18m2
#No_Data
 
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

SlaveAdr = $01 * 2 'shift left by a bit to allow read/write bit.

sertxd("Beginning data:",CR,LF)

Initialize:
' Return to this section on error condition on I2C bus CRC
Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte

Again: ' RAM location $07 is the object temperature in Kevin * 50 
  
    RamLocation = $27
    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
    Sertxd ("Temp: ", #Temperature,".",#Tenths,CR,LF)
    Sertxd ("Addr: ", #SlaveAdr,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
that I'm hoping would scan for the channel in use. I figured that it would start at addr $01 and if it got a valid answer out of any of the temp reg at any of the locations it would be a valid address. Didn't get anything but I can't test it either because my sensor is poofed....Ordered up a couple more of these buggers to try and figure out wtf is going on here.
 

Armp

Senior Member
I suspect its slave address is set to address 00 which picaxe can't handle.

Try this simplified test - will show if anything is read, regardless of pec validity. Are any data fields <>$FF?

Code:
#picaxe 18m2
#No_Data

SYMBOL Lo 		= B0	
SYMBOL Hi 		= B1
SYMBOL PEC 		= B2
SYMBOL RamLocation= B3 	
SYMBOL SlaveAdr = B4

sertxd("Beginning Test:",CR,LF)

Main:

For SlaveAdr = 0 to 254 step 2
    Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte 
    RamLocation = $27
    Hi2cin  RamLocation, (Lo, Hi, PEC)    
    Sertxd ("Address: ", #SlaveAdr," Data: ",#Lo," ",#Hi," ",#PEC,CR,LF)
    Pause 900	' Results in approx 1 reading per second 900                  
Next
If that tells us nothing you can send it to me. I can give it a thorough test and send it back. Check your private mail
 
Last edited:

jlangholzj

New Member
I suspect its slave address is set to address 00 which picaxe can't handle.

Try this simplified test - will show if anything is read, regardless of pec validity. Are any data fields <>$FF?



If that tells us nothing you can send it to me. I can give it a thorough test and send it back. Check your private mail
I was thinking along the same lines as the above. I'll check it out and see what I get.
 

Armp

Senior Member
armp said:
PICAXE doesn't implement the general call, and that's probably a good idea.
I totally disagree.

General call should be implemented as a broadcast that every PICAXE slave reacts to.
Well Buzby - after spending a week 'playing' with the picaxe I2C support I'm going to agree with you.
I've spent far too much time trying to figure out what I2C features they support, and what they don't.

I would add:
hI2Csetup should not arbitrarily specify which addresses may or may not be used.
hI2cin and hI2Cout should return error codes .
They should also support RESTART and not issue a STOP on each operation. Try writing a full 64byte page to eeprom.

Anyone got bit banged routines for the picaxe?
 

Buzby

Senior Member

Armp

Senior Member
Bit banged I2C exists, hippy did it.

I was going to re-implement his code, but thought better of it.
I was just trying to find a way for jlangholzj to verify that his sensor would respond to $00.
I have several platforms that implement I2C completely and correctly ;)
 

Armp

Senior Member
If you have a Master that can send General Call, Arduino maybe, you could see what a PICAXE slave does with it. I'd really like to know.
BTW Pete Anderson did reads and writes to address 0 using a 20X2 by using any nonzero address in setup, and the [newslave] parameter in i2cin/out.

Code:
Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte 

    SlaveAdr_2 = $00 * 2 ' use general slave adr

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

Buzby

Senior Member

I would add:
hI2Csetup should not arbitrarily specify which addresses may or may not be used.
hI2cin and hI2Cout should return error codes .
They should also support RESTART and not issue a STOP on each operation. Try writing a full 64byte page to eeprom.
Hi Armp,

Addresses, totally agree, PICAXE Masters should not limit ending to any address.

Error codes, not sure about this. The '255' that comes back after a 'read' from a faulty or non-existent Slave is just the same a a valid 255 from a working device. How could the Master tell the difference ?

RESTART and STOP, let's get GC working first, then we'll move on toi more advanced stuff !.

Cheers,

Buzby
 

Buzby

Senior Member
BTW Pete Anderson did reads and writes to address 0 using a 20X2 by using any nonzero address in setup, and the [newslave] parameter in i2cin/out.

Code:
Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte 

    SlaveAdr_2 = $00 * 2 ' use general slave adr

    Hi2cin [SlaveAdr_2], RamLocation, (Lo, Hi, PEC)
I wish I'd known that !.

Does that mean that the optional [Slave Adr] in hi2cin / out behaves differently that the address in hi2csetup ?

And if a $00 address can be sent, what does the PICAXE Slave do with it ?.
 

Armp

Senior Member
Error codes, not sure about this. The '255' that comes back after a 'read' from a faulty or non-existent Slave is just the same a a valid 255 from a working device. How could the Master tell the difference ?
That's what ack/nack is there for I think?
 
Top