Electronics Champ
Published

Bidirectional Speed Calculator using Infrared (IR) Sensors

This project demonstrates how to calculate the speed of a moving object using Arduino and two IR Sensors irrespective of the direction.

BeginnerShowcase (no instructions)3,160
Bidirectional Speed Calculator using Infrared (IR) Sensors

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
IR Sensor
×1
Breadboard (generic)
Breadboard (generic)
×1
LED (generic)
LED (generic)
×1
128x64 OLED I2C Display
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematic

Code

Code

Arduino
/*  Speed Sensor

  This sketch is used to detect the speed of a moving object between two IR
  Sensors connected to the Arduino. The IR Sensors are placed at a set distance.

  The program calculates the speed using the formula Speed = Distance/Time.
  The program then prints the speed of the object on the OLED Display.
  In addition, start time, end time and the speed are displayed on the
  Serial Monitor. The unit used here is metre per second (m/s).

  This program is made by Shreyas for Electronics Champ YouTube Channel.
  Please subscribe to this channel. Thank You.

*/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> //Including the libraries

double startTime = 0; //Initialize the start time
double endTime = 0;  //Initialize the end time
double timeTakenInSeconds = 0; //Difference between start and end time
double speedOfObject = 0;  //Holds the value distance divided by time taken
const double distance = 1;  // Distance between the two sensors is set to 1 metre
int executed = 0;   //Flag to run the code in the loop only once. When set to 1, code in the loop is not executed.
int sensor1 = 9;    //First sensor is connected to pin 9
int sensor2 = 11;   //Second sensor is connected to pin 11
int led1 = 10;   //An LED to indicate that the first sensor has sensed an object
int led2 = 12;   //An LED to indicate that the second sensor has sensed an object

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT);

//Prints the logo on OLED Display
static const uint8_t PROGMEM logo[] = {

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x07, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x01, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x07, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x07, 0xfc, 0x11, 0xf1, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
  0x0f, 0xfc, 0xf1, 0xf1, 0xe7, 0xfe, 0x00, 0x7e, 0x60, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00,
  0x1f, 0xfd, 0xfb, 0xf3, 0xe7, 0xff, 0x00, 0x60, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x1f, 0xfd, 0xff, 0xff, 0xe7, 0xff, 0x00, 0x60, 0x63, 0x87, 0xbb, 0xc7, 0x1f, 0x33, 0xcf, 0x00,
  0x3f, 0xfd, 0xff, 0xff, 0xe7, 0xff, 0x80, 0x60, 0x66, 0xcd, 0xb3, 0x4d, 0x9b, 0x36, 0xdb, 0x00,
  0x3f, 0xfd, 0xf9, 0xf3, 0xe7, 0xff, 0x80, 0x7e, 0x64, 0x48, 0x33, 0x08, 0x99, 0x34, 0x18, 0x00,
  0x7e, 0x40, 0x11, 0xf1, 0x20, 0x1f, 0xc0, 0x60, 0x67, 0xc8, 0x33, 0x08, 0x99, 0x34, 0x1f, 0x00,
  0x7e, 0x7d, 0xf9, 0xf3, 0xe7, 0xdf, 0xc0, 0x60, 0x64, 0x08, 0x33, 0x08, 0x99, 0x34, 0x01, 0x00,
  0x7e, 0x7d, 0xfb, 0xff, 0xe7, 0xdf, 0xc0, 0x60, 0x66, 0xcd, 0xb3, 0x0d, 0x99, 0x36, 0xdb, 0x00,
  0x7e, 0x7d, 0xff, 0xff, 0xe7, 0xdf, 0xc0, 0x7e, 0x63, 0xc7, 0xbb, 0x07, 0x19, 0x33, 0xde, 0x00,
  0x7e, 0x7d, 0xf9, 0xf3, 0xe7, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7c, 0xf1, 0xf1, 0x67, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7e, 0x11, 0xf1, 0x0f, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xfb, 0xf3, 0xff, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xe0, 0x3c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x7e, 0x7f, 0xff, 0xff, 0x7f, 0xdf, 0xe0, 0x7e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x7e, 0x7f, 0x27, 0xf8, 0x9f, 0xdf, 0xc0, 0x62, 0x7c, 0x71, 0xf7, 0x3e, 0x00, 0x00, 0x00, 0x00,
  0x7e, 0x7e, 0xf1, 0xe1, 0xcf, 0xdf, 0xc0, 0x60, 0x6c, 0x59, 0xbb, 0x36, 0x00, 0x00, 0x00, 0x00,
  0x7e, 0x7e, 0xf8, 0xe3, 0xef, 0xdf, 0xc0, 0x60, 0x64, 0x09, 0x91, 0x32, 0x00, 0x00, 0x00, 0x00,
  0x3e, 0x7c, 0xf9, 0xf3, 0xef, 0xdf, 0x80, 0x60, 0x64, 0xf9, 0x91, 0x32, 0x00, 0x00, 0x00, 0x00,
  0x3f, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0x80, 0x62, 0x64, 0x89, 0x91, 0x32, 0x00, 0x00, 0x00, 0x00,
  0x1f, 0xfc, 0xf9, 0xf3, 0xef, 0xff, 0x80, 0x7e, 0x64, 0x99, 0x91, 0x36, 0x00, 0x00, 0x00, 0x00,
  0x1f, 0xfe, 0xf8, 0xe3, 0xef, 0xff, 0x00, 0x3c, 0x64, 0xf9, 0x91, 0x3e, 0x00, 0x00, 0x00, 0x00,
  0x0f, 0xfe, 0x71, 0xf1, 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
  0x0f, 0xff, 0x01, 0xfc, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
  0x07, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
  0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x07, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 

};

void setup() {

  Serial.begin(9600);
  //Sets the pin modes of sensors and LEDs
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  
  //LEDs are turned off
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);

  //OLED setup (Change the address (0x3C) according to the display)
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.clearDisplay();
  oled.drawBitmap(0, 0, logo, 128, 64, 1);
  oled.display();
  delay(1000);
  oled.clearDisplay();

}

void loop() {

  if (executed == 0) { //Flag is initialized to 0 to ensure that the loop runs only once

    if (digitalRead(sensor1) == 1) { //If movement is detected by the first sensor

      digitalWrite(led1, HIGH); //Turn on the LED 

      if (startTime == 0) { //If startTime is 0 and no time has been logged yet

        startTime = millis(); //Assign Arduino time to startTime

      }

    }

    if (digitalRead(sensor2) == 1) { //If movement is detected by the second sensor

      digitalWrite(led2, HIGH); //Turn on the LED

      if (endTime == 0) {  //If endTime is 0 and no time has been logged yet

        endTime = millis();   //Assign Arduino time to endTime

      }

    }

    if ((startTime != 0) && (endTime != 0)) { //Now calculate the speed of the object if both times have been registered

      if (startTime < endTime) { //If the object moves from sensor on pin 9 to sensor on pin 11

        timeTakenInSeconds = (endTime - startTime) / 1000.0; //Convert miliseconds to seconds
        speedOfObject = distance / timeTakenInSeconds; //Calculate speed in metres per second

        /* Print the values to the serial monitor */
        Serial.print("Start Time: "); //Print to the serial monitor
        Serial.print(startTime);  //Print value
        Serial.println(" milliseconds");
        Serial.print("End Time: "); //Print value
        Serial.print(endTime);    //Print value
        Serial.println(" milliseconds");
        Serial.print("Speed of Object = ");
        Serial.print(speedOfObject);
        Serial.println(" m/s");
        Serial.println(" ");
        oled.clearDisplay();
        oled.setTextSize(2);
        oled.setCursor(0, 0);
        oled.setTextColor(WHITE);
        oled.print("Speed of");
        oled.setCursor(0, 19);
        oled.print("Object is");
        oled.setCursor(0, 37);
        oled.print(speedOfObject);
        oled.println(" m/s");
        oled.display();
        executed = 1; //Set the value to 1 to stop the loop from running again
        reset();

      }

      else {     //If the object moves from sensor on pin 11 to sensor on pin 9

        timeTakenInSeconds = (startTime - endTime) / 1000.0; //The value of startTime is greater than endTime
        speedOfObject = distance / timeTakenInSeconds;  //Calculate speed in metres per second

        /* Print the values to the serial monitor */
        Serial.print("Start Time: ");
        Serial.print(endTime);
        Serial.println(" milliseconds");
        Serial.print("End Time: ");
        Serial.print(startTime);
        Serial.println(" milliseconds");
        Serial.print("Speed of Object = ");
        Serial.print(speedOfObject);
        Serial.println(" m/s");
        Serial.println(" ");

        /* Print the values on the OLED Display */
        oled.clearDisplay();
        oled.setTextSize(2);
        oled.setCursor(0, 0);
        oled.setTextColor(WHITE);
        oled.print("Speed of");
        oled.setCursor(0, 19);
        oled.print("Object is");
        oled.setCursor(0, 37);
        oled.print(speedOfObject);
        oled.println(" m/s");
        oled.display();
        executed = 1;   //Set the value to 1 to stop the loop from running again
        reset();  //A function to start the loop from running again

      }
    }
  }
}

void reset() {

  delay(5000);
  executed = 0;
  startTime = 0;
  endTime = 0;    //Set the value to 0 to start the loop from running again
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);  //Turns off both the LEDs
  speedOfObject = 0;    //sets the speed to 0

  //Resets the OLED Display
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setCursor(0, 0);
  oled.setTextColor(WHITE);
  oled.print("Speed of");
  oled.setCursor(0, 19);
  oled.print("Object is");
  oled.setCursor(0, 37);
  oled.print(speedOfObject);
  oled.println(" m/s");
  oled.display();

}

Credits

Electronics Champ
5 projects • 11 followers
Projects based on breadboard electronics and Arduino with clear step-by-step instructions, circuit diagrams, schematics, and source code.

Comments