Project 9.01 Getting an Actual Temperature Reading

In this project you’ll learn how to convert the analog value read from the sensor into an actual temperature. This can get a bit complicated but it’s how many sensors work in the real world.

Project Code:

//////////////////////////////////////////////////////
// 9.01 - Getting an Actual Temperature Reading

byte tempSensorPin = A3;

void setup() {
  pinMode(tempSensorPin, INPUT);
  Serial.begin(9600);

}

void loop() {

  float currentTemperature = ReadTemperature();
  
  Serial.print("The temp in C is: "); Serial.println(currentTemperature);
  Serial.print("The temp in F is: "); Serial.println(CtoF(currentTemperature)); 
  delay(1000);

}

/*
   This function reads a temperature in degrees C from the MCP9700AT-E/TT and returns it.
*/
float ReadTemperature() {
  int currentTempReading = analogRead(tempSensorPin);

  float currentTempVoltage = currentTempReading * (5.0 / 1024.0); 

  float temperature = (currentTempVoltage - .5) /  .01;           

  return(temperature);
}

/*
   This function converts a temperature passed in degrees C to degrees F and returns it.
*/
float CtoF(float temp) {
  return ((temp * 1.8) + 32);
}
//////////////////////////////////////////////////////

*If you’re copying and pasting the code, or typing from scratch, delete everything out of a new Arduino sketch and paste / type in the above text.

Before we look at the code let’s figure out how we are going to go about getting an actual temperature reading. The first thing that we need to find is the equation for converting the analog value read to a temperature. This can be found in the datasheet for the part on page 10.

https://www.mouser.com/datasheet/2/268/MCP9700_Family_Data_Sheet_DS20001942-3132871.pdf

Datasheets can be very intimidating, even for seasoned engineers. Take a look at the datasheet for the Atmega32u4 (The chip you’re programming):

https://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf

It’s 438 pages!

The equation on page 10 states:

  • Vout = Tc * Ta + V0degreesC

Let’s break that down:

Symbol Description
Vout Voltage produced by the temperature sensor
Tc Temperature Coefficient
Ta Ambient Temperature
V0degreesC Voltage produced at 0 degrees C

So, what do we know? Only the voltage read right now. Let’s go back to the datasheet.

On page 4 we can find the temperature coefficient (10mV per degree C), on page 3 we can find the V0degreesC (500mV) and what we are trying to figure out is the ambient temperature.

Now we know the voltage being read (with analogRead), the temperature coefficient, and the V0degrees, we can re-arrange the equation for ambient temperature:

  1.  Vout = Tc * Ta + V0degreesC

  2.  Vout – V0degreesC = Tc * Ta          <- Subtracted V0degrees

  3.  (Vout – V0degreesC) / Tc = Ta        <- Divided by Tc

  4. Ta = (Vout – V0degreesC) / Tc        <- Just re-written from #3

When we read the analog voltage value from the temperature sensor it will be a value between 0 – 1023. Unfortunately, that is in the wrong form for us. What we need is voltage, not a 10-bit value. In order to convert from a 10-bit number to the voltage it represents we can use the equation:

10bitValue * (5 / 1024)

For example, we would expect a value of about 2.5 with an analog value of 512:

512 * (5 / 1024) = ~2.5v

We can use this equation to convert from 10-bit to voltage.

Now that we have all of the tools we need let’s look at how to use them.

In the loop() function, we have created a variable of type float and assigned it the value that the function ReadTemperature() will return. All this does is run the function and assign the value it returns to the currentTemperature variable.

float currentTemperature = ReadTemperature();

In the ReadTemperature() function, we first take an analogRead of the temperature sensor pin.

int currentTempReading = analogRead(tempSensorPin);

After that we then convert that analog value read into a voltage and assign it to a variable of type float. You may notice the “.0” on the end of the numbers. This specifies these numbers as float type numbers. The number “5” is an int and the number “5.0” is a float. So, if we’re trying to do floating point math, we have to use the “.0” with our numbers. If we did “5 / 1023“ the result would be 0!

float currentTempVoltage = currentTempReading * (5.0 / 1023.0); 

Next, we use the equation we re-arranged earlier to convert to an actual temperature. That value is assigned to a float type variable.

float temperature = (currentTempVoltage - .5) /  .01; 

Then that value is returned.

return(temperature);

Going back to the loop() funciton, we then Serial print the temperature value out in Celsius and Fahrenheit.

Serial.print("The temp in C is: "); Serial.println(currentTemperature);
Serial.print("The temp in F is: "); Serial.println(CtoF(currentTemperature)); 

The CtoF function is there to convert from Celsius to Fahrenheit.

/*
   This function converts a temperature passed in degrees C to degrees F and returns it.
*/
float CtoF(float temp) {
  return ((temp * 1.8) + 32);
}

A one second delay is used after the Serial prints to prevent flooding of the Serial port.

delay(1000);

Who knew reading temperature could be so complicated? Luckily, these functions we made can just be copied and pasted into other programs. This is why people create libraries!

Previous
Previous

Project 9.02 Doing Something Based on Temperature

Next
Next

Project 9.00 Using the Temp Sensor