cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 - SMBus and Melexis MLX90614

Miguel Antunes
Associate II
Posted on May 23, 2018 at 17:49

Hello,

I'm trying to read temperature values from a Melexis MLX90614 sensor with SMBus but something seems to be wrong.

I used the HAL_SMBUS_IsDeviceReady to see if I can connect to the sensor and I can.

#define MLX90614_ADDRESS (0x5A << 1)

#define MLX90614_TA 0x06

(...)

return_value = HAL_SMBUS_Master_Transmit_IT(&hsmbus1,MLX90614_ADDRESS,(uint8_t*)MLX90614_TA,1,SMBUS_FIRST_FRAME);

while(HAL_SMBUS_GetState(&hsmbus1) != HAL_SMBUS_STATE_READY);

if (return_value != HAL_OK)

{

   return return_value;

}

return_value = HAL_SMBUS_Master_Receive_IT(&hsmbus1,MLX90614_ADDRESS,(uint8_t*)data_read,2,SMBUS_LAST_FRAME_NO_PEC);

while(HAL_SMBUS_GetState(&hsmbus1) != HAL_SMBUS_STATE_READY);

if(return_value != HAL_OK)

{

   return return_value;

}

This is the code I'm using to read to bytes from that sensor.

The code seems to stop in the first while.

The SMBus peripheral is configured in SMBus-Two-Wire-Interface in CubeMX.

I don't understand what should I put in the XferOptions field in either one of those functions and I don't know if that's the problem.

In

Thank you in advance.

Miguel Antunes

29 REPLIES 29
FIlse
Associate II

Hi Thomas,

I'm sorry but I haven't tested that yet.

But I'll try when I'm at work tomorrow! Have you checked the the documentation on that? https://www.melexis.com/-/media/files/documents/application-notes/mlx90614-changing-emissivity-unlocking-key-application-note-melexis.pdf

Remember that you have to WRITE the new set emissivity value to your EEPROM. You can do that by using HAL_I2C_Master_Transmit(); Remember that when doing an write-operation, you have to append the package error code (PEC).

Here's an write example to change the slave-address of the sensor:

/* USER CODE BEGIN 2 */
uint8_t i2cdata[4];
 
 
i2cdata[0] = 0x2E; //EEPROM-address
i2cdata[1] = 0x00; //Delete-Byte, low
i2cdata[2] = 0x00; //Delete-Byte, high
i2cdata[3] = 0x6F; //PEC -> CRC8-checksum for 2E0000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
 
 
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);
HAL_Delay(500);
 
i2cdata[0] = 0x2E; //EEPROM-address
i2cdata[1] = 0x50; //newaddress, low
i2cdata[2] = 0x00; //newaddress, high
i2cdata[3] = 0x63; //PEC -> CRC8-checksum for 2E5000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
 
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);
HAL_Delay(500);
 
 
/* USER CODE END 2 */

Changing the emissivity should be quite similar...

thomasFromBrittany
Associate II

Hey Franz,

Where do you find this snippet code ?

For me, this does't work..

When I send a new emissivity value (ex : Ke= 0x3333 => emissivity = 0.20), I read the EEPROM after (Ke = 0xFAE0 => emissivity = 0.98), this is not what I set !

"

uint8_t i2cdata[4];

i2cdata[0] = 0x24; //EEPROM-address

i2cdata[1] = 0x33; //Delete-Byte, low

i2cdata[2] = 0x33; //Delete-Byte, high

i2cdata[3] = 0xB7; //PEC -> CRC8-checksum for 243333, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

HAL_I2C_Master_Transmit(&hi2c1, 0x5A<<1, i2cdata, 4, 0xFFFF);

"

If you have any idea about my problem, it's with pleasure !!

thomasFromBrittany
Associate II
 
FIlse
Associate II

Hi Thomas,

in my experience the sensor needs to be plugged of the power supply to "update" values, written in the EEPROM since it was the case when I changed the slave-address of my sensor.

The code snippet is something I wrote to change the slave address of my sensor. Since it's also an EEPROM-writing-process, it can be applied to any writing-operation.

Pls also try another value for Ke. Try this and maybe it will work - maybe I can tell you more about the emissivity-stuff tomorrow.

thomasFromBrittany
Associate II

Of course my sensor is plug to power !

Okok, so it's does't work for me.

My I2C speed : 100 KHz standard mode, u ?

FIlse
Associate II

No, I meant you have to unplug it from the power source and then plug it again, so it has the written settings updated.

No, in this form it won't work for oyu, because you have to customize the code to your needs. But the writing process is identical.

My I2C-speed is 50 kHz but that's not that important I think...

thomasFromBrittany
Associate II

Hum ok, I will test it.

I already customize thee code, like I write previously :

I send a new emissivity value (ex : Ke= 0x3333 => emissivity = 0.20)

"

uint8_t i2cdata[4];

i2cdata[0] = 0x24; //EEPROM-address

i2cdata[1] = 0x33; //Byte, low

i2cdata[2] = 0x33; //Byte, high

i2cdata[3] = 0xB7; //PEC -> CRC8-checksum for 243333, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

HAL_I2C_Master_Transmit(&hi2c1, 0x5A<<1, i2cdata, 4, 0xFFFF);

FIlse
Associate II

Also remember to DELETE the values EEPROM-cells first! In my code I did that with:

i2cdata[0] = 0x2E; //EEPROM-address
i2cdata[1] = 0x00; //Delete-Byte, low
i2cdata[2] = 0x00; //Delete-Byte, high
i2cdata[3] = 0x6F; //PEC -> CRC8-checksum for 2E0000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);

Just THEN it will work. Only if this procedure is done, I can write the new values into the EEPROM:

HAL_Delay(500);
 
i2cdata[0] = 0x2E; //EEPROM-address
i2cdata[1] = 0x50; //newaddress, low
i2cdata[2] = 0x00; //newaddress, high
i2cdata[3] = 0x63; //PEC -> CRC8-checksum for 2E5000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
 
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);
HAL_Delay(500);

In your case, the code should look like this:

/* USER CODE BEGIN 2 */
uint8_t i2cdata[4];
 
 
i2cdata[0] = 0x24; //EEPROM-address
i2cdata[1] = 0x00; //Delete-Byte, low
i2cdata[2] = 0x00; //Delete-Byte, high
i2cdata[3] = 0xE8; //PEC -> CRC8-checksum for 240000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
 
 
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);
HAL_Delay(500);
 
i2cdata[0] = 0x24; //EEPROM-address
i2cdata[1] = 0x33; //new emissivity, low
i2cdata[2] = 0x33; //new emissivity, high
i2cdata[3] = 0xB7; //PEC -> CRC8-checksum for 243333, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
 
HAL_I2C_Master_Transmit(&hi2c1, 0x00<<1, i2cdata, 4, 0xFFFF);
HAL_Delay(500);
 
 
/* USER CODE END 2 */

After that, plug off the sensor from the power supply and connect it again.

thomasFromBrittany
Associate II

Hey,

I manage to make it work !! My mistake was in my CRC8 calculation, I didn't take into account the address of the sensor !

If it's can help someone, my code :

uint8_t i2cdata[4];

i2cdata[0] = 0x24; //EEPROM-address

i2cdata[1] = 0x00; //Delete-Byte, low

i2cdata[2] = 0x00; //Delete-Byte, high

i2cdata[3] = 0x28; //PEC -> CRC8-checksum for 240000, calculation: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

HAL_I2C_Master_Transmit(&hi2c1, 0x5A<<1, i2cdata, 4, 0xFFFF);

osDelay(500);

i2cdata[0] = 0x24; //EEPROM-address

i2cdata[1] = ke & 0xFF; //Byte, low

i2cdata[2] = ke >> 8; //Byte, high

i2cdata[3] = crc8(ke, (0x5A<<1), 0x24); //PEC -> CRC8-checksum

Thanks a lot,

Thomas

FIlse
Associate II

Hi Thomas,

I'm glad that it worked! Are you sure, it was not "just" the "deleting"(the first part of the code)-process that caused your sensor to work?

Because I'm pretty sure that the PEC only has to be calculated for the data to be written (excluding the sensor-address, since it's part of the HAL_I2C_Master_Transmit command).

Anyway, I'm glad you succeeded!