Error in "love-o-meter" temp sensor tutorial?

I'm going through the Arduino Projects Book as an introduction to working with these boards, and am on the third project, and am wondering if this line of code is correct:

float voltage = (sensorVal/1024.0) * 5.0;

It's intended to map a range of 0-1023 to a range of 0-5, but wouldn't it give you (very) slightly inaccurately low values, and never return a full 5 volts? Shouldn't it be written as follows:

float voltage = (sensorVal/1023.0) * 5.0;

Am new to programming and electronics and am educating myself, so please forgive me if this is a stupid question. Tried googling this project and question without results, wasn't sure what kind of general search to enter, and searches involving general "off by one" and "voltage mapping" queries drowned me in irrelevant answers.

Clearly you need to divide by whatever the range - the maximum count - of the ADC is.

Haven't researched just how the ADC in the ATmega works.

And of course, the only reason ever to use floating point maths, is to provide a human-readable display. If you are not going to display it, you do not need floating point.

The tutorial indicates that the analog to digital converter returns values ranging from 0-1023 from analogue inputs ranging from 0 to 5 volts. Wouldn't the range therefore be 1024, which if used in this line of code would seem to give slightly low values, and never return a value of 5 volts? Or am I misunderstanding the definition of "range."

The authors of the tutorials used float as the data type (I think that's correct terminology) - not sure why that was chosen over int.

I can't speak for the "Arduino Projects Book" as such, whichever this is, but the Arduino site "tutorials" are notorious for subtle "skill tests" - obvious and not-so-obvious blunders which cause varying degrees of malfunction and which puzzle beginners when they encounter these.

The "range" of values that can be represented in 10 bits is 1023 minus zero - there are only 1023 steps; the last "step" in a counter would be back to zero. Zero must represent zero and 1023 must represent full-scale, so the steps are not one 1024th of 5V, but one 1023rd, and you therefore must divide by 1023.

Float is used because people assume you need floating point mathematics to perform a division. You don't. If you convert the int to a long in the process of multiplying it by not 5, but 5000 and divide that by 1023, the result is the voltage expressed in millivolts whcih you can print as volts simply by inserting a decimal. Of course, if you do not want to print it, you do not need to either multiply it by 5 or divide by 1023 in the first place, you simply use or compare the value according to your desired calibration.

Zero must represent zero and 1023 must represent full-scale

"1023 must represent almost full-scale and above"

(I'd multiply by five and then divide by 1024)

(I’d multiply by five and then divide by 1024)

If only because it is so much easier. :smiley:

No, simply because it is the right thing to do.

Ever wonder why so many voltage reference devices have strange, non semiconductor bandgap output voltages like 1.024 or 2.048 volts?

(Hint: The correct answer does not include the value "1.000977517106549mV")