Introduction: Ultrasonic Sensory Device for the Visually Impaired (Arduino)

This project was done as a final exam for a college class. Both my lab partner, Chris and myself spent several weeks on this project and we're fairly happy with the results.

The idea behind this project is to assist the visually impaired with getting around without the need for a big long cane that just gets in the way. This device is compact and still allows the user to have use of their hands and without having to fold up and stow away a cane.

This instructable will teach you how to create a device that uses an ultrasonic sensor to detect the distance of objects, and based on that distance, give an output of your desired intensity of vibration to help the user "feel" their surroundings using vibrations. This project is fairly complicated and requires some background in circuitry, soldering, and coding.

Step 1: Materials and Tools


  • soldering iron
  • wire cutters
  • screwdriver
  • laser cutter (optional)
  • a computer with the arduino program


  • arduino uno
  • ultrasonic sensor (we used an HC-SR04)
  • haptic motor
  • DRV2605L haptic driver
  • small Adafruit Perma-Proto board
  • assorted wires (solid core is preferred)

Step 2: Step 1: General Hardware and Wiring

Locate in which position you want your mini controller to be on the board-DO NOT SOLDER THE CONTROLLER OR THE MOTOR YET, YOU WILL NEED THEM FOR SOFTWARE TESTING,YOU CAN DO THAT LATER ON.

Based on the location you chose begin to solder the necessary wires to the board: one wire for the VIN, one for the GND, one for the SCL and one for the SDA (no wire is needed for the IN of the controller). VIN and GND will have both ends soldered, one side close to the controller and the other on the positive and negative parts of the board. Make sure to make the wires for SCL and SDA long enough to connect to the ARDUINO.

For a better range, do not solder the ultrasonic sensor directly to the board, rather attach to long jumper wires that you will then solder. You will use the same wiring for the sensor as you did for the controller. The wires for both the VCC and GND will have both ends soldered to the board, while for the Trig and Echo you will solder on long wires so that it may later on connect to the ARDUINO.

Finally, solder on two more wires that ultimately connect the VCC/VIN of the controller and the sensor to the one 5V port of the ARDUINO, and one wire that will connect the GND of the controller and the sensor to one single GND port of the ARDUINO.

Once everything is soldered on, connect SCL of the controller to port A5 and SDA to port A4 of the ARDUINO. Connect the Trig of the sensor to the DIGITAL 4 and Echo to DIGITAL ~5 of the ARDUINO.

Step 3: Step 2: the Code

So, funny story, when we first began testing this code it worked perfectly. But then, all of a sudden, the sensor only worked up to 50cm instead of 4m for no apparent reason. So, due to time constraints, we made a separate version of the code (the one that says 0 to 50) just so that we could prove that our device worked, we were just having problems with our sensor. So, that is why we included two versions of the code, one that works up to 4 meters and one that works up to 50 centimeters.

There is one library that you will have to download and include in your code that contains all of the commands for the haptic controller. You can find this on the adafruit website where you purchased the device. All you have to do is download it and unzip it in to the libraries folder in your Arduino folder on your computer. So, now I'll try to break down the code so you can better understand it.

#include -These are the necessary libraries that you need to include in the code
#include "Adafruit_DRV2605.h"

Adafruit_DRV2605 drv; -This line just initializes the driver object basically

int maximumRange = 400; -Sets the max range to 4 meters

int minimumRange = 0; -Sets the minimum range to 0 meters

long duration, distance; -Makes variables for the duration and distance of the pulses from the sensor

int distancegroup, measurecount;

const int TRIG_PIN = 4; -Sets the trig pin of the sensor to the 4 slot on the arduino (can be changed)

const int ECHO_PIN = 5; -Sets the echo pin of the sensor to the 5 slot on the arduino (can be changed)

void setup() {

pinMode (TRIG_PIN, OUTPUT); -Sets the pins to the necessary settings

digitalWrite (TRIG_PIN, LOW);


drv.begin(); -Starts up the driver and tells it to use library number one

drv.selectLibrary(1); }

uint8_t effect = 1;

void loop() { -The loop contains a few other voids that will be made below






delay(60); }

void measuredistance(){ -This section basically calculates the distance that the sensor is reading (in or cm)

unsigned long t1;

unsigned long t2;

unsigned long pulse_width;

float cm;

float inches;

digitalWrite(TRIG_PIN, HIGH);


digitalWrite(TRIG_PIN, LOW);

while (digitalRead(ECHO_PIN) == 0);

t1 = micros();

while (digitalRead(ECHO_PIN) ==1);

t2 = micros();

pulse_width = t2 - t1;

cm = pulse_width / 58.0;

inches = pulse_width / 148.0;

distance = cm; -You can set the device to measure in inches or centimeters


void printdistance() { -This section creates groups for different distances and can be modified for your needs

if (distance >= maximumRange || distance <= minimumRange) {

Serial.println("Error: Out of Range"); }

else {

Serial.println(distance); } }

void getdistancegroup() {

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

distancegroup = 1; }

else if (31 <= distance && distance <= 70) {

distancegroup = 2; }

else if (71 <= distance && distance <= 100) {

distancegroup = 3; }

else if (101 <= distance && distance <= 200) {

distancegroup = 4; }

else if (201 <= distance && distance <= 300) {

distancegroup = 5; }

else if (301 <= distance) {

distancegroup = 6;

} }

void playeffect() { -This section uses the above groups and plays different vibration effects based on the group

switch (distancegroup) { -This whole section is just a big switch statement

case 1: if (measurecount < 1) {


break; }

drv.setWaveform(0, 16); // play effect -The second number here is where you put the number for your effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Under 30 cm");

measurecount = 0;


case 2: if (measurecount < 2) {


break; }

drv.setWaveform(0, 15); // play effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Under 70 cm");

measurecount = 0;


case 3: if (measurecount < 4) {


break; }

drv.setWaveform(0, 7); // play effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Under 100 cm");



case 4:

if (measurecount < 4) {


break; }

drv.setWaveform(0, 9); // play effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Under 200 cm");



case 5:

if (measurecount < 9) {


break; }

drv.setWaveform(0, 67); // play effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Under 300 cm");



case 6:

if (measurecount < 9) {


break; }

drv.setWaveform(0, 68); // play effect

drv.setWaveform(1, 0); // end waveform

Serial.println("Over 300 cm");

measurecount=0; break;

} }

There is a chart that can be found on the adafruit website on the page for the microcontroller that has numbers for every vibration effect, so you can go through and test to find your desired effect. We had it so that the vibrations get more intense and more alarming the closer something got to the sensor.

Be sure to run plenty of tests to make sure that you have it exactly how you want it to work.

Step 4: Step 3: Mounting

After testing, screw the device onto a hard base (we used acrylic but it doesn't matter what material you use). Due to the fact that we had a deadline, no external power source was added, so for a power source we simply connected a USB cable to a laptop. However, an external power source can be added fairly easily.

To mount the device on the users arm/hand, we used an old fingerless glove and an elastic strap with velcro and ran the wires to where they needed to be. You can place the motor in a variety of different places, but we chose to tape it around the pinky finger because we felt that you could really notice the vibrations best in that spot.

Step 5: Bugs and Such

So, as I mentioned before, we had the problem with the range of the sensor. When we first started testing it, it worked up to the intended 4 meters. But then, seemingly out of the blue, it only worked up to 50 centimeters for whatever reason. Our professor couldn't find any problems in our code, so we concluded that it was just the sensor. However, we didn't have time to order a new one. If you do find a problem in our code though, just tell us in the comments.

Also, we seemed to have times where every once in a while the sensor would just stop working and it would stop sending distances to the arduino, so the whole system would just stop. However, if we just hit the reset button on the arduino or uploaded the code again it would start working immediately.

If anybody knows why these problems may be occurring, please let us know! Thank you and enjoy!

Microcontroller Contest 2017

Participated in the
Microcontroller Contest 2017