jgaeddert / liquid-dsp

digital signal processing library for software-defined radios
http://liquidsdr.org
MIT License
1.87k stars 439 forks source link

Trouble getting simple frame64 working on real hardware #164

Open wtfuzz opened 5 years ago

wtfuzz commented 5 years ago

I've been experimenting with frame64 using my bladeRF and LimeSDR mini with SoapySDR and I can't quite get them to reliably pass data.

I put together a simple example here https://github.com/wtfuzz/sdrtest which just instantiates the SDR device, tunes to 915MHz, sets the sample rate to 100k, and creates two threads with a framegen64 and framesync64.

I'm filling the 8 byte header with 0xAB and the 64 byte payload is filled with 0x1D.

Even in loopback mode on the bladeRF, the received frames are slightly corrupt.

Here's an example output with RF loopback enabled on the bladeRF:

-=[ Packet Callback ]=-
    EVM                 :     0.00000000 dB
    rssi                :   -33.94402313 dB
    carrier offset      :    -0.00037891 Fs
    num symbols         :   600
    mod scheme          :   qpsk (2 bits/symbol)
    validity check      :   crc24
    fec (inner)         :   none
    fec (outer)         :   g2412
Header valid: 0
Payload valid: 0
Header:
AB AE 22 AB AB AB AB AB
Payload:
1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D
1D 15 5D 1D 1D 1D 1D 1C 5D AD 9D 1D 1D 1D 1D 1D
1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 5D 5D
1D 1D 1D 1D 1D 1C 19 1D 1D 1D 1D 1D 1D 1D 1D 1D
-=[ Packet Callback ]=-
    EVM                 :     0.00000000 dB
    rssi                :   -33.96026611 dB
    carrier offset      :    -0.00020248 Fs
    num symbols         :   600
    mod scheme          :   qpsk (2 bits/symbol)
    validity check      :   crc24
    fec (inner)         :   none
    fec (outer)         :   g2412
Header valid: 0
Payload valid: 0
Header:
AB AB AB AB AB AB AB AA
Payload:
3F 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D
1D 15 5D 3D 0D 1D 1D 1D 1D AD 9D 1D 1D 1D 1D 1D
1D 1D 1D 1D 1D 1D 1D 1D 1D 1C 5D 1D 1D 1D 1D 1D
1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D
wtfuzz commented 5 years ago

I was able to get this working by applying a gain of 0.1 to all IQ samples before sending via Soapy. The frames are received flawlessly via loopback, and from bladeRF TX to LimeSDR RX over the air.

Does anyone have any idea why the amplitudes of the samples need to be reduced so much? Even with the VGAs on the bladeRF TX path set to the lowest possible gains (txvga1 = -35dB, txvga2=0dB), I have to reduce the IQ output to get the receiver to successfully receive the frames. Any gain of the samples over about 0.2 results in excessive bit errors.

I'm wondering what I'm missing, or if there's a bug somewhere in the bladeRF library or Soapy in conversion from the float values to SC16Q11 format, as it would seem odd that I wouldn't be able to use the whole dynamic range of the DACs.

dl1chb commented 5 years ago

I have a similar problem using PlutoSDR. My case seems worse than yours, but I have some idea, why this happend to you (and maybe to my setup). The output spectrum contains lots of harmonics. By lowering the output-power they get less. I am measuring the Pluto these days in out lab. Have you measured the output of your bladeRF?

jgaeddert commented 5 years ago

I don't have a LimeSDR, but in my experience the signal gain can cause a lot of distortion on the transmitted signal (clipping or compression). This aligns with what @dl1chb said.

I have considered a very simple debugging option for the frame synchronizers to log binary values to a file or database for post processing later. I occasionally get questions like these asking why the signal reception on hardware isn't good, and it's difficult for me to debug without connecting to test equipment.

Having said that, I disabled the error-vector magnitude computation (EVM) which would be a strong indicator of what's wrong. It's not as good as plotting the signal, but showing a poor EVM with a strong signal power is a clear indication of over-driving an amplifier somewhere.

jgaeddert commented 5 years ago

With 116eb4c24ec5624b145fb80e84f0d3224a574262 and 549f961cf553cbe82e351c8b9f0740f7fd695236 I added a simple EVM calculation in the qpilotsync object; this is now returned in the callback. It won't be a great estimate as it's just done through the pilots, but it was an easy enough to add and drop into the framesync64 object.