Real-time range detection performed by radar. Distance (y-axis) is in meters and the time (x-axis) is in seconds. Magnitude is in dBFS relative to the max ADC input.
This repo includes the custom PCBs, PC control software and FPGA gateware necessary to build and operate a 6GHz FMCW radar. It also includes a number of other useful additions, such as RF and SPICE simulations (in progress) as well as CAD designs for useful additions (e.g. to build the horn antennas).The project is a fork of Henrik’s excellent design. Although I’ve made a number of significant changes, most of the PCB design (as of this writing) is still identical to Henrik’s. Despite the fact that Henrik deserves a large share of the credit for this project, he is in no way affiliated with this fork.
This project is still a work in progress. While rev1 achieves good results, the noise floor is higher than it should be. In particular, this version suffers from an excessively noisy switching converter. Rev2 has been designed to fix these issues, but still requires a few changes before it’s ready to be built. In the meantime, if you’re able to track down the power amplifier Henrik used in his design (it’s deprecated, but some people have had luck on Ebay), I would recommend that over rev1.
This radar (and associated software) can display the range of remote objects in real-time out to at least 250m. The radar should be capable of ranges up to 1km, but this has not yet been tested. The radar code is also designed to be quite flexible. For instance, you can display data at any intermediary processing step (including the raw receiver channel data) without recompiling the FPGA code. All display configurations support real-time plotting. The many configuration options can be viewed by invoking the software shell environment (see usage)
The PCB is capable of angle detection as well, but the associated FPGA and software code has not yet been written to support this. A future update will also add an RF switch to multiplex the receiver channels for better angular resolution.
Using the radar requires an installation of OpenOCD (for loading the bitstream onto the FPGA), libFTDI1 for communicating between the host Linux machine and the radar and a Python3 installation including NumPy, SciPy, PyQtGraph, as well as a Cython compiler to compile a small amount of optimized C code.Finally, it is necessary to have unprivileged access to the radar in
order to use it. Add the following to /etc/udev
(for instance, in
/etc/udev/rules.d/99-local.rules
):
# FMCW Radar
ENV{ID_VENDOR_ID}=="0403", ENV{ID_MODEL_ID}=="6010", MODE:="666"
To register the changes, run:
sudo udevadm control --reload-rules && udevadm trigger
The FPGA bitstream is updated in this repo whenever the Verilog code
changes. As a result, if you just want to use the radar you should
never need to compile the bitstream yourself. If you do want to modify
the FPGA configuration, you can edit the Verilog source files to your
liking (located in gateware/verilog/src) and then recompile the
bitstream with make bitstream
in the gateware/verilog
directory. This requires an installation of Vivado. I’ve only tested
this with v2017.2, although it should work with newer versions as
well. If this is not the case please file a bug report.
Verilog functional tests and formal verification can be run from
gateware/verilog directory with make test
(for Cocotb tests), make
sim
for more traditional Verilog testbenches, and make formal
for
formal verification. There are also subtargets for specific
modules. Cocotb tests require an installation of Cocotb and
traditional Verilog testbenches require an installation of Icarus
Verilog. Formal verification requires SymbiYosys, yosys, and the yices
SMT solver.
Microwave simulations are performed with OpenEMS, using my own python interface tool, pyems. These are located in the simulations/openems directory and can be run individually.
Ngspice simulations are a work-in-progress. Nevertheless, if you’d like to test them they can be found in the simulations/ngspice directory and the python files can be run individually. They require an installation of SKiDL, PySpice, and, of course, Ngspice.
The antenna mount and horn antenna CAD designs are available in the hardware/cad directory. The OpenSCAD source files as well as the generated STL files are available there. If you only want to 3D print the objects, the STL files are sufficient. If, however, you’d like to modify them, you’ll need an installation of OpenSCAD (or you can modify the STL files in another CAD program like FreeCAD).
The KiCAD PCB design files are located in subdirectories of hardware/boards. They require KiCAD to view and modify. The gerbers are available as zip files here. Note that because rev2 is not yet complete, those gerbers are not up-to-date. The hardware directory also contains some projects which are in development, such as an antenna switch and various prototype boards. These are not, in general, complete and are thus not recommended for use.
When the radar is setup and plugged in, administer power to the PCB,
navigate to the top-level directory and type make
. This will program
the bitstream to the FPGA and invoke a custom shell for interacting
with the radar. If everything so far has worked, you will be presented
with the following shell environment:
Available commands: ---------- conf : Display current configuration. exit : Exit. help : This display. run : Instantiate the current configuration, begin data acquisition, and display output. set : Change the value of a configuration variable. menu : Automatically set configuration variables based on one of several common tasks. fmcw >
We can redisplay this menu at any point by typing fmcw > help
(fmcw >
is prompted as part of the shell display, so you only need to
type help
), and we can exit with fmcw > exit
.
The set of possible commands appears in the left column, with their
associated descriptions to the right. All commands can be typed
exactly as displayed, or you can type the minimum number of letters
that uniquely differentiates a menu entry from the other entries. So,
for instance, if I wanted to see the current configuration I could
type fmcw > c
(conf
is the only command that begins with the
letter c
).
fmcw > c Configuration: ---------- FPGA output : RAW display output : FFT log file : /home/matt/src/fmcw/software capture time (s) : 35 plot type : HIST dB min : -120.0 dB max : -20.0 plot save dir : /home/matt/src/fmcw/software/plots subtract last : True receiver channel : B ADF start frequency (Hz) : 5600000000.0 ADF bandwidth (Hz) : 300000000.0 ADF sweep time (s) : 0.001 ADF delay time (s) : 0.002 min plotting frequency (Hz) : 0 max plotting frequency (Hz) : 470325 min plotting distance (m) : 0 max plotting distance (m) : 235 dist/freq axis : dist report average : False
If I wanted to view, say, a spectrum plot instead of a histogram, I
would start by typing fmcw > s
.
This presents the configuration options
fmcw > set Set options (enter the corresponding number): ---------- 0. FPGA output 1. display output 2. log file 3. capture time (s) 4. plot type 5. dB min 6. dB max 7. plot save dir 8. subtract last 9. receiver channel 10. ADF start frequency (Hz) 11. ADF bandwidth (Hz) 12. ADF sweep time (s) 13. ADF delay time (s) 14. min plotting frequency (Hz) 15. max plotting frequency (Hz) 16. min plotting distance (m) 17. max plotting distance (m) 18. dist/freq axis 19. report average
Since I wanted to change plot type
, which is entry 4, I’d type set
> 4
,
set > 4 Parameter : plot type Current Value : HIST Possible Values : {TIME (except FFT output), SPECTRUM, HIST} (case insensitive) **Note that when setting selection options (e.g. plot type), it is only necessary to type the first characters that fully differentiate the selection from all other choices.
This tells me the available selections for this parameter. Like
before, I’m allowed to just type the first differentiating letters,
which in this case is simpy new value > s
new value > s New value set.
which presents a comfirmation that the value has been correctly set. Indeed, if we redisplay the current configuration, we see that plot type is now SPECTRUM:
fmcw > conf Configuration: ---------- FPGA output : RAW display output : FFT log file : /home/matt/src/fmcw/software capture time (s) : 35 plot type : SPECTRUM dB min : -120.0 dB max : -20.0 plot save dir : /home/matt/src/fmcw/software/plots subtract last : True receiver channel : B ADF start frequency (Hz) : 5600000000.0 ADF bandwidth (Hz) : 300000000.0 ADF sweep time (s) : 0.001 ADF delay time (s) : 0.002 min plotting frequency (Hz) : 0 max plotting frequency (Hz) : 470325 min plotting distance (m) : 0 max plotting distance (m) : 235 dist/freq axis : dist report average : False
Tweaking all of these values can become a bit tedius, so the shell can
conveniently set all values for a number of commonly-needed
setups. For instance, imagine we’d like to measure the receiver noise
floor. We can select the menu option, fmcw > m
.
fmcw > menu Menu options (enter the corresponding number): ---------- 0. Range Plot (235m) 1. Noise Floor
This currently just provides two configurations, but the list will
grow over time. We’d select fmcw > 1
. Now, if we view the
configuration we will see that many values have been updated. Indeed,
this is precisely the configuration we want to compute the noise floor
(if you’re following along, make sure you’ve terminated your
transmission and reception ports with 50ohm loads before proceeding).
fmcw > conf Configuration: ---------- FPGA output : RAW display output : RAW log file : /home/matt/src/fmcw/software capture time (s) : 10 plot type : SPECTRUM dB min : -120.0 dB max : -20.0 plot save dir : /home/matt/src/fmcw/software subtract last : False receiver channel : B ADF start frequency (Hz) : 5600000000.0 ADF bandwidth (Hz) : 300000000.0 ADF sweep time (s) : 0.001 ADF delay time (s) : 0.002 min plotting frequency (Hz) : 50000 max plotting frequency (Hz) : 1000000 min plotting distance (m) : 24 max plotting distance (m) : 499 dist/freq axis : freq report average : True
Finally, when we’re satisfied with the configuration we can type fmcw
> r
(run), which will perform additional FPGA configuration and begin
acquiring and plotting data. The configuration settings specify a
capture time. Currently, it is set to 10s. So, after 10s the plot will
end and we will be represented with the prompt.
The KiCAD PCB files contain a full BOM of components needed to build the circuit board. You will, of course, need a way to assemble it (or you can have a 3rd party assemble the board for you). This design contains a lot of small components. Therefore, I highly recommend you use a reflow process if you intend to assemble this yourself.
The PCB board requires a 12V DC power supply (it is not USB-powered). Also ensure you get the right size barrel jack connector for the port. A USB cable is required to connect to a host PC. A gen2 cable is sufficient because the PCB USB chip does not support gen3. Similarly, the host PC should support at least USB 2.0 High Speed. Otherwise, this may limit the realtime performance of your radar.
The radar requires at least 2 antennas to operate. The choice of antennas is up to you, but you should at least make sure that their bandwidth includes the 5.3 to 5.9GHz range. I’m using 3D-printed horn antennas, which work quite well. If you’d like to take full advantage of the radar’s range, the horn antennas are a good choice because they have a high directivity. The design files to print these are included in the CAD designs of this repo. If your 3D printer does not support the z height, you can print the antenna in 2 parts and then glue the parts together. Finally, if you’re using the horn antennas you’ll additionally need WR159 waveguide-coax adapters. These can be picked up on Ebay or other similar sites. The ones I purchased were $60 each. The PCB uses SMA connectors, so if the waveguide coax port is not SMA you will additionally need an adapter for that (or an asymmetric cable that supports the port it uses). Painting the antennas require a number of other materials specified in the link above. I personally achieved a better result using a traditional paint jar than the recommended spray paint, but either should work. Another option which I haven’t tried but could work is coating the antenna in copper foil.
Pull requests and issues welcome. I’m open to suggestions for hardware modification, although may or may not be able to merge those commits depending on whether I can test the change.
- Henrik, of course (see About).
- An additional thanks to AlexBdx for finding a way to 3D print horn antennas.