melexis / mlx90640-library

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

MLX90640_GetTa() and MLX90640_CalculateTo calculate weird values #80

Open Berkajerk opened 3 years ago

Berkajerk commented 3 years ago

I get data similar, see below, but when I call GetTa() or CalculateTo() I get garbage data that definitely doesn't match me pointing the sensor at a desk or piece of paper that should be close to the same temp. Using the example data I get most of the same parameters calculated back out except for alpha (uint16), kv (int8) and kta (int8) are different because the example data are in decimals. My ksTo doesn't calculate properly for some reason other but even hard-coding -0.0002 hasn't helped. Ambient Ta comes out around 22.5, which makes sense but the Ta inside MLX906490_To() is 30.6?

My order of function calls is: MLX90640_SynchFrame() MLX90640_GetFrameData() MLX90640_GetVdd() MLX90640_ClearNewDataBit() //my own MLX90640_GetTa() MLX90640_CalculateTo() while(!MLX90640_CheckNewFrame) //my own //loop through twice as per the Melexis data sheet Measurement flow

RAM data 0xff94,0xffaf,0xffac,0xffac,0xffa8,0xffa3,0xff9f,0xff9e,0xff9c,0xff95,0xff8e,0xff8f,0xff8d,0xff8c,0xff80,0xff87,0xff81,0xff81,0xff79,0xff86,0xff7c,0xff83,0xff7a,0xff88,0xff7f,0xff89,0xff7d,0xff8f,0xff86,0xff92,0xff89,0xffa3,0xff9f,0xffbb,0xffae,0xff9f,0xff9c,0xff8f,0xff99,0xff91

Calculated values from MLX90640_GetImage() display with printf("%6.1f,", fTempResult[i]); 592.0,338272480.0,362236960.0,451677376.0,385740224.0,357841664.0,352839072.0,475474240.0,376040288.0,442351360.0,466023392.0,582827584.0,461466912.0,553721088.0,547306240.0,868710400.0,2073485824.0,1457174016.0,1639923584.0,1062499648.0,1117048576.0,1007729472.0,1176669312.0,879932992.0,835734784.0,817753600.0,914897472.0,799963840.0,703102208.0,733174976.0,809205696.0,751047872.0,584132416.0,718254464.0,727529920.0,732689984.0,592247680.0,722966720.0,742125504.0,791069504.0,623380992.0,879549504.0,863016000.0,849186432.0,711014208.0,1036032896.0,1065976704.0,1397301376.0,1953519232.0,717029248.0,930322368.0,625610176.0,823806528.0,471457376.0,657431424.0,563241280.0,568958144.0,422298112.0,595941056.0,526872288.0,473833376.0,384111200.0,546840512.0,500078720.0,364202208.0,400743552.0,427827680.0,505806528.0,415574816.0,424173664.0,465272864.0,537820032.0,476969216.0,450454080.0,583294464.0,651005760.0,669964096.0,614491712.0,835286528.0,1300244608.0,5021978112.0,3191158272.0,2957620480.0,1885567488.0,1862405376.0,1625331584.0,2040611968.0,1472667904.0,1337811456.0,1350845952.0,1630382464.0,1237255168.0,1087828608.0,1179745408.0,1401025536.0,1229205760.0,901572352.0,1152956672.0,1189396608.0,1176895488.0,904684224.0,1178945664.0,1352280704.0,1265989760.0,935620992.0,1309102336.0,1523960960.0,1398909568.0,1321256064.0,1681935104.0,2320309248.0,323784160.0

Calculated values from MLX90640_CalculateTo() display with printf("%6.1f,", fTempResult[i]); -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, 9291.8, -273.1, -273.1, -273.1, 11478.3, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, 5429.8, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1, -273.1

Berkajerk commented 3 years ago

Figured out the Ta difference. That's just the shift that isn't subtracted from MLX90640_GetTa() when called inside MLX90640_CalculateTo().

Can't figure out where the temperature calculations are going wrong though.

slavysis commented 3 years ago

Frame data seems OK. Can you please share the dump of the EEPROM?

Some remarks regarding the function calls:

  1. Normally you do not need to call the Sync frame function every cycle. It is not a problem to do that, but this wastes time and you should do it only if it is really needed.
  2. GetVdd is automatically called when needed. So unless you need to know the Vdd in you application, you can skip that call too.
  3. MLX90640_ClearNewDataBit() - I am not sure what that function does, but if the name is appropriate and it only clears that bit, you do not need that function as this bit is already being handled in the GetFrame data function as well as in the Sync frame function.
  4. while(!MLX90640_CheckNewFrame) - as for 3. - not sure what it does, but if the name is appropriate and it only waits for the new data bit to be set, you can skip that and simply call the GetFrameData function - it does wait for that bit to bi set. Please note that it is not a good practice to constantly check this bit as you would keep the whole I2C line busy. I would suggest that you start doing that in the last 10% of the refresh time.

Best regards

Berkajerk commented 3 years ago

MLX90640 const arrays.txt MLX90640_25Feb data out.txt

I attached the const arrays I calculated after getting the EEPROM data stored as a constant. The alpha, offset, kta, and kv had to calculated separately due to memory constraints. There is also an example of the data I'm getting. I'm going to redump the EEPROM and try out your suggestions. Really appreciate the help.

  1. okay. Currently it is just for testing to setup the device for a clean sample.
  2. Cool. Will move it to test data menu.
  3. I wasn't sure and the the MLX90640 data sheet says the user has to clear the bit. I will remove it and give it a shot.
  4. okay.
Berkajerk commented 3 years ago

refresh rate is 2Hz, I2C is 400k

register 0x800D returns 0x1901

slavysis commented 3 years ago

Everything seems OK at first glimpse. In MLX90640_25Feb data out.txt I see "FrameData using my EEPROm 25Feb 14:25 facing my desk scan says 24.2C". What does the 24.2C part mean?

Best regards

Berkajerk commented 3 years ago

redid the EEPROM dump and I get the same values for all 832 words

Berkajerk commented 3 years ago

The 24.2C is just my own reference for what my cheap laser temperature gun gives me so I can compare the temperatures.

Berkajerk commented 3 years ago

My current code. It just runs once on each key press. iStatus = MLX90640_TriggerMeasurement(TEMP_ADDR);

        iStatus =  MLX90640_SynchFrame(TEMP_ADDR); //DEBUG: possible infinite loop

        //get data for sub-page 0
        iStatus = MLX90640_GetFrameData(TEMP_ADDR, aFrameData16); 
        printf("\nDEBUG: GetFrameData subpage0 status: %i",iStatus);

        MLX90640_GetImage(aFrameData16,&paramMLX90640,fTempResult);

        //wait for data to be available or delay
        __delay_ms(RR_DELAY_2HZ);

        //whole frame data should be stored now
        iStatus = MLX90640_GetFrameData(TEMP_ADDR, aFrameData16);
        printf("\nDEBUG: GetFrameData subpage1 status: %i",iStatus);
        MLX90640_GetImage(aFrameData16,&paramMLX90640,fTempResult);

Output:

fTempResult[0] 5.7969722E8 0x4E0A35E9

the calculated results vary across 768 words from 1.99E8 to 1.18E9 with the sensor facing a warm light with a ceiling behind it. So I'm pretty convinced my frame data is good. Just getting the output scaled seems to be where I'm stuck.

slavysis commented 3 years ago

The EEPROM data and the FrameData both seem OK. The calculated Ta value also looks OK. I do not see where you call the CalculateTo function. Normally, the GetImage function is intended to give back a temperature image faster than the calculateTo function, but it does not calculate the temperatures - you only have normalized values. If you want to have a frame with calculated object temperatures you need to call MLX90640_CalculateTo() instead of MLX90640_GetImage().

Berkajerk commented 3 years ago

Okay I will give that a try. I was rechecking my parameters and noticed the KsTo[5] was coming back with infinity and a couple others were being calculated properly. I fixed the other ones to calculate close to the example the but KsTo doesn't want to calculate write. My EEPROM[61] = 0x00bf Example = 0x0EC00 EEPROM[62] = 0xf300 Example = 0x9797 EEPROM[63] = 0x9ec5 Example = 0x9797 KsTo[0-4] = Infinity KsTo[5] = -0.00020 So i coded all the KsTo array to be -0.00020 to match the example.

Which gives me this now: 11.8,18.5,15.8,20.7,17.0,21.9,17.4,22.6,18.1,23.3,17.8,23.5,18.5,23.8,18.3,23.6,18.5,23.7,18.4,23.6,18.0,23.3,17.9,22.8,17.8,22.4,16.7,21.6,16.3,20.7,13.7,20.7,17.8,13.3,21.3,15.5,22.8,16.3,23.1,17.8,23.9,17.9,23.5,18.1,24.3,18.3,24.1,18.0,24.2,18.0

With KsTo calculated with my EEPROM values (Note: not the exact same pixels) 28.4,29.8,-27.6,29.8,-28.9,29.8,-27.6,29.8,-28.0,29.8,-27.1,29.8,-28.0,29.8,-25.8,29.8,-26.7,29.8,-25.8,29.8,-26.2,29.8,-27.1,29.8,-25.8,29.8,29.8,-29.6,29.8,-28.5,29.8,-29.6,29.8,-29.6,29.8,-30.7,29.8,-29.6,29.8,-30.0,29.8,-30.0,29.8,-30.4,29.8,-30.0,29.8,-30.0,29.8,-29.

So I think I'm close. My EEPROM values are stored in ROM and not read on startup do to memory limitations of the PIC18. Are there any specific EEPROM values that should checked on powerup?

slavysis commented 3 years ago

I think I have an idea what might be wrong - probably the int type of the PIC18 is 16-bit and the kstoScale variable which is specified as int simply overflows and becomes 0 - that is why you get the infinity in ksto. Could you please update your MLX90640_API.cpp and give it a try?

Best regards

Berkajerk commented 3 years ago

I changed KsToScale to int32_t but still got infinity for KsTo[0..3] and KsTo[4] is -0.0002

Some of my output with KsTo as inifnity: 27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,27.64,27.82,

some of my output with KsTo[0..4] set as -0.0002 .49,20.59,20.43,19.52,18.82,18.79,18.64,18.56,19.19,22.40,22.32,23.70,24.34,25.19,21.92,22.11,21.20,18.99,17.46,16.12,16.45,21.23,17.77,22.01,17.62,20.11,18.28,22.10,19.31,21.05,19.54,21.37,21.17,22.02,20.56,20.57,20.11,19.39,19.76,20.88,19.37,21.19,21.88,24.66,24.86,24.72,25.54,21.26,21.47,19.87,19.77,17.35,19.61,16.56,14.87,17.09,15.82,17.62,16.47,18.37,17.52,19.05,18.54,19.83,19.76,20.17,19.18,18.61,18.70,18.66,18.24,18.36,18.86,19.48,20.88,21.16,23.36,23.55,21.86,20.21,19.16,18.77,18.46,17.16,17.04,23.86,19.28,24.79,18.23,21.56,19.78,23.18,20.11,21.11,20.37,22.42,21.75,22.06,20.72,21.14,20.70,19.71,19.69,20.01,20.44,21.06,21.08,23.79,23.97,22.56,23.61,21.17,19.79,19.05,20.29,19.35,19.34,15.50,10.72,16.89,15.17,18.94,16.56,17.76,17.69,18.88,17.69,19.43,18.61,19.07,18.16,18.97,18.06,17.93,17.83,18.38,18.56,19.10,20.06,20.78,20.66,20.61,19.08,19.39,18.44,18.96,17.59,15.99,13.96,42.39,25.40,36.50,24.55,28.94,24.24,32.46,24.94,25.97,24.48,29.53,23.92,24.01,23.32,27.11,23.88,21.76,22.74,24.23,24.05,22.48,24.43,27.35,25.20,22.29,24.02,26.92,23.03,23.45,23.86,23.63,28.47,

slavysis commented 3 years ago

That is strange: mlx90640->ksTo[i] = mlx90640->ksTo[i] / KsToScale; - looks like the only way to get infinity is if kstoScale is 0. Can you share all of the paramsMLX90640 to see if there are other 'strange' values?

Best regards

Berkajerk commented 3 years ago

MLX90640_parameters

Here's the parameter dump just after MLX90640_ExtractParameters().

I have definitely been moving some things around as I'm well over my memory limit pushing the kv, kva, alpha, offset, and eeprom arrays as constants. But I am calculating Kva, kv, and alpha on powerup just not the parts that push to the arrays. Just the alphaScale, for example.

In ExtractKsToParameters() I am doing an I2C read to get the EEPROM fresh from 0x2461 and 0x2462. But everything else is from my const EEPROM array.

slavysis commented 3 years ago

The parameters also look OK. The only strange thing is the ksto. For your device ksto[0]=0, ksto[1] = -0.000198, ksto[2] = -0.0009 and ksto[3] = -0.001495, but -0.0002 is a good approximation and should not give too big of an error. I would still like to sort that ksto = infinity issue. Are you sure you are correctly passing the parameters to the functions?

Best regards

Berkajerk commented 3 years ago

I only have the one variable for the parameters structure.

MLX90640_ExtractParameters(EEPROM_Dump,&paramMLX90640);

void ExtractKsToParameters(uint16_t eeData, paramsMLX90640 mlx90640) { //int KsToScale; //force to large int int32_t KsToScale;

int8_t step;

//my code
uint16_t eeKsTo[2];

step = ((eeData[63] & 0x3000) >> 12) * 10;

mlx90640->ct[0] = -40;
mlx90640->ct[1] = 0;
mlx90640->ct[2] = (eeData[63] & 0x00F0) >> 4;
mlx90640->ct[3] = (eeData[63] & 0x0F00) >> 8;    

mlx90640->ct[2] = mlx90640->ct[2]*step;
mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3]*step;
mlx90640->ct[4] = 400;

KsToScale = (eeData[63] & 0x000F) + 8;
KsToScale = 1 << KsToScale;

MLX90640_Read(TEMP_ADDR, 0x2461, 2, eeKsTo);

mlx90640->ksTo[0] = eeData[61] & 0x00FF;
mlx90640->ksTo[1] = (eeData[61] & 0xFF00) >> 8;
mlx90640->ksTo[2] = eeData[62] & 0x00FF;
mlx90640->ksTo[3] = (eeData[62] & 0xFF00) >> 8;      

for(int i = 0; i < 4; i++)
{
    if(mlx90640->ksTo[i] > 127)
    {
        mlx90640->ksTo[i] = mlx90640->ksTo[i] - 256;
    }
    mlx90640->ksTo[i] = mlx90640->ksTo[i] / KsToScale;
} 

mlx90640->ksTo[4] = -0.0002;

}

slavysis commented 3 years ago

I did not realize you changed the code. I think you should modify your code:

MLX90640_Read(TEMP_ADDR, 0x243D, 2, eeKsTo); // The EEPROM address is 0x243D (61st EEPROM address). Also I hope this '2' in the parameters means 2 address = 4 bytes

mlx90640->ksTo[0] = eeKsTo[0] & 0x00FF; //You should use the data you just read from the device - other wise you never write anything in the eeData and you get some random values mlx90640->ksTo[1] = (eeKsTo[0] & 0xFF00) >> 8; mlx90640->ksTo[2] = eeKsTo[1] & 0x00FF; mlx90640->ksTo[3] = (eeKsTo[1] & 0xFF00) >> 8;

Best regards

Berkajerk commented 3 years ago

I will give that a shot. Double checking that address I definitely added 61d to 2400h. No wonder the ksTo is off.

I only have enough memory to read a couple EEPROM values on each power up. Next iteration I plan on a more powerful microcontroller.

Edit: Yes the 2 is actually reading 4 bytes.

Berkajerk commented 3 years ago

Still getting infinity values for ksTo. My fresh EEPROM reads from 0x243D are 0xF300 and from 0x243E are 0x93C5.

MLX90640_Read(TEMP_ADDR, 0x243D, 2, eeKsTo); //gets two words

mlx90640->ksTo[0] = eeKsTo[0] & 0x00FF;
mlx90640->ksTo[1] = (eeKsTo[0] & 0xFF00) >> 8;
mlx90640->ksTo[2] = eeKsTo[1] & 0x00FF;
mlx90640->ksTo[3] = (eeKsTo[1] & 0xFF00) >> 8;      
Berkajerk commented 3 years ago

Register 0x800D, in sensor RAM, is consistently 0x9901 now. Before it was 0x1901. What is the 16th bit for? It's not in the data sheet. My EEPROM reads 0x1901 during operation and in my const array.

slavysis commented 3 years ago

KsToScale uses data from eeData[63} (address 0x243F). Can you check what is the value you have there? What is the KsToScale value that you get.

Reading the MS bit as '1' in the register at address 0x800D means that you are writing it. Note that setting that bit to 1 should not influence the calculations, but could mean that you are writing to it instead of some write you wanted to do to some other register.

Best regards

Berkajerk commented 3 years ago

at 0x243f i get 0x2558

slavysis commented 3 years ago

The EEPROM value you get is correct, but is that same value in eeData[63] in your code?

KsToScale = (eeData[63] & 0x000F) + 8; KsToScale = 1 << KsToScale;

What is the KsToScale value after executing those 2 lines?

Best regards

Berkajerk commented 3 years ago

DEBUG: Extracting Parameters...please wait DEBUG: eeData[63] 0x2558 // printf("\nDEBUG: eeData[63] %#06x\n",eeData[63]); DEBUG: KsToScale middle: 16 //in between the two assignments to KsToScale DEBUG: KsToScale 0 //printf("\nDEBUG: KsToScale %i\n",KsToScale);

I'm still getting a large variation in temperatures across the sensor.

Is there a formula to calculate my Celcius values from the raw sensor data? Like 0xFFab == x in celcius? I need to prove to my professor, this is a school capstone project, that the Celsius output is accurate.

Latest data (this is just the bottom half or so of the output) held against a paperbox. Would my fingers touching it throw off the temperature that much? 28.5 28.2 28.6 27.5 27.9 28.2 27.9 27.1 27.5 28.1 26.0 25.9 25.7 27.0 24.7 24.5 22.3 27.2 26.9 26.0 29.2 26.4 27.2 28.2 30.1 27.7 27.7 29.6 31.3 28.2 28.9 29.9 30.8 30.1 28.1 29.4 29.9 29.6 27.9 29.8 28.9 29.1 25.4 29.2 27.0 27.6 24.2 29.3 24.5 29.8 25.1 21.4 25.5 24.2 26.6 24.6 27.6 26.2 27.9 26.6 28.4 28.0 28.5 27.3 28.6 28.4 28.2 27.8 28.3 28.2 27.8 27.7 27.8 27.7 26.7 26.8 26.7 27.8 25.6 31.1 23.6 28.8 26.2 26.1 30.8 26.2 27.5 28.1 31.0 28.3 28.0 29.7 30.7 29.9 28.6 30.4 31.6 30.1 28.3 30.3 31.0 30.1 28.1 30.5 29.7 29.8 26.6 30.6 28.3 29.2 24.7 29.1 25.2 30.6 28.0 22.9 27.0 25.0 28.1 24.7 28.2 27.1 28.8 27.1 29.0 28.3 29.5 28.2 28.9 28.8 29.0 27.9 29.0 28.8 28.8 27.6 28.3 28.2 26.9 26.9 26.7 28.0 26.4 26.2 23.9 29.8 30.4 29.0 33.8 29.0 30.6 29.2 33.0 29.8 30.5 30.9 32.3 30.6 30.5 31.5 32.2 31.4 29.7 31.7 32.2 30.8 28.9 31.5 30.8 30.5 26.6 30.6 29.2 29.0 25.7 30.9 27.3 32.8 28.9 23.3 28.3 25.3 29.2 25.5 29.1 27.2 28.9 27.6 29.7 28.8 29.3 27.8 29.5 29.3 29.4 28.7 29.7 29.1 28.9 27.9 28.3 28.8 27.9 27.0 27.1 27.7 26.6 25.3 24.2 30.7 33.4 31.6 35.9 31.0 32.9 31.2 35.0 30.4 31.2 32.3 33.8 32.8 31.4 32.5 33.5 31.7 30.3 32.6 33.1 31.8 29.5 31.8 31.5 31.2 27.2 31.4 29.6 30.8 26.5 30.9 28.9 33.8 30.3 23.0 28.6 25.2 29.9 25.4 29.6 28.3 29.1 27.8 30.5 28.8 29.4 28.1 30.0 29.3 29.4 28.1 29.8 30.4 28.6 27.7 28.5 29.3 27.5 26.7 27.0 29.3 26.8 26.1 24.2 30.3 36.4 31.7 38.6 30.8 34.0 31.8 37.5 33.1 31.4 34.1 36.4 33.0 31.4 32.6 34.1 32.7 30.7 33.3 34.5 32.7 28.9 32.6 32.2 32.6 27.5 31.4 30.3 32.2 27.3 32.7 27.1 35.3 34.2 23.6 31.4 25.9 31.7 26.2 30.0 28.2 31.4 27.6 30.1 29.2 31.5 28.6 30.2 29.8 29.2 28.4 29.8 30.4 29.5 28.1 28.7 29.2 27.4 26.4 27.1 27.9 26.4 25.4 23.9 29.9 46.5 38.2 47.0 35.0 38.6 35.2 42.5 35.7 37.2 34.6 37.4 35.0 34.6 34.4 36.5 35.5 31.4 35.1 37.2 34.2 31.4 33.8 34.3 33.9 28.9 33.1 32.2 31.3 27.9 33.9 29.6 36.9 39.6 25.4 34.5 27.7 33.3 26.1 32.7 28.7 32.4 28.4 31.9 30.6 31.8 28.3 31.1 31.1 30.0 28.6 29.9 31.0 30.2 28.1 28.4 29.4 27.9 27.8 28.4 28.5 25.4 25.1 22.4 27.2 57.5 45.4 54.9 38.9 43.5 40.0 46.6 38.1 39.2 38.0 42.3 38.4 37.2 37.3 40.2 38.1 33.9 37.0 37.4 36.8 33.4 36.0 36.1 36.2 31.8 37.3 36.2 33.7 28.7 34.7 32.5 36.4 46.4 20.1 37.4 29.0 36.8 27.1 33.5 30.7 32.9 28.1 34.0 31.2 31.7 28.4 33.5 31.0 29.3 28.9 30.3 30.6 29.4 28.2 29.7 29.2 28.6 25.7 29.0 28.0 28.5 23.7 24.5 27.1 103.1 70.2 82.8 57.5 61.9 53.7 68.1 51.5 51.4 50.3 60.0 48.3 46.1 47.2 54.9 48.6 41.1 46.9 48.5 46.7 39.8 45.8 50.8 46.2 37.8 45.8 51.9 45.6 43.3 49.4 54.7 37.6 Highest temp: 103.10 at 736 Lowest temp: 14.32 at 1 Average (including bad pixels and outliers: 29.31 //I haven't run the functions for badpixels or outliers Measured ambient with offset eTa: 25.895675

Berkajerk commented 3 years ago

2Mar_celcious output.txt

slavysis commented 3 years ago

The formula is implemented in the driver. If you want to do the calculations externally, you can refer to the MLX90640 datasheet : https://www.melexis.com/-/media/files/documents/datasheets/mlx90640-datasheet-melexis.pdf . Touching the sensor is not a good idea as it creates thermal gradients and spoils the performance. How much time after POR are you taking your measurements? Did you put the appropriate decoupling capacitors as described in the datasheet?

I wonder why KsToScale=0 after executing KsToScale = 1 << KsToScale;. Did you make sure that KsToScale is 32 bit int?

Best regards

Berkajerk commented 3 years ago

My temperature average seems to stay about 2C from expected. I'm going to run the code on a beefier chip to see if it's just this micro that can't calculate fast enough between frames.

mlx-kva commented 3 years ago
KsToScale = 1 << KsToScale;

The type of the expression 1 << KsToScale is defined by the type of the constant 1. On a 16 bit MCU, the 1 is 16 bit.

You might want to use something similar to:

KsToScale = 1ul << KsToScale;

1ul is 1 but with type unsigned long, which is, I believe, 32 bit on a 16 bit system.

my 2 cents.