This project will show you how to calculate a distance with an ultrasonic sensor. It will be split up into three parts:
- Programming Ultrasonic Sensors + Displaying It Onto Serial Monitor
- How to Display the Distance Onto an LCD
- Using Interrupt with an Ultrasonic Sensor
At the end of this section, your project should look like this:
As you can see, the distance changes as I move my hand. When I move my hand away, the distance also changes - it increases. And as I move my hand closer to the sensor, the distance decreases. You may have noticed, sometimes the distance was a 3 digit number. This was because my hand was too close to the sensor. The sound-wave that was sent, bounced back to quickly for the sensor to read it.
The Schematic:
The wire connecting to Gnd is the 'Gnd' leg on the sensor, the wire connecting to pin no. 9, is the 'Echo' leg, the wire connecting to pin no. 10 is the 'Trig' leg and the wire connecting to 5v is the 'Vcc' leg.
The Code:
To start, add this to the beginning of your code.
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
Secondly, we need to define the variables.
long duration;
int distance;
In the void setup() function, we need to state the Input/ Output of each pin. We also need to start a serial communication.
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
Now, for the void loop() function, add this:
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
This code clears the trigPin. Then, to set the pin onto HIGH for 10 microseconds, add this:
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Next, write the following:
duration = pulseIn(echoPin, HIGH);
This line reads the echoPin, returns the sound wave travel time in microseconds.
Finally, to calculate the distance and print it onto your serial monitor, write this to your code.
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.println(distance);
delay(10);
Your code should be similar to the following:
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
delay(10);
}
If your code works, then great. But if it doesn't, then you might need to check the following:
- Whether you have wired the circuit correctly.
- Whether you have the same serial port and serial connection (9600).
- If your ultrasonic sensor is working properly.
Now, instead of displaying the distance onto the serial monitor, we will be displaying it onto an LCD. At the end, your project should look like this:
The Schematic:
The Code:
Now, add this to the start of your code.
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
LiquidCrystal lcd(
To display 2 different types distances, change the 'int distance' into the following:
int distanceCm, distanceInch;
This means that the LCD will display the distance in centimeters and inches. Next, in the void setup() function add this:
lcd.begin(16,2);
Also, delete the serial.begin() function since we don't need to communicate with the CPU. Now, to calculate the distance in inches, we need to add the following code.
distanceInch = duration * 0.0113 / 2; /*remember to change the 'distance' variable
into distanceCm*/
Add this code to print the distance onto the LCD.
lcd.setCursor(0,0);
lcd.print("Distance: ");
lcd.print(distanceCm);
lcd.print("cm ");
delay(10);
lcd.setCursor(0,1);
lcd.print("Distance: ");
lcd.print(distanceInch);
lcd.print("inch ");
delay(10);
In this code, the cursor is set to row 0, column 0 on the LCD. Then, the word 'distance: ' will be shown and next to that, the distance in centimeters will be printed on the LCD. Same with the distance in inches but that will be one row down. Your code should look like this:
#include <LiquidCrystal.h>
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
lcd.begin(16,2);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distanceCm = duration * 0.034 / 2;
distanceInch = duration * 0.0113 / 2;
lcd.setCursor(0,0);
lcd.print("Distance: ");
lcd.print(distanceCm);
lcd.print("cm ");
delay(10);
lcd.setCursor(0,1);
lcd.print("Distance: ");
lcd.print(distanceInch);
lcd.print("inch ");
delay(10);
}
If your project is not working like the one in the video, you should do the following:
- Check if your code is correct.
- Check if you have wired your circuit and the LCD correctly.
In this part of the project, you will use an interrupt to control when the sensor will measure the distance. It should look like this:
You may have noticed that when I press the button, the distance on the LCD changes. This is because the Ultrasonic Sensor only checks the distance when the button is pressed.
The Schematic:
I connected the button onto pin number 2 on the Arduino board because it, and pin number 3 are the only pins that the interrupt() function can be used.
Update (08/08/2018): The Interrupt() function can actually be used in pins 18, 19, 20 and 21 as well as pins 2 and 3. Thank you to Walter Stroebel for pointing that out.
The Code:
Firstly, we need to state the pin that the push button is connected to, so add this to the start of your code.
const int buttonPin = 2;
Then, to add the interrupt() function, add this line to the void setup() function.
attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);
All we have to do now is take everything from the void loop() function and add it to another function, this one called pin_ISR(). In the end, your code should look like this:
#include <LiquidCrystal.h>
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
const int buttonPin = 2;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
lcd.begin(16,2);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);
}
void loop() {
}
void pin_ISR(){
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distanceCm = duration * 0.034 / 2;
distanceInch = duration * 0.0113 / 2;
lcd.setCursor(0,0);
lcd.print("Distance: ");
lcd.print(distanceCm);
lcd.print("cm ");
delay(10);
lcd.setCursor(0,1);
lcd.print("Distance: ");
lcd.print(distanceInch);
lcd.print("inch ");
delay(10);
}
Update (08/08/2018) Walter Stroebel has commented, improving the current code into the following:
#include <LiquidCrystal.h>
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
volatile bool buttonPressed = false;
const int trigPin = 9;
const int echoPin = 10;
const int buttonPin = 2;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
lcd.begin(16,2);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);
}
void loop() {
if (buttonPressed) {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distanceCm = duration * 0.034 / 2;
distanceInch = duration * 0.0113 / 2;
lcd.setCursor(0,0);
lcd.print("Distance: ");
lcd.print(distanceCm);
lcd.print("cm ");
delay(10);
lcd.setCursor(0,1);
lcd.print("Distance: ");
lcd.print(distanceInch);
lcd.print("inch ");
delay(10);
buttonPressed = false;
}
}
void pin_ISR(){
buttonPressed = true;
}
// I would like to thank Walter Stroebel for suggesting this code.
This code is better since it is shorter meaning the interrupt will work better and more can be used at the same time.
If your code doesn't work, check the following:
- If you have wired your LCD, button and sensor correctly.
- If you have written the code right.
Hope you had a good time. Good luck on future projects!
Comments