Radar Emulator with Arduino + Python
“As an Amazon Associates Program member, clicking on links may result in Maker Portal receiving a small commission that helps support future projects.”
The word radar is a combination of ‘RAdio Detection And Ranging’ - which describes the function of early radar systems that were developed to detect and range approaching enemy aircraft using radio waves. Commonly, radar systems use a visualization tool called a plan position indicator (PPI), which places points in a polar configuration to represent objects occupying space in the range of the detector (read more about radar: Introduction to Radar Systems). In this tutorial, an ultrasonic sensor (HC-SR04) will be used in place of a radio emitter; and a plan position indicator will be constructed in Python by recording the angular movements of a servo motor. An Arduino board will both record the ranging data from the ultrasonic sensor while also controlling and outputting the angular position of the servo motor. This will permit the creation of a PPI for visualizing the position of various objects surrounding the radar system.
The replication of a radar system involves two essential components: a ranging device and an angular motor/detector. As stated above, the ranging device can be any device that detects distance from a stationary point. The HC-SR04 ultrasonic device will be used, however the VL53L0X ranging sensor (uses the time-of-flight technique with a 940nm laser) has also been used and works just fine with this tutorial as well. A kit has been assembled specifically for replicating this tutorial, and it is recommended for following along with this tutorial. The only thing needed in addition to the kit is an Arduino board and a computer. The individual components are listed below as well, in case the user wants to assemble the components independently:
Tutorial Kit:
Arduino Radar Kit with HC-SR04 and MG90S - $ 15.00 [Our Store]
Entire Component List:
Arduino Uno Board - $13.00 [Our Store]
MG90S Micro Servo Motor - $7.00 [Our Store]
HC-SR04 Ultrasonic Sensor - $6.00 [Our Store]
Jumper Wires - $1.80 (12 pcs: 8 male-to-female, 4 male-to-male) [Our Store]
Mini Breadboard - $3.00 [Our Store]
VL53L0X Time-of-Flight Sensor - $10.00 [Our Store]
Raspberry Pi 4 Computer - $55.00 [2GB from Our Store]
The HC-SR04 and MG90S can be wired to an Arduino Uno board using the following diagram:
The Arduino code uses this particular wiring configuration, however, the pins can easily be changed in the code to represent specific wirings. The Python code given later will also describe how the Arduino is being read through the serial port, and why certain Serial.print() methods are called.
The Arduino code uses the servo library to communicate via pulse-width modulation (PWM) over one of its pins [read more about PWM with the Raspberry Pi Panning Camera Tutorial or the Arduino Servo Basics Tutorial]. A custom algorithm is used to retrieve ranging data from the HC-SR04, using the time-of-flight effect for sound waves. Both the angle of the MG90S servo motor (0° - 180°) and the distance approximated from the HC-SR04 (2cm - 400cm) are outputted to the serial port for a Python program to read (more on this later). The Arduino code is thus given below:
The time-of-flight equation, given in the ‘dist_calc()’ function, uses the following principle:
where d is the distance from the HC-SR04 sensor to the object it is detecting, c is the speed of sound in air (~343m/s), and Δt is the recorded time it takes for the pulse to reach the target and arrive back at the receiver (detector).
Opening the serial port on the Arduino should read the following:
If the printout is not similar to that above, then the Python serial reader code in the following section will not work properly. The ‘Radar Start’ printout tells the Python code to start its radar analysis, and the comma-separated 'angle,distance' format feeds the data exactly as it needs to be read in the Python code. Therefore, if the printout does not mimic that above, then the Python code will return errors.
In Python, this project become exponentially more complex. The reason being, as stated in the introduction to this tutorial, a plan position indicator (PPI) will be used to visualize the point map as the MG90S motor rotates 180° back and forth about its axis. The reason why this becomes difficult, is that we now need to take a polar plot and populate it with the outputs of the Arduino board. Therefore, our process becomes the following:
Start communication with Arduino board
Create polar plot for radar emulator
Begin looping through incoming Arduino data
Wait for ‘Radar Start’ to begin plotting
Update scatter points and PPI
And if this were to be done exactly as it is referenced above, it would take quite a bit of resources to do in real-time. Thus, a few work arounds are implemented to ensure efficiency in the plotting and reading of data. The following are simplifications and implementations of efficient methods for update and plotter the angle and ranging scatter points received by the Arduino:
Only update the data, not the plot (restore_region(), drawartist(), and blit() snippets of code below)
Only plot every 5 degrees of rotation
All of the routine and implementations above are given below in the code, with comments where necessary:
After running the code above, the following plot should appear:
The graphical user interface (GUI) allows users to stop the program or close the plot and exit the program. Meanwhile, the plot should be updated every 5 degrees (about every 300ms), with scatter points being placed where objects are detected by the HC-SR04. There is also a sweeping arm that is part of the plan position indicator, which notifies the user of the approximate location of the motor or area being ranged.
A full video demonstration of the Arduino sweeping radar using the MG90S servo and HC-SR04 sensor is given below, where the Python code is implemented on a Raspberry Pi via its USB port:
One final thing to note is that the HC-SR04 does not produce perfect points in space. Its cone of detection is roughly 15° - meaning that it can accurately predict distances at short range, but at longer ranges it has difficulty discerning small area objects from larger area objects. The 15° cone of direction amounts to roughly an object area of 13% of the distance it might be. As an example, an object that is 1m away will need to be 130cm for the HC-SR04 to properly detect it. If the area is smaller, then it may misinterpret the size of the object and therefore its ability to recognize it. If the object is larger than 130cm, then it may register over multiple angles until it is out of the majority sight of the sensor. If we assume a person is about 50cm wide, this means that at about 400cm the HC-SR04 will properly recognize it. If the person is further than 400cm, then the sensor may not register the person, whereas if the person is within 400cm, then it will recognize it over multiple angles.
An Arduino-based radar project was implemented in this tutorial using an Arduino, HC-SR04 ultrasonic distance sensor, MG90S micro servo motor, and Python code run on a Raspberry Pi. The goal of this project was to introduce a novel concept related to real-world technology, but implemented through inexpensive tools available to the maker and aspiring engineer. The HC-SR04 uses sound waves to approximate the distance between its receiver and an object in the distance, while the MG90S servo rotates in a prescribed fashion according to pulse-width modulation signals controlled by the Arduino board. In order to visualize the outputted angular position and approximate ranging of the HC-SR04 - Python code was implemented on a Raspberry Pi to create a plan position indicator on a polar plot. This PPI gives the user a way of visualizing the objects that surround the motor and ultrasonic sensor, much like a radar approximates the objects surrounding its base station. Several skills used in this tutorial can be applied to real-world applications, whether through obstacle detection, motor control, distancing and ranging, or even a new tool for visualizing data.
See More in Arduino and Python: