We love seeing the incredible work many RF enthusiasts manage to pull off — they make it look so easy! Though RF can be tricky, it’s not quite the voodoo black art that it’s often made out to be. Many radio protocols are relatively simple and with tools like gnuradio and PocketSDR you can quickly put together a small system to receive and decode just about anything.
[Jean-Michel] wanted to learn more about GNSS and USB communication. Whenever you start a project like this, it’s a good idea to take a look around at existing projects for designs or code you can reuse, and in this case, the main RF front-end board is taken from the PocketSDR project. This is then paired with a Cypress FX2 development board, and he re-wrote almost all of the PocketSDR code so that it would compile using sdcc instead of the proprietary Keil compiler. Testing involved slowly porting the code while learning about using Python 3 to receive data over USB, and using other equipment to simulate antenna diversity (using multiple antennas to increase the signal-to-noise ratio):
The main board uses two MAX2771 GNSS front-ends, which filter and convert the received signals to either a digital output or optionally as I and Q outputs for conversion with discrete ADCs. This data is then read by the 8051 core on the FX2, and the data is sent over USB to maintain a fast and reliable stream. On the PC side, this can be decoded using the original PocketSDR software, or one can build a decoder using gnuradio.
The result is a working GNSS decoder. If you would like to see more detail about the project, [Jean-Michel] put together a YouTube video talking about his work in cloning and porting the code, which you can see below:
Maybe its my low IQ that I never understood the purpose of using I-Q while sampling RF signals. No explanation really made sense at a base level.
Or maybe because I have a CS degree.
The explanation is sort of long, and this wont explain it either, but it involves sine and cosine. If we only measure as “normal”, its as if we are only reading the cosine value. By measuring 90° later, we can read the sine value.
When we have both sine and cosine, we can have phase and amplitude, otherwise, we only have phase of a signal.
Renember how in trigonometry, cosine is just like sine + 90°? Well thats kind of the reason why we sample in Quadrature.
I can keep throwing so many “components” on this long explanation, but they all add to one thing;
Trigonometry
Lots and lots of trigonometry concepts
The first things that jump to my mjnd are: you have more information for frequention analysis and you lose less power after the frequency mixing
Trying to simplify:
If you directly sample only 2 samples per sine wave cycle on the receiver, the sampling has to be perfectly synchronized with the transmitter. Otherwise your sampling point will wander around the sinewave. By sampling 4 samples per cycle, you can mathematically rebuild the signal even if they are not synchronized.
Electronically it is easier to do 4 samples per cycle by using two separate channels, which each do 2 samples per cycle but with 90° offset.
For receiving the data, we care about the amplitude and phase of the sinewave. Easiest way to get this is to invert every other sample on each channel and then lowpass the signals. These are the I and Q Then you get the amplitude by square-summing I and Q, and phase by their arcustangent.
The practical reality is a bit more complex because of downconversion and intermediate frequencies.
Using I/Q is only required when you have information above and below 0Hz, if you have an IF signal nothing stops you from sampling I or Q only (at above the Nyquist rate, obviously)
Basically it’s because of math. RF is math. Quadrature signals are easier to do math with.
One way of looking at it is this: we all know that you need to sample at 2*f if you were sampling a frequency up to f (the Nyquist criterion). This is because if your sampling frequency is too low you just subsample and get a low-frequency aliased result. To see that, imagine sampling a signal with frequency ‘f’ with samples also at ‘f’: you would just get a constant value, and if your signal would increase in frequency to ‘f+delta’ you would measure something with a low frequency ‘delta’ because your sampling point would creep slowly along the high frequency ‘f+delta’ signal (this is actually used to sample very-high-frequency signals by so called ‘_sampling oscilloscopes_’, but it assumes that the measured signal repeats over and over, so it can’t be used to recover arbitrary signals)
Now, imagine what happens if you measure a frequency ‘f’ with samples at 2*f. You would just be hitting the signal at the same points over and over; if you’re ‘very lucky’, you could hit it at the maximum and minimum and get a correct measurement, but all the other phases would give you a fake reduced amplitude, and in particular If you’re ‘very unlucky’, you could be sampling the signal at zero-crossings, and get a constant zero output.
Note that ‘very lucky’ and ‘very unlucky’ measurements are just sampling the signal with the phases 90 degrees off each other. So the idea is to always measure both of them, and it’s called ‘quadrature sampling‘ or I+Q sampling. It turns out that you can correctly reconstruct all signals up to frequency ‘f’ from I+Q samples at frequency 2f. It turns out they are easy to capture because shifting the phase is just a fixed time delay of 1/4f, so the I channel measures samples at t0 and t0+1/2f, and the Q channel measures at t0+1/4f and t0+3/4*f.
I tried describing the reason for IQ sampling at https://www.youtube.com/watch?v=_0xF_eQoSGA and most importantly tackling “experimentally” using GNU Radio the concepts of imaginary part of the signal and negative frequency. Indeed whether the complex multiplication is performed in hardware with the issue of IQ imbalance, or in software with an IF is up to design considerations since IF will waste quite some sampling bandwidth. Actually in my experiments I had to use IF (real) mixing and perform the complex multiplication by software to get rid of baseband noise which is still under investigation.
+100 for getting rid of the Keil dependency !
It all has to do with the invention of the wheel. For real. Trigonometry is just the math version of a wheel.
We discovered that depending on how fast you spin that wheel, is correlated to what phenomena you get.
You can go from nothing, up to microwaves, visible light, UV, xrays.
I just keep thinking how interesting is to see the wheel, even as a concept in logical spaces.
How something as simple as 90° makes stuff such a sine appear as cosine, real numbers appear as imaginary, orthogonal frequencies appear that wont affect your signal, and such.
There is a huge universe there, 90° right ahead of you.
You can express any arbitrary sine wave (adjustable amplitude and phase) just by modifying a pair of coefficients
A sin(x) + B cos(x)
trigonometry tells us that cos(x) = sin(x + 90°)
Therefore:
A sin(x) + B sin(x + 90°) can express any arbitrary sine wave, both in amplitude and phase
I/Q is just that, the readings of those 2 coefficients, A and B. With those, you can very easily represent the exact same sine signal, with the exact same phase and exact same amplitude
Otherwise, you could only represent the same amplitude, but your signal wont be on the same phase
Read: https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Linear_combinations