2018-05-23 8: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 8: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 3: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 2: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 2: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 2: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 2: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 2:52 AM
Hi Franz,
How do you manage to set emissivity ?
Regards,
Thomas
