Author: Joseph Pizzimenti
This project implements an indoor wireless localization system inspired by the "SpotFi" research paper. It utilizes a PLUTO+ Software Defined Radio (SDR) with two receive antennas to estimate the Angle of Arrival (AoA) of an OFDM signal.
Unlike the Wi-Fi NIC-based approach of the SpotFi research paper, this project uses raw I/Q samples processed in MATLAB to perform direction finding on a single SDR with 2 receive antennas. It can handle multipath interference and is somewhat resiliant at further distances (as long as calibration is successful).
- Receiver: 1x PLUTO+ SDR (with custom AD9361 firmware enabled for 2RX/2TX MIMO support, instructions below for use with custom firmware).
- Transmitter: 1x Analog Devices ADALM-PLUTO (Standard firmware is fine).
- Antennas: 2x matching antennas with their centers spaced about 9 cm apart (will vary depending on carrier frequency).
- Computer: Windows PC (for MATLAB Receiver) and Windows/Linux PC (for GNU Radio Transmitter).
This project relies on a specific stack of drivers, toolboxes, and external libraries. All components below are required.
MATLAB requires these underlying libraries to communicate with the SDR hardware via USB/Network.
Note: You must install the Development Headers (.h) and Libraries (.dll). If the installer does not add them to your system PATH automatically, you must add them manually or reference them in MATLAB (see Installation section).
- Required Add-Ons (Install via Home -> Add-Ons):
- Analog Devices, Inc. Transceiver Toolbox - (note: this is NOT the standard ADALM-PLUTO toolbox, it requires the following dependencies)
- Simulink
- Communications Toolbox
- DSP System Toolbox
- HDL Coder
- Signal Processing Toolbox
- Simulink Coder
- Phased Array System Toolbox
- gr-iio (Standard
iioblocks for PlutoSDR Sink). - If using windows, other drivers may be required for SDR communication
- Download and run the installers for
libiioandlibad9361-iio. - Locate Headers: Locate where the
.hfiles were installed.
- Location found on MY laptop:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\ - Alternative:
C:\Program Files\IIO\include - If missing: You may need to manually download
iio.handad9361.hfrom their respective GitHub repositories and place them in a known folder for MATLAB to reference.
The Analog Devices Transceiver Toolbox likely WILL NOT automatically find the required headers to run. You MUST point MATLAB to them at the top of your script:
% Add path to libiio/libad9361 headers
addpath('C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\');
% Add path to system DLLs (if not in PATH)
addpath('C:\Windows\System32');The PLUTO+ comes with standard AD9363 firmware (1RX/1TX). You must unlock the AD9361 mode for MIMO support (2RX/2TX).
- Download the PLUTO+ firmware from the plutoplus repo: Download plutosdr-fw.zip
- Physically open up the PLUTO+ and move the DIP switches in the bottom right to be in the stock firmware position.
- Plug in the PLUTO+ and drop the
pluto.frmin the PLUTO device found in file explorer. - Press the eject button in the file explorer, and wait for the device to reappear.
- SSH into the PLUTO+ (
ssh [email protected], password:analog). - Run the following commands IN THIS EXACT ORDER!:
fw_setenv attr_name compatible
fw_setenv attr_val ad9361
fw_setenv mode 2r2t
pluto_reboot resetNote: If these commands aren't run in this exact order or if at any point the device is unplugged, power flush the device and SSH back into the PLUTO+ to repeat these steps.
- Open
OFDMSignalGen.grcin GNU Radio Companion. - Ensure the PlutoSDR Sink is configured for:
- URI:
ip:192.168.2.1(or USB context defined by you in the firmware) - LO Frequency:
1.56 GHz(or whatever frequency you choose) - Sample Rate:
20 MSPS
- Load the
custom_ofdm_signal.binfile (generated by the MATLAB helper script to ensure known seed synchronization). - Run the flowgraph.
- Connect the PLUTO+ to the Windows PC via USB (Ethernet may be more reliable, but USB was used for this experiment.
- Open
AngleTracking.min the Receiver folder. - One-Time Calibration:
- Place the transmitter at the reference point you want to be 0 degrees from the receiver.
- Run
Calibration.mto generatephase_cal.mat.
- Start Localization:
- Run
AngleTracking.m. - The heatmap will display the estimated Angle of Arrival (AoA).
AngleTracking.m: Main real-time localization script to find AoACalibration.m: NECESSARY calibration script to calculate phase offsets between 2 RX ports.AngleTracking.mREQUIRES the result of this script to be present to run.
Sim1_AoA_Test.m: Simulated Angle-of-Arrival testing with variable SNRSim2_ToF_Test.m: Simulated Time-of-Flight testing with variable SNR
CSITest.m: Debug tool to visualize raw CSI magnitude and phase.CustomFirmwareTest2RX.m: A quick script written to test if the custom firmware functionality of the PLUTO+ (with 2*RX) is working.HighResNoiseFloorSweep.m: A script used to find the least noisy frequencies of the surrounding RF environment.
OFDMSignalGen.grc: GNU Radio flowgraph for the constant OFDM transmittercustom_ofdm_signal.bin: Pre-generated binary file (generated fromgenerateOFDM.m) for transmission.generateOFDM.m: Generates the I/Q binary file with a fixed RNG seed.
"Expected ChannelMapping to be a scalar":
- Cause: MATLAB sees the device as a standard Pluto (1RX).
- Fix: Ensure you are connecting via
ip:192.168.2.1and that you have run the SSH unlock commands on the PLUTO+.
"Could not find file ad9361-wrapper.h":
- Cause:
loadlibrarycannot find the header files. - Fix: Verify the
addpathcommand in the MATLAB script points to the folder containingad9361.handlibiio.h.
MATLAB refuses to generate an sdrrx component for your PLUTO+
- Cause: The firmware was likely flashed incorrectly for the PLUTO+
- Fix: Run
fw_printenv modewhen SSHing into the SDR. It should say "mode=2r2t". Additionally, runningfw_printenv attr_valshould say "attr_val=ad9361". If they don't say this, repeat the firmware installation process carefully.