Close

some of the math can be modified or removed, or 64 bit float can be added.

A project log for mlx90640 sensor works w 800 bytes

Everywhere i read people are excited to get mlx90640 working. here are examples using arduino w 800bytes ram, and 1k with calibrated DEG C

jamesdanielvjamesdanielv 08/26/2019 at 11:420 Comments

here is the main math areas of the calculation of To (thermal value to deg c) some lines are left out, just the math intensive areas are shown below. i feel that this much calc is not needed, and use of both pow and sqrt can be reduced to one or the other. 

granted, that this will in the end most likely only need to be performed on 4, maybe 5 pixels and the rest will be thermal sensor image data from get image data and not need so much calculations

look at how some values are pow(base, exponent) and then at the end sqrt() . i can't help but think that the math can be simplified, and at least the pow  removed. it might require a little bit different thinking.

so at first i'm going to switch to 64bit float math library. (when i know it works i will credit the author) and then i'll try to simplify the math down to not require pow. the pows and sqrts create numbers that need so much resolution detail that the UNO can not process them all correctly with 32bit floats.

    sub_calc_vdd = MLX90640_GetVdd();
    sub_calc_ta = MLX90640_GetTa();
    sub_calc_ta4 = SimplePow((sub_calc_ta + 273.15), (double)4);//prob remove x1x2x3x4
    sub_calc_tr4 = SimplePow((tr + 273.15), (double)4);//prob remove x1x2x3x4
    sub_calc_taTr = sub_calc_tr4 - (sub_calc_tr4-sub_calc_ta4)/emissivity;/redo because no pow
    
    sub_calc_alphaCorrR[0] = 1 / (1 + ksTo[0] * 40);
    sub_calc_alphaCorrR[1] = 1 ;
    sub_calc_alphaCorrR[2] = (1 + ksTo[2] * ct[2]);
    sub_calc_alphaCorrR[3] = sub_calc_alphaCorrR[2] * (1 + ksTo[3] * (ct[3] - ct[2]));

  irData = irData - offset[pixelNumber]*(1 + kta[pixelNumber]*(ta - 25))*(1 + kv[pixelNumber]*(vdd - 3.3));

            sub_calc_Sx = SimplePow((double)sub_calc_alphaCompensated, (double)3) * (sub_calc_irData + sub_calc_alphaCompensated * sub_calc_taTr);
          
            sub_calc_Sx = Q_rsqrt((sub_calc_Sx))       * ksTo[1];


            sub_calc_To = Q_rsqrt(Q_rsqrt(sub_calc_irData/(sub_calc_alphaCompensated * (1 - ksTo[1] * 273.15) + sub_calc_Sx) + sub_calc_taTr)) - 273.15;// remove outer sqrt's, and just have some numbers be sqrt. this avoids the pow to sqrt conversion

            if(sub_calc_To < ct[1])
            {
                sub_calc_range = 0;
            }
            else if(sub_calc_To < ct[2])   
            {
                sub_calc_range = 1;            
            }   
            else if(sub_calc_To < ct[3])
            {
                sub_calc_range = 2;            
            }
            else
            {
                sub_calc_range = 3;            
            }      
            
            sub_calc_To =Q_rsqrt(Q_rsqrt(sub_calc_irData / (sub_calc_alphaCompensated * sub_calc_alphaCorrR[sub_calc_range] * (1 + ksTo[sub_calc_range] * (sub_calc_To - ct[sub_calc_range]))) + sub_calc_taTr)) - 273.15;
            
           
           
           return sub_calc_To;//we return value to main loop rather than do each pixel (all together)

Discussions