Temperature seems an obvious thing to measure, so a bit of rummaging disgorged a classic LM335 temperature sensor that produce an output voltage directly calibrated in Kelvin at 10 mV/K: room temperature runs 296 K = 2.96 V. Nothing could be easier than this:

The downside: a 1 °C temperature change corresponds to only 10 mV, which is barely two LSB of the Arduino ADC. In round numbers, a 1 °F change = 1 LSB, which doesn’t leave much room for measurement noise. I average five successive readings, which may be excessive, but the result seems stable enough:
const float AVREF = 4.94; // Arduino analog reference
#define TAVG 5
float ReadLM335(byte Pin) {
float Kelvin;
Kelvin = (float)analogRead(Pin);
for (byte i = 1; i < TAVG; i++)
Kelvin += (float)analogRead(Pin);
return Kelvin * (100.0 * AVREF) / (TAVG * 1024.0);
}
For better accuracy, you must measure VCC on the Arduino board and plug that into the AVREF constant, because the ADC reference voltage comes from the power supply. If you’re powering the Arduino from a USB port, then don’t bother worrying about analog conversion accuracy, because VCC depends on which PC you use, the USB cable length, what load current you draw from the regulator, and probably the phase of the moon.
The magic number 100.0 converts 10 mV/K to K.
The four character DL1414 LED display works well enough for the kind of temperatures you might find around a human being and, if you have an LED bargraph display, you may as well throw that into the mix, too.

The bargraph has RRYYGGYYRR LEDs, so I scaled the temperature at 5 °C/bar and put 0 °C on the bottom of the display, which means 15-19 and 20-24 °C occupy the green bars in the middle. Fingertip temperatures light up the two yellow bars and body heat gets you into the red, so it’s a reasonable display. Just to show it works, here’s a closer look (0 °C is on the right, but you can reverse that easily enough):

The Arduino source code:
// LM335 Temperature sensor sensor
// Ed Nisley - KE4ANU - November 2012
//#include <stdio.h>
//#include <math.h>
//----------
// Pin assignments
const byte PIN_TEMPERATURE = A1; // Temperature sensor - LM335 = 10 mV/K
const byte PIN_MOSI = 8; // data to shift reg
const byte PIN_SCK = 6; // shift clock to shift reg
const byte PIN_RCKB = 7; // latch clock for LED Bargraph
const byte PIN_RCKC = 12; // latch clock for LED character display
const byte PIN_HEARTBEAT = 13; // DO - Arduino LED
//----------
// Constants
const int UPDATEMS = 1000; // update LEDs only this many ms apart
const float AVREF = 4.94; // Arduino analog reference
const float KTOC = -273.2; // Kelvin to Centigrade offset
const float BARSCALE = 5.0; // degrees per bar increment
#define TCCRxB 0x02 // Timer prescaler
#define LED_SIZE 4 // chars per LED
#define LED_DISPLAYS 1 // number of displays
#define LED_CHARS (LED_DISPLAYS * LED_SIZE)
union DL1414_ {
word ShiftWord; // word overlay
struct { // bitfield sent to the display
unsigned int Addr:2;
unsigned int NotWrite:1;
unsigned int Ctl3_7:5; // unused bits
unsigned int Data:7;
unsigned int Data7:1; // unused bit
} ShiftBits;
};
//----------
// Globals
int Temperature, BaseTemperature;
word LEDBits;
char LEDCharBuffer[LED_CHARS + 1] = "HELO"; // raw char buffer, can be used as a string
unsigned long MillisNow;
unsigned long MillisThen;
//-- Helper routine for printf()
int s_putc(char c, FILE *t) {
Serial.write(c);
}
//-- Send bits to LED bar driver register
void SetBarBits(word Pattern) {
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,Pattern >> 8);
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,Pattern & 0x00ff);
digitalWrite(PIN_RCKB,HIGH);
digitalWrite(PIN_RCKB,LOW);
}
void PulsePinHigh(byte PinID) {
digitalWrite(PinID,HIGH);
digitalWrite(PinID,LOW);
}
//-- Write single char to DL1414
void WriteLEDChar(char Char,char CharID) {
union DL1414_ DL1414;
DL1414.ShiftBits.Data = Char & 0x7F;
DL1414.ShiftBits.Addr = ~CharID & 0x03; // reverse order of chars
DL1414.ShiftBits.NotWrite = 1; // set up data and address
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord >> 8);
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord & 0x00ff);
PulsePinHigh(PIN_RCKC);
// delay(1000);
DL1414.ShiftBits.NotWrite = 0; // write the character
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord >> 8);
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord & 0x00ff);
digitalWrite(PIN_RCKC,HIGH);
PulsePinHigh(PIN_RCKC);
// delay(1000);
DL1414.ShiftBits.NotWrite = 1; // disable write
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord >> 8);
shiftOut(PIN_MOSI,PIN_SCK,MSBFIRST,DL1414.ShiftWord & 0x00ff);
PulsePinHigh(PIN_RCKC);
// delay(1000);
}
void WriteLEDString(char *pString) {
for (byte i=0; (i < LED_CHARS) && *pString; ++i)
WriteLEDChar(*pString++,i);
return;
}
//-- Sample temperature with a dab of averaging
#define TAVG 5
float ReadLM335(byte Pin) {
float Kelvin;
Kelvin = (float)analogRead(Pin);
for (byte i = 1; i < TAVG; i++)
Kelvin += (float)analogRead(Pin);
return Kelvin * (100.0 * AVREF) / (TAVG * 1024.0);
}
//------------------
// Set things up
void setup() {
pinMode(PIN_HEARTBEAT,OUTPUT);
digitalWrite(PIN_HEARTBEAT,LOW); // show we arrived
// TCCR1B = TCCRxB; // set frequency for PWM 9 & 10
// TCCR2B = TCCRxB; // set frequency for PWM 3 & 11
pinMode(PIN_MOSI,OUTPUT);
digitalWrite(PIN_MOSI,LOW);
pinMode(PIN_SCK,OUTPUT);
digitalWrite(PIN_SCK,LOW);
pinMode(PIN_RCKB,OUTPUT);
digitalWrite(PIN_RCKB,LOW);
pinMode(PIN_RCKC,OUTPUT);
digitalWrite(PIN_RCKB,LOW);
Serial.begin(9600);
fdevopen(&s_putc,0); // set up serial output for printf()
printf("Temperature sensor - LM335\r\nEd Nisley - KE4ZNU - November 2012\r\n");
BaseTemperature = KTOC + ReadLM335(PIN_TEMPERATURE);
WriteLEDString(LEDCharBuffer);
LEDBits = 0x5555;
SetBarBits(LEDBits);
printf("Base Temperature: %d C\n",(int)BaseTemperature);
delay(1000);
MillisThen = millis();
}
//------------------
// Run the test loop
void loop() {
MillisNow = millis();
if ((MillisNow - MillisThen) > UPDATEMS) {
digitalWrite(PIN_HEARTBEAT,HIGH);
Temperature = KTOC + ReadLM335(PIN_TEMPERATURE);
printf("Temperature: %d C\n",(int)Temperature);
LEDBits = 0x0200 >> (1 + (int)(Temperature/BARSCALE)); // move upward on display!
SetBarBits(LEDBits);
sprintf(LEDCharBuffer,"%-3dC",(int)Temperature);
WriteLEDString(LEDCharBuffer);
digitalWrite(PIN_HEARTBEAT,LOW);
MillisThen = MillisNow;
}
}












