a 2 cent thermometer you can add to your Arduino Uno

Greetings to all,
I wrote the following little bit of code to turn an Arduino Uno and a 2c 1N4001 diode into a thermometer.
This makes it, with appropriate ebay-ing, a $12 data logging thermometer. This hopefully will allow a much greater range of science teachers access to data logging technologies for their class.
A simple "cut and paste" of the console output will let you plot it in Excel. (or rewrite the Serial.print() lines to feed PLX-DAQ into excel, and graph in real time.

It was written as part of a set of teacher resources to illustrate the power of Arduino in STEM teaching, and to help link concepts that in traditional curricula have not really been updated in the last 100 years or more. (Eg almost every device you own that measures something does linear algebra to turn ADC values into useful units - it is really "alive" today!). I hope that this is of interest, both for a couple of basic-intermediate programming tricks that may not be of really common knowledge, and also hardware tricks such as using internal pullup resistors to bias a sensor.

The paper containing the student worksheets and description are here https://drive.google.com/file/d/0B8NyMDTl1ovXYndyVnZrdDhZd1U/edit?usp=sharing

The student sketch is here (you want them to do the legwork so that they get to learn).

The actually useful thermometer, which stores its calibration in eeprom, and auto starts if you don't stop it by typing xxxx into the console when it first powers on is shown in the code box below

Hope this is of interest, and thanks for a wonderfully stimulating forum.
Harristotle

[code]
// a functioning diode thermometer with stored calibration
// To recalibrate, open the serial console and hold down the letter x a few times, then press return, within 1 second of starting
// Then expose the diode to two different, known temperatures. The classic way is with ice water and boiling water, but you
// can use a known thermometer and any two temperatures to callibrate.

//Leon Harris, 2014
// Version: 0.2
// Fully working, but not cleaned up


#include <EEPROM.h>
#include <avr/eeprom.h> //needed for eeprom_read_block function

struct calib_t
{
  float slope;
  float offset;
} calib;

 
float Temperature=0;
float Slope, Offset;
char junk;

// Callibration data goes into Temp[] and Raw[]
float Temp[2]={0};
int Raw[2]={0};

float readTemp() {
  float raw=0;;
  float temp;
  for (int i=0; i < 5; i++) {
    raw+=(float)analogRead(0);
    
  }
  raw=raw/5;
 
  temp= (raw * Slope) + Offset;

  return temp;
}

void setup() {

  // configure the circuit
pinMode(A0,INPUT_PULLUP);
pinMode(A1,OUTPUT);
digitalWrite(A1,LOW);

  Serial.begin(9600);
Serial.println("Arduino Thermometer");
Serial.println("type xxx [enter] within a second to callibrate");
Serial.flush();
  delay(1000);

  if ((char)Serial.read()=='x'){
    
    for (int i=0; i < 512; i++){
      EEPROM.write(i,0);
    }
  }
  
  
  // check for callibration data
eeprom_read_block((void*)&calib, (void*)0, sizeof(calib));
Serial.print(calib.slope);
Serial.print(" ");
Serial.println(calib.offset);
if ( calib.slope == 0 ) { //no slope, no calibration
  // start calibration routine

  Serial.println("Enter first temperature on the serial console");
  
  Serial.flush();
       while (Serial.available() > 0) {
       junk=Serial.read();
     }
  while (Serial.available() == 0) {
   Temp[0]=Serial.parseFloat();

  }
  Raw[0]=0;
 for (int i=0; i < 10; i++){
   Raw[0]+=analogRead(0);
 }

  Raw[0]=Raw[0]/10;


  Serial.println("Enter second temperature on the serial console");
  Serial.flush();
     while (Serial.available() > 0) {
       junk=Serial.read();
     }
     
  while (Serial.available() ==  0) {
    Temp[1]=Serial.parseFloat();
  }

    Raw[1]=0;
 for (int i=0; i < 10; i++){
   Raw[1]+=analogRead(0);
 }

  Raw[1]=Raw[1]/10;

// slope and intercept calculations go here
Slope= (Temp[1] - Temp[0])/ (Raw[1] - Raw[0]);
Offset= Temp[1] - ( Slope * Raw[1]) ;

calib.slope=Slope;
calib.offset=Offset;
Serial.println("#############################################################");
Serial.println("#                                                           #");
  Serial.print("# Slope= ");
             Serial.print(calib.slope);
               Serial.println("                                             #");
  Serial.print("# Offset= ");
             Serial.print(calib.offset);
                 Serial.println("                                           #");
Serial.println("#############################################################");

eeprom_write_block((const void*)&calib, (void*)0, sizeof(calib));
} //end if

else {
Slope=calib.slope;
Offset=calib.offset;
}

}




void loop() {

delay(1000);

Temperature=readTemp();


Serial.println(Temperature);

}

[/code]

Terrifically informative post. Well worth a look Thanks

I used an LED and did the calibration by setting the first temp at my known room temp and then clasping the LED between thumb and forefinger for about 5 seconds and adding 3 degrees to the room temp . 23 and 26
Worked like a charm straight off

Remember to turn CR and line feed on in the serial terminal to get the initial sttings in

I spent hours mucking around with LM 7225 's with no result at all so this was great

Thank you for your kind words.

Be careful with using a LED that you are not looking at a photovoltaic effect.

Light on LEDs means more current will pass through them, darkness means less. It may not be your finger that is heating it up! I have used LEDs as photodiodes in the past.
Cheers,
H.