PDA

View Full Version : IR temp sensor



astanapane
- 18th September 2020, 16:35
Dear all,

i need your help regarding the following code for the MLX90614 ir temp sensor.

Finally i have some readings from the sensor at Object1 address $07.

I do get the right temp value from the first 2 digits (XX) XX.YY

For the second 2 digits (YY) XX.YY i see that numbers goes up to .49 and then the first two XX digits increase by one. It suppose XX change when the YY goes up to .99

Could anyone help please?



'*****************************************
'* Name : MLX90614.BAS *
'* Notes : 4D Systems - IR TEMP SENSOR *
'*****************************************


#IF __PROCESSOR__ = "18F26k22"

@ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of *
; crossing page boundary - make sure bits are set *
'************************************************* ********************************

#CONFIG ; The PBP configuration for the PIC18F26K22 is:
CONFIG FOSC = HSHP ; HS oscillator (high power > 16 MHz)
CONFIG PLLCFG = OFF ;Oscillator used directly
CONFIG PRICLKEN = ON ;Primary clock enabled
CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled
CONFIG IESO = OFF ;Oscillator Switchover mode disabled
CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
CONFIG WDTEN = ON ; WDT is always enabled. SWDTEN bit has no effect
CONFIG WDTPS = 32768 ; 1:32768 ---> HERE enable the watchdog timer with a 1:32768 postscale
CONFIG PWRTEN = ON
CONFIG HFOFST = ON ; HFINTOSC output and ready status are not delayed by the oscillator stable status
CONFIG MCLRE = EXTMCLR ; MCLR pin enabled, RE3 input pin disabled
CONFIG LVP = OFF ; Single-Supply ICSP disabled
CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
CONFIG DEBUG = OFF ; Disabled
CONFIG CP0 = OFF ; Block 0 (000800-003FFFh) not code-protected
CONFIG CP1 = OFF ; Block 1 (004000-007FFFh) not code-protected
CONFIG CP2 = OFF ; Block 2 (008000-00BFFFh) not code-protected
CONFIG CP3 = OFF ; Block 3 (00C000-00FFFFh) not code-protected
CONFIG CPB = OFF ; Boot block (000000-0007FFh) not code-protected
CONFIG CPD = OFF ; Data EEPROM not code-protected
CONFIG WRT0 = OFF ; Block 0 (000800-003FFFh) not write-protected
CONFIG WRT1 = OFF ; Block 1 (004000-007FFFh) not write-protected
CONFIG WRT2 = OFF ; Block 2 (008000-00BFFFh) not write-protected
CONFIG WRT3 = OFF ; Block 3 (00C000-00FFFFh) not write-protected
CONFIG WRTC = OFF ; Configuration registers (300000-3000FFh) not write-protected
CONFIG WRTB = OFF ; Boot Block (000000-0007FFh) not write-protected
CONFIG WRTD = OFF ; Data EEPROM not write-protected
CONFIG EBTR0 = OFF ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
CONFIG EBTR1 = OFF ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
CONFIG EBTR2 = OFF ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
CONFIG EBTR3 = OFF ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
CONFIG EBTRB = OFF ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks

#ENDCONFIG

#ELSE
#MSG "Wrong Processor selected!"
#ENDIF

;*-----------------------------------------------------------------------------|
;*-----------------------------------------------------------------------------|
define OSC 16

INCLUDE "modedefs.bas"
INCLUDE"ALLDIGITAL.pbp"

OSCCON = %01110000 ; 16Mhz
'------------------------------------------------------------------------------|
' INITIALIZE RAM |
'------------------------------------------------------------------------------|
initialize:
CLEAR

TRISA = %00000000
TRISB = %00000000
TRISC = %10000110

'------------------------------------------------------------------------------|
'----------------------- At start all PORTS LOW -------------------------------|
'------------------------------------------------------------------------------|
PORTA = 0 'make low all ports at A range |
PORTB = 0 'make low all ports at B range |
PORTC = 0 'make low all ports at C range |
'------------------------------------------------------------------------------|

'------------------------------------------------------------------------------|
'-------------------------- COMPARATORS OFF -----------------------------------|
'------------------------------------------------------------------------------|
CM1CON0.7 = 0 'Disable comparator1 |
CM2CON0.7 = 0 'Disable comparator2 |
'------------------------------------------------------------------------------|

'*-----------------------------------------------------------------------------|
Timeout CON 2000
addr var byte
reg var word

ORANGE var LATA.2 ' ORANGE LED TO INDICATE POWER ON OF THE PIC
BLUE var LATC.0 ' BLUE LED TO INDICATE SENSOR WOKRING CONDITION
SDA var portc.1 ' DATA PIN
SCL VAR portc.2 ' CLOCK PIN

sign var byte ' for + or -
TEMP var word ' this is the word variable for TEMP
temperature var word ' for result and output to lcd
TEMPIR var word ' set a variable tempir
Remainder var word ' Get the remainder = tempir//50
Sign_Bit VAR Temp.Bit14 ' Sign-Bit for +/- Temp. 1 = Below 0 deg C
SignCold CON 1 ' Define Sign Cold = 1
'*-----------------------------------------------------------------------------|
'* | --------------------- | |
'*----------------------- | EUART 1 Configuration | --------------------------|
'* | --------------------- | |
'*-----------------------------------------------------------------------------|

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 25 ' 38400 Baud @ 16MHz, 0.16%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

'*-----------------------------------------------------------------------------|
'*-----------------------------------------------------------------------------|


' -----------------------------------------------------------------------------|
' [ LCD Initialization ] |
'------------------------------------------------------------------------------|
gosub initlcd
'------------------------------------------------------------------------------*
start:
gosub object

goto start
'------------------------------------------------------------------------------*
' Measure object temp *
'------------------------------------------------------------------------------*
object:
reg = $07 ' based on the datasheet $07 is the object's temp
addr = %10110100 ' $B4 binary value: %10110100
i2cwrite SDA, scl, addr ' shift the address B4, 8 bits where LSB is W = 0
i2cwrite sda, scl, reg ' register is $07

addr = %10110101 ' $B5 Binary value: %10110101
i2cwrite sda, scl, addr ' shift the address B5, 8 bits where LSB is R = 1, clock idles low
i2cread SDA, SCL, 0,reg,[temp.lowbyte,temp.highbyte] ' reg = $07

Sign = "+"
'shifts 8 bits to the left
tempir = temp.highbyte << 8
tempir = tempir + temp.lowbyte ' add the temp.lowbyte

temperature = tempir/50 ' based on the manual we need to divide by 50 or 0.02
temperature = temperature - 273 ' subtract 273 for Degree in C,actually is 273,15
remainder = tempir//50 ' i think this gives me a wrong result or it may need some better maths to get the right value.

pause 100
gosub display
return

'------------------------------------------------------------------------------*
' Display the parameters *
'------------------------------------------------------------------------------*
display:

hserout [$73,$00,$02,$12,$00,$ff,"TEMP =", Sign,dec2 temperature,".",dec2 remainder,"*C",00]
Hserin timeout,error,[wait(6)]
hserout [$73,$02,$06,$10,$ff,$00,"RAW IR = ",dec tempir,00]
Hserin timeout,error,[wait(6)]
hserout [$73,$02,$08,$10,$ff,$00,"T HI = ",dec temp.highbyte,00]
Hserin timeout,error,[wait(6)]
hserout [$73,$02,$0A,$10,$ff,$00,"T LOW = ",dec temp.lowbyte,00]
Hserin timeout,error,[wait(6)]
return

'------------------------------------------------------------------------------*

error:
high blue
PAUSE 10
return
'------------------------------------------------------------------------------*

' FIRST TIME BOOTUP: We give plenty of time for tbe LCD '
initlcd:
pause 1000
HSEROUT[$55] ' uOLED Initialize this is the 'U' character of autoband rate to LCD
Hserin timeout,error,[wait(6)]
hserout[$56,$01] ' this is the Version info --> '01 10 17 28 28 -->> "(("
Hserin timeout,error,[wait(1),wait(16),wait(23),wait(40),wait(40)]
PAUSE 1000
HSEROUT [$45] ' clear the LCD
Hserin timeout,error,[wait(6)]
pause 500

Hserout[$4F,$01] ; Set Transparent-Opaque Text - 4Fhex
Hserin timeout,error,[wait(6)]

HSEROUT [$45] ' clear the LCD
Hserin timeout,error,[wait(6)]

high orange
return

end



As a last thought, i would like to add a sign depends on the bit which is responsible to + or -.



IF sign_Bit = signCold THEN Change_Sign ' If Sign_Bit = 1, it's below "0" deg C

'------------------------------------------------------------------------------*
' If it is cold change to "-" *
'------------------------------------------------------------------------------*
Change_Sign:
Sign = "-" ' Display - symbol for negative temp
tempir = temp.highbyte << 8
tempir = tempir + temp.lowbyte ' add the temp.lowbyte

temperature = tempir/50 ' based on the manual we need to divide by 50 or 0.02
temperature = temperature - 273 ' subtract 273 for Degree in C,actually is 273,15
remainder = tempir//50
return

HenrikOlsson
- 18th September 2020, 19:45
Yeah, when you do x= y // 50 it will do a divide by 50 and then give you the remainder which can't be more than 49, right?

If you first multiply the raw value by 2 it means you can then divide by 100 (instead of 50) and do modulo 100 (that's the // operator) to give you two digits after the decimal point. This won't increase the resolution, you'll still have 50 "steps" to the right of the decimal point but they will range from 0 to 98 instead of from 0 to 49.

astanapane
- 18th September 2020, 20:36
Yeah, when you do x= y // 50 it will do a divide by 50 and then give you the remainder which can't be more than 49, right?

If you first multiply the raw value by 2 it means you can then divide by 100 (instead of 50) and do modulo 100 (that's the // operator) to give you two digits after the decimal point. This won't increase the resolution, you'll still have 50 "steps" to the right of the decimal point but they will range from 0 to 98 instead of from 0 to 49.

Thanks Henrik,

i will try it out now.

In the mean time i was playing with the ERPROM registers in order to assign the sign bit. I will leave that on a side and try your advice.

pedja089
- 18th September 2020, 20:36
Can you display raw register data?
So you can compare result of your calculation with register value. Maybe sensor have some drift issues.

astanapane
- 18th September 2020, 21:01
Henrik,

it worked!!!

i did the following.


remainder = (TEMPIR*2)//100

It looks like it worked as expeced.

Now i'm focusing to get the sign bit.

astanapane
- 18th September 2020, 21:05
Can you display raw register data?
So you can compare result of your calculation with register value. Maybe sensor have some drift issues.

i can display values depends on the temp...yes.

like 14971. When i divide that by 50 it give me 299,42.

Then i seperate the 299 and the 42 as remainder.

The calculation then is : 299 - 273 in order to get the value in Degree C. The problem is that i do not have the right knowledge to divide that by 273,15. But that is ok for me at the moment.