Internet PLC Forum
General => Technical support => Topic started by: nealbert on February 18, 2019, 03:26:21 PM

I'm not sure if this is a bug or a feature, but I'll throw it out there for your consideration....
In my FMD8810 I have a Custom Function that takes an incoming analog voltage, scales it and converts the voltage to a temperature. The last step in my CF is to convert the temperature from degrees C to degrees F using the commonly known equation:
F = (C * (9/5)) +32
Great, right? WRONG! The unnecessary pair of parentheses around the "9/5" causes the TBasic to yield an incorrect answer.
At room temperature (25C), the above equation yields and answer that's 17F degrees low. At a temperature of 200C, the answer is over 150F too low.
What I know is...
 That the "()" around the "9/5" is unnecessary.
 That "F = (C * (9/5)) +32" is mathematically identical to "F = (C * 9/5) +32".
 That with or without the "()", the above equations will yield the identical answers when calculated in a spreadsheet, with a hand calculator or using simple pencil and paper.
So, the question is... why does TBasic yield an incorrect answer when unnecessary "()" are there? Shouldn't it just ignore them?

Integer math and operator precedence is the answer to your perplexity.
9 divided by 5 is 1 with integer math.
Your spreadsheet and your calculator are doing floating point math. 9 divided by 5 is 1.8 with floating point math. That is why the results are different then when you use a spreadsheet or a calculator.
Operator precedence. The parenthesis in your expression:
F = (C * (9/5)) +32
Forces TBASIC to perform the 9/5 division first. Remember that 9/5 is 1. The next thing TBASIC does is multiply the value of C by 1. Then TBASIC adds 32 and finally will assign the results of the arithmetic expression to the variable F.
I do not know how smart TBASIC's expression parser is. If it was really smart it would, at compile time, precompute that the division of the constant subexpression 9/5 to be 1 and not actually do a division at run time. If may, also, recognize that the multiplication of the variable C by 1 is always the value of C. TBASIC could simplify your expression to this because this is exactly what you wrote:
F = C +32
Rule #1 for integer math is to do all your additions and multiplications first. Do your division last to preserve accuracy.
You might want to rethink how you are converting an ADC value to temperature in F. if you need F go from ADC units directly to F.
I would used scaled integer values.
I would, also, oversample the ADC so that I are working with a 14 bit ADC value rather than the advertised 12 bit value.
Gary D*ckinson

Neal,
I suggest that you try this equation to convert from C to F:
F = (C * 9) / 5 + 32
That equation just forces the multiply before the division operation. It gets you more accurate results when you are limited to integer math.
This is my spreadsheet results comparing doing the conversion with floating point vs. integer math:
CÂ Â Â F FloatÂ Â Â F IntegerÂ Â Â Error %
0Â Â Â 32.0Â Â Â 32Â Â Â 0.000
1Â Â Â 33.8Â Â Â 33Â Â Â 2.424
2Â Â Â 35.6Â Â Â 35Â Â Â 1.714
3Â Â Â 37.4Â Â Â 37Â Â Â 1.081
4Â Â Â 39.2Â Â Â 39Â Â Â 0.513
5Â Â Â 41.0Â Â Â 41Â Â Â 0.000
6Â Â Â 42.8Â Â Â 42Â Â Â 1.905
7Â Â Â 44.6Â Â Â 44Â Â Â 1.364
8Â Â Â 46.4Â Â Â 46Â Â Â 0.870
9Â Â Â 48.2Â Â Â 48Â Â Â 0.417
10Â 50.0Â Â Â 50Â Â Â 0.000
If you can tolerate the size of the errors then your are good to go!
Best regards,
Gary D* ckinson

Thanks Gary for the formula.
To increase precision you can use a fixed point format
F = C*90/5 + 320
The result will be expressed in 0.1 degree F.
E.g. C = 22 degree
F = 22*90/5 + 320 = 716 = 71.6 degree F.

Gary, et al,
Thanks for the explanation. I totally forgot I'm working with Integer math.
The conversion equation works fine without the extra parentheses and the client is happy now.
I'll keep in mind the methods you describe to increase accuracy. I may need that some day.
Thanks again,
Neal Cooper

Neal,
I am glad that you were able to get the PLC firmware sorted out for your client.
Please feel free to contact me if you have questions with how to get the most out of these PLCs. My email address is in my profile on the forum.
Thanks,
Gary D*ckinson