2018-05-23 08:49 AM
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
2019-02-13 03:20 AM
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...
2019-02-13 05:27 AM
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 !!
2019-02-13 05:28 AM
2019-02-13 05:36 AM
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.
2019-02-13 05:48 AM
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 ?
2019-02-13 05:51 AM
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...
2019-02-13 05:54 AM
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);
2019-02-13 06:08 AM
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.
2019-02-13 08:55 AM
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
2019-02-13 09:10 AM
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!