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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.