Antenna Pointer
Dual-wielding a tablet and an antenna while spinning to find a tiny dot on a screen is ridiculous. Adding a radio to the mix with a free finger to press the PTT button makes the setup more awkward. This is what I found myself doing when trying to find satellite repeaters with my amateur radio club. We had started by using azimuth data and compasses and moved on to satellite tracking apps when that gave no results. Though it was easier to tell where to point the antenna, it was hard to line it up with the marker on the screen and we could not seem to point it precisely enough to hear the satellite.
This challenge lined up with a robotics class I took in the spring, so I took this as the problem I wanted my term project to solve. Since I couldn’t point my antenna precisely enough, a computer would have to. Servos strong enough to move my antenna were outside the budget of the class, so I focused on a model that moved a small arrow around. Having a physical object to line the antenna up with would be much easier than a phone app and I was hoping it would allow me to line the antenna up close enough to reach a repeater satellite.
Methods
To give a direction to the arrow I would be pointing, I needed an elevation and azimuth. This can be found from the Antenna Pointer’s position and the satellite’s. The device’s position is in latitude and longitude, which doesn’t account for the rotation of the Earth and is a geodetic coordinate system. The satellite’s position would be in a Cartesian coordinate system but had to be somehow extracted from its seven Keplerian elements.
Going into this, I assumed there would be a wealth of documentation and analyses on turning the elements into a 3D vector and doing coordinate conversions to compare them with latitude and longitude. When researching, I was surprised I found no complete nor concise analyses on the math required to go between these. I went to a website I often use for satellite pass predictions, AmSat.org, and found they had daily bulletins of Keplerian elements as well as a guide that gave me hints on how to start. I ended up pulling from this and many other sources to build a fragmented outline, used unit analysis to fill in the gaps, and fiddled with the equations in MATLAB until they lined up with known values.
In part for my learning and to make it easier for someone like me in the future, I made an analysis on going from Keplerian elements and GPS coordinates to ECI coordinates to find the azimuth and elevation. So as to not clog up this article with equations, I will summarize what the analysis does.
I took the Keplerian elements and turned them into a function of time that gave position in Earth-Centered Inertial (ECI) coordinates. I took the latitude and longitude of the Satellite Pointer and converted them into Earth-Centered Earth-Focused (ECEF) Coordinates. I calculated the Julian date, found the Greenwich sidereal angle and used those to rotate the ECEF coordinates into ECI. Once both the satellite and position were in ECI coordinates, I used dot products and projector matrices to find the angles I needed.
Though only a paragraph, this process took me hours to figure out. Even once I had all the right pieces in order, it took me a while to realize it as any little error completely throws the final result off. My favorite error was using an incorrect projection matrix formula the whole time and only realizing when making flashcards for a linear algebra test. Once I fixed that, the program worked. I had spent so much time doing research on different coordinate conversions and Kepler’s Laws, trying wild things, and over-thinking the whole process when I just needed to practice my linear algebra.
Components
After all this math, I now had the two values I needed. To rotate the pointer, I got two SG90 servos and to control them, I opted for an Arduino Nano, both due to their small sizes and expenses. The servos worked well, but they only had pi radians of motion, so they could only point the arrow in one hemisphere. As satellites are often below the horizon, I did some additional math so it would point in the exact opposite direction if the satellite was below the horizon. If the elevation angle is negative and the azimuth is greater than pi, pi is subtracted and if the azimuth is smaller, pi is added. After this step, the elevation and azimuth angles are adjusted to suit the servos that only have a range of pi. This is done where if the azimuth is greater than pi, it equals itself minus pi and the elevation angle is subtracted from pi for the new elevation.
For time and location information, I got a NEO-6M GPS module. This was a mistake. It takes a long time to get a lock on its position after being dead or moved to a new location. It cannot work inside or under covered areas, even under small trees. A better option would be a time board and either hardcoding the location or having the user enter it in a keypad. Satellite passes come quickly and I would not remember to have it sitting outside for fifteen minutes beforehand so it knows where it is.
I decided to hardcode the Keplerian elements, which means the Antenna Pointer needs to be manually updated every few days. This is because I wanted it to function without internet access, but going forward I would get a Wi-Fi module so updating the elements simply involves turning it on when it’s near Wi-Fi.
I found a simple 4 by 4 keypad to allow the user to select satellites and the whole thing was powered by a 5 volt powerbank meant for charging phones. I was not familiar with selecting batteries at the time and got something more advanced than I needed, which ended up hurting the process. The power bank would turn off after 15 seconds if it didn’t have enough current draw. While testing the servos and keypad, I thought I would have to scrap my plans for the battery, but it ended up being above the minimum with the NEO-6M. This created another problem of not being able to turn it off without unplugging it, which made it annoying to turn it on and off. It was also bulky and expensive for what I needed to power just two servos, a GPS, and a microprocessor.
Program
I was not as familiar with C, so I used MATLAB when coming up with my analysis for ease of testing. Once it was working, I translated it into C for use with the Arduino upon which it gave wildly different angles. I double-checked every line to make sure I didn’t miss anything, but everything seemed right. I went line-by-line to see where the one in C diverged. The first noticeable difference was in the Greenwich sidereal angle, which differed by 0.3 radians. This came from their Julian dates being slightly off, which amplified once it was put in the equation.
It looked like a rounding error and it was. Both MATLAB and C use “double” to describe a variable, but MATLAB’s is a 64 bit precision variable while C’s is only 32 bits. This becomes a problem when it gets to the Julian date. The epoch it is compared to is quite large, but it is the small numbers at the end the program cares about. C loses these numbers that correlate to the day, hour, and seconds and ends up with an entirely different set of angles. I was worried C wouldn’t be able to handle the precision I wanted, but realized the epoch was an arbitrary date. I changed the epoch to be more recent and the fix turned out to be as simple as subtracting a large constant when initially calculating the Julian date and excluding it from later equations.
Assembly
With the program and the parts working, it was on to assembly. I am ashamed to say I designed this ugly but utilitarian box for everything to fit in. There were no major problems and everything was working. I then unplugged my computer. I had been using it to print the values and monitor the NEO-6M data for testing. When I unplugged it, the Antenna Pointer decided it was done. The servos just twitched over and over.
They were resetting, which was probably a power issue since it worked when my computer was plugged in. The power bank had turned off at the beginning because of not enough current and now it seemed it couldn’t provide enough. I did what I should have done at the very beginning of the project and started looking for a better power solution. I went to my project document to look at the list I had made at the beginning. Right below the list of possible batteries were a few notes I had made about the problems of the power bank. What caught my eye in the list was a note saying adding a resistor had allowed me to test it with just the servos. I checked and the resistor was still there. I removed it and it worked. One small and silly problem lifted was all it took.
Result
The Antenna Pointer was fully functional, but I hadn’t tested if it worked. I knew it pointed at satellites, but did it serve its purpose of helping me point my antenna precisely enough to listen to them?
Before I could use my Antenna Pointer during an actual satellite pass, I had finals and went to an amateur radio camp straight after. There, I learned more about satellite communications and found how accurately I pointed my antenna was not the gigantic problem I had inflated it to be. It was a small problem piled on many other small problems that made my attempts not work, which was on theme for this entire project. I learned how to fix these problems and properly track satellites without relying on any tracking device. As I saw with the incorrect projection formula and again here, some problems do not need an over-thought or engineering solution. They just need practice.
What now? My Antenna Pointer was obsolete before ever seeing proper use. Luckily, I seem to keep running into inconveniences. While the device itself is now a decoration on my windowsill, the work I did on my analysis was not going to waste because I quickly found another problem.