Testing Antennas with the LimeSDR Mini

I recently bought a LimeSDR Mini to test antennas and those little transceivers. As usual there are some startup hurdles so I thought I’d document my voyage to turning it into an antenna analyzer.

A LimeSDR Mini

There are spectrum analyzer applications but at the moment there’s no way to generate the tracking sweep generator and interface it correctly. So, I decided to try more raw programming of the streams.

First Steps

3d Printed LimeSDR Mini case

First I 3d printed a case for the mini. I used copper foil to create a reasonable Faraday cage.

The mini generates some heat so small lines let it breathe.


The LimeSuite is confusing. Lots of controls with, as far as I could tell, very little documentation. I got in the habit of load it, connect to the mini, click Reset, click Default, exit — as a way of reloading default values. I did finally change a few defaults (such as antenna).

I tried Pothos Flow for a while and it had numerous stability issues so I switched to Gnu Radio. The windows installation works but is large since it installs gtk and qt and …

RF Reflection Bridge

I purchased a $7 RF bridge on Ebay as a start. It got very good reviews and it seems to be well built. I printed a 3d case for it, as well. If you want the bridge case design there is a Rhino3d (3dm) file and the top and bottom STL files here: RFBridge_3dCase.


Looking at the schematic for the bridge the DUT and Ref are in a bridge and the Out should show differential mismatch. Ref contains a 50 ohm dummy load, In is the output of the LimeSDR mini, Dut is (in this case) a 11 inch wire (so I have a known resonance) and Out is connected to the receiver input on the LimeSDR mini.

The RF Bridge connected

Gnu Radio Settings

Getting Gnu Radio to work was a phew… not a lot of documentation. For example the Doxygen documentation on FFT says: “See the Doxygen documentation for details.” Pretty useful.

Things to understand ->

The Osmocom Source is the data coming in from the Lime Receiver port.

The device arguments determine the driver. Make sure you specify the correct Antenna (LNAW for ≤2GHz or LNAH for ≥2GHz). I have variables for sample rate and base frequency, usually 10e6 and (tunable) 433e6. The frequency of the Source is the center frequency of the scan.

The osmocom sink is the transmitter. Setting the frequency of the sink determines the carrier frequency (essentially) and incoming data modulates the carrier. The Sink uses the same Device Arguments as the source and set Antenna to BAND2 for ≤2GHz and BAND1 for ≥2GHz (according to the doc, my experience differed).

Here’s my first test circuit.

A simple swept transmitter and raw receiver

Here samp_rate is set as a variable (10M) and base_freq comes from Freq which is set by a slider. The transmitter circuit creates a 10M wide sweep (approximately).

When I run this I see this:

Response at 220MHz, 285MHZ, and 420MHz

I generated more frequencies using the slider at the bottom but am only showing three. As you can see the 285MHz response is substantially lower than the 220 and 420 responses. Math says the wire should resonate at about 280MHz so this looks pretty good as a first step.

Showing the connections with a stub antenna

Next Steps

Now I need a slow sweep that runs through a much larger bandwidth and a way to capture and display the data like a real spectrum analyzer.

Here’s a first pass. A python block acts like a sawtooth with the counter more or less in synch with the application. Otherwise the blocks are all Gnu Radio blocks.

The data file is TestTransmit.grc.

A plot of reflection versus frequency for a 1/4 wave antenna showing the min at resonance

As you can see in the plot above, this is now working (more or less) but the labels aren’t there and the setup time is pretty obvious. Turning this into a 1-data-point-per-frequency is tbd.

Circuit Description

This circuit uses a sawtooth to interpolate between min and max sweep frequencies and uses that selected frequency to set the base frequencies for the LimeSDR source and sink. The sink transmits at Fc-1MHz.

On receive it filters out the carrier junk leaving the received (reflected) signal. The math gets max amplitude of the signal per time block and displays it.

The latest flow graph

Antenna Analysis Python

After some thought, I decided to use ‘raw’ Python, starting with programs that Myriadrf provides as examples. Here’s my first ‘real’ graph:

Reflections from a droopy 3 inch wire

Here’s a view of a stub antenna I’ve been using at 915MHz.

A short stub antenna reflections

It took days to get the LimeSDR mini working in Linux. Another story…

GnuRadio and Semtech Sx1276 Data

I hooked up a system that sends constant Lora messages at 915MHz using an SX1276-type system and monitored it with the Lime and GnuRadio. The spectrum looks like this when a message is sent. The spikes move around a little so eventually the peak looks like a horizontal line segment. I’m not using frequency hopping.

The SX1276 Ism Packet Spectrum for a 915MHz short packet

Note that the bandwidth here looks < 40KHz. In fact the Lora setting is 31.25 KHz so really good agreement :)

See here for a short clip showing the spectral pulses. The peak at 915MHz is DC offset primarily (zero IF).

Here I reprogrammed the test app to change base frequencies along the entire ISM spectrum. Each time it finishes a packet it adds 1 MHz. The Lime Mini easily samples this.

Like a swept transmitter. Transmitted with a dipole whip 6" long.

Here, for your amusement, I replaced the commercial dipole whip antenna with a 3.15" (or so) piece of wire. Literally. Note I had to rescale the plot to fit the higher peak :) No change to the LimeSDR receiver antenna or position.

Transmitted with a wire antenna

Here’s the GnuRadio trivial workspace. One might add a slider for the sample rate (smaller rates run noticeably quicker).