Ultrasonic Radar

by Evan Breeze in Circuits > Arduino

4268 Views, 69 Favorites, 0 Comments

Ultrasonic Radar

Screenshot 2023-08-18 183948.png


This simple yet very cool-looking radar uses an ultrasonic sensor to detect objects in its path. One of the most popular fields in which radars are used is air traffic control, for detecting incoming/outgoing traffic. Radars send out radio waves that hit the object and come back to the sensor. Since waves travel at a certain speed, the radar reads the time it takes for the wave to come back and calculates how far the object is.

For this project, we are using high-frequency sound waves to calculate the distance to the object, as radio waves are much harder to use. This project is very useful to learn about sound waves and the application of radars. This radar can even be used to make a sentry turret to defend your house or room!

Supplies

image0 (1).jpeg




  • Plywood sheets (buy from a hardware store; not needed if you have a 3D printer)



  • 4x M2 bolts and nuts (buy from a hardware store)

Make the Case

image1 (1).jpeg

Use a laser-cutter, manual saw, or a 3D printer to make the enclosing for this project. You can use any material you like however, 2mm thick plywood will be the easiest.

Dimensions of the case panels :

  • 10cm x 5cm bottom panel
  • 10cm x 5cm top panel (with a custom hole for the servo)
  • 10cm x 4cm side panel (2x)
  • 5cm x 4.4cm back panel (with a slot for the USB-C port)
  • 5cm x 4.4cm front panel

Laser-cutting will be the best method if available as there are tiny slots and holes that will be hard to make manually. The SVG files for laser-cutting are attached below. The files are attached separately so that you can move them around when cutting. I have also attached the 3D file for the whole box in case you want to 3D print the case. Once the case is done, paint the case if you'd like to.

Solder the Header Pins to the Board

image3.jpeg
image2 (1).jpeg

Solder the male header pins onto the board, with the pin side facing the side of the board with the electronics. Try not to use too much solder, and try your best to create pointy solder joints so that they would drive into the board and let the board sit flush with the bottom panel. For reference, use the image above.

Faster the Board to the Bottom Panel

image4.jpeg

Fasten the RP2040 Feather to the bottom panel with the USB-C port pointing outward. Lay the board flat on the bottom panel, take a flat sheet, put the sheet on top of the header pins, and then apply downward pressure on the sheet. The pointy solder joints should drive into the bottom panel, and the board should sit flat on the panel. To fasten the board, use 2 M2 bolts and nuts at two diagonal points.

Fasten the Servo to the Top Panel

image6.jpeg
image7.jpeg

Take any attachments off the servo and place the servo on a flat surface. Then, take the top panel with the un-painted side facing the servo, and put it on top of the servo.

The servo should poke out of the rectangular hole in the panel. With 2 M2 bolts and nuts, fasten the servo to the top panel. Use the image for reference.

Prepare the Sensor Mount

image8.jpeg
image20.jpeg
image18.jpeg
image11.jpeg

Now, it's time to make the mount to attach the sensor to the servo. The files for 3D printing are linked below, and this method will be the most accurate. However, you can also make a similar shape with cardboard and then glue the servo arm to the bottom side. If you are 3D printing the mount, push the servo arm into the slot, fasten one end of the arm to the mount, and then drive a screw through the mount's bottom panel, through the servo arm, and into the servo.

Next, get 4 female-female jumper wires, and glue one end of all 4 wires to the inward side of the sensor mount's front panel. Thread the other end of the jumper wires through the big hole.

Downloads

Glue the Case Together (almost)

image15.jpeg
image16.jpeg

Glue all the panels together EXCEPT THE TOP PANEL. Glue it on only after you confirm that everything is working fine because it would be extremely hard to take it off if you need to check the wiring or redo something. Make sure that the USB-C port is aligned with the slot in the back panel.

Connect the Servo and Sensor to the Feather RP2040


Connect the servo and the ultrasonic sensor header to the RP2040 :

Servo wirings :

  • 5V (red wire) to 3.3V
  • GND (brown wire) to GND
  • SIGNAL (yellow wire) to A0

Ultrasonic sensor wires (Position given is from the top view of the sensor mount) :

  • Left-end wire to A3
  • 2nd wire from left to D24
  • 3rd wire from left to D25
  • Right-end wire to 3.3V (the pin to the right of the servo red wire is 3.3V)


Setup the RP2040 Libraries

First, download the Arduino IDE if you don't have it. Go to File > Preferences on Windows or Linux, or Arduino > Preferences on OS X. In the Additional Board URLs box, paste: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json and click OK to save.

Go to Tools > Board > Boards Manager and search "RP2040". Install this library.

Program the RP2040

To connect your RP2040 microcontroller-based board, connect it to your computer via a known good USB-C power+data cable. Hold down the BOOTSEL button when you're plugging it in to enter the bootloader. It should then show up as a USB drive with the name RPI-RP2 (or something similar) in your computer File Explorer / Finder.

Then in the Arduino IDE, go to Tools > Board > Raspberry Pi RP2040 Boards and select the board you are using (Adafruit RP2040 Feather in this case).

Copy and paste the code given below into the sketch, and click upload (Right-pointing arrow in the top left region).

// Includes the Servo library
#include <Servo.h>
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 25;
const int echoPin = 24;
// Variables for the duration and the distance
long duration;
int distance;
Servo myServo; // Creates a servo object for controlling the servo motor
void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);
  pinMode(29,OUTPUT);
  digitalWrite(29,LOW);// Sets the echoPin as an Input
  Serial.begin(9600);
  myServo.attach(26); // Defines on which pin is the servo motor attached
}
void loop() {
  // rotates the servo motor from 15 to 165 degrees
  for (int i = 0; i <= 180; i++) {
    myServo.write(i);
    delay(10);
    distance = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree
    Serial.print(i); // Sends the current degree into the Serial Port
    Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
    Serial.print(distance); // Sends the distance value into the Serial Port
    Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
  }
  // Repeats the previous lines from 165 to 15 degrees
  for (int i = 180; i >=0; i--) {
    myServo.write(i);
    delay(10);
    distance = calculateDistance();
    Serial.print(i);
    Serial.print(",");
    Serial.print(distance);
    Serial.print(".");
  }
}
// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
  distance = duration * 0.034 / 2;
  return distance;
}

Test

Now, connect the ultrasonic sensor to the mount. Use a working USB-C power + data cable to connect the radar to the laptop. The servo should "sweep" left and right. In the Arduino IDE, go to Tools > Port and select an available COM port. Open the serial monitor (magnifying lens icon in the top right region). You should see numbers being printed. If everything looks good, you can glue the top panel to the case.

Download Processing for Windows

Seeing random numbers on the screen is practically useless. In order to make sense of things better, we need to visualize the data. For this, we are going to use a software called "Processing 4" which can visualize the data sent by the sensor. Go to https://processing.org/de/download/ and download the appropriate software for your OS. In the zip folder, open the .exe file. If it tells you to extract files, make a new folder somewhere and extract all the files into the folder. Go to the extracted folder and open the .exe file. Processing 4 should start.

Processing Code

Open a new sketch in Processing. Make sure the language is Java (there is a selector at the top right corner). Then, copy and paste this code into the new sketch :

import processing.serial.*; // imports library for serial communication
import java.awt.event.KeyEvent; // imports library for reading the data from the serial port
import java.io.IOException;
Serial myPort; // defines Object Serial
// defubes variables
String angle="";
String distance="";
String data="";
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {

 size (1600,900); // ***CHANGE THIS TO YOUR SCREEN RESOLUTION***
 smooth();
 myPort = new Serial(this,"COM5", 9600); // starts the serial communication
 myPort.bufferUntil('.'); // reads the data from the serial port up to the character '.'. So actually it reads this: angle,distance.
 //orcFont = loadFont("OCRAExtended-30.vlw");
}
void draw() {

  fill(98,245,31);
  // textFont(orcFont);
  // simulating motion blur and slow fade of the moving line
  noStroke();
  fill(0,4); 
  rect(0, 0, width, height-height*0.065); 

  fill(98,245,31); // green color
  // calls the functions for drawing the radar
  drawRadar(); 
  drawLine();
  drawObject();
  drawText();
}
void serialEvent (Serial myPort) { // starts reading data from the Serial Port
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('.');
  data = data.substring(0,data.length()-1);

  index1 = data.indexOf(","); // find the character ',' and puts it into the variable "index1"
  angle= data.substring(0, index1); // read the data from position "0" to position of the variable index1 or thats the value of the angle the Arduino Board sent into the Serial Port
  distance= data.substring(index1+1, data.length()); // read the data from position "index1" to the end of the data pr thats the value of the distance

  // converts the String variables into Integer
  iAngle = int(angle);
  iDistance = int(distance);
}
void drawRadar() {
  pushMatrix();
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  noFill();
  strokeWeight(2);
  stroke(98,245,31);
  // draws the arc lines
  arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
  arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
  arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
  arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
  // draws the angle lines
  line(-width/2,0,width/2,0);
  line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
  line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
  line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
  line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
  line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
  line((-width/2)*cos(radians(30)),0,width/2,0);
  popMatrix();
}
void drawObject() {
  pushMatrix();
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  strokeWeight(9);
  stroke(255,10,10); // red color
  pixsDistance = iDistance*((height-height*0.1666)*0.025); // covers the distance from the sensor from cm to pixels
  // limiting the range to 40 cms
  if(iDistance<40){
    // draws the object according to the angle and the distance
  line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
  }
  popMatrix();
}
void drawLine() {
  pushMatrix();
  strokeWeight(10);
  stroke(30,250,60);
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // draws the line according to the angle
  popMatrix();
}
void drawText() { // draws the texts on the screen

  pushMatrix();
  if(iDistance>40) {
  noObject = "Out of Range";
  }
  else {
  noObject = "In Range";
  }
  fill(0,0,0);
  noStroke();
  rect(0, height-height*0.0648, width, height);
  fill(98,245,31);
  textSize(20);

  text("10cm",width-width*0.3854,height-height*0.0833);
  text("20cm",width-width*0.281,height-height*0.0833);
  text("30cm",width-width*0.177,height-height*0.0833);
  text("40cm",width-width*0.0729,height-height*0.0833);
  textSize(30);
  text("Object: " + noObject, width-width*0.875, height-height*0.0277);
  text("Angle: " + iAngle +" °", width-width*0.48, height-height*0.0277);
  text("Distance: ", width-width*0.26, height-height*0.0277);
  text("        " + iDistance +" cm", width-width*0.225, height-height*0.0277);
  textSize(20);
  fill(98,245,60);
  translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30)));
  rotate(-radians(-60));
  text("30°",0,0);
  resetMatrix();
  translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
  rotate(-radians(-30));
  text("60°",0,0);
  resetMatrix();
  translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
  rotate(radians(0));
  text("90°",0,0);
  resetMatrix();
  translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
  rotate(radians(-30));
  text("120°",0,0);
  resetMatrix();
  translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
  rotate(radians(-60));
  text("150°",0,0);
  popMatrix(); 
}


In line 19, change the COM port to the COM port used by the radar. If you don't know the COM port, you can simply connect the sensor to the laptop, open the Arduino IDE and the COM port should show up in Tools > Port.

Witness the Magic!

Congratulations on making it this far! It's time to see the magical powers of your creation! Connect the radar to the laptop using a WORKING USB-C DATA + POWER CABLE, and click the play button in the top left region of the Processing 4 window. A very cool-looking radar should pop up, and you should see your project come to life!

Thank you so much for checking out this project! If you end up making this, please drop an "I Made It". Good luck with all your projects!