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
2018-05-24 08:09 AM
I changed a couple of things in the configurations (screenshots below) and changed the code to the following:
(...)
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_OTHER_AND_LAST_FRAME_NO_PEC);
while(HAL_SMBUS_GetState(&hsmbus1) != HAL_SMBUS_STATE_READY);if(return_value != HAL_OK)
{ return return_value; }(...)
Right now I can read values from the sensor but they don't seem to be correct.
Any help?
2018-09-12 03:43 AM
Hi,
did you or anyone else manage to solve the problem? I'm asking because I have the same problem with the MLX90614-sensor. Instead of the STM32L4 I'm using one of the F0-series. I'm facing just the same problem while reading the ambient temperature from the sensor. I get values which don't make sense. Also when I'm trying to read the object temperature (address 0x07) I literally get nothing back. I'm kind of desperate and hope someone could me/us.
My code looks like this:
HAL_SMBUS_Master_Transmit_IT(&hsmbus1, 0x5A<<1, MLX90614_TOB, 1, SMBUS_FIRST_FRAME);
while(HAL_SMBUS_GetState(&hsmbus1) != HAL_SMBUS_STATE_READY);
HAL_SMBUS_Master_Receive_IT(&hsmbus1, 0x5A<<1, buffer, 2, SMBUS_OTHER_AND_LAST_FRAME_NO_PEC);
while(HAL_SMBUS_GetState(&hsmbus1) != HAL_SMBUS_STATE_READY);
int_temp = buffer[0] <<8 | buffer[1];
temperature = int_temp*0.02 - 273.15;
thank you in advance!
2018-09-13 02:33 AM
My sensor is now working! Here's the code:
char buffer[5];
float temperature;
int main(void){
while (1)
{
HAL_I2C_Mem_Read(&hi2c1, 0x5A<<1, 0x07, 1, buffer, 2, 100);
int_temp = (buffer[1] <<8 | buffer[0]);
temperature = int_temp*0.02 - 273.15;
HAL_Delay(200);
}
Since the sensor needs a repeated start, HAL_I2C_MEM_Read() will do the job for you! Because of the stop-condition, which is set by HAL_I2C_Master_Transmit and HAL_I2C_Master_Receive you wouldn't be able to read the values properly because of that missing repeated start. Mem_Read on the other hand does the following: start, I2C address + Write, Memory address, repeated start, I2C address + Read, N bytes, stop. Besides that when combining the two data bytes you have to pay attention that the lsbyte (in my example buffer[0]) comes first, so you have to shift the msbyte by 8 and "OR" it with lsbyte. After that you'll get proper temperature-values.
Hope this will help other people, struggling with this sensor.
2018-10-11 02:18 PM
So you are running the sensor in I2C mode instead of SMBus?
2018-10-12 12:25 AM
Ok, got it working in standard I2C mode. Thank you!
2019-02-09 11:07 PM
Hi,
has anyone been able to use franz's code to read the sensor and could help me out? I have tried it multiple times on stm32F0x micro's but am unable to receive any data from the mlx90614.
Thanks.
2019-02-13 02:23 AM
Hi Monty,
I'm able to read MLX90614 data in I2C mode too, but when I set emissivity (and then read it, to be sure), I have two different values...
That's what I use to read temperature :
HAL_I2C_Mem_Read(&hi2c1, (0x5A<<1), MLX90614_REGISTER_TOBJ1, 1, buffer, 2, 100);
Thomas
2019-02-13 02:46 AM
Hi, sorry for answering late.
Yes, there was already someone who messaged me and I went through the process of getting any signals from the sensor, step by step.
Do you have an UART-adapter? If so, you could print the result of the communication to your terminal. In the case of the person, who messaged me, the I2C-interface was broken and so didn't get a signal. After he bought a new board, the code was working just fine.
I would suggest you to check if you get any signal from the sensor.
You can do this by checking all the i2c-addresses, the sensor is able to communicate with for example:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
char uartbuffer[24];
uint8_t i = 1;
HAL_StatusTypeDef result;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
for (i = 0; i<128; i++)
{
result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t) (i<<1), 2, 2);
if (result != HAL_OK)
{
sprintf(uartbuffer, ".");
HAL_UART_Transmit(&huart1, uartbuffer, 1, 0xFFFF);
}
if (result == HAL_OK)
{
sprintf(uartbuffer, "0x%X", i);
HAL_UART_Transmit(&huart1, uartbuffer, 4, 0xFFFF);
}
}
}
/* USER CODE END 3 */
}
This scans all addresses and prints the result on a terminal. If there are just dots and no addresses like 0x5A or 0x00, there is probably something wrong with your I2C-interface.
2019-02-13 02:52 AM
Hi Franz,
How do you manage to set emissivity ?
Regards,
Thomas