
Chapter 2. Digital Ruler
You've made it to chapter 2! Congrats! From now on things are going to get a bit complicated as we try to make the most of the powerful capabilities of the Arduino micro controller. In this chapter we are going to learn how to use a sensor and an LCD board to create a digital LCD ruler.
Put simply, we will use the ultrasound sensor to gauge the distance between the sensor and an object. We will use the Arduino and some math to convert the distance into meaningful data (cm, inches) and finally display this on the LCD.
- Prerequisites
- Using an ultrasound sensor
- Hooking up an LCD to the Arduino
- Displaying the sensor data on the LCD
- Summary
Prerequisites
The following is a list of materials that you'll need to start coding on an Arduino; these can be purchased from your favorite electrical hobby store or simply ordered online:
- 1 x Arduino-compatible board such as the UNO
- 1 x USB cable A to B 1 x HC—SR04 ultrasound sensor
- 1 x I2C LCD1602
- 10 x male to male wires
- 9V battery with 2.1 mm barrel jack connector (optional)
- Laser pointer (optional)
Components such as the LCD panel and the ultrasonic sensor can be found in most electronic hobby stores. If they are unavailable in a store near you, you will find online stores that ship worldwide.
A bit about the sensor
The SR04 is a very powerful and commonly used distance/proximity sensor. And that is what we are going to look at first. The SR04 sensor emits ultrasonic waves which are sound waves at such a high frequency (40 kHz) that they are inaudible to humans. When these waves come across an object, some of them get reflected. These reflected waves get picked up by the sensor and it calculates how much time it took for the wave to return. It then converts this time into distance.
We are firstly going to use this sensor to make a simple proximity switch. Basically, when you bring an object closer than the set threshold distance, an LED is going to light up.
This is the circuit that we need to construct. Again, be very careful about where everything goes and make sure there are no mistakes. It is very easy to make a mistake, no matter how much experience you've had with Arduinos.

In reality it is going to look something like this, much messier than the Fritzing circuit depicted in the previous screenshot:

Open a new sketch on the Arduino IDE and load the SR04_Blink.ino
program that came with this book.
Save the code as SR04_Blink.ino
in your codes directory. This enables us to keep the supplied code as a backup if we tweak it and end up messing up the program. Do this in every instance. Now, once more, check and ensure that the pins match the topmost lines of the code. Upload the code. Now open the Serial Monitor on the Arduino IDE and select 9600 as the baud rate. Place your hand or a flat surface (a book) in front of it and keep changing the distance.
You should be able to see the sensor distances being displayed on the screen, as in the following screenshot:

It says Outside sensor range
if the sensor is picking up values greater than 200 cm because that is the most it can measure. Otherwise, if you make it point at nothing at a distance, it will still display around 200 cm because that is its range.

You will notice that, as you bring the object closer to the sensor than 15cm, it lights up. This is because the threshold is set at 15cms
, as you can see in the following code snippet:
if (distance < 15) { // Threshold set to 15 cm; LED turns off if object distance < 15cms digitalWrite(ledPin,HIGH); } else { digitalWrite(ledPin,LOW); } if (distance >= 200 || distance <= 0){ Serial.println("Outside sensor range"); } else { Serial.print(distance); // prints the distance on the serial monitor Serial.println(" cm"); } delay(500); // wait time between each reading }
This is the same principle used in cars (the beeping sound while reversing if you are too close to a wall), except usually it is an infrared sensor that emits light instead of sound.
In the code, we had the following line:
distance = duration / 58
This line is used to convert a time interval into distance. I will briefly explain the logic behind this. Sound travels at 340m/s, which is 29 microseconds per centimeter. The ping needs to travel twice the distance (to the object and its rebound back to the sensor). Hence, we need to use 2*29 which is 58 microseconds per centimeter. This same logic is applied in the case of inches.
Now think about the maximum and minimum range. As seen in the above snippet, the maximum is set to 200 cm. Most hobby ultrasonic sensors can measure up to 200 cm without hassle, but this can be decreased according to your project. The minimum is set to 0cm because the sensor can indeed measure values at that distance but with lower accuracy.
In some cases, your Serial Monitor may be spamming 0cm as the sensor value, even though you know this is not the case. To fix this issue, simply replace if (distance < 15)
with if ((distance > 0) && (distance < 15))
.
Now that you have learnt how to use the ultrasound sensor, let's move on to the LCD part of the project.
Hooking up an LCD to the Arduino
The LCD screen that we will be using is an I2C LCD1602.

This display screen can be programmed to display whatever you want in a 16x2 matrix. This means that the screen (as you will soon find out) has two rows capable of fitting 16 characters in each row.
Before setting up the complete circuit, look at the back of the LCD. Plug in four wires, as follows:

And then set up the circuit, as follows:

Now you will have to trust me on this next step. We are going to manually install a library that the LCD requires to run. You will be using this same method in future, so be patient and try to understand what we are doing here.
Download the LiquidCrystal_I2C.zip
file from http://www.wentztech.com/filevault/Electronics/Arduino/.
Now, in the Arduino IDE, go to Sketch | Include Library | Add ZIP library and browse to the downloaded ZIP file. You are good to go.
If this doesn't work, you can manually extract the contents to: C:\Users\<Username>\Documents\Arduino\libraries\LiquidCrystal_I2C
on Windows or Documents/Arduino/libraries/LiquidCrystal_I2C
on the Mac and the same on Linux.
You will have to restart the IDE for it to be detected.
Now create a new sketch. Copy the following:
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); // set the LCD address to 0x20 for a 16 chars and 2 line display void setup() { lcd.init(); // initialize the lcd // Print a message to the LCD. lcd.backlight(); lcd.print("Hello, world!"); } void loop() { }
So few code lines after all that trouble? Yes! This is the beauty of using libraries, which enable us to hide all the complicated code so that the visible code is easier to read and understand. Save it as I2C_HelloWorld.ino
. Plug in the Arduino and upload the code.
And you should have something like this:

At this moment you are free to play with it, change the text from Hello, world!
to whatever you like, such as "I like Arduino!".
But, what if I want to use the second line too? Well, don't worry. Change the code as follows:
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); // set the LCD address to 0x20 for a 16 chars and 2 line display void setup() { lcd.init(); // initialize the lcd // Print a message to the LCD. lcd.backlight(); lcd.print("I like Arduinos!!!!!"); lcd.setCursor(0,1); lcd.print("So Awesome!"); } void loop() { }
Best of both worlds
Now comes the part where we combine what we have learnt so far in this chapter into one project. We are going use the sensor to calculate the distance between an object and relay this information to be displayed on the LCD screen in real time.
You are going to combine both the circuits from the previous two sections and create something like this:

Note that, at the bottom of the setup, you can see two power VCC/5V/red wires merging into one. We did not use a breadboard because we wanted to save space. A simple way to go about this is to use a male splitter. A crude way is to cut a male to male in two and cut one female to female wire in two, strip off a bit of their plastic insulation and twist the copper ends (two males and one female) together and simply tape the joint.
Open up a new sketch and load the Digital_Ruler.ino
file.
Save it as Digital_Ruler.ino
in your Chapter 2
directory and upload the code to the Arduino.
The result, if everything has gone right, will be exactly what you expect. It should look something like this:

Pretty neat, huh? But, if you want to make it compact, you can create something like this:

The LCD view will be like this:

Hold on a second! How did you get there? Well, as much as I would like to give you a step-by-step tutorial for putting the setup into a box, I'd like to take this moment to ask you to put on your creativity cap, scramble around your home/office, and find scraps that you could use to convert this into an art and craft project. You can use anything you can find: a box, tin can (insulated of course), a bottle, anything would do. I merely chose the packaging box that the LCD came in.
But what if I want to make it completely portable? As in, without that annoying USB cable? Well, let me show you what you can do. You simply need to have these two things:
- A 9V Battery:
- A 9V battery connector:
And build the following circuit:

The code is the same. Everything remains the same except that there is a battery to power the board instead of the USB cable. A standard 9V battery connected to a 2.1mm barrel jack can be connected to the Arduino to power it. The Arduino UNO can handle between 5-20V of voltage. But the onboard voltage regulator ensures that no more than 5V is fed to the components connected to it. If you want to, you can also mount a laser pointer on the sensor so that it improves the accuracy of the device. Plus, it would look a lot cooler.
Summary
That was fun, right? And a bit challenging, correct? Good! That's when you know you are learning. So let's just summarize what we achieved in this chapter. We first programmed a HC-SR04 Ultrasound sensor and used it to measure a distance which was then displayed on the Arduino UNO Serial Monitor. Next, we played around with the I2C LCD1602 screen, and then, we combined what we learned from the two sections into one project called the Digital Ruler (Scale). You successfully created a digital measuring tape, which made it compact and less cumbersome to use. But since it can measure between 0 to 2 meters, it can only be used indoors. Higher ranges can be achieved using better (and more expensive) sensors.
In the next chapter, we will learn about touch sensors, which will along with a powerful processing software allow us to convert finger gestures to text.