02.5: Accurate reading of Analog Sensors with an Arduino
Posted on April 21, 2014 by super
In the previous tutorial we learnt how to read an analog sensor and have the Arduino react to the sensors output. We measured the relative light level of the surroundings using an analog light sensor and used this to turn on an LED when it is dark. However this approach does not help us if we are trying to accurately measure a physical phenomenon like temperature. When using an analog temperature sensor we would like to know what temperature it is measuring and not what voltage it is outputting. In order to determine what temperature the sensor is actually measuring we need to map the voltage output by the sensor to the temperature that this represents.
Components required for this tutorial:
Step 1: First we need to connect all of the components up to the Arduino using the jumper wires and the breadboard. You can just follow the photo of the circuit bellow it is very simple! There are more detailed explanations in the next section. The code for this tutorial has been written with the analog sensor on pin A0 of the Arduino.
Step 2: If you have not already done so download and install the Arduino IDE from here. Then open the Arduino IDE and go to File–>Examples–>Basics–>AnalogReadSerial, this will load an example sketch that can be used to read most analog sensors.
Connect the Arduino to your computer using the USB cable and upload the code to the Arduino using the arrow at the top that points to the right (circled red in the picture). Then click on the serial monitor this is the button with the magnifying glass in the top right-hand corner (circled in yellow).
A new window will pop open that should show you an ever changing stream of numbers, this is a value of what your sensor is measuring. If you touch the temperature sensor the value of the sensor should increase and stabilize until the sensor reaches your body temperature.
Step 3: In the previous step the values that we got are only a measurement of the voltage being produced by the analog sensor and do not tell us what temperature the sensor is actually measuring. In order to determine the temperature being measured we need to map this voltage to the temperature range of the sensor. Here is a quick way to do this, with an explanation in the next section on why we do this.
Copy paste this code after the delay and before the close bracket at the end of the code. The map command will take the voltage the sensor is outputting and turn it into a temperature value from 2 to 150 degrees centigrade. If you want to measure the temperature in Fahrenheit just change the values to 35.6 and 302. Upload this code to the Arduino and you will soon be able to read the temperature from the sensor.
Step 4: Now open up the serial monitor again, you will see two values, one is the measured voltage and the other one under TEMP will be the measured temperature. The measured temperature should be approximately that of the ambient air. If you hold the sensor the measured temperature should change to be near your body temperature. Congratulation you are done! You have just gotten your Arduino to react to an input and transform that input into a useable value, you can use this technique with many other analog sensors!
Note: The sensor used is not very precise and will only measure values in degree increments. It also takes a longish time to adjust to the real temperature around it (up to 4minutes!), so do not be alarmed if the temperature measured is not perfect at first. I tested my sensor in the oven at 70 degrees and it eventually stabilized to 70 degrees.
Step 1: In this step we wired up the components. Because we are only going to measure the value of the temperature sensor this will be very easy. To connect the temperature sensor to the Arduino we need 3 connections (GND, Vcc, and a Signal output). The GND pin on the sensor should be connected using a jumper wire to the GND pin on the Arduino. Repeat this with the Vcc pin on the sensor and connect it to the 5v pin on the Arduino. For analog sensors the signal output pin should be connected via jumper wire to one of the Arduino’s analog inputs (A0 to A5 on an Arduino Uno), in this case we used A0. Now we have fully wired up the sensor so that the Arduino can read it! Analog sensors produce a voltage output that varies depending on the value the sensor is sensing, this is what the Arduino reads through one of the analog pins and converts into a measurement. Most Analog sensors need a power source as they compare the value they measure (as a voltage) to a known voltage (3.3 or 5v) that the Arduino produces. For an analog sensor to work all three connections must be wired up!
Step 2: In this step we uploaded some code to the Arduino so that we could read what value the analog sensor was measuring. Without this code the Arduino would not know what we want it to do. Analog sensors connected to the Arduino will produce a value from 0 to 1023 depending on what is being measured and what type of sensor is being used. As the phenomenon being measured changes the value read by the Arduino will also change, in the case of the temperature sensor as it heats up the value will increase, I got a reading of 50 when I put my finger on it.
The code in the AnalogReadSerial example is very simple and the minimum code required to read and display an analog sensor value. The included comments do a good job of explaining what each part does but we will look at it in more detail here.
We include the Serial.begin command in the void setup so that the Arduino knows to communicate back to the computer. The 9600 value refers to the baud rate or how quickly the Arduino communicates with the computer, if you are inexperienced leave this alone.
int sensorValue = analogRead(A0);
This line in the void loop is the one that reads the value coming from the analog sensor. The int sensorValue portion creates a variable called sensorValue that will store the value read from the sensor. We could have called this anything such as lightsensorValue or sensor1. The analogRead(A0) portion tells the Arduino to read the value of the sensor on pin A0, if we had connected the sensor to another pin then we would need to change the A0 portion to match (A1-A5).
This line tells the Arduino to send the reading from the sensor back to the computer so that we can see it on the serial monitor. Note that the sensorValue portion must match what we called the variable in the line above.
This line slows down the program by 1 millisecond, this is done to ensure the program stays stable. If you want to slow down the sensor readings coming from the Arduino increase the value of the number in-between the brackets. delay(1000); would read the sensor once every second.
Step3: Analog sensors connected to the Arduino can only produce a value from 0 to 1023, the value produced is relative to the voltage being output by the sensor. A value of 0 indicates 0 volts on the analog pin and a value of 1023 signifies 5 volts on the analog pin. The value produced from analog read does not tell us very much on its own about what we are measuring as it does not relate the value produced to what we are trying to measure. What does a temperature sensor reading of 50 mean? How many degrees is that?
sensorValue = map(sensorValue, 0, 307, 2, 150);
This line of code tells the Arduino to transform the sensorValue from a voltage into the actual temperature being measured by the sensor. The first two values denote the voltage measured from the Arduino and are equivalent to 0v and 1.5v, the second two values denote the temperature at those voltages. Any sensor values that fall in-between the extremes will be linearly mapped to some value in-between. This sensor has a linear response to temperature changes so we can do this without affecting the accuracy of the temperature output.
How did we know to map these values for this sensor? Well we found the sensor’s datasheet online (LM35 by Texas Instruments) and this tells us how to map it. As you can see from the figure above the output of the sensor is 0 volts at 2 degrees and the voltage goes up by .01V/C° up to 150 degrees. Therefore at 150 degrees the voltage output of the sensor is 1.5v. Similarly the datasheet tells us that the sensors response it linear. So we need to map 0 to 1.5v to 2 to 150 degrees in order to convert the voltage measured by the sensor to a temperature we can use. However as we discussed before the analog pin measures 0 to 5v and automatically maps it to a value from 0 to 1023. So we need to convert 1.5 volts to a number in-between 0 and 1023, this is easy enough just divide 1.5/5 and multiply it by 1023, this gives you a value of roughly 307. So now we can relate the 1.5 volts (307) to the maximum temperature measured by the sensor, 150 degrees. This technique can be applied to any analog sensor allowing you to convert its voltage output into a value of the physical phenomenon being measured. We could have done the same in the light sensor example except it was not necessary for what we were trying to achieve.
If you need more information on the map command you can look it up here.
These two lines serial print the word TEMP and the sensors new value after it has been mapped. This lets you read the temperature measured by the sensor in the serial monitor window. It is the same as the previous Serial.println(); commands. The one difference this time is the word in quotations, by putting the word in quotations the Arduino just prints out that word and not a value. If you want more information on this look up the hello world example!
This tutorial builds on the previous one and teaches you how to calibrate analog sensors by using their datasheet. Now you know how to translate a voltage value into what is actually being measured. It is very handy as analog sensors are very robust and can measure a wide variety of physical phenomenon. The map command can also be used for other things like mapping a temperature range to a number of different states but we will cover this later. The only downside to analog sensors is that the standard Arduino Uno can only use 6 of them at one time.