Decoding radio transmissions received by a consumer Software-Defined Radio

Using a couple of RTL-SDR Blog V3 software defined radios, homemade antennas, and free software, I was able to download and interpret radio communications from both airplanes and satellites. To make this sound less scary, I could listen to airplanes and satellites when they talk to something else.

I could download ADS-B data, which contains an aircraft's location, registration, height, route, and speed, then plot that using dump1090 and Virtual Radar Server. The data was received by the SDR plugged into a computer on one side and a groundplane antenna tuned to 1090 mHz on the other end.

I also downloaded pictures from weather satellites including NOAA-15, NOAA-18, NOAA-19, and GOES-16. The NOAA series are polar orbiting satellites meaning they pass over the poles every hour and a half or so. To receive this data, I had to build a QFH (Quadrifilar Helix) antenna with PVC piping and speaker wire. This could not be received with a standard antenna because the data is helically polarized. This antenna is seen on the right.

The GOES satellite is one of two geostationary weather satellites that NOAA has in orbit. It takes high definition photos of Earth and transmits that LRIT data which contains the picture the satellite took. This can lead to some stunning and impressively clear photos of our planet. Below are a couple of them.

The Satellites

The GOES 16's sister satellite, GOES 17, is above the Pacific Ocean on the equator while GOES 16 is above Ecuador on the equator. If I lived somewhere else in the United States, I would be able to receive data from the GOES-17 satellite. This highlights something interesting about the NOAA satellites - since they are polar orbiting, a different satellite could pass over your home every day. This means I was able to receive photos from NOAA 15, NOAA 18, and NOAA 19.

There is a Russian satellite (that failed very recently) named Meteor M-2 that transmits higher quality photos of Earth than the NOAA series satellites since it uses the higher bandwidth LRPT instead of APT like the NOAA series. This also makes it harder to receive and decode.

The Antennas

In the course of this project, I used three types of antennas - a parabolic grid antenna, a quadrifilar helix antenna, and a groundplane antenna.

The grid antenna was a slightly modified Wifi antenna I bought off ebay. Since these signals are digital, there is no such thing as receiving a partial image. You either receive it or you don't. That means you have to have the best signal possible. In order to filter out unwanted noise, a SAW (Surface Acoustic Wave) filter. The one I used in my two implementations of the setup was the Nooelec SAWBIRD+. If you have a SDR with a bias tee, you can power the SAW filter with only the SDR. You can enable the bias tee on the SDR I used by following the instructions given in the user guide. My research said to increase the arm length approximately 2 inches and to install the reflector there but I am skeptical how much that did to affect performance.

The QFH antenna was made with PVC and speaker wire. I roughly followed this guide but found it lacking in the sections about actually constructing the antenna. I do recommend the guide if you intend to build this antenna but trust the designs from this antenna dimension calculator more than the mock-up photos of the instructable guide. Basically just make sure you offset all of your drill holes to ensure perpendicular pieces of PVC don't collide. The guide also uses copper wire but in my experience, speaker wire is easier to work with and has little to no effect on the antenna's reception.

The groundplane antenna was a couple of pieces of copper wire soldered, badly, to a SO-239 female connector. I roughly followed this guide. If I were to do this again, I would not solder directly to the connector but instead use nuts and screws to connect the copper wire with the connector.

NOAA Satellites

You have to use a cocktail of software in order to receive good pictures from NOAA satellites. I have only done this specific project using a computer running Windows 7. Once the SDR is plugged into your computer, the SDR# suite can help you install drivers. There is a batch script you must run named instal-rtlsdr.bat. This installs dependencies you need, including Zadig. With Zadig, you can install the necessary drivers to connect the SDR and the computer. Once the drivers are installed, you are ready to listen to the radio on your laptop.

To check that everything is in working order, connect a coax cable to your SDR, plug that into your computer, launch SDR#, and tune to your local college radio station. If you can hear the radio through some noise, try touching the other end of the coax cable with your finger. If you do it right, you will be acting as an antenna that the SDR can "hear" the radio station through. Once you are able to hear the radio station, close the SDR# application.

Since the satellites are moving relative to you, we have to deal with the doppler effect so our photos don't have a slant to them. Practically this means a satellite may be transmitting their signal at 137.1 mHz but we receive it at 137.78 mHz - something that can't be corrected for without its own software. For this purpose, I use Orbitron installed and linked to SDR# with this tutorial. As long as your tracking files are updated, Orbitron will deal with doppler correction.

To process the images, I use one of two programs - WXtoImg and noaa-apt. I've found noaa-apt is so much easier to use than WXtoImg and also does slant correction better than WXtoImg. This being said, WXtoImg is the first program I run the file through because of its built-in recording function.

Install WXtoImg normally then navigate to File -> Base Station Location to tell the program where you are located in order for it to begin recording the signal it receives once a satellite comes overhead.

We're going to pipe the data from SDR# to WXtoImg using Virtual Audio Cable. Install this as normal and launch SDR#. There is a dropdown menu on the left side of the screen called "audio out." Change the audio out to your VB Cable. Now go to WXtoImg and change the audio in to the VB Cable as well. When the next satellite passes over (track with n2yo.com) navigate to WXtoImg and click File -> Recording Options -> Auto Record. The software will now begin recording as long as there is a satellite overhead.

GOES Satellite

The most important thing to realize about the GOES 16 or 17 satellites is that it is incredibly far away (almost 23 thousand miles) and its signal is relatively weak. This means we must have a big antenna with good positioning in order to receive data from it. We already have the big antenna but we must buy or build a mount for the antenna. I opted to build one and, using two scrap pieces of wood and nails, I made a suitable mount, seen on the right. If you are closer to the equator, make sure your antenna has the range of motion to go directly up. Conversely, if you are far away from the equator, ensure your antenna is able to point towards the horizon. Most premade mounts don't expect you to require this range of motion.

I built this setup following this guide. I ran it with a raspberry pi 3b, RTLSDR blog V3, a Nooelec Sawbird+, and the parabolic grid antenna mentioned earlier. Once the physical connections are made between your raspberry pi and antenna, the setup process is quite simple. Watch the viterbi (vit) error rate as a high rate could mean no picture is getting downloaded. A high vit average of 2000+ means we are not receiving any signal. This can be caused by a few things. The most common I’ve seen is the antenna not pointed correctly. Make sure you have the antenna facing the right way in the sky. This can also be caused by something being wrong with the antenna circuit. Make sure everything is plugged/screwed in and that the LNA is powered. Lastly, this could be caused by the SDR dongle getting too hot. Especially down in Louisiana, the dongle can get very hot to the touch when running a program like goestools. There’s not a whole lot I have been able to do to fix this except turning the system off for a few minutes or unplugging/replugging the dongle. Rebooting a few times can also fix this issue as long as it isn’t a signal issue.

ADS-B for Tracking Aircraft

I had two setups for ADS-B reception. One with a raspberry pi and one with a windows computer. Using dump1090 and virtual radar server, I could plot the location, speed, and height of planes in my area. I also downlaoded the Flight Radar 24 OS for raspberry pis. You can link your pi with your flightradar24 account and get a free business plan which is nice. I noticed height is super important for these setups. I could only see 11 aircraft in my area when the antenna was low but once I put it at the top of a 9 ft PVC pipe, it saw 40 aircraft in the area.

The Results

All of our work has finally paid off. Below are a collection of pictures from these projects.

My best NOAA capture. Captured during a rain storm.
Me capturing that photo.
The first photo I ever captured from a NOAA satellite. Mexico is seen here.
The full image received during that rain storm. On the left is the IR photo and the right is the visible light photo.

Useful Links

Building a homemade Go-Kart using a salvaged treadmill motor and an arduino

https://www.github.com/wilsonmcdade/gokart

This all started with the crazy idea to make a vehicle using a treadmill motor. My justification was that a treadmill has a motor that can move a person so it should be able to move a person plus a couple pounds for a frame and wheels. Boy was I wrong.

The parts were really not that hard to take out of the treadmill; You just need a good drill or a lot of grip strength to unscrew the chassis. The motor was screwed to the chassis with a belt between it and the axle. The motor controller had a few electrical connections leading from the headpiece of the treadmill. There were also connections going to the motor, linear actuator, and a tachometer.

Using this schematic for my MC2100LS-30 Rev motor controller, I built a small circuit to activate the motor controller and start the motor. This same circuit was able to move the linear actuator as well.

Once I was able to drive the motor, I began building a frame for the go-kart out of 2x4s and wood nails. This is where the project fell apart. I could not find good wheels for the axle that I salvaged from the treadmill. Since I am not a mechanical engineer, I could not figure out another way to attach the wheels to the axle other than using hot glue. The wheels did not adhere to the metal and would slide around when the axle moved. I also could not keep tension on the belt which meant the motor could not move the axle.

The Code

Below is the code I used to control the motor controller. Keep in mind lots of this is commented out in order to test different aspects of my code. This is a working version that spins the motor as soon as it is connected. My full setup is on my github.

#include  
//definitions
#define PWM_CYCLE 50.0
#define PWM_OUT 9
#define MAX_DUTY 869
#define MIN_DUTY 0
#define inPin 12

//int
int speedLevel;
int ACC = 0;
int reading;
int previous = LOW;

void setup()
{
//init pwmout and timer1
pinMode(PWM_OUT, OUTPUT);
pinMode(10, OUTPUT);
Timer1.initialize(PWM_CYCLE * 1000);
Timer1.pwm(PWM_OUT, 0);
//acc switch
pinMode(inPin, INPUT);
Serial.begin(9600);
}

We first set our output pins to OUTPUT. We also have to initialize Timer1 and start Timer1 with the output pin. Serial must also be turned on for logging.

void loop() 
{
reading = digitalRead(inPin);
//if switch is in on position, accelerate
if (reading == HIGH && previous == LOW) {
ACC = ACC + 20;
}
//if switch is in off position, decelerate
if (reading == LOW && previous == HIGH) {
ACC = ACC - 20;
}
}

This portion of the code implements an on/off switch in lieu of a potentiometer. Most of the above code is commented out because I did not opt to include a potentiometer in this project.

speedLevel = map(ACC, 0, 1023, 0, MAX_DUTY); 

Timer1.setPwmDuty(PWM_OUT, speedLevel);
Serial.print("speed: " + speedLevel);
Serial.print("ACC: " + ACC);

We need to begin sending PWM signals to the motor controller. We do this mapping our ACC variable (acceleration) to the MAX_DUTY of the motor. We then tell Timer1 to output a PWM signal with a duty of speedLevel (our map of ACC and MAX_DUTY). We also print the speed and acceleration for testing and debug purposes.

Final Thoughts

All in all, the project took a lot of time but was very fulfilling. I'll never forget the moment I saw the motor controller board LED turn on and having the motor turn. The project took about 2 months because I had quite a few issues when taking the treadmill apart and I could not find a good schematic for the motor controller. Only when I found that was I able to finish the project.