If in your code you move configuration of ADMUX to chipTemp ...
One reason that I am concerned with making all configurations at each reading, and restoring them again, is that I intend to reuse the code. I will probably make it into a library, if it seems to work fine for me I will post it for general use. That is why I make no assumptions about the initial value of any registers, and try to restore them when I am done. But now I understand more about how this works, so to be safe I might check the initial value of e.g. ADMUX, change it only if necessary and in that case either wait for the reading to stabilize or return a value/flag telling the caller to wait a while and try again.
In you modified example you are not waiting for any ongoing conversion to complete. Is this safe? I also notice that you do not clear the ADC interrupt enable or auto trigger enable. Why? (As I wrote earlier I am rather new to this low level ADC coding, so I just want to understand how to code it safe and correct.)
I do not really need sub degree precision, and according to an application note (see below) even with correct calibration the true precision may not be better than 1-2 degrees. By using a ring buffer and a moving average I can "flatten the curve", as it would take more than one sample significantly different from the others in order to alter the result. (CaptainObvious: When I will need precision temperature readings I will indeed use an external circuit, but in this project a free thermometer is a nice bonus.)
In the application where I will first be using this technique I want to monitor true changes in temperature in intervals of five or fifteen minutes. The project is controlling a heating fan inside a car (in the winter). The fan uses a lot of energy, translating into money, and I do not want it to run more than necessary. It will be controlled by a relay, and I want to be able to start the fan earlier the colder it is outside (i.e. inside the unheated car), and also be able to turn it off when it is warm enough inside the car. If nobody comes to the car, disconnecting the mains wire to the heater assembly, I want my project to act as a crude thermostat, running the heater in periods of maybe five or fifteen minutes to keep the inside temperature above a specified limit.
During testing I plan to put an Xbee module in the box with the rest of my circuit, and let it send basic information about temperature readings and when the relay is turned on or off back to my main computer. (This project is for a good friend and neighbour of mine, and I hope to do field testing and final adjustments in the "production environment" of his car.)
The difference between -24.6 and -26.3 is completely irrelevant to me in this application. In fact I could probably do just fine with a precision/resolution of 5 degrees, as long as I know that it is a "true" reading, not a single sample that is off due to noise or anything else. Simple pseudo code might look like this:
On power up check initial temperature Ti
Set initial delay to two hours minus 20 minutes for each ten degrees that Ti is below zero
Sleep for initial delay
Turn on relay
Sleep one hour
Turn off relay
Repeat forever
Check average temperature during fifteen minutes, one sample every 15 seconds
If avg temp above zero, turn off relay, else turn on relay
The initial delay is to let the lower powered engine heater have enough time to get the engine up to a good working temperature before starting it. (We live in Stockholm, Sweden, and for those of you living in warmer climates I could tell a lot about the process of standing in the pitch black early morning in -25C/-13F with an unheated car, scraping a thick layer of ice from all windows and side mirrors while the engine is running and the ventilation is at maximum power and heating to try to reduce the ice on the inside of the windows...)
I have not studied them in detail yet, but I will be looking into the following excellent application notes too:
I looked into the topic of oversampling and averaging earlier when experimenting with an accelerometer, and found good information on Wikipedia and on Wikibooks. The latter also have some good books on C programming, by the way.
So far in my tests I have not done anything specific to reduce the ADC noise, I wanted to get the temperature readings working at all first.
I am not sure if it is true, but I did get the impression that the readings might change with Vcc. To get a good reading in the fridge, for a second calibration point, I hooked the Arduino (display and all) up to a 3 AA battery box. The LCD had trouble updating at about 8 degrees C (of course) but I did get a good and stable reading. After keeping the circuit in room temperature for an hour or two I got significantly lower readings (on battery power) than I did earlier, but when switching to USB power it jumped right back to where I started.
BenF (or anyone else), would you know where I can find a reference to what registers might be modified by other Arduino code, and what registers that it is imperative that I restore after changing them?