Project tutorial
Portable Range Detection Device

Portable Range Detection Device © CC BY-NC

Portable range/distance detection device using an Arduino, ultrasonic sensor, and buzzer.

  • 20 respects

Components and supplies

Necessary tools and machines

3D Printer (generic)
I used an Anet A8
09507 01
Soldering iron (generic)
Hy gluegun
Hot glue gun (generic)
Or any rotary tool

Apps and online services

Ide web
Arduino IDE
Will need to download NewPing library
Or any slicer of choice

About this project


Last week I was approached by a good friend who conducts studies in the Exercise Science Department at his college. There was an issue of subjects not knowing where their range of motion ends on the leg press machine. I was able to construct a device which detects distance with a variable indicator. It can be applied to virtually anything that requires distance detection for a decently sized object. Here were the conditions I had to consider:

  • Minimally Invasive (no gluing/leaving permanent fixtures on the machines)
  • Tripod Compatible
  • Portable (no tethering)
  • Adjustable Distance

This is the same concept and function of endstops on 3D printers to determine where the "zero" is for an axis; however, using traditional options for endstops such as microswitches, hall effect sensors, or optical sensors could not satisfy meeting all the conditions. This forced me down the path of IR/Ultrasonic sensors.



As I tend do to, I forgot to include some parts listed above in the picture, so follow the BoM above! The parts I used are selected not because they're optimal; that's just what I had lying around. A LiPo battery would have saved a tremendous amount of space, for instance.


Download the Arduino IDE.

Download the NewPing library and extract it to your library folder.

Simply upload the code I provided at the end of the guide to the Arduino Nano, and you should be good to go. You can alter the frequency of the buzzer and the upper/lower distance bounds for the potentiometer (knob).

int frequency =      700;     //Frequency in Hz
int lower_bound =    60;      //Distance in mm
int upper_bound =    200;     //Distance in mm

In setup(), I have the buzzer go off 3 times so that there's an auditory indicator for turning the unit on. Following that, loop() simply keeps checking the distance and beeps when the distance drops below the threshold distance, which is set by the potentiometer.

3D Printing

All the files can be found here, or one condensed file can be found at the bottom of the page. I won't go into the 3D modeling portion of this too much other than the fact that a surprising amount of time went into reorganizing the components to be compact, yet not create an impossible wiring scenario. I made sure to give access to all necessary ports for charging and programming. You can view a short clip of the model in Fusion 360 here. Now onto the printing. Everyone's print settings will be different, so I won't include settings here.

Despite removing the need for supports in all possible places during the modeling phase, there did remain 3 locations that needed it. Do NOT simply turn on automatic supports as it will attack the entire model with them. Add manual supports as illustrated in the images above.

The prints should come off the build plate ready to go without any post processing. I left generous clearances, so if something doesn't fit, then tune those print settings! Have an Exacto Knife on hand regardless. My print times were as follows:

  • Top Piece: 2 hours 40 minutes
  • Bottom Piece: 2 hours 20 minutes
  • Knob: 20 minutes


Refer constantly to the circuit schematics at the bottom of the page for this part. First insert the electronics to confirm that they fit properly (particularly those LEDs as the clearances are quite small for them). Don't glue anything down just yet.

For the wiring, I decided to use a salvaged ribbon cable from inside an old PC. These wires are attached together, so you peel a bunch of wires like string cheese. This was cost efficient as they're quite easy to salvage; plus, they can remain attached together, which cleans up the wiring.

Despite the enclosure looking a little clunky, it is a tight fit on the inside. About 85% of the electronics is mounted onto one of the printed parts, so the wiring must be efficient.

On the TP4056 board, there are 2 SMD indicator LEDs. Remove them with your soldering iron, and replace them with larger LEDs at the end of a ribbon cable. There's no need to add current limiting resistors, as they're already on board. Here's a video of someone doing this.

Since 5 components share a common ground, I created a breakout with some spare stripboard. I used some sturdy solid core wire to connect the 5V, and that was sufficient enough to hold up the breakout board.

I used a drill bit (any sharp object will work) to break the connection of the copper strip so that I can have a 5V breakout and a Ground breakout on a single piece. The red "X" illustrates the location of the break. Remember, you just need to scrape the copper off the surface, not snap the stripboard. This helped tremendously!

Next go ahead and solder all the components together. Trim the leads of the components as much as possible. Periodically fit the dangling mess of components to make sure nothing is in the way.

Note that I trimmed the potentiometer 6mm with my dremel, and the printed knob is meant to fit onto a shortened potentiometer.

I had some trouble making a solid connection between the wires from the TP4056 and the battery, so I soldered directly onto the battery. This is NOT good practice, as you can damage your lithium ion cell with too much heat. The joint was poor, but I was low on time; avoid doing this. Once you have all the parts soldered and you've tested the circuit one last time, you can move on to the final step.

Mount all the components into the printed parts and add small beads of hot glue to keep them down. Finally, close it up, add the knob, and screw it down with the M3 bolts! For the sake of permanence, I super glued the inside of the knob that slides on the potentiometer. Test it once more to make sure that nothing was damaged in the process and you're done!


In retrospect, I would have preferred using an IR sensor rather than the Ultrasonic, but there was no way I could have known this until I began to experiment with the Ultrasonic sensor. IR sensors have a narrower FOV with a tradeoff of a far lower maximum distance (~3ft).

If I were to produce a "V2" of the project, I'd replace the 18650 cell with a small LiPo. I would order this nut to replace the enormous and heavy 3/8" -> 1/4" adapter. This would have reduced the size and weight significantly. If you really want to be picky, it would have also reduced the amount of filament used, power spent on running the printer, and time. Those things all add up when you have a tight schedule with limited time to work on projects.

Criticism aside, I'm quite happy with how it turned out.

Future of the Project

When I was experimenting with the ultrasound sensor, I learned more about its limitations. The first being that its FOV has an angle of ~±15° (30° total). This meant that an object can trigger the buzzer before it's directly above the sensor. This yields inaccuracies and undesirable readings. Additionally, if the object's plane is not perpendicular (or within the angle of tolerance) to the transmitted sound wave, the sensor will not receive a reflected wave and won't be able to process a value for distance.

My initial plan was to have the unit rest on the ground and allow for the plates on a weight training bar to trigger the buzzer when they were lowered past the threshold. This system consisted of a fixed sensor and a moving trigger. My fellow engineering buddy had proposed an alternative solution, which involved inverting the system. He proposed mounting the sensor to the moving bar while pointing it to the ground. This way the ground became the trigger. It also eliminated inaccuracies due to a wide FOV as previously mentioned.

The proposal was not only a great solution to the given issues, but it is also very easy to implement. The order for the 1/4" tripod nut adapter came with a 1/4" -> 3/8" adapter AND a 3/8" -> 1/4" adapter. The second one will actually come into use!

As I did not have access to my dremel when I first began to 3D model, that forced me to account for the entire tripod adapter. This in combination with an 18650 cell increased the weight significantly. I do not want to add any more weight than I need to, so I will cut down the second tripod adapter before modeling the mount. I will get back to the project in a week to complete this alternative mounting solution. Until then, it still works nonetheless!


    Viktor Silivanov
    Portable distance detection device using the HC-SR04 Ultrasonic sensor with distance adjustment for triggering the buzzer.

//******************** Libraries ****************************************************************************************************************************************************************************************************************
#include <NewPing.h>

//******************** Pins ********************************************************************************************************************************************************************************************************************

//Analog Pins
#define wiper        A5
//Digital Pins
#define echo         2
#define trig         3
#define ON_LED       7
#define buzzer       8
#define buzzer_LED   9

//******************** Global Variables *********************************************************************************************************************************************************************************************************

//User Modification Allowed
int frequency =      700;                                                   //Frequency in Hz
int lower_bound =    60;                                                    //Distance in mm
int upper_bound =    200;                                                   //Distance in mm

//Do Not Modify
int buzz_time =      250;                                                   //Time in milliseconds for buzzer right upon startup
int buzz_delay =     280;                                                   //Time in milliseconds for buzzer delay right upon startup
int max_distance =   400;                                                   //Argument for object in the NewPing library
int i =              0;
int distance;
int threshold;
NewPing sonar(trig, echo, max_distance);                                    //Instanciation of object "sonar"

//******************** Setup ********************************************************************************************************************************************************************************************************************
//This function runs only once

void setup() {
  Serial.begin(9600);                                                       //Allows use of serial monitor with a baud rate of 9600

  //Pin I/O Type Declaration
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(buzzer_LED, OUTPUT);
  pinMode(ON_LED, OUTPUT);

  digitalWrite(ON_LED, HIGH);                                               //Turns on green LED; Stays on while unit is on

  //Buzzer beeps 3 times upon turning on device 
  while(i < 3){
    digitalWrite(buzzer_LED, HIGH);
    tone(buzzer, frequency, buzz_time);
  digitalWrite(buzzer_LED, LOW);

//******************** Runs Endlessly ***********************************************************************************************************************************************************************************************************

void loop() {
  distance = sonar.ping_cm();                                              //Object "sonar" utilizes ping_cm() function from the library, which returns a value in cm. Distance then take on that value
  threshold = analogRead(wiper);                                           //Obtain analog value from wiper of the potentiometer
  threshold = map(threshold, 0, 1023, lower_bound, upper_bound);           //Translate analog readings into trigger range. Update values of threshold
  if(distance != 0 && distance < threshold){                               //Condition to trigger the buzzer
    tone(buzzer, frequency);
    digitalWrite(buzzer_LED, HIGH);
  else{                                                                    //State of buzzer & LED otherwise
    digitalWrite(buzzer_LED, LOW);

  //serial_test();                                                           //Uncommment this to view data from the serial monitor

//******************** Test Function ************************************************************************************************************************************************************************************************************
//Utilizes serial monitor to display some values. Used for testing/debugging purposes.

void serial_test(){
  Serial.print("Ping: ");

  Serial.print("Range: [");
  Serial.print(", ");
  Serial.println("] cm");
  Serial.print("Threshold: ");

Custom parts and enclosures

All 3 parts are saved to one file


Circuit Schematic
Circuit schematic ccwyc5xrr2


Similar projects you might like

Otto DIY+ Arduino Bluetooth Robot Easy to 3D Print

Project tutorial by Team Otto builders

  • 162 respects

Tito - Arduino UNO 3D-printed robot

Project tutorial by Camilo Parra Palacio

  • 39 respects


Project tutorial by Unexpected Maker

  • 123 respects


Project tutorial by Amit Nandi (BigWiz)

  • 46 respects

IoT for coins

Project tutorial by Erik Moran

  • 1 comment
  • 42 respects

DIY Distance Meter with Arduino and a Nokia 5110 Display

Project tutorial by Nick Koumaris

  • 16 respects
Add projectSign up / Login