The Arduino Inventor's Guide (34 page)

BUILD THE TEMPERATURE MONITOR

First let’s take a look at the part of the greenhouse control system that will measure temperature. There are a lot of different temperature sensors out there. A few common types that you might encounter are
thermistors
, which change resistance based on temperature, and
thermocouples
, which output a really small voltage (less than 10 mV) and require an amplifier circuit to use. The TMP36 device is a third type of sensor that simply outputs a voltage calibrated to be 0.75 V at 25 degrees Celsius. The voltage then varies linearly based on the temperature of its surroundings. This means that as the temperature changes the voltage changes accordingly, as shown in
Figure 7-8
.

FIGURE 7-8:
The linear temperature versus voltage response of the TMP36 sensor

Measure Temperature with the TMP36

The TMP36 is one of the easiest temperature sensors to use. The sensor is encased in a small plastic shell shaped like a cylinder with a flat edge and has just three pins.

As we mentioned earlier, the TMP36 looks very similar to the transistor, which also comes in the SparkFun Inventor’s Kit, so check the flat side of the component by tilting it at an angle under a light source, and look for the letters
TMP
. If it says
2N2222
or anything else, it’s the wrong part.

The TMP36 provides a voltage output directly related to the temperature in Celsius of its surroundings. Since you already know how to measure voltages using the
analogRead()
command, this sensor will be easy to use.

The outer pins are for ground and power connections, and the center pin is the voltage signal for the sensor. To use the TMP36, simply connect one pin to 5 V, one pin to ground, and the sensing pin to an Arduino analog pin to read the temperature. Pay attention to how you connect the sensor. With the flat edge facing to the left, the top pin should connect to 5 V and the bottom pin should connect to ground. At 25 degrees Celsius, the sensing pin will have a voltage reading of 0.750 V (750 mV). As the temperature changes, the voltage on this pin will change at a rate of 0.010 V (10 mV) per degree Celsius. Now, this might seem like a lot of math-speak, but we’ll show you how to use this information to get an actual temperature reading in your code and convert it to degrees Fahrenheit. But first, let’s wire it up.

Connect the Temperature Sensor

Figure 7-9
shows the temperature monitor circuit wired up on its own. Most of your components will be on the right side of the breadboard,
so connect a jumper wire from 5 V and GND on the Arduino board directly to the power rails on the right side of the breadboard. Next, insert the TMP36 sensor into the lower portion of the breadboard, with the flat side of the sensor facing left, as shown in
Figure 7-9
.

FIGURE 7-9:
Simplified wiring diagram showing only the temperature sensor

Next, use two short jumper wires to connect the TMP36 sensor’s top pin to 5 V and lower pin to ground, making sure the flat side is facing left. The middle pin is the output voltage of the sensor. Run a jumper wire from this pin to pin A0 on the Arduino board, and that’s it!

Now let’s take a look at a code example to see how to get temperature readings from this sensor.

Program the Temperature Sensor

The TMP36 sensor produces a voltage output relative to the ambient temperature. The datasheet for the TMP36 gives a couple of reference points for converting the voltage reading to a temperature: it shows that the voltage changes at a rate of 0.010 V per degree Celsius and that at 25 degrees Celsius, the sensor has a voltage of 0.750 V. Using this information, if you measure the output voltage from the sensor, you can convert this into a temperature reading in the code.

You may recall from
Project 5
that the
analogRead()
function reads voltage as a whole number, with
1023
for an input of 5 V and
0
for 0 V. To make sense of this, you’ll need to convert that number to a voltage, then convert that voltage to degrees Celsius, and finally translate that value into Fahrenheit. To keep the code clean, you’ll first write a custom function to do the conversion from the raw
analogRead()
number to volts.

Create a Custom Conversion Function

Listing 7-1
shows an example of a custom function that will convert the raw
analogRead()
value and report back an answer that’s been converted to volts.

LISTING 7-1:
Custom function
volts()
to convert from raw analog value to voltage


float

volts(

int
rawValue)
  {

   
const
float
AREF = 5.0;

   
float
calculatedVolts;

   calculatedVolts = rawValue * AREF / 1023;

   
return

calculatedVolts;
  }

In
Project 3
, we showed you how to write your own custom functions to shorten your code and make the
loop()
easier to read. In those examples, the data type of the function was always set as
void
because the function didn’t report back a value. In this case, you’ll want the function to report back the conversion of
analogRead()
to volts, so you’ll have to specify a data type. Use the data type
float

, because you’ll want this function to return the voltage with as many decimal places as possible for accuracy. Name the function
volts

, to be as descriptive yet concise as possible, and then define the parameter(s)

that you pass to this function. In this example, it is the raw value from
analogRead()
.

The math needed to convert between raw
analogRead()
and voltage is pretty straightforward since, as we mentioned earlier, we already know that the
analogRead()
function returns
1023
for an input of 5 V and
0
for 0 V. This means that an
analogRead()
value of
1023
would be equal to 5 V. The custom
volts()
function uses this ratio to convert a raw
analogRead()
measurement to a voltage.

NOTE

It’s common practice to use ALL CAPS to designate objects or names that are constants.

First, declare a variable to use as a reference, named
AREF

, and use this to define the reference voltage, which is 5.0 V. Because you’ll want to use it throughout the code, set it as a constant using the keyword
const
.

Next, you’ll define a variable to store the result of the conversion, named
calculatedVolts

. Notice that the data type for this variable is set as a
float
as well. You’ll want to make sure that any math you perform is accurate beyond whole numbers. To calculate the voltage, simply multiply the
rawCount
by the ratio of
AREF
(5.0 V) to 1,023

.

The
return
instruction

is a command we haven’t used in the previous projects. When the sketch gets to the
return
instruction, it exits the custom
volts()
function and
returns
to the point in the code
where it was called. When you put a value after the
return
instruction, the function returns and reports back that value. The
return
data type must match the data type of the function. For all the functions we’ve used to this point, we didn’t bother to include
return
, because those functions were defined as
void
data types and did not report back a value. Here, the
return
instruction is followed by the variable
calculatedVolts

. This tells the sketch to report the value of
calculatedVolts
back to the point in the code where it was called.

Note that the
return
instruction can also be used with functions that have a
void
data type to instruct the sketch to leave the function and return. In that case,
return
is left blank with no value following it (see
Listing 7-2
).

LISTING 7-2:
A custom function with a
void
data type and a
return
instruction

void
blink
()
{
  
digitalWrite
(13,
HIGH
);
  
delay
(500);
  
digitalWrite
(13,
LOW
);
  
delay
(500);
  
return
;
}

Test the Function

Let’s test the new
volts()
function with an example sketch. Add a few lines in
setup()
and
loop()
to the code from
Listing 7-1
to read the voltage on pin A0, and print it to the Serial Monitor. The complete code example is shown in
Listing 7-3
.

LISTING 7-3:
Testing the analog-to-volts conversion

//Example sketch – reads analog input from A0 and prints the
//raw analog value and the voltage
int
rawSensorValue;
float
rawVolts;
void
setup
()
{
  
Serial
.
begin
(9600);  
//initializes the serial communication
  
Serial
.
print
(
"raw"
);
  
Serial
.
print
(
"\t"
);  
//tab character
  
Serial
.
print
(
"volts"
);
  
Serial
.
println
();    
//new line character
}
void
loop
()
{
  rawSensorValue =
analogRead
(A0);   
//read in sensor value
  rawVolts = volts(rawSensorValue);  
//convert sensor value
                                     
//to volts
  
Serial
.
print
(rawSensorValue);  
//print raw sensor value
  
Serial
.
print
(
"\t"
);
  
Serial
.
print
(rawVolts);  
//print raw voltage reading
  
Serial
.
println
();        
//new line character
}
/***********************************************************/
float
volts(
int
rawCount)
{
   
float
AREF = 5.0;
   
float
calculatedVolts;
   calculatedVolts = rawCount * AREF / 1023;
   
return
calculatedVolts;
}

Connect your Arduino board to your computer with a USB cable, upload this example, and then open up the Serial Monitor. You should see text scroll up the screen like in
Figure 7-10
. According to this, an analog value of 156 is equal to a voltage of 0.76. You can check the output voltage with this calculation: 156 × (5.0 / 1,023) = 0.762 V. It’s always good when the math works out!

FIGURE 7-10:
Serial Monitor output of raw sensor value and voltage

Other books

The Arcanist by Greg Curtis
Shifters of Grrr 2 by Artemis Wolffe, Wednesday Raven, Terra Wolf, Alannah Blacke, Christy Rivers, Steffanie Holmes, Cara Wylde, Ever Coming, Annora Soule, Crystal Dawn
The Gray Wolf Throne by Cinda Williams Chima
A Woman in Arabia by Gertrude Bell
Priestess of Murder by Arthur Leo Zagat