Avi Kahn
Published © GPL3+

Using Remote to Show Speed/Distance on an LCD Display

Use an ultrasonic sensor to calculate an object's distance and/or speed, then use a remote to control what is displayed on an LCD screen.

BeginnerProtip1,446
Using Remote to Show Speed/Distance on an LCD Display

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
RGB Backlight LCD - 16x2
Adafruit RGB Backlight LCD - 16x2
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
JustBoom IR Remote
JustBoom IR Remote
Any IR remote will work fine
×1
RobotGeek IR Receiver
RobotGeek IR Receiver
×1
Jumper wires (generic)
Jumper wires (generic)
×30
Breadboard (generic)
Breadboard (generic)
×1

Story

Read more

Schematics

Hand Drawn Circuit Diagram

Code

Set up the Ultrasonic sensor

C/C++
The first task is to get the Ultrasonic sensor up and running, and figure out how to interpret the information it gives as a distance or velocity. To keep the sensor stable, I suggest taping it to a flat surface near your Arduino.

The sensor only has four pins, hook the VCC pin to the 5V source on your Arduino, the GND pin to the Arduino GND, and the echo and trigger should each go to a Digital pin in your Arduino. I choose echo - pin10 and trig - pin8. The following is the snippet of code used to calculate the distance from the echo and trigger.
const int pingPin = 8; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 10; // Echo Pin of Ultrasonic Sensor


void setup() {
   Serial.begin(9600); // Starting Serial Terminal
}
   
void loop() {
   long duration, inches, cm; // define variables
   
   pinMode(pingPin, OUTPUT); //make the trigger pin an output
   
   // send a pulse to trigger detection
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);   	 
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   
   // now listen for the echo back	 
   pinMode(echoPin, INPUT);
   
   // set duration equal to the time it took between to come back
   duration = pulseIn(echoPin, HIGH);
 
   // from simple kinematics (d=vt) and knowing the speed of sound = 343 m/s = 0.01715 cm/ micorsecond
   // we can calculate the distance the object is from the sensor
   cm = duration/ 58;
   
   
   Serial.println("distance: ");
   Serial.println(cm);
   
   
  // this delay controls how much time there is between pulses
   delay(1000);
}

Print to an LCD Display

C/C++
Now that we can calculate the distance and speed, we can work on printing that information to an LCD display. The first step is
to wire the LCD screen to our circuit. In addition, a potentiometer is needed to control the screen's contrast.
The LCD has 16 pins, so you will need a lot of jumper cables. The following table shows the name of each pin, where it should be connected, and what it does (sorry for the awful format, copied and pasted from Latex).

Format:
LCD pin & Connected to & Function/Purpose

VSS & GND & Ground Pin
VDD & 5V (Arduino) & Power
V0 & Potentiometer Output (Center Pin) & Potentiometer uses pin to control contrast
RS & 13 (Arduino) & Register Select (Data or Instructions)
RW & GND & Reading or Writing Mode
E & Digital 2 (Arduino) & Enables writing to the registers
D0 & Not Used & Data Pin - send data when writing to the registers
D1 & Not Used & Data Pin
D2 & Not Used & Data Pin
D3 & Not Used & Data Pin
D4 & Digital 4 (Arduino) & Data Pin
D5 & Digital 5 (Arduino) & Data Pin
D6 & Digital 6 (Arduino) & Data Pin
D7 & Digital 7 (Arduino) & Data Pin
A & 5V (Arduino) & Anode for backlight
K & GND & Cathode for backlight


We don't use all 8 of the data pins, because we are using the LCD in 4 bit mode. Now that everything is connected let's go back and edit the code to print our distance and velocity to the LCD screen. The first thing we need to do is add some lines at the beginning.
#include <LiquidCrystal.h>

//initialize the object lcd and associate its pins to the arduino pins
LiquidCrystal lcd(13, 2, 4, 5, 6, 7); //(rs, enable, d4, d5, d6, d7)
const int pingPin = 8; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 10; // Echo Pin of Ultrasonic Sensor


void setup() {
  Serial.begin(9600); // Starting Serial Terminal
  // We are using a 16 column by 2 row LCD
	lcd.begin(16, 2);
}
   
void loop() {
   long duration, inches, cm; // define variables



   pinMode(pingPin, OUTPUT); //make the trigger pin an output
   
   // send a pulse to trigger detection
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);   	 
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   
   // now listen for the echo back	 
   pinMode(echoPin, INPUT);
   
   // set duration equal to the time it took between to come back
   duration = pulseIn(echoPin, HIGH);
 
   // from simple kinematics (d=vt) and knowing the 
   // speed of sound =  343 m/s = 0.01715 cm/ micorsecond
   // we can calculate the distance the object is from the sensor
   cm = duration/ 58;
   
   //put cursor in top left
	 lcd.setCursor(0, 0);
	 
	 // print to the LCD screen
   lcd.print("d(cm): ");
   lcd.setCursor(0, 1);
   
   // print the calculated distance. DEC just means use base 10
   lcd.print(cm, DEC);
   
    // edit the delay to control the refresh speed on the display
   delay(200);
   lcd.clear();
}

Final Product After Adding Remote

C/C++
Finally, we are ready to incorporate our remote control. The remote sends out a coded IR signal, which is detected by an IR receiving module. The circuit diagram for the module is shown in Figure~\ref{fig: irr}. Depending on your remote, different codes will be transmitted when you hit different buttons.


You can use this handy link (https://www.hackster.io/techmirtz/finding-the-ir-codes-of-any-ir-remote-using-arduino-c7a852) if you want to figure out the codes yourself, or you may be able to look them up if you know the model of the remote. I was able to determine that the code transmitted from pressing the "1" button is "0xFF30CF", and for the button "2" it is "0xFF18E7". Before we move on to the code we need to connect the IR receiver to our circuit. The receiver module has 3 pins, one goes to ground, the other to the Arduino 5V source, and the last to a Digital pin (I used pin 9).


Now to bring it home, we want to achieve a few things: (1) Prompt user to press 1 or 2, (2) Display the distance if they press 1, display the speed if they press 2, (3) keep looking for signals, so they can switch between distance and speed at will.


In order to accomplish this we can use the following structure. Create a boolean variable called "buttonPress," that is false if the user hasn't pressed anything, and true if they have. We initialize it to be zero, and then run a while loop: while buttonPress is false, ask the user to press 1 or 2. once they press one or the other, we break the loop.


Then we write two more while loops: if we pressed 1, run the code that prints the distance, if we pressed 2 then print the velocity. and we make sure that inside the loop that we replicate part the code above to make sure we are always looking for new signals. After clearning up a bit and putting it all together, you get the finished product:
// Using a remote to switch between displaying d(cm) and v(m/s) on an LCD 


#include <LiquidCrystal.h>
#include <IRremote.h>
#include <IRremoteInt.h>

//initialize the object lcd and associate its pins to the arduino pins
LiquidCrystal lcd(13, 2, 4, 5, 6, 7); //(rs, enable, d4, d5, d6, d7)

const int pingPin = 8; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 10; // Echo Pin of Ultrasonic Sensor

int receiver = 9; // the pin connected to the IR Receiver
IRrecv irrecv(receiver);
decode_results results;

void setup() {
   Serial.begin(9600); // Starting Serial Terminal
   
     // We are using a 16 column by 2 row LCD
   lcd.begin(16, 2);
	irrecv.enableIRIn();// allow receiver to take in signal

   
}

   bool buttonPress = false;
   long duration, inches, cm;
   
   // declare variables to be used in velocity calculation
   float speed, d1, d2, t1, t2;
   
   // Variable to keep track of which button was pushed
   int button = 0;


void loop() {

// if we get an IR signal, run the getcode function, and continue looking for more signals
 if (irrecv.decode(&results))
 {
  getcode();
  irrecv.resume();
  buttonPress = true;
 
 
 }

  // before a button is pushed
  while (buttonPress == false)
  {
	lcd.setCursor(0, 0);
	lcd.print("Press 1 or 2");
 	
 	// if you get a signal, figure out which button it is
 	if (irrecv.decode(&results))
 	{
	  getcode();
	  irrecv.resume();
   	  buttonPress = true;
  	}
  	
  	// if user presses a button, clear the screen and end the loop
	if (button == 1 || button == 2)
	{
  		lcd.clear();
  		break;
	} 	 
  }
  
  
 
   // If 1 is pushed, calculate and display distance
  while (button == 1)
   {
   // call function to calculate distance
   	distance();
   	if (irrecv.decode(&results))
	{
  		getcode();
  		irrecv.resume();
  		buttonPress = true;
	}
   }
   
  	//  If 2 is pushed, calculate and display speed
   while (button == 2)
   {
   call function to calculate velocity
	veloc();
	if (irrecv.decode(&results))
  	{
    	getcode();
    	irrecv.resume();
    	buttonPress = true;
  	}
   }
   
   
}

// used to calculate distance in cm
long microsecondsToCentimeters(long microseconds) {
   return microseconds / 29 / 2;
}

// decipher IR code from remote
void getcode()
{
// sets button variable to whichever button we press on the physical remote
  switch(results.value)
  {
	case 0xFF30CF: button = 1;	break;
	case 0xFF18E7: button = 2;	break;
  }
}

//calculates distance
void distance()
{

   pinMode(pingPin, OUTPUT);
   
    // send a pulse to trigger detection
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   pinMode(echoPin, INPUT);
   duration = pulseIn(echoPin, HIGH);
   
   cm = microsecondsToCentimeters(duration);
   
   
   lcd.print("d(cm): ");
   
   // set cursor to bottom left
   lcd.setCursor(0, 1);
   
    // print the calculated distance. DEC just means use base 10 
   lcd.print(cm, DEC);
   
    // edit the delay to control the refresh speed on the display
   delay(200);
   lcd.clear();

 
}

// calculates speed
void veloc()
{
	 
   pinMode(pingPin, OUTPUT);
   
    // send a pulse to trigger detection
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   
   // now listen for the echo back 	
   pinMode(echoPin, INPUT);
   
   // set duration equal to the time it took between to come back
   duration = pulseIn(echoPin, HIGH);
   
   cm = microsecondsToCentimeters(duration);
   lcd.setCursor(0, 0);
   lcd.print("speed(m/s):");

 
   
   // measure first distance
   d1 = microsecondsToCentimeters(duration) / 10;
   
   // record the time, then wait a second
   t1 = micros();
   
    // wait a bit and then send another pulse   
   delay(300);
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   
   // now listen for the echo back 	
   pinMode(echoPin, INPUT);
   
   // set duration equal to the time it took between to come back
   duration = pulseIn(echoPin, HIGH);
   
   // calculate second distance and record time
   d2 =  microsecondsToCentimeters(duration) / 10;
   t2 = micros();
   
   // simple speed calculation, with conversion from micro seconds to seconds
   speed = (d2-d1)/((t2-t1)/1000000);
   lcd.setCursor(0, 1);
   lcd.print(speed, DEC);
   
   // edit the delay to control the refresh speed on the display
   delay(500);
   lcd.clear();
}

Credits

Avi Kahn

Avi Kahn

0 projects • 0 followers

Comments