View previous topic :: View next topic |
Author |
Message |
Gusu
Joined: 24 Feb 2020 Posts: 1
|
MLX90614 i2c communication with PIC18F248 |
Posted: Mon Feb 24, 2020 1:30 pm |
|
|
Hello guys! I am getting some problems programming a PIC with MLX90614 sensor, to read temperature. I am not sure where is the problem. Do I read the ACK/NACK correctly? Do I have to add some delay between i2c functions?
Please if you could help me I would be very thankful!
I add the code below:
Code: |
#include <Project_Test.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N)
#use delay(clock=20000000)
#use i2c (master, sda=PIN_C4, scl=PIN_C3, address=0x5A, force_hw)
#define Temp_Ambient_Address 0x06 // Ambient Temperature - The Sensor's internal temperature
#define Temp_Object_Address 0x07 // Object Temperature - Whats in the Sensor's FOV
//EEPROM Addresses for Configuration/Writing
#define TO_Max 0x00
#define TO_Min 0x01
#define PWM_Control 0x02
#define TA_Range 0x03
#define Emissivity_Address 0x04
#define Config_Address 0x05
#define SMBUS_Address 0x0E
#define SDA PIN_C4
#define SCL PIN_C3
void main()
{
//unsigned int16 RAWPotentiometer = 0;
//float Suspension = 0;
int8 DATA_high=0;
int8 DATA_low=0;
unsigned int data;
int i=0;
int8 SA1=0x5A;
int CRC=0;
int ACK_data;
int PEC;
//setup_low_volt_detect(FALSE);
while(TRUE)
{
printf("Start MLX90614 lecture \r\n ");
//delay_ms(1000);
i2c_start(); //start the bus
i2c_write(0xB4); //Slave address + write bit
printf("MLX90614 Temperature\r\n ");
ACK_data=i2c_read(1);
//printf("Llegir temperatura del MLX90614 \r\n ");
if (ACK_data=0x00){
i2c_write(Temp_Ambient_Address); //Read Tobject1 from RAM
ACK_data=i2c_read(1); //Read ACK bit from slave
if(ACK_data=0x00){
i2c_start(); //restart the bus
i2c_write(0xB5); //Slave address + read bit
ACK_data=i2c_read(1);
if(ACK_data=0x00){
//Recibir datos de temperatura//
DATA_low = i2c_read(); //Lectura LSByte
i2c_write(0); //Send ACK to slave
DATA_high = i2c_read(); //Lectura MSBytey NACK(se envia informacion de Maestro a Esclavo)
i2c_write(0); //Send ACK to slave
}
}
PEC = i2c_read();
i2c_write(0); //Send ACK to slave
i2c_stop(); //Finaliza communicacion
data=(unsigned int)DATA_low; //guarda los 16 bits en variable data
data=data<<8;
data=data+DATA_high;
printf("\rTemperature: %d\r\n",data);
}
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Mon Feb 24, 2020 3:33 pm |
|
|
Couple of things...
1) What version MX, the A - 5 volt or B - 3 volt ? Hopefully one that matches VDD of PIC.
2) Download PCM Ps 'I2C scanner' program and see if it 'sees' the MX device
You may have to use the SMB option in #use I2C(......) for compatibilty.
3) Search this site, there may be a driver or code in the 'code library'.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Tue Feb 25, 2020 12:56 am |
|
|
You are mishandling the SMBUS/I2C transactions.
The sequence is:
For a read
1) Send start
2) Send device address (write bit low).
3) Send command to access register required (command includes
register address)
4) Send repeated start.
5) send device address with write bit high.
6) I2C read from then requested register (two reads = 16 bits).
7) Extra read for the PEC.
8) send I2C stop.
For a write
1) Send start
2) Send device address (write bit low).
3) Send command to access register required (command includes
register address)
4) send the bytes to write (again two writes since registers are 16bits).
5) Send I2C stop.
You don't tell us your PIC?. Check its data sheet. Does it support
SMBUS on the I2C peripheral ? If it does, add the SMBUS option to the
I2C setup line. The chip is an SMBUS device and will run better if
this is used.
You can't read from a device set to write mode. The bus has to be
reversed before the read. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
|
|