I’ve been working on a satellite orbit prediction app for iOS and wanted to validate that the satellite positions it was reporting were, in fact, correct. I’ve compared against the calculations made by other web apps, but then I thought, “What if I could use actual signals from GPS satellites do this?” It turns out there are relatively inexpensive hardware modules designed to work with Arduino that I could use.
As one might expect, these modules can tell you the current UTC time (which I will use later for a satellite powered wall clock project) and your latitude and longitude, and many of these modules can also output the raw data about which specific satellites it is receiving from, where they are located, and even relative signal strength.
So – tl;dr – I set up a GPS receiver and antenna here at the house and successfully used that to validate the predictions my app is generating.
I looked at a few options and settled on the Ultimate GPS Breakout from Adafruit. I wanted a unit that could output NEMA GSV sentences – since they are the ones with the GPS satellites’ details, a unit that could be connected easily to an Arduino, and a unit with an external active antenna option (in case I couldn’t receive adequate signal strength indoors.)
I ordered the Adafruit module, uFL to SMA adapter cable, and active antenna. Some minor soldering is required to attach the header pins and backup battery holder to the module, but otherwise assembly just involves connecting the antenna, connecting the Arduino, and firing up the provided sketch. I didn’t even bother putting the antenna outdoors. I just left it facing up on my workbench.
On opening the Arduino serial monitor (and setting it for 115200 baud), I was pleasantly suprised to see the GPS module was already outputting satellite details like these:
The interesting lines here are the ones that start with $GPGSV – they are the GNSS Satellites in View details, and with 11 satellites in view, it takes three lines to dump all the details.
I opened my Look Alpha App in the iOS simulator and set set to work comparing the satellites it reported “nearby” to the lines from the receiver.
The first satellite in the first line has PRN 21 at Elevation 82 deg and Azimuth 342. On my iOS simulator I tapped on the satellite nearest Seattle. It showed GPS BIIR-9 (PRN 21). Huzzah! The PRN matches! On the App the satellite appeared NNW of Snohomish, which is pretty close to 342 degrees Azimuth. Huzzah! (Once I add pertubations and geoid shape irregularities to the library, I expect to be able to get exact agreement there.) And with the pin so close to Snohomish, the high elevation angle and strong signal make sense.
The next satellite (PRN 18) made sense too!
And the next one (PRN 15) too!
But the next one (PRN 51) didn’t make sense. I thought PRNs were supposed to be in the range of 1 to 32, but here was a 51. A little quick Googling revealed that PRN 51 is a special PRN assigned to a WAAS satellite, Anik F1R. Woot! I’ll need to add that satellite’s TLE to the app.
Checking through the other satellites we were locked onto I was excited to see I was receiving signals from satellites located just West of Hawaii, over the middle of the Atlantic, another near the Philippines and another Northeast of Venezuela. All from a GPS receiver I put together in less than half an hour.
Here’s what the simulator and receiver data look like side by side:
Next steps? Software: Improve the accuracy of the library by taking pertubations and geoid irregularities into account. Hardware: Build an Arduino powered GPS synced UTC clock with big red seven segment displays, and with a USB interface to send the raw satellite data to the Mac.