Arduino Nano – Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

For visually impaired individuals, walking safely and confidently can be a challenge, but with the help of technology, we can make it easier for them. This DIY Blind Stick is an innovative and simple solution designed to help users detect obstacles in their path. It uses an Arduino Nano, ultrasonic sensor, and buzzer to sense obstacles in the path and immediately emit a sound alert. This way, they can navigate independently.

The advantage of this Arduino blind stick project is that it is easy to build and affordable. The ultrasonic sensor acts like a third eye, helping to calculate the distance to objects. The Arduino continuously processes data from the ultrasonic sensor and quickly triggers an audio alert when an object is detected nearby.

Here, learn how to connect the ultrasonic sensor to the Arduino and how to write code to respond instantly to nearby obstacles with zero delay. This is crucial for navigation for visually impaired individuals. Let’s start building this Arduino blind stick to provide a safer life for those who need it!

How Does the Arduino Blind Stick Work?

This Arduino stick is designed to help visually impaired individuals walk safely and independently. It works by detecting obstacles and alerting the user through a buzzer. Additionally, I have added an LED indicator light to assist those with partial vision. Now, let’s take a step-by-step look at how this smart stick works:

Obstacle Detection

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

The core of this stick is the ultrasonic sensor, which acts as the stick’s “eye.” Whenever the TRIG pin of the sensor is triggered by the Arduino, it emits ultrasonic waves, which bounce back after hitting an object. It then measures the time taken for the ultrasonic waves to return and sends this measured time as a (timing pulse signal) through the ECHO pin to the Arduino.

Data Reception and Distance Calculation

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

The Arduino acts as the brain of the stick. It retrieves the timing pulse signal from the ECHO pin of the ultrasonic sensor to calculate the time taken for the ultrasonic waves to hit the object and bounce back.

Knowing the time taken (in microseconds), the distance in centimeters can be calculated using the following formula.

{Distance = (Time taken by the signal to Hit and bounce back / 2) / 29.1}

For example, if the signal takes 500 microseconds to reach and bounce back, then

Distance = (500 / 2) / 29.1 => 8.59 cm

The object is approximately 8.59 centimeters away from the sensor.

Implementing Audio-Based Obstacle Detection and Alerts with Arduino

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

When an obstacle is detected within a safe range (50 centimeters), the Arduino triggers two alert systems:

  • Buzzer: Emits a sound to warn the user of nearby objects. The closer the object, the faster the buzzer beeps to alert the user that an object is approaching.

  • LED Light: Blinking lights provide a visual alert for those with impaired vision. The blinking frequency also increases as the object approaches.

This is how the Arduino blind stick works. Next, let’s look at the materials needed to make it.

Components Required for the Smart Blind Stick

Here is a simple list of components needed to build the blind stick project using Arduino.

  • Arduino Nano

  • HC-SR04 Ultrasonic Sensor

  • 5V Active Buzzer

  • LED Light

  • Current Limiting Resistor

  • 9V Battery

  • Slide Switch/Toggle Switch

  • Breadboard

  • Connecting Wires

  • PVC Pipe

Next, we will use Arduino to view the block diagram of this smart stick to clearly understand how its components work together.

Block Diagram of the Arduino-Based Blind Stick

The following diagram shows the topology of the smart blind stick using Arduino Nano, illustrating the relationship between each component.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Wiring Diagram of the Smart Blind Stick Using Arduino

The following wiring diagram illustrates the complete hardware setup of the Arduino-based smart blind stick, detailing how to connect the Arduino Nano, ultrasonic sensor, buzzer, and LED light to form a functional blind stick hardware unit.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

For power, I decided to use a 9V battery, but it is actually better to use a rechargeable 9V battery. Here, you will find that I directly power the ultrasonic sensor from the Arduino GPIO pins to avoid connection complexity, especially on smaller breadboards.

Note that the ultrasonic sensor typically consumes only 15mA, which is sufficient to be powered directly from the Arduino GPIO.

Hardware Connections for the Blind Obstacle Detection Stick

Here is the actual hardware setup we built using the Arduino board and ultrasonic sensor for the ultrasonic blind stick. This setup is based on the previously discussed wiring diagram, demonstrating the actual assembly process of the system..

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

The hardware wiring part ends here, and now it’s time to bring the actual hardware to life by writing software. Let’s proceed to the coding part.

Blind Stick Using Arduino Code

At the bottom of this page, you will find the complete Arduino code for building the smart blind stick using Arduino Nano and ultrasonic sensor. This code continuously calculates the distance to objects using the ultrasonic sensor and checks if the distance is less than 50 and greater than 0. If the distance is within range, it triggers the alert. Additionally, as the distance decreases, the alert frequency also increases.

In this code, I use millis() to perform multitasking for LED blinking and buzzer beeping.

Pin Definitions Using Macros

/* ========================== Pin Definitions ========================== */

// Ultrasonic Sensor Pins

#define vccPin 4 // Ultrasonic sensor VCC pin

#define trigPin 5 // Ultrasonic sensor Trigger pin

#define echoPin 6 // Ultrasonic sensor Echo pin

#define gndPin 7 // Ultrasonic sensor GND pin

// Output Signal Pins

#define ledPin 9 // LED signal pin

#define buzzerPin 2 // Buzzer signal pin

This section defines the pin connection details for the ultrasonic sensor, LED, and active buzzer. These pins will connect to the GPIO pins of the Arduino.

Global Variables for Storing Important Data

/* ========================== Ultrasonic Sensor Data ========================== */

long duration = 0; // Duration of ultrasonic signal bounce-back (in microseconds)

int distance = 0; // Calculated distance between the object and sensor (in cm)

These variables are used to store relevant data from the ultrasonic sensor. Here, “duration” stores the time taken for the ultrasonic signal to reflect back, while “distance” stores the calculated distance value.

/* ========================== Timing Variables ========================== */

// Stores the last time LED and Buzzer states were updated

unsigned long previousLedMillis = 0;

unsigned long previousBuzzerMillis = 0;

Here, these variables hold the previousMillis values for the LED and buzzer, initially set to zero to ensure they work correctly during the first trigger of the LED and buzzer alerts.

/* ========================== Multitasking Interval Variables ========================== */

// Determines the interval between LED blinks and buzzer beeps (in milliseconds)

int ledInterval = 0; // LED blink interval — varies based on object distance

int buzzerInterval = 0; // Buzzer beep interval — varies based on object distance

These variables are crucial for multitasking, allowing independent changes to the LED blinking frequency and buzzer beeping frequency without interference. In short, they define the rates of the buzzer and LED blinking. Initially, they are set to zero but will be updated based on the distance variable during execution.

/* ========================== State Variables ========================== */

// Tracks the current state of LED and Buzzer

bool ledState = LOW; // LED state (ON or OFF)

bool buzzerState = LOW; // Buzzer state (ON or OFF)

These state variables are used to save and track the current state of the LED and buzzer, whether they are ON or OFF.

/* ========================== Current Time Variable ========================== */

// Holds the current time in milliseconds

unsigned long currentMillis = 0;

These currentMillis variables are used to track the value after the timer starts running. This maintained value is crucial for the independent multitasking of LED blinking frequency and buzzer beeping frequency without interference.

measureDistance() function

/* ========================== Measure Distance ========================== */

/**

* Triggers the ultrasonic sensor and calculates the distance to the nearest object.

*/

void measureDistance() {

// Send a 10µs pulse to the trigger pin to start the measurement

digitalWrite(trigPin, LOW);

delayMicroseconds(2);

digitalWrite(trigPin, HIGH);

delayMicroseconds(10);

digitalWrite(trigPin, LOW);

// Measure the duration of the pulse on the echo pin

duration = pulseIn(echoPin, HIGH);

// Calculate the distance in centimeters (speed of sound: 343 m/s)

distance = (duration / 2) / 29.1;

// Output the distance measurement to the Serial Monitor

Serial.print(“Distance: “);

Serial.print(distance);

Serial.println(” cm”);

}

This function actually triggers the ultrasonic sensor by sending a low and high pulse sequence to the TRIG pin. It causes the ultrasonic sensor to emit sound waves. It calls the pulseIn() function to find the echo signal from the sensor’s ECHO pin to measure the time taken for the signal to bounce back.

After obtaining the time, it uses a simple formula mentioned earlier to calculate the distance to the object (in centimeters). Finally, it prints this distance value on the serial monitor.

task_triggerBuzzer()

/* ========================== Task: Trigger Buzzer ========================== */

/**

* Controls the buzzer beep rate based on object proximity.

* Buzzer beeps faster when the object is closer.

*/

void task_triggerBuzzer() {

// Map the distance to a buzzer interval (30ms when close, 100ms when far)

buzzerInterval = map(distance, 0, 50, 30, 100);

// Toggle the buzzer state when the interval has passed

if (currentMillis – previousBuzzerMillis >= buzzerInterval) {

previousBuzzerMillis = currentMillis; // Update the last buzzer time

buzzerState = !buzzerState; // Toggle the buzzer state

digitalWrite(buzzerPin, buzzerState); // Apply the new state to the pin

}

}

task_triggerBuzzer() function controls the speed of the buzzer beeping based on the distance to the object. Here, it continuously maps the buzzerInterval value based on the distance to the object. This, in turn, affects the frequency of the buzzer beeping.

Here, you can find map(distance, 0, 50, 30, 100);; this means the mapping is done based on distance values from 0cm to 50cm and time intervals from 30ms to 100ms. That is, at 0cm, the buzzer beeps every 30ms, and at 50cm, the buzzer beeps every 100ms.

task_triggerLed()

/* ========================== Task: Trigger LED ========================== */

/**

* Controls the LED blink rate based on object proximity.

* LED blinks faster when the object is closer.

*/

void task_triggerLed() {

// Map the distance to an LED interval (150ms when close, 1000ms when far)

ledInterval = map(distance, 0, 50, 150, 1000);

// Toggle the LED state when the interval has passed

if (currentMillis – previousLedMillis >= ledInterval) {

previousLedMillis = currentMillis; // Update the last LED time

ledState = !ledState; // Toggle the LED state

digitalWrite(ledPin, ledState); // Apply the new state to the pin

}

}

task_triggerLed() function controls the speed of the LED blinking based on the distance to the object. Here, it continuously maps the ledInterval value based on the distance to the object. This, in turn, affects the frequency of the LED blinking.

Here, you can find map(distance, 0, 50, 150, 1000); this means the mapping is done based on distance values from 0cm to 50cm and time intervals from 150ms to 1000ms. That is, at 0cm, the LED blinks every 150ms, and at 50cm, the LED blinks every 1000ms.

stopAlert()

/* ========================== Stop Alerts ========================== */

/**

* Deactivates the LED and buzzer when no object is within range.

*/

void stopAlerts() {

digitalWrite(buzzerPin, LOW); // Turn off the buzzer

digitalWrite(ledPin, LOW); // Turn off the LED

ledState = LOW; // Reset LED state

buzzerState = LOW; // Reset buzzer state

}

This stopAlert() function stops the buzzer and LED alerts by using the digitalWrite() function to set the buzzer and LED alerts to low.

setup()

/* ========================== Setup Function ========================== */

/**

* Initializes hardware components, configures I/O pins, and stabilizes the sensor.

*/

void setup() {

// Configure Ultrasonic Sensor Pins

pinMode(vccPin, OUTPUT);

pinMode(trigPin, OUTPUT);

pinMode(echoPin, INPUT);

pinMode(gndPin, OUTPUT);

// Configure Output Signal Pins

pinMode(ledPin, OUTPUT);

pinMode(buzzerPin, OUTPUT);

// Power up the Ultrasonic Sensor

digitalWrite(vccPin, HIGH); // Provide 5V power

digitalWrite(gndPin, LOW); // Connect GND to 0V

// Ensure all signals are in their default LOW state

digitalWrite(ledPin, LOW);

digitalWrite(buzzerPin, LOW);

digitalWrite(trigPin, LOW);

// Initialize Serial Monitor for debugging

Serial.begin(9600);

// Stabilize the ultrasonic sensor after powering up

delay(1000);

}

This setup() function ensures that all hardware pins are correctly initialized, such as setting the respective pins as inputs (INPUTS) and outputs (OUTPUTS). It also initializes the Serial Monitor at 9600 baud rate. After that, it uses a delay to stabilize the ultrasonic sensor after powering up.

loop()

/* ========================== Main Loop ========================== */

/**

* Continuously checks distance and triggers LED and buzzer alerts based on proximity.

*/

void loop() {

// Capture the current time in milliseconds

currentMillis = millis();

// Measure the distance from the ultrasonic sensor

measureDistance();

// Activate LED and buzzer alerts if object is within 30cm range

if (distance >= 0 && distance <= 50) {

task_triggerBuzzer();

task_triggerLed();

} else {

// Stop alerts if the object is out of range

stopAlerts();

}

}

This loop function continuously checks the distance and triggers the buzzer and LED tasks when the distance is >= 0 and <= 50, otherwise, it calls the stopAlerts() function to stop the alerts. Here, the currentMillis function captures the current time of the timer. This timer is crucial for running the buzzer_beep task and led_flash task simultaneously without interference.

Uploading the Code to Arduino

I hope you understand the logic behind the program. Now it’s time to inject the binary file into memory and bring our lovely Arduino back to life. To do this, we need to open the Arduino IDE and ensure that the Arduino Nano board is selected correctly.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Unlike other Arduino boards, the Arduino Nano has two different processor series, namely ATmega328p and ATmega168. My Arduino Nano is equipped with the ATmega328p processor chip, so I selected Arduino328p.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Next, we need to select the corresponding USB associated with our Arduino Nano.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Finally, click the upload button on the Arduino IDE to flash the code into our Arduino Nano.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Alright, the coding part is done. Now, let’s assemble the hardware into the PVC pipe to create a real cane for visually impaired individuals.

Installing the Blind Stick Circuit on the PVC Pipe

The following image shows how I assembled the hardware circuit into the PVC pipe. I securely fixed the breadboard to the PVC pipe using zip ties. Here, I used double-sided tape to attach the battery to the bottom of the breadboard.

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Complete Project Code:

/*************************************************************

Smart blind stick system Arduino Code

More details : https://circuitdigest.com/microcontroller-projects

************************************************************/

/* ========================== Pin Definitions ========================== */

// Ultrasonic Sensor Pins

#define vccPin 4 // Ultrasonic sensor VCC pin

#define trigPin 5 // Ultrasonic sensor Trigger pin

#define echoPin 6 // Ultrasonic sensor Echo pin

#define gndPin 7 // Ultrasonic sensor GND pin

// Output Signal Pins

#define ledPin 9 // LED signal pin

#define buzzerPin 2 // Buzzer signal pin

/* ========================== Ultrasonic Sensor Data ========================== */

long duration = 0; // Duration of ultrasonic signal bounce-back (in microseconds)

int distance = 0; // Calculated distance between the object and sensor (in cm)

/* ========================== Timing Variables ========================== */

// Stores the last time LED and Buzzer states were updated

unsigned long previousLedMillis = 0;

unsigned long previousBuzzerMillis = 0;

/* ========================== Multitasking Interval Variables ========================== */

// Determines the interval between LED blinks and buzzer beeps (in milliseconds)

int ledInterval = 0; // LED blink interval — varies based on object distance

int buzzerInterval = 0; // Buzzer beep interval — varies based on object distance

/* ========================== State Variables ========================== */

// Tracks the current state of LED and Buzzer

bool ledState = LOW; // LED state (ON or OFF)

bool buzzerState = LOW; // Buzzer state (ON or OFF)

/* ========================== Current Time Variable ========================== */

// Holds the current time in milliseconds

unsigned long currentMillis = 0;

/* ========================== Setup Function ========================== */

/**

* Initializes hardware components, configures I/O pins, and stabilizes the sensor.

*/

void setup() {

// Configure Ultrasonic Sensor Pins

pinMode(vccPin, OUTPUT);

pinMode(trigPin, OUTPUT);

pinMode(echoPin, INPUT);

pinMode(gndPin, OUTPUT);

// Configure Output Signal Pins

pinMode(ledPin, OUTPUT);

pinMode(buzzerPin, OUTPUT);

// Power up the Ultrasonic Sensor

digitalWrite(vccPin, HIGH); // Provide 5V power

digitalWrite(gndPin, LOW); // Connect GND to 0V

// Ensure all signals are in their default LOW state

digitalWrite(ledPin, LOW);

digitalWrite(buzzerPin, LOW);

digitalWrite(trigPin, LOW);

// Initialize Serial Monitor for debugging

Serial.begin(9600);

// Stabilize the ultrasonic sensor after powering up

delay(1000);

}

/* ========================== Main Loop ========================== */

/**

* Continuously checks distance and triggers LED and buzzer alerts based on proximity.

*/

void loop() {

// Capture the current time in milliseconds

currentMillis = millis();

// Measure the distance from the ultrasonic sensor

measureDistance();

// Activate LED and buzzer alerts if object is within 30cm range

if (distance >= 0 && distance <= 30) {

task_triggerBuzzer();

task_triggerLed();

} else {

// Stop alerts if the object is out of range

stopAlerts();

}

}

/* ========================== Task: Trigger Buzzer ========================== */

/**

* Controls the buzzer beep rate based on object proximity.

* Buzzer beeps faster when the object is closer.

*/

void task_triggerBuzzer() {

// Map the distance to a buzzer interval (30ms when close, 100ms when far)

buzzerInterval = map(distance, 0, 30, 30, 100);

// Toggle the buzzer state when the interval has passed

if (currentMillis – previousBuzzerMillis >= buzzerInterval) {

previousBuzzerMillis = currentMillis; // Update the last buzzer time

buzzerState = !buzzerState; // Toggle the buzzer state

digitalWrite(buzzerPin, buzzerState); // Apply the new state to the pin

}

}

/* ========================== Task: Trigger LED ========================== */

/**

* Controls the LED blink rate based on object proximity.

* LED blinks faster when the object is closer.

*/

void task_triggerLed() {

// Map the distance to an LED interval (50ms when close, 1000ms when far)

ledInterval = map(distance, 0, 30, 50, 100);

// Toggle the LED state when the interval has passed

if (currentMillis – previousLedMillis >= ledInterval) {

previousLedMillis = currentMillis; // Update the last LED time

ledState = !ledState; // Toggle the LED state

digitalWrite(ledPin, ledState); // Apply the new state to the pin

}

}

/* ========================== Stop Alerts ========================== */

/**

* Deactivates the LED and buzzer when no object is within range.

*/

void stopAlerts() {

digitalWrite(buzzerPin, LOW); // Turn off the buzzer

digitalWrite(ledPin, LOW); // Turn off the LED

ledState = LOW; // Reset LED state

buzzerState = LOW; // Reset buzzer state

}

/* ========================== Measure Distance ========================== */

/**

* Triggers the ultrasonic sensor and calculates the distance to the nearest object.

*/

void measureDistance() {

// Send a 10µs pulse to the trigger pin to start the measurement

digitalWrite(trigPin, LOW);

delayMicroseconds(2);

digitalWrite(trigPin, HIGH);

delayMicroseconds(10);

digitalWrite(trigPin, LOW);

// Measure the duration of the pulse on the echo pin

duration = pulseIn(echoPin, HIGH);

// Calculate the distance in centimeters (speed of sound: 343 m/s)

distance = (duration / 2) / 29.1;

// Output the distance measurement to the Serial Monitor

Serial.print(“Distance: “);

Serial.print(distance);

Serial.println(” cm”);

}

Simulation project download link:

File shared via cloud: Blind_stick.rar

Link: https://pan.baidu.com/s/15Y_sKA2Y4xr8kRxX5AHueg?pwd=gp17 Extraction code: gp17

Welcome to follow, click the blue text at the top “Embedded Simulation Project” or long press to identify the QR code to follow

Arduino Nano - Building an Ultrasonic Sensor Blind Stick with Proteus (Complete Code and Simulation Project Link at the End)

Leave a Comment