I needed an accurate and inexpensive temperature logger to calibrate our stage incubator for live cell microscopy and make sure that it was stable over time, so I built one. This was a very quick project, using a $30 Dataq DI-145 data logger and a $4 epoxy-coated thermistor from Adafruit. (To power the thermistor from USB, which is safe and easy, add a micro-USB breakout board, a matching USB cable, and a small solderless breadboard for the complete package!)
Thermistors have a resistance that depend on temperature. By placing a thermistor in a voltage divider configuration with a known resistance, you can measure a voltage, determine the resistance, and then use a lookup table or a formula to calculate the temperature. I used the 10 Kohm resistor Adafruit included as my reference resistor.
We wanted to calculate and display the temperature in real time. The WinDAQ software that Dataq offers for free doesn't offer this feature (you can apply a linear scale but not an arbitrary function) and doesn't run on OS X or Linux. Happily, the DI-145 has a very friendly ASCII serial protocol. A short Python script using pyserial lets us read the voltage divider voltage and the value of Vcc off the DI-145, compute the resistance, and then calculate the temperature using a numpy spline interpolation function against the lookup table from Adafruit.
We've observed that we can measure temperature to about 0.25 °C, which is good enough for us. Using a higher Vcc or a data logger with higher resolution would improve our precision but would have added cost and complexity.
I tested the logger by sticking the probe in a bucket of melting ice, which is an easy temperature reference for 0 °C. Here's what it looks like:
So the system looks pretty accurate! I probably should have tested boiling water as well, but I didn't get around to it.
To actually run my twiddle.py code, hook Vcc to input 1, the voltage divider output (I put the thermistor on top and connected the 10K reference to ground) to input 2, and give it the name of the serial port on the command line. On Windows, this looks like "python twiddle.py COM6"; on Linux (and OS X, I think), you'll use something from /dev instead of COM6. We like to run it with tee so that the temperature is both displayed on-screen and written to a file, like "python twiddle.py COM6 | tee templog.txt".