Working Passive UHF RFID reader using the LimeSDR

Hi all,

As my final year project at university, I have successfully configured the LimeSDR-USBv1.4 to work as an RFID reader of standard commercial UHF RFID tags. Thanks to all those on this forum who helped me with some of the issues I encountered along the way.

SoapySDR was used with SoapyUHD, in order to use standard UHD blocks in a GNU Radio application. I ended up having to edit the SoapyLMS7 drivers in order to resolve a few problems. I have uploaded my edited version of the drivers to a github repo here, along with my GNU Radio application. Further details of my implementation can be found in the readme.

I wrote up my findings in a final report, which is also included in the repo. The report includes some relevant background, along with a discussion of the problems encountered, the solutions implemented, and an evaluation of the LimeSDR’s performance as an RFID reader. Warning: the report is almost 50 pages long!

I no longer have access to the LimeSDR or any of the relevant equipment so I won’t be able to develop the code further; I am however happy to answer any questions that people may have.

I hope people find the above useful.

Disclaimer: I was (and still am) very much a beginner at SDR in general, let alone the LimeSDR specifically. It is possible that there are therefore mistakes in my implementation, conclusions, and/or analysis - if you spot any, please post them here in order to help others!


Hello DasSidG

What is the distance of this kind of RFID reader?

Is it possible to add some amplifier, so that this SDR based reader could work in a larger range than a commercial reader?


Hi shao,

In this experiment I did not measure the maximum range. I used a near-field antenna and placed the tag directly on top. I did however estimate the sensitivity of the reader (assuming that the range is reverse-link limited), so if you have a model for the attenuation in air you could probably estimate it from that.

In principle there is no physical reason why you could not add an amplifier to the transmit output to increase the range; however you have to be careful of a couple of things:

  1. Some of the transmitted signal will leak back into the receiver, and this will be increased if the transmitted signal is amplified, which means that more amplification might not actually gain you more range.
  2. If your amplifier is not very linear then you might add a lot of noise.
  3. The transmit power of commercial readers are (I believe) generally limited by regulatory constraints, as opposed to any fundamental physical or electronic limits. Thus, if you intend to use this in a commercial context then you might not be able to do better than a commercial reader in terms of transmit power.

Thanks DasSidG. I am little bit confused. Your project is passive rfid reader, so does it sends out any radio waves before receiving information? Or it’s just receive only?

Hi DasSidG,

What is the power in db whith the frequency 850 / 900 Mhz.

Best regards


Thank you Siddharth for open-sourcing your project and for your contribution to RFID field.

In your file, you set the adc_rates and dac_rates with the same values that the previous work for the USRP N210, but multiplied by a factor of 3.35.

Why did you use that value of 3.35?
I am trying to understand it, since I want to use the BladeRF and USRP B200-mini.

Thank you

Hi Laura,

When using the LimeSDR I struggled to meet the latency requirements, specifically getting the ACK back quickly enough after seeing the RN16. I increased the adc_rates and dac_rates to reduce this latency: there are various sample buffers in different layers of the stack, which contribute to latency, and by increasing the sample rate these buffers filled up more quickly, thus causing them to be emptied more often and therefore reducing the average latency. A factor of 3.35 was the largest number I found that wouldn’t cause the program to break - I can’t remember why larger values than this caused problems, but they did.

Hi all,
I got a LimeSDR :grinning: excited to try it out!.
I followed your installation guide in the README file on your github.

When I run the / file, the SDR board is not found

RuntimeError: LookupError: KeyError: No devices found for ----->
Device Address:
driver: lime
soapy: 0

However, when I run $ SoapySDRUtil --info I get the board recognized
I have already done troubleshooting, and google for some information, but with no success.
Any advice of how to debug/work on this problem?
Thank you very much in advance, appreciate your time.

## Soapy SDR – the SDR abstraction library ##

linux; GNU C++ version 7.3.0; Boost_106501; UHD_003.010.003.000-0-unknown

[INFO] [UHD] linux; GNU C++ version 7.4.0; Boost_106501; UHD_3.14.1.1-release
Found device 0
addr = 1d50:6108
driver = lime
label = LimeSDR-USB [USB 2.0] 90726074F2827
media = USB 2.0
module = STREAM
name = LimeSDR-USB
serial = 00090726074F2827

Hi Laura,

Unfortunately I don’t really have any idea of which version of LimeUtil, SoapySDR etc you have installed, and if you have installed a different version to what I used (I used the drivers as they were in sometime late 2017/early 2018) then there is a very good chance that my project code will not work straight off the bat. Since SoapySDR can see it, it looks like the SoapyUHD driver is not able to see the LimeSDR. I would suggest that before you try and use my, just try a really simple flowgraph and try and get that to recognise the LimeSDR first.

It’s possible for example that the driver arguments ‘driver:lime’, ‘soapy=0’ are no longer the correct device arguments, and there could be many other reasons that SoapyUHD can’t find the LimeSDR.

Also, a few other general points:

  1. I notice that you are using the LimeSDR via USB2.0, this could cause a number of issues. You should power the LimeSDR separately rather than relying on the USB2.0 power, as it’s likely that the USB2.0 port won’t be able to give it enough power when it’s doing anything intensive. Also, it is unlikely that the lime_reader will work with USB2.0, as I suspect the round-trip latency will end up being too high.

  2. If you are using my version of limesuite included in my github repo, I would encourage you to instead try the latest version of the limesuite drivers that are available. Rather than trying to use my code directly I would encourage you to read my report and try and understand the issues that I faced, and they may already be solved in updated versions of the drivers (I took my version of the drivers about 2 years ago). Then if you see some of the same issues that I saw in my report you can take a diff between my version of the drivers and the original version that I modified (which I linked to on my github) to see what I changed.

Thank you very much for your response.

I updated the LimeSuite drivers and the board is being recognized now (the driver arguments ‘driver:lime’, ‘soapy=0’ still work fine).

So I will just update manually myself the updated drivers.


Thanks for the share, would you mind providing more info on the actual setup, which antenna you used and to which connector you’ve attached it? I am thinking about replicating your setup with the latest drivers (after the mod).

Hi ahf,

Unfortunately I did this quite a long time ago, so my memory of the details are a bit hazy. Looking back I would have written a lot more details down!

I used a near-field antenna with a tag placed directly on top of it, but there’s no reason it shouldn’t work with a far-field RFID antenna either.

I can’t remember which antenna on the board I connected it to, but hopefully it should be fairly easy to figure this out from the GNU radio file.

You can find the block diagrams of a few of my setups in the report I wrote (which I’ve included in my github repo), in section 4. These setups were a bit contrived as I was trying to evaluate a few different metrics of the LimeSDR; for example, in Figure 14 I’m explicitly coupling some of the TX to the RX, which you would never want to do in practice. So you could get rid of the attenuators. the splitter combiner, and the TX directional coupler to get a working system. The key thing (as you’re probably aware) is to try and avoid your TX leaking to your RX as far as possible.

Good luck with this, and if you get it working with the new drivers, I encourage you to share the details here - it would be good for someone to demonstrate it working with a much more up to date set of drivers.

Hey @DasSidG,
Thank you for this project, very cool. I’m curious about one aspect that was touched on previously, why does this need to use TX at all if only reading a tag? Also, do you have the original flow graph file for sharing? Thanks!

Hi axwaldo,

TX is needed because this is trying to read a passive tag. This means that the tag doesn’t have any power source of its own. So first the tag needs to be powered up - this is achieved by the reader transmitting a constant wave (CW) signal, which is just a pure sine wave, which the tag harvests energy from.

In addition, rather than transmitting back directly to the reader (which could use a lot of energy), the tag ‘backscatters’ - it modulates the impedance connected to its antenna, which changes its reflection coefficient, which changes the amount of energy reflected back from the tag to the reader’s receiver. In this way the tag can communicate information back to the reader, but this requires the reader to be constantly transmitting a CW for the tag to backscatter.

With regards to a flowgraph - if you look at the start of this thread I link to my GitHub repo where I stored the end result of the project, which includes my flowgraph. Unfortunately I didn’t have the relevant XML files so it can’t be opened in GRC, but it can be triggered from the command line.