This is my first time on this forum.
I've been trying to get temperature and distance readings via the PIC16F877A. The distance works fine but I can't seem to get a reading from the MLX90614. I've tried every I2C code I could find online. Here is my code, can you please tell me if anything's wrong?
Code: Select all
// LCD module connections
sbit LCD_RS at RD3_bit;
sbit LCD_EN at RC5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD3_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
#define slave_address 0x5A
#define data_address 0x07
void main()
{
float time, distance, temp;
int temp_low, temp_high, pec;
char dist[6], tmp[5];
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
TRISB = 0b00000001; //RB0 input, RB1 output
OPTION_REG = 0b10000111; //prescale TMR0
I2C1_Init(100000); //initialize I2C with 100KHz
Lcd_Out(1,1,"IR Thermometer");
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
PORTB.B1 = 0;
while(1)
{
//start measuring distance
PORTB.B1 = 1; //trigger start
Delay_us(10);
PORTB.B1=0; //trigger end
while(PORTB.B0 == 0); //wait for pulse to be sent
TMR0 = 0; //start counting
while(PORTB.B0 == 1); //wait for echo
time = TMR0 * 277.77; //time in us
distance = time / 58.00; //distance in cm
//finished measuring distance
//start reading temperature
I2C1_Start();
I2C1_Wr(slave_address << 1);
I2C1_Wr(data_address);
I2C1_Repeated_Start();
I2C1_Wr((slave_address << 1) + 1);
temp_low = I2C1_Rd(1); //read low byte and send acknowledge
temp_high = I2C1_Rd(1); //read high byte and send acknowledge
pec = I2C1_Rd(0); //control byte that has no interest but has to be read, send not acknowledge
I2C1_Stop();
temp_high = temp_high & 0x7F; //mask the error bit
temp = (temp_high << 8) + temp_low;
//finished reading temperature
temp = (temp * 0.02) - 273.15; //convert temperature to celsius
//display values
if(distance < 2 || distance > 400)
{
Lcd_Out(1,1,"Out of range");
}
else
{
FloatToStr(distance,dist);
Lcd_Out(1,1,dist);
Lcd_Out(1,8," cm ");
}
FloatToStr(temp,tmp);
Lcd_Out(2,1,tmp);
Lcd_Out(2,8," ºC");
Delay_ms(500);
}
}