melexis / mlx90640-library

MLX90640 library functions
Apache License 2.0
241 stars 192 forks source link

Minimum I2C speed for this driver? #24

Closed dcomins closed 4 years ago

dcomins commented 5 years ago

Hi,

I tried this driver to communicate MLX90640 thermopile sensor with a Raspberry Pi. Can this driver operate with an I2C clock speed of 10 kHz?

Pogsquog commented 5 years ago

Why would you do that? I have it working OK at 1Mhz on RPI 2, giving me 64 fps.

dcomins commented 5 years ago

Hey @Pogsquod It need It working at 10KHz because I have another sensor attached to the RP that only works at 10KHz i2c bus speed.

Pogsquog commented 5 years ago

10 Khz is pretty slow. You could consider using a different pin, and bit-banging it (manually clocking the i2c, see https://github.com/robotrovsky/rpi_i2c_bit_banging), or alternatively the second i2c interface may be available on rpi 3 with up to date firmware (see: https://www.raspberrypi.org/forums/viewtopic.php?t=187477)

dcomins commented 5 years ago

Ok thanks for your concern @Pogsquog so, the only way that you found is using another i2c interface or pins? It is not possible to modify the RP-Melexis Driver in order to be able to work with 10 kHz?

Pogsquog commented 5 years ago

The device goes down to 0.5 Hz framerate, which should be usable at 10Khz i2c speed (64 Hz requires 1Mhz, therefore 0.5Hz requires 1/128 of that i.e. ~8Khz). Note that it will take almost all of the time transmitting the data, so you will need to write your program to take this into account, Failing that, I think it is possible to set the bit B4 of the status register, which will make the device not overwrite the ram, meaning that you should then be able to read-out the image as slowly as you like (I've not actually tried this).

slavysis commented 5 years ago

At 10KHz you would need around 1.5seconds to readout the frame data. This leaves you only with the option of using the device at 0.5Hz refresh rate.

dcomins commented 5 years ago

Thanks for your concern. I set the Bit B4 to 0 into the MLX90640_GetFrameData() function. error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0020); Instead of error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);

The problem is always the same, I am not able at 10 kHz to get the frame data, I obtain this I2C Read Error: image

When I use 100 kHz or more I do not have any problems with this driver, but I need to use 10 kHz to get my app working.

Pogsquog commented 5 years ago

I have tried my device at 10Khz i2c speed, and can confirm that it does indeed not work, even at 0.5Hz. It would appear that the device does not support i2c speeds that slow. I would suggest using a second i2c bus, as above.

slavysis commented 5 years ago

If you want to use at that low I2C speed, you should do the following:

  1. Configure the device to work at 0.5Hz refresh rate status = MLX90640_SetRefreshRate(slaveAddress,0);

  2. Read the EEPROM and extract the parameters (execute the code up to the point where you need to start reading)

  3. Synchronize with the device data ready flag so that you have the maximum amount of time to read out the frame data.

    uint16_t synch = 0;

    status = MLX90640_I2CWrite(slaveAddress[0], 0x8000, 0x0030); while(synch == 0) { status = MLX90640_I2CRead(slaveAddress[0], 0x8000, 1, &synch);
    synch = synch & 0x0008; }

  4. Read out the frame data

  5. Make sure that all the data processing takes less than 400ms - this should ensure that you call the MLX90640_GetFrameData function less than 2 seconds after the previous call. 6 Go back to 4

If your data processing takes more than 400ms you may need to re-synch

I hope this helps you! Best regards