program IR_Thermometer ' * IR_Thermometer ' * Copyright C.TAVERNIER- 2010 ' * for Elektor Magazine ' * www.tavernier-c.com ' * ' * Microchip PIC16F876A and ' * Melexis MLX90614 IR Thermometer ' LCD module connections ' LCD used in 4 bits mode on Port B dim LCD_RS as sbit at RB2_bit LCD_EN as sbit at RB3_bit LCD_D4 as sbit at RB4_bit LCD_D5 as sbit at RB5_bit LCD_D6 as sbit at RB6_bit LCD_D7 as sbit at RB7_bit LCD_RS_Direction as sbit at TRISB2_bit LCD_EN_Direction as sbit at TRISB3_bit LCD_D4_Direction as sbit at TRISB4_bit LCD_D5_Direction as sbit at TRISB5_bit LCD_D6_Direction as sbit at TRISB6_bit LCD_D7_Direction as sbit at TRISB7_bit ' End LCD module connections ' Variable definitions dim SensorLow as byte ' Raw temp. low byte SensorHigh as byte ' Raw temp. high byte SensorRaw as word ' Raw temp. word SensorRawCur as word ' Current raw temp. SensorRawMax as word ' Max. raw temp. SensorRawMin as word ' Min. raw temp. Sensor as float ' Real temp (floating point) SensorString as string[9] DisplayString as string[9] PEC as byte ' Control byte (read but not used) com as byte ' MLX90614 command PosDecPoint as byte ' Decimal point position i as byte ' Procedure definition ' Read Temperature From MLX90614 ' Input : com specify temp. to read ' Output : raw temp as a word Sub procedure Read_temp(dim com as byte) I2C1_Start() ' issue I2C start signal I2C1_Wr(0x00) ' send address (device address + W) I2C1_Wr(com) ' send command I2C1_Repeated_Start() ' issue I2C signal repeated start I2C1_Wr(0x01) ' send address (device address + R) SensorLow = I2C1_Rd(1) ' Read temp. low byte (acknowledge) SensorHigh = I2C1_Rd(1)' Read temp. high byte (acknowledge) PEC = I2C1_Rd(1) ' Read PEC (not used) (acknowledge) I2C1_Stop() ' issue I2C stop signal SensorRaw = SensorLow + (SensorHigh << 8) ' Build temp. word End sub ' Convert raw data in SensorRaw ' to displayable string in DisplayString Sub procedure Convert_raw Sensor = SensorRaw * 0.02 - 273.15 ' Raw temp to Celsius FloatToStr (Sensor, SensorString) ' Float to string PosDecPoint = Strchr (SensorString,".") ' Search for dec. point For i = 0 to PosDecPoint+2 ' Limit display to two digits DisplayString[i] = SensorString[i] ' after decimal point Next i DisplayString[PosDecPoint+3]= "" DisplayString = DisplayString + " C" End sub ' Main Program main: ' Initialize I/O PORTB = 0 TRISB = 0 ' All PORTB lines as output ADCON1 = 0x0F ' Configure AN pins as digital I/O ' Initialize LCD display Lcd_Init() ' Initialize Lcd Lcd_Cmd(_LCD_CLEAR) ' Clear display Lcd_Cmd(_LCD_CURSOR_OFF) ' Cursor off ' Initialize Min and Max object temp. SensorRawMax = 0 SensorRawMin = 0xFFFF ' Initialize SMBus I2C1_Init(100000) ' I2C/SMBus Clock speed 100 kHz SETBIT (SSPSTAT,6) ' Force MSSP in SMBus mode while true Read_temp (0x06) ' Read ambiant temp. Convert_raw Lcd_Out(1,1,"T Amb. : ") ' Write ambiant temp in first row Lcd_Out(1,10,DisplayString) Read_temp (0x07) ' Read object temp. SensorRawCur = SensorRaw ' Make obj. temp. current temp. If SensorRawCur > SensorRawMax Then ' Is current temp. higher than max. temp. SensorRawMax = SensorRawCur ' Make max. temp. equal current temp. End if If SensorRawCur < SensorRawMin Then ' Is current temp. lower than min. temp. SensorRawMin = SensorRawCur ' Make min. temp. equal current temp. End if Convert_raw Lcd_Out(2,1,"T Obj. : ") ' Write object temp in second row Lcd_Out(2,10,DisplayString) SensorRaw = SensorRawMax Convert_raw Lcd_Out(3,1,"T Max. : ") ' Write Max object temp in third row Lcd_Out(3,10,DisplayString) SensorRaw = SensorRawMin Convert_raw Lcd_Out(4,1,"T Min. : ") ' Write Min object temp in fourth row Lcd_Out(4,10,DisplayString) Delay_ms (1000) wend end.