melexis / mlx90640-library

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

GetFrameData failure #33

Closed Kiogora closed 4 years ago

Kiogora commented 5 years ago

The following code within the function as title will always return -8. cnt is incremented till value 5, and outside the loop, it will fail the check if(cnt > 4) return -8

while(dataReady != 0 && cnt < 5)
    { 
        error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
        if(error == -1)
        {
            return error;
        }

        error = MLX90640_I2CRead(slaveAddr, 0x0400, 832, frameData); 
        if(error != 0)
        {
            return error;
        }

        error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
        if(error != 0)
        {
            return error;
        }    
        dataReady = statusRegister & 0x0008;
        cnt = cnt + 1;
    }

    if(cnt > 4)
    {
        return -8;
}
slavysis commented 5 years ago

Hi,

In order to get valid frame data you need to read the whole frame before a new frame is available. The function is trying to achieve that. If it returns -8, this means that the function did not manage to get the whole frame data before a new frame i available. The most probable reason for this to occur is that the I2C frequency is not fast enough and/or the MLX90640 refresh rate setting is too fast. For example: if the MLX90640 refresh rate is set to 32Hz, you would get a new frame data every 32ms. If your I2C frequency is such that reading the full frame takes 50ms, you would never be able to get valid frame data. In this case you would need to either use faster i2C frequency in order to read faster the frame data (in less than 32ms) or have a slower refresh rate (to have new frame data available in more than 50ms).

Best regards

Kiogora commented 5 years ago

Hi @slavysis, Thanks for that. My actual query is: The while loop occurs if the cnt variable is less than 5, at the value 5 it breaks out of the loop and fails the next check, if the value cnt is greater than 4, returning -8 always.

Kiogora commented 5 years ago

Should the while loop check be while(dataReady != 0 || cnt < 5) such that say, if dataReady is set while on the third loop...it will exit the loop and not return -8

slavysis commented 5 years ago

Hi A while loop in C repeatedly executes some code as long as a given condition is true. The goal of the loop that you are referring to is to try to get valid frame data. A frame data is valid if the I2C communication did not return error and the whole frame was read before a new data is available. The dataReady bit is indicating if a new frame data is available ('1' - new data is available, 0-no new data available). Thus, if at the end of the frame data read, the dataReady bit is 0, we achieved our goal to get valid frame data and we do not need to loop again -> the condition in the while statement is dataReady != 0 - this means the loop will be executed while dataReady != 0 and if dataReady == 0 will will get out of the loop. Now, if the code remains with just that one condition, there is a high chance that at certain conditions the program will be stuck in this loop forever (or until a watchdog interrupts it). Thus it would be nice to have some other condition that would limit the loop iterations - cnt < 5. The loop should execute only if the counter is <5 -> no more than five loops will be made (cnt starts from 0). If we use what you suggest -> while(dataReady != 0 || cnt < 5) , then the cnt < 5 does not really limit the loop iterations. Example: cnt = 100 and dataReady = 1 -> the first condition dataReady != 0 is true and the second condition cnt<5 is false, but the result true || false is still true, so we will continue looping.

I hope this makes sense to you.

Best regards