melexis / mlx90632-library

MLX90632 library for the Melexis 90632 Infra Red temperature sensor.
Apache License 2.0
42 stars 15 forks source link

ESP-IDF implementation - 16 bit register #40

Closed domko99 closed 2 years ago

domko99 commented 2 years ago

Hi. I am trying to implement MLX90632 functions for reading and writing value from MLX90632 register address. I am using ESP32 chip. The problem is that all i2c functions are made for uint8_t register address - 8 bit register (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html?highlight=i2c#communication-as-master). But MLX90632 have 16 bit register address (int16_t). Is there anyone who was implementing MLX for ESP-IDF framework and somehow solve this issue? There is an example for STM32 chip provided by Melexis but functions which is using are supporting int16_t. Thanks for your help.

Letme commented 2 years ago

Can you explain in a bit more detail what is your issue?

As general discussion: The I2C write and read functions take number of bytes (data) you read and then you simply need to either cast the read 2 byte array to (int16_t) or fix endianness and then cast (or if CPU uses different integer representation, that is the second step). The mlx90632_init function has a conditional read of the known/fixed EEPROM values to help you debug the endianness issues https://github.com/melexis/mlx90632-library/blob/master/src/mlx90632.c#L454

domko99 commented 2 years ago

Hi. I think I solve this problem and I was able to code i2C communication. The code was working in ESP-IDF framework so I have tried to run MLX sensor in Arduino IDE enviroment to prove my results in ESP-IDF framework. I did and then tried running code in ESP-IDF but I am getting stuck at same results for object and ambient temperature. The same results are even after flashing new project once again or after erasing flash memory of ESP32 chip and flash project once again. Code in Arduino IDE is working and after switching to ESP-IDF values for temperatures are changed but I am always stuck with new values.... The code was working but somehow it is not working now. Do you have any suggestions or maybe you encountered with this kind of problem... I am sending you my code if you want to take a look. I also changed 5 sec interval to 1 sec interval before values get stucked... Thanks. main.zip

Letme commented 2 years ago

Much easier with snippets than zip file, but OK. Few remarks:

You have commented out mlx90632_init() function which basically confirms that connection to sensor is working and sane (i2c reads are correct) as well as preparing sensor for clean start.

Next one is shifts. I didn't work with ESP, but it could be that 1 is shifted in through carry so that would mean problems. So I would explicitly and with 0x00ff and 0xff00 to ensure consistent or.

Calculated values are the same, but raw values change right? That would mean that EEPROM parameters read are wrong or are casted wrong and it saturates the calculations.

You are mentioning ESP framework vs Aruduino IDE: the difference could be compiler and that is something that makes integer casting implementation-specific.

domko99 commented 2 years ago

Even raw data are not changing. mlx90632_init() is working well. I dont know where can be issue. I will try something.

Letme commented 2 years ago

Raw data for ambient might be constant (although not really), while the object raw temperature should never be. I am thinking that the case where those values could be constant is if you have set extended range (on supported) sensor, but you are calling and using normal functions?

domko99 commented 2 years ago

I am using code with no mode selected. I am not sure if my write function is okey. There is description of function which I am using. image

I am beginner in embeded system programming but I am trying... There is my function. Thanks for any help.

int32_t mlx90632_i2c_write(int16_t register_address, uint16_t value){ uint8_t write_buf[] = { (register_address >> 8) & 0xff, register_address & 0xff }; i2c_master_write_to_device(I2C_MASTER_NUM, CHIP_ADDRESS,write_buf,sizeof(write_buf),1000 / portTICK_PERIOD_MS); return 0; }

Letme commented 2 years ago

You are discarding the return value of master_write_to_device function and in this case it would be very useful to see what it gets. If ESP_OK is defined as 0, then you can just directly return to higher functions (maybe with a cast - check how esp_err_t typedef is defined). Does mlx90632_init return 0 or ERANGE?

domko99 commented 2 years ago

I made a new project in ESP-IDF environment, new build of project and it works... I didnt change anything from past so it was a strange bug. I hope it will work well. Can I ask you something how do I know if the extended mode is supported? And are there 3 modes normal, medical and extended or only medical and extended. Because right now I dont set any mode... Thanks for your help once again.

Letme commented 2 years ago

That is good news - that you were able to solve it.

Return value of init function is ERANGE if extended mode is supported by your sensor: https://github.com/melexis/mlx90632-library/blob/master/inc/mlx90632.h#L356-L368 . That is the easiest way if you have communication with the sensor.

domko99 commented 2 years ago

The printing was support extended so I can assume that extended is supported?


int32_t ret = 0;
    ret = mlx90632_init();
    if(ret == 0){
        printf("not support extended\n");
    }
    if(ret < 0){
        printf("bad init\n");
    }
    if(ret>0){
        printf("support extended\n");
    }
domko99 commented 2 years ago

And can I ask again that standard mode is by default, it means it is set when I dont call function mlx90632_set_meas_type(). When I want medical mode I need to call mlx90632_set_meas_type(MLX90632_MTYP_MEDICAL), when I want extended mode I need to call mlx90632_set_meas_type(MLX90632_MTYP_EXTENDED). I can add to MEDICAL and EXTENDED BURST mode (for example mlx90632_set_meas_type(MLX90632_MTYP_EXTENDED_BURST). Burst mode is for sleeping (I think). It is not clear for me from datasheet. Especially STANDARD mode is confusing, it is not possible to declare it in mlx90632_set_meas_type(). Thanks again.

Letme commented 2 years ago

I will let @slavysis look at the possible difference between the datasheet and explain what is meant as STANDARD mode there.