GPS revisited and some confessions
The book
An interesting book is:
"A software defined GPS and Galileo receiver" , a single frequency approach, by Kai Borre et al.
In the back of the book is a CDROM with a dataset. That dataset contains the if-output of a real SDR tuned to a GPS-signal. I copied the test-file to a convenient place and renamed it to testdata.dat.
That started my struggle with GPS. In that timeperiod I did a course on java and wanted to do something ‘useful’ with that knowledge. I decided to build a GPS-receiver and program it in java. So, I bought some books, read a lot about it on the internet and really got a deep understanding of the system and the signals used in a GNSS-system.
I decided to first develop the software and later concentrate on the hardware. The software was difficult enough for me…
To make a really long story short I finally managed to read almanac-data from the GPS-signals. However I got stuck in the tracking loop. I never got the loop stable. That last problem never made it to my blog at http://www.qsl.net/pa1kdg/ by the way.
So, I also did not succeed in calculating the position from the data in that huge data-file. But, what the heck, I learned soo much of that whole project…
Next step
My next step now is restart that whole project with a bladeRF-board. I want to use python now as a programming language. Just because I can ;>))
TANSTAAFL There aint no such thing as a free lunch
Being a retired engineer, the Mathworks, the developers of MATLAB, is no longer interested in me. When I worked at Wageningen University and Research I got an enormous lot of software free. I was addicted to MATLAB (and LABVIEW by the way), with that software you can solve all your scientific problems. After my retirement I soon discovered that the love of the Mathworks I felt was quite different than real life love I perceive on a daily basis from the people around me. Just before retirement I got an SDR-board with a huge Xilinx FPGA. That would be my big and only project after retirement! Nope, Xilinx too discovered I am not longer interesting for them. Real-life for a CEO is about earning money, not about supporting retired engineers. I have not any problem to pay for hardware or software but 2000 bucks for my hobby is in-explainable to my wife (ok, this whole hobby is inexplainable…) OK, I am back on earth now with two feet on the ground, with my bladeRF and open source software. This is my real life now!!
Life is complicated though
On my way along my GPS-project I discovered a lot about linux, VMWare, github, python-eggs, C, VHDL, makefiles, Quartus, SDR-Radio, gnuradio, Octavo and finally plotting in python (and kind of python-MATLAB too). And I found many sidepaths, DesignSpark Mechanical e.g. and soldering SMD’s.
What now
Back to GPS. I want to record a data-file with real-bladeRF-data and try to process that file. First discover what satellites are visible, later read the almanac data. Finally try to get past that data-tracking-loop problem and solve the position-equations. In the meantime I want to try to get some calculations done in the FPGA. It should be possible to do the correlation-part in the FPGA. Quite a challenge!
Some facts
I concentrate on GPS, not GLONASS. GPS transmits on one frequency. All satellites transmit on the same frequency, that is to say, because of Doppler effects there is a slight deviation of that frequency for every satellite. Each satellite has a different code. If you know the code and the Doppler-frequency you can decode the signal of that very satellite. The signal is simply almanac-data at 50 baud. The satellites tell you constantly where they are. Because you know exactly which bit of the code-sequence you receive and because you ‘see’ 4 satelites or more you can calculate where your GPS-antenna is. For 50 $ you can buy a module that does this trick in a very good way, so…
Practical now
Ok, I tune bladeRF to 1575.42 MHz. With a bandwidth of 2 MHz I might expect to get a weak noisy signal, barely a signal, -160dBW. So, only noise.
There are 32 different code sequences. Just try all those sequences one by one.
There are about 60 different frequencies to consider because of the unknown Doppler shift. So try all frequencies.
In a 3D-display one can find some peaks. Then you know some codes and some Doppler shifts. From then on you can decode the satellite signals and get the almanac data. Then you know te distance to each found satellite. In 3D, if you know the distance to 3 or more satellites, you can calculate where you are. Because you know where the satellites are you know where you are. Simple eh? That is GPS
GLONASS, the Russian system, uses different frequencies. No problem, bladeRF can handle that too. And, with an FPGA you can put the most time-consuming calculations on that chip.
That is the theory.
Tune to 1575.42 MHz. Bandwidth 2 MHz, so samplerate 4 MHz. VGA-gains at 30 dB. Get 1M samples into a file. Perform an FFT. Hopefully something interesting will show up.
Filename A1575.csv without GPSantenna connected and B1575.csv with the GPSantenna connected and pearing out of my window. In the meantime I have a TomTom and a Garmin device locked at the satellites in the sky so I know some data already.
Got my first two files with bladeRF-cli. GPS-systems say: satellites in the sky: 2,4,5,8,9,10,13,16 of which 2,4, 9 are strongest. So I might see satellites 2, 4 and 9 in my datafiles.
[INFO] Using libusb version 1.0.16.10774 [INFO] Found a bladeRF [INFO] Claimed all inferfaces successfully [WARNING] extract_field: Field checksum mismatch [WARNING] Could not extract VCTCXO trim value [WARNING] extract_field: Field checksum mismatch [WARNING] Could not extract FPGA size bladeRF> load fpga hostedx115.rbf Loading fpga from hostedx115.rbf... [INFO] Change to alternate interface 3 [INFO] Change to alternate interface 1 [INFO] Changed into RF link mode: LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 Done. bladeRF> print rxvga1 RXVGA1 Gain: 33 bladeRF> print rxvga2 RXVGA2 Gain: 3dB bladeRF> set rxvga2 33 [WARNING] Setting gain above 30dB? You crazy!! bladeRF> set rxvga2 30 bladeRF> print rxvga2 RXVGA2 Gain: 30dB bladeRF> set bandwidth 2000000 Set RX bandwidth - req: 2000000Hz actual: 2500000Hz Set TX bandwidth - req: 2000000Hz actual: 2500000Hz bladeRF> set frequency 1575420000 Set RX frequency: 1575420000Hz Set TX frequency: 1575420000Hz bladeRF> set bandwidth 2000000 Set RX bandwidth - req: 2000000Hz actual: 2500000Hz Set TX bandwidth - req: 2000000Hz actual: 2500000Hz bladeRF> set samplerate 4000000 [INFO] Setting integer sample rate: 4000000 [INFO] Found r value of: 1 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 4000000 + 0/1 [INFO] Set actual integer sample rate: 4000000 Setting RX sample rate - req: 4000000Hz, actual: 4000000Hz [INFO] Setting integer sample rate: 4000000 [INFO] Found r value of: 1 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 4000000 + 0/1 [INFO] Set actual integer sample rate: 4000000 Setting TX sample rate - req: 4000000Hz, actual: 4000000Hz bladeRF> set bandwidth 2000000 Set RX bandwidth - req: 2000000Hz actual: 2500000Hz Set TX bandwidth - req: 2000000Hz actual: 2500000Hz bladeRF> rx config format=csv n=1000000 file=/temp/A1575.csv bladeRF> rx start bladeRF> rx start bladeRF> rx start bladeRF> rx config format=csv n=1000000 file=/temp/B1575.csv bladeRF> rx start bladeRF> rx start bladeRF> rx start bladeRF>
Note the warning about gain higher than 30 dB ;>))
Run the program for the file without antenna connected: I would expect simply noise but there are three peaks at -583kHz, 0 kHz and 1022 kHz. Perhaps the gain was too big# FFTSDRdata03.py # Nov-2013 Kees de Groot # # show and analyse snapshot file from bladeRF # remove DC-component # show data in different ways; I/Q, realtimeplot, FFT import pylab as pl import numpy as np import math filename = 'B1575.csv' fsample = 4E6 timestep = 1 / fsample f = open('/Temp/' + filename, 'r') print f print "fsample = ", fsample dataI = [] dataQ = [] n = 0 sumI = 0 sumQ = 0 # read I, Q - values into memory for line in f: list = line.split(',') # two values with comma inbetween Q = int(list[0]) I = int(list[1]) # print 1st 10 lines of data-file if n == 0: print '1st 10 lines of I/Q-values' if n < 10: print I, Q dataI.append(I) # save data in memory dataQ.append(Q) sumI += I sumQ += Q n += 1 averI = sumI / n # calculate average averQ = sumQ / n #averI = 0 # debug #averQ = 0 # debug print "n = ", n # remove DC-component and construct complex dataC dataC = [] for i in range(n): I = dataI[i] - averI Q = dataQ[i] - averQ dataI[i] = I dataQ[i] = Q dataC.append(complex(I,Q)) # this one has complex data pl.figure(1) pl.title("Q versus I of " + filename) pl.xlabel('=======> I') pl.ylabel('=======> Q') pl.plot(dataI, dataQ, 'ro') pl.figure(2) pl.subplot(211) pl.title("I-values of " + filename) pl.ylabel('=======> I') pl.plot(dataI) pl.subplot(212) pl.title("Q-values of " + filename) pl.ylabel('=======> Q') pl.plot(dataQ) pl.figure(3) sp = np.fft.fft(dataC) # use fft, not rfft, since dataC is complex freq = np.fft.fftfreq(n, d=timestep) # for convenient x-axis-ticks pl.title('fft of ' + filename) pl.xlabel('frequency') pl.ylabel('magnitude') pl.plot(freq, abs(sp)/n) # abs converts to magnitude; /n normalizes pl.show()
I would expect simply noise but there are three peaks at
-583kHz, 0 kHz and 1022 kHz.
Now connect GPS-antenna
Perhaps the gain was too big
bladeRF> set rxvga2 27 bladeRF> set rxvga1 27 bladeRF> rx config format=csv n=1000000 file=/temp/C1575.csv bladeRF> rx start bladeRF> rx start bladeRF> rx start bladeRF>
I am still puzzled about the fact that I see a signal when no antenna is connected. I remove the SMB cable from RX and set gains to 0 dB. Then create file D1575.csv:
Biggest peak is at 0 Hz exactly, the other is at 1.01882E6, so around 1 MHz
Again without antenna but a 50 ohm dummyload directly connected to bladeRF-RX-input.
Something went wrong with the board. Error because of physical touching it with too big dummyload directly connected?
Beware: sample rate = 1 Mhz[INFO] Using libusb version 1.0.16.10774 [INFO] Found a bladeRF [INFO] Claimed all inferfaces successfully [WARNING] extract_field: Field checksum mismatch [WARNING] Could not extract VCTCXO trim value [WARNING] extract_field: Field checksum mismatch [WARNING] Could not extract FPGA size bladeRF> load fpga hostedx115.rbf Loading fpga from hostedx115.rbf... [INFO] Change to alternate interface 3 [INFO] Change to alternate interface 1 [INFO] Changed into RF link mode: LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 Done. bladeRF> print rxvga1 RXVGA1 Gain: 33 bladeRF> set rxvga1 0 bladeRF> set rxvga2 0 bladeRF> set samplerate 1000000 [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 Setting RX sample rate - req: 1000000Hz, actual: 1000000Hz [INFO] Setting integer sample rate: 1000000 [INFO] Found r value of: 4 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx a + b/c: 316 + 4/5 [INFO] MSx P1: 0x00009c66 (40038) P2: 0x00000002 (2) P3: 0x00000005 (5) [INFO] Calculated samplerate: 1000000 + 0/1 [INFO] Set actual integer sample rate: 1000000 Setting TX sample rate - req: 1000000Hz, actual: 1000000Hz bladeRF> set frequency 1575420000 Set RX frequency: 1575420000Hz Set TX frequency: 1575420000Hz bladeRF> set bandwidth 2000000 Set RX bandwidth - req: 2000000Hz actual: 2500000Hz Set TX bandwidth - req: 2000000Hz actual: 2500000Hz bladeRF> rx config format=csv n=1000000 file=/temp/E1575.csv bladeRF> start Unrecognized command: start bladeRF> rx start bladeRF> rx start Error: Operation invalid in current state bladeRF> rx start bladeRF> rx start bladeRF> rx start bladeRF>
Now samplerate = 2 MHz
Still, no antenna connected, but dummyload directly at RX
Conclusion
I have a problem. I expected a flat noise floor without any antenna connected. But I see some spurious signals. I might be able to explain the signal at 0 Hz. But the others are strange.
I have to check again without any antenna connected and vary the parameters that I can set:
n, the number of samples, it might be a hickup of the interface
samplerate, there is a clock, so there are some signals
frequency, mixer-products?
rxvga1 the more gain, the more spurious signals
rxvga2 same
bandwidth, dont think so
Well I had a nice evening trying to get a GPS-satellite-signal but discovered my bladeRF also is very creative?
No comments:
Post a Comment