And now that we have perhaps sorted out the major things, let's go with the nitpicking
@Rick Law:
I'm not a fan of extra casts, as I prefer to make sure that the expression is correctly written in the first place.
I treat them as a strong spice in a recipe: it's has its place, in moderation
.
#define ADC_AMPS(adc,counts) ( (float)((float) adc)*26.7/( ((float)counts)*1023.0) )
The guideline to put parenthesis around a function-like macro parameter is definitely sound and correct.
Unfortunately, the code above does not do that!
Can you spot the case where the (float) cast is not applied correctly to the #define parameter?
It is, I admit, an uncommon, situation, but, it happens, and, is difficult, to spot.
Hint in the period above.
It does not make much difference here (conversion to float is guaranteed by all the other operands), but could in other contexts.
@metrologist
A couple of remarks, the first one is very general:
We have till now talked about
float constants, but there isn't any in all the posted code!
Am I kidding?
Actually not, all the constants here are floating point, but their type is, according to
6.4.4.2 clause 4 actually
double.
For the Arduino (AVR+gcc) implementation, floats and doubles are in reality the same type, or to be more precise, have the same internal representation.
In other environment using 100.0 instead of 100.0f can change the type of an expression and lead e.g. to different execution times (floats can be slower or faster than doubles).
The second point is a specific value:
1023.
The ATmega ADC specifications say, in chapter 24.7 of the
328 datasheet that:
$$ADC = {V_{IN} \cdot 1024 \over V_{REF}} $$
and:
0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one LSB.
So, why divide by 1023 instead of 1024?
- It's not correct according the DS for this ADC
Note that other ADCs (e.g. LTC2400, Tabe 2) might use an all ones code to represent VREF - It could have performance impacts.
More or less guaranteed when using integers, but a smart compiler can also optimize the FP division by a constant of the form 2n
(Hint: FLT_RADIX)
Given the relatively low precision of the ATmega ADC (2LSB, IIRC) this also is a moot point, but let an old man rant...
PS: Picture from Kara no Kyoukai: Fukan Fuukei (The Garden of Sinners: Overlooking View), first instalment of a great anime movie series. Recommended if you like dark supernatural stories. Not for kids.