Tracking Satellites by Radio

Using this antenna

and these two little black boxes

I have been able to track satellites as they pass through the NAVSPASUR radar fence.

using a combination of the Spectrum Lab software and my own programs

to produce accurate identification and tracking update information

Project Description

My informal plan to build a radio tracking system using COTS equipment as much as possible is still in progress.  The project has developed in stages:

1.  Learn how to get the radio to work and receive signals.

2.  Learn how to get the data from the radio into the computer.

3.  Write a program or programs to pick satellite signals out of the radio data.

4.  Figure out how to ID the satellites.

5.  Use the data to calibrate the fence parameters (az, tilt, width), calibrate my clock, find actual IF, find the operational antenna beam width in AZ and EL, update the RCS (Radar Cross Section) database to include unlisted satellites.

6.  Update orbits with accurate time and Doppler information.

7.  Learn how to get the computer to gather data autonomously.

8.  Figure out how to get directional information from an antenna array.

9.  Update orbits with directional information to find the orbits of unknowns.

I am now at stage 8 and 9.

Stage 1.  SpectrumLab software + SDR-IQ radio is the current solution. Both the radio and the software are readily available. The software is free and the SDR-IQ is reasonably priced. SpectrumLab appears to have all the features to do most of the operations I am planning.

The fence transmits at 216.980 MHz. The SDR-IQ requires an input frequency below 30 MHz. I choose an IF of 29 Mhz. The crystal frequency required was:

216.980 - 29.00 = 187.98 Mhz or a crystal operating at 187.98/9 = 20.886666 Mhz

Hamtronics sent me a frequency converter with a crystal tuned to 20.886666 Mhz. Initially there was some frequency drift in the crystal and I had to manually adjust it back into the desired operating range. The crystal drift seems to have stopped after several months of operation.

Stage 2.  Use the SpectrumLab export feature. These were my initial settings

This was the output in the exported1.txt file:


2009-11-09 21:30:59.02;28994433;29007100;-102.4;-105.1;-101.6;-104.5
2009-11-09 21:30:59.06;28999762;29007710;-102.3;-105.1;-102.1;-104.5
2009-11-09 21:30:59.10;28999885;29000819;-102.0;-104.9;-101.9;-104.5
2009-11-09 21:30:59.25;28998380;29002354;-101.9;-104.9;-101.5;-104.6
2009-11-09 21:30:59.28;28995774;29002353;-102.1;-104.8;-100.5;-104.5
2009-11-09 21:30:59.32;28997360;29002352;-099.8;-104.9;-101.3;-104.5 <--- start hit window
2009-11-09 21:30:59.36;28997349;29007712;-100.4;-104.8;-102.2;-104.5
2009-11-09 21:30:59.39;28997347;29001920;-098.7;-105.0;-101.5;-104.7
2009-11-09 21:30:59.50;28997347;29002623;-101.1;-104.6;-102.4;-104.8
2009-11-09 21:30:59.54;28997347;29002001;-099.8;-104.7;-101.9;-104.8
2009-11-09 21:30:59.69;28997321;29007832;-096.0;-104.8;-102.0;-104.7 <--- 1
2009-11-09 21:30:59.73;28997320;29001161;-094.2;-104.7;-101.9;-104.6 <--- 2
2009-11-09 21:30:59.76;28997320;29005352;-093.0;-104.8;-101.3;-104.7 <--- 3 epoch & Doppler
2009-11-09 21:30:59.80;28997320;29003968;-093.7;-104.8;-101.4;-104.6 <--- 4
2009-11-09 21:30:59.84;28997320;29006476;-094.4;-104.7;-101.7;-104.6 <--- 5
2009-11-09 21:30:59.98;28997319;29002109;-100.1;-104.9;-100.4;-104.6
2009-11-09 21:31:00.02;28997320;29002110;-100.5;-104.9;-101.6;-104.7
2009-11-09 21:31:00.06;28997319;29007235;-101.3;-104.8;-102.3;-104.7
2009-11-09 21:31:00.10;28997320;29007779;-100.3;-104.8;-101.6;-104.6
2009-11-09 21:31:00.13;28997319;29002284;-100.4;-104.9;-102.4;-104.7 <--- end hit window
2009-11-09 21:31:00.28;28999560;29001485;-101.8;-104.8;-101.7;-104.6
2009-11-09 21:31:00.32;28999560;29001485;-101.6;-104.8;-101.3;-104.9
2009-11-09 21:31:00.43;28998080;29002800;-101.9;-104.9;-101.5;-104.7
2009-11-09 21:31:00.46;28997687;29004537;-102.1;-104.9;-101.3;-104.9
2009-11-09 21:31:00.50;28997688;29002394;-102.0;-104.9;-101.6;-105.0

Stage 3.  I have written a program named SPECTRUM to use the data in the export1.txt file to find and identify the satellite hits. This short excerpt from the exported1.txt file shows a satellite hit starting at time 2009-11-09 21:30:59.32 in the PeakFreqLo column. The Doppler shifts in the PeakFreqLo column (PeakFreqLo - 29000000) will all be negative which means this satellite was going through the fence away from the observer. You will notice at the start of the hit window that the PeakFreqLo column values begin to be within 20 Hz of each other. You will also notice that the signal strength in the PeakLo column begins to show a steady increase and then decrease as the satellite passes through the fence.

SPECTRUM uses a combination of frequency pattern (frequencies within 20 Hz) and signal amplitude for hit detection. It then uses the epoch of the hit and Doppler to ID the hits. SPECTRUM finds the hit epoch by identifying the largest value of signal amplitude in a running average of 5 consecutive lines in the export file that are within the frequency hit window, as shown above. The middle of the peak will be the hit epoch, at point 3, time 21:30:59.76, in the above example.

I have broken the frequency range into lower and upper bands primarily as a way to block out the constant high amplitude near 500 Hz. This division has the added benefit of enabling the program to detect simultaneous hits in the low and high bands. More bands would enable more than two simultaneous hits but I initially didn't want to complicate the program. All hits are easily detected if one watches the SpectrumLab waterfall display, but that is impractical.

[UPDATE] Currently I am receiving data from 5 frequency bands:

[-8000 Hz, -4000 Hz]
[-4000 Hz, 0 Hz]
[0 Hz, 1000 Hz]
[1000 Hz, 4000 Hz]
[4000 Hz, 8000 Hz]

This division enables the system to automatically differentiate between 5 different satellite signals if they are in different bands. The small band from 0 Hz to 1000 Hz captures the occasional bright return from the ionosphere (reflected from the transmitter) near 500 Hz. I use the long, zero chirp signal returns from this region to calibrate the system IF.

Stage 4.  SPECTRUM picks the hits out of the export file and ID's the satellites by comparing the hit epoch and Doppler to the predictions made by the FENCE.TXT file. The FENCE.TXT file is a list of hits predicted for the time interval of the observation. This file is produced by the program FENCE.EXE. Here is a prediction excerpt from FENCE.TXT :

  SSN    EPOCH	         AZ       EL   DOPP CRP RCS
14144 09329.85517450 314.63 50.79  2629   -34   4.06
14180 09329.85587680 323.32 55.74  2187   -35   2.20
25017 09329.87416707 317.93 35.08  5600   -52   2.81
23233 09329.87985019 346.98 51.30 -3076   -65   4.43
31701 09329.91265959 345.19 57.51 -1434   -48   7.64
31708 09329.91274262 346.60 57.67 -1506   -48   5.75
23908 09329.91438174 025.10 51.01 -3946   -53   2.19
23936 09329.91448387 026.25 50.71 -3992   -53   4.53
23862 09329.92180000 002.45 53.41 -2976   -61   8.54
08836 09329.92743547 021.41 37.84 -4700   -86   2.87
28095 09329.94952655 331.74 55.21  2903   -42   8.61
28097 09329.94961839 333.04 55.61  2844   -42   6.12
16591 09329.95250243 327.69 58.62  2003   -33   0.77
16623 09329.98082435 308.90 48.31  2822   -30   3.61
16624 09329.98102797 309.17 48.46  2817   -31   4.12
16631 09329.98151759 334.84 60.67  1737   -33   1.70
21798 09329.98152646 310.87 37.75 -3566   -52   2.42


EPOCH is the predicted time of the satellite hit. AZ is the predicted azimuth of the satellite hit as seen from the observer, EL is the predicted elevation of the satellite as seen from the observer, DOPP is the predicted Doppler, CRP (chirp) is the predicted Doppler rate in Hz/s, and RCS is the radar cross section derived from Mike McCants RCS.TXT file, if known.

It is interesting to note that all objects passing through the fence will have a decreasing Doppler signature. Chirp is always negative. All noise is zero Doppler and zero or positive chirp. The longer the span of a hit, the closer the measured chirp is to the predicted chirp.

If SPECTRUM successfully ID's a hit it adds the PREDICTED AZ and EL from the FENCE.TXT file to the OBSERVED epoch and Doppler. The AZ and EL information is NOT directly observed yet. I will need to build an interferometer to do that. Here are some sample ID'ed hits :


SSN    DATE                  AZ      EL     DOPP CRP SPAN SIG
08836  9329.92739173 021.41 37.84 -4679  -25   0.63   14
08836  9330.31423344 027.72 42.78     -53  -25   0.48     7
10594  9330.14067154 030.87 29.66 -6082    -4   0.48     9
11389  9330.15582648 012.76 50.44 -2331  -54   1.51   22
13874  9330.23675931 349.42 60.69  1236  -29   1.39   21
14144  9329.85521066 314.63 50.79  2212    52   0.25     4
14144  9330.43152380 024.59 37.24 -5603  -29   0.89   19
14180  9329.85591156 323.32 55.74  2128    -4   0.26     5
14728  9330.04909501 353.69 61.66  1121  -36   1.51   20
16623  9330.55711211 011.90 42.98 -4655  -35   1.20   21
16624  9329.98101343 309.17 48.46  2831    -2   0.44     7
16624  9330.55728662 012.61 42.96 -4705  -79   1.38   23
16631  9329.98149590 334.84 60.67  1746    -5   0.55     9

All these parameters are observed except for the AZ and EL. SPAN is the time in seconds from the beginning of the hit to the end. DATE is the observed time of the hit in TLE format as found near the middle of the span. DOPP is the observed Doppler, CRP (chirp) is the observed Doppler rate. The SIG column is the observed signal strength minus the signal noise calculated from the columns: PeakLo - noiseLo.

When there are several satellites appearing near the same time and Doppler (amazingly this is not a rare occurrence) I use signal strength to break the ties. Additionally, I have used the signal strength and radar cross sections of known satellites to create a radar cross sections file of satellites based on the strength of radar returns. It may not be perfectly accurate but these values are still useful for predicting signal strength to provide some discrimination in the satellite ID process.

The hits that are not identified wind up in the unknowns file:

SSN    DATE                                 DOPP CRP SPAN SIG
00000 10281.16217616                     -34     -7    0.30     8
00000 10281.16250231                  7205    -36   1.26   10
00000 10281.16373148                  7266    -47   0.96     7
00000 10281.16518542                 -6824    -27   4.17   11
00000 10281.17140671                 -3452     -5    0.59   10
00000 10281.17837986                  8199    -66   6.31     7
00000 10281.17943611                  6772    -65   1.77   18
00000 10281.17970961                    -50   -111   0.41     7
00000 10281.18026644                 -2490    -45   1.25   16
00000 10281.18161435                     -21       2   0.37   18
00000 10281.18889780                  6824    -59   0.77   13
00000 10281.18895961                   -467    -20   0.52     7
00000 10281.19455810                  6022    -17   0.96   21
00000 10281.20312361                  7942    -34   1.73   11
00000 10281.20487755                    -70    133   0.22     7

Some unknowns have a nice long SPAN and very strong SIG. There are more unidentified unknowns than identified hits.  No AZ or EL information is shown for UNKNOWNS because that information is not available until the hit is identified. Because the Doppler range is so exclusive (-8000 Hz to +8000Hz) I don't expect to see any meteors.

The first stage of hit ID tries to match each hit with a FENCE.TXT prediction to within plus or minus 6 seconds and plus or minus 200 Hz of the predicted time and Doppler. I have discovered that a satellite may make several hits as it passes through the fence due to tumbling and changing orientation of the reflecting surfaces. The second stage of hit ID tries to recombine multiple hits that belong to a single satellite. I am still left with many unknowns. There seems to be a lot of unidentified junk up there.

Stage 5.  I am able to ID about 4500 satellite hits in every 24 hour period. I have used several days worth of ID'd output to calibrate the NAVSPASUR fence geometry. So far the data has consistently agreed that the fence is not true east-west but is rotated so that the eastern azimuth is 91.41 degrees. The fence does not project straight up to the zenith but leans to the north by 0.24 degrees.

My Yagi antenna seems to cover all the elevation necessary to see the vertical extent of the satellites and also covers an azimuth of + - 60 degrees from antenna boresight for the larger satellites. I used the SPACETRACK database to compare predicted hit times with observed hit times and calibrated my permanent clock offset to within 0.01s. I use an external GPS time standard to update the computer clock but Windows does not accurately transmit time to programs.

Stage 6.  I am currently collecting data on satellites and comparing my radio observations to visual observations. The goal was to be able to update orbits of satellites not found in SPACTRACK using radio data. This goal has been achieved! Ultimately, (Step 8 and Step 9) I would like to be able to indentify the many UNKNOWNS that I see flying through the fence!!

Stage 7.  The radio collects data without user attention. Once a day, I run the SPECTRUM program to process the data and produce orbit updates to the satellites of interest. The daily export files are about 200 MB after 24 hours of operation. There would be no way to do this without a computer!

SpectrumLab Issues


I initially noticed that my Doppler values were somewhat off from the predicted values. The pattern emerged that the measured values were about 500Hz too large. So instead of subtracting 29000000 Hz (IF frequency) from the measured frequency I now subtract 29000500 Hz and all predicted values were then much closer to the measured values. Additionally, the frequency drifts daily in a periodic manner about +-50 Hz around this central value (~500 Hz). I believe that temperature causes the daily frequency drift by changing the physical parameters of the equipment. The problem has been resolved by using the ionosphere hit strings in the [0 Hz, 1000 Hz] window to give an accurate "zero Doppler" drift map that is applied to correct the received frequencies. With this hit map, my received frequencies match the predicted frequencies within a few Hz.

I have set SpectrumLab to send an output line to the export1.txt file every 0.05 seconds. You will notice in the sample export1.txt file above that the actual intervals are anywhere from .03 to .15 seconds. I have created a work around to this variation by calculating a weighted running average for some of the values that would prefer even intervals.

SpectrumLab has a built in feature called Correlogram. This feature seems to have the potential to solve the interferometer problem. It would be ideal to have the Correlogram phase difference data between two antennas output as an additional column in the export1.txt file.


Setup is very easy. The antenna feeds a 50 Ohm coax directly into the Down East Microwave Preamp set to 216.98 MHz. The preamp is powered by a 12V motorcycle battery mounted at the antenna and the black wires are grounded at the antenna. The coax from the preamp continues into the house where it feeds the Hamtronics frequency converter, which feeds directly into the SDR-IQ, which is connected to the computer through USB.

Initial operation began without a preamp. There seemed to be a lot of hits without the preamp but when I added a preamp at
the antenna the number of hits doubled and the observed strength and duration of hits increased so much that the hits are now more likely
to be stepping on each other. This is another signal processing problem.

The SETTINGS.INI file must be put in the same folder where SpectrumLab resides. The satellites.usr must be activated to use the same settings as I am using. Both of these files can be found in the PROGRAMS link below.


Procedures and Software



Batch mode is what is described above. I harvest the information in the export1.txt file once a day with the program SPECTRUM.EXE. This does the signal processing and produces several output files.

SPECTRUM must run in a directory with the following files present:






Output Files:

fence.txt - predicted fence hits for the same time interval as exported1.txt data.

c_hits.txt - classified hits predicted during the time interval of exported1.txt data

r_obs.txt - observed classified hits during the time interval of exported1.txt data in IOD format

hits_filter.txt - details of the hit filtering decisions made by SPECTRUM

hits_unknown.txt - unidentified hits

cal.txt - observed hits within the 1 second filter. these are used to calibrate the system.

hits_data_log.txt - exported1.txt repeated with hit markers inserted after every detected hit


Capture mode is "real time" processing. As I observe the SpectrumLab waterfall

 I can run CAPTURE.EXE and it will ID all the satellites currently displayed. 

CAPTURE must run in a directory with the following files present:





Output Files:






BISTATIC.ZIP - Program for predicting Doppler from bistatic satellite reflections