Two Axis Star Tracker




This project is a two axis pointer, complemented by software to track any star in the sky. The software is also able to track the sun and the planets.

It should be noted that this project is a continuation of the single axis star tracker. In the instructable for that project, movement of stars is explained in some fair detail, as well as how I drive a stepper motor and (mis)use the real time clock as non-volatile RAM. I think this is an essential read to understand this project. This project takes the idea to the next level, moving the complex calculations from hardware into software and therefor enabling the tracker to track any star and planet, from any place on earth. Both the hardware as the software has become far more complex:

  • The hardware has evolved from a single axis, fixed angle, single speed system, to a true dual axis tracker under full software control.
  • The software has internalized all movements that were earlier calculated in an analog, hardware bound way..
  • Doing so enabled tracking of non-static objects (from the viewpoint of the earth), notably the planets, moon and sun)

Step 1: Some Additional Theory

Let's start with tracking a distant (static) star, just like the original star tracker. With the mental image of the earth rotating in the black sphere as the night sky, calculating in what direction a pointer should point is not very simple but conceptually not too complex either.

  1. Imagine you are on top of the North pole, Polaris straight above your head, staring to the horizon (meaning a declination of 0 degrees) in the direction of a Right Ascension of 0:00. It is now possible to find your star by rotating counter clockwise to it's RA and and stare up to the star's declination. Imagine setting a vector in that direction.
  2. Now correct the RA using the local sidereal time (LST). The beauty of the LST is that it incorporates both the rotation of the earh, changing with time, and at what longitude the observer is.
  3. Next tilt the vector over, based on ones own latitude, or to be more precise, based on how far south you are from the north pole, so 90 degrees minus the latitude.

The initial vector pointing to the star can be easily calculate using straightforward trigonometry math, producing x, y and z coordinates.

The two rotations can be performed by doing two matrix multiplications.

Finally, the three components of the resulting vector, now in the azimuthal 3D space, are converted back to an azimuth angle (the rotation of the observer on the ground in his location relative to the north) and an altitude angle, how far to look up from the horizon, and these correspond to the position of both stepper motors.

Using the software I created for the original star finder, but now for two motors, one for azimuth and one for altitude, we can point a physical pointer to the star of your choice, from any location on the earth.

Calculation of the solar system objects is rather complex, involving calculating the position on their elliptic trajectory and making further refinements (pertubations) for objects that are influenced by others, i.e. for the moon the position of the Sun, and for Saturn the position of Jupiter. Also, for the planets we need to have the vectors of both Sun as well as the object relative to the Sun. These calculations are taken from this great article by Paul Schlyter. The end result of these calculations are given again in a RA / Dec pair and these are fed in the same transformation routine as for stars.

Step 2: The Hardware

The hardware, just like the one axis tracker, is build in a candy can. The main difference is it has two stepper motors.

One motor is mounted inside the can, rotating a vertical axle that points straight up. This motor controls the azimuth of the pointer. The vertical axle is a brass tube with an inner diameter of 5 millimeter, an exact fit on the stepper motor. I glued it on the motor using more two component resin.

I drilled two 3.5 mm holes in the side of the pipe to guide the wires from the second motor through. I had to cut off the connector and soldered it on again later. The lower motor was mounted on two long bolts to create a bit of space where the wires of the upper motor could freely curl while rotating. As you can see in the picture, I glued the two 3mm bolts to the cap, but this broke off later. I created some extra surface area using a small piece of PCB, but you can also use for instance washers.

I glued the side of the second altitude motor to the side of the vertical brass tube.

Finally I made a pointer from some straight wire and a tiny piece of the same brass tubing.

With the exception of now needing two motor driver PCBs instead of one, the components used are basically the same as the one axis tracker.

Step 3: The Electronic Parts and Schematic

Part list:

  • An Arduino pro mini, or clone. Make sure the processor is a 328P version;
  • A LiPo battery, i.e. an old phone battery. I used a 18650 type cell from a small power bank;
  • A TP4056 charger PCB;
  • A DS3231 precision real time clock PCB;
  • Two 28BYJ-48 Stepper motor with ULN2003 driver PCB;
  • A small power switch;
  • A small pushbutton switch for motor calibration;
  • An active piezo beeper.

Like the single axis tracker, I removed the power LED and the power regulator from the Arduino PCB.

The schematic should be pretty self explanatory. All components are driven by the Arduino and the power switch alternates between connecting the battery to either the charger or to the other components. Have a look at step 5 of the single axis star finder for addition details.

Notice there is quite a bit of wiring involved. I would recommend to solder one side of the wires before gluing in the PCB's.

Step 4: The Software

The software is complex but pretty self explanatory. There are blocks for power management and handling the RT clock that you can safely skip. Also the routines to drive the motors can be regarded as black boxes that "just work", though you can delve in and read the details.

A few components though are worth mentioning.

Sidereal time is calculated by taking the real time in milliseconds, subtracting a known date-time where the Greenwich sidereal time is 0:00, compensating for the latitude and then taking that value modulo the length of a sidereal day.

Transformation from Right Ascension / Declination to Azimuth / Altitude is handled by a separate routine. Since the RA / Dec of stars is static, this is enough for star tracking.

Calculation of the solar system objects is done using the algorithms decribed in Paul Schlyter's article that I linked to earlier. It is programmed in one long routine called getObject, resulting in setting the globals object_ra and object_dc. Every part of the routine has a reference to the relevant part of said article. Note that other than the article, all calculations use rads as angle units.

The main loop checks for the battery voltage, moves the pointer and sleeps for approximately 40 seconds.

Step 5: First Time Boot Up and Calibrating

The first thing to do is set the clock. There is a small companion sketch to do this, described in the single axis tracker instructable.

Next load the companion firmware into the Arduino Pro Mini. Now, before doing so for the first time, I strongly recommend to unplug the two motors from their respective driver boards. Reason is the position of the motors is unknown and it will probably try to rotate the motors several revolutions driving the pointer into the can and/or ripping the wire of the altitude motor. Next, check that the azimuth motor can make at least one full rotation in either direction and that the pointer is in a full up position. Reconnect the motors and power up the device.

If everything goes well it emits two short beeps and rotates the pointer through three positions.

Now press and hold the calibration switch until it beeps once, then let go. The pointer will rotate to a position that should correspond to the north. You can change the azimuth pressing the button. It will change direction between each press and will move faster if you hold it for more than a second. Be careful not to wind up the wires for the altitude motor too far. It should be able to rotate freely for at least half a rotation on both direction, preferably a bit more.

If you don't press the button for 5 seconds, it will do the same for altitude: the pointer will move to a position that should correspond to horizontal. Use the button again to get it horizontal. Again, take care not to move the pointer too low against the can.

As before, if you don't press the button for 5 seconds, it will move on to selecting the object you want to track. This is indicated by 2 very fast beeps, followed by a one short beep. This indicates object 1 (the sun). Pressing the button selects 2 (Mercury), 3 (Venus), 4 (the moon), 5 (Mars) etcetera all the way up to Neptune (9). The next three objects are the stars Arcturus (10), Dubhe (11) and Vega (12), after which it will cycle back to 1 (sun).

The following step is the location, indicated by 3 very fast beeps. There are 3 locations pre-programmed, and you should put you own latitude and longitude in the firmware. I have put in the locations of the Nordkapp in Norway and Singapore to show the effect of these extreme latitudes.

Finally, there is a demo mode, indicated by 4 very fast beeps. If you press the button within 5 seconds, the tracker will show the movement of the selected object from the selected location as fast as it can. Any button press while it is running puts it back to the select object state.

When all is set, simply reboot. It will first beep, then rotate to the north, horizontal altitude, then to it's minimum altitude, then to the position of the object.


2 People Made This Project!


  • Barbecue Challenge

    Barbecue Challenge
  • Backyard Contest

    Backyard Contest
  • Games Contest

    Games Contest

10 Discussions


2 years ago

Hey yoh,

I built your thing, cool - kinda. I had to add #include <TimeLib.h> to get

setSyncProvider (RTC.get); to compile. Also, it doesn't matter which object or location I choose, it points to the same place. Motors work, sequencing works (object, location, demo mode), and what ever it thinks it's pointing to it tracks it. Thoughts?

1 reply

Reply 2 years ago


First of all: cool you made it!

Second: picture (or video) or it didn't happen ;-)

So if it is in normal mode it tracks "something" too (you're looking at a subtle step every minute to two minutes or so), noticable if you keep it in your hand. At least that would exclude a clock problem.

I suspect a problem with your EEPROM, so it reverts to the same object. To check that, set an object, then reboot. It should beep the same number of times (and the same for the ocation index).

If that doesn't help, please document the changes you made (processor, pin usage, RT clock, sogtware, etc etc), as it is happily sitting next to me doing it's thing very dilligently.


2 years ago

Good stuff. I'm going to try to adapt to a go to control for a small telescope. But where did you get the DS3232RTC.h from? I bought the DS3231 from AdaFruit, but the driver they have posted is different. RTClib.h.

2 replies

2 years ago

Great work. But from the comments I understand you had no previous astronomy knowledge??? I am impressed

2 replies

Reply 2 years ago

Thank you! Knowledge, just on the level of "how things work", gravity and all, teaching kids about the size of things and motions. But nothing about i.e. sidereal time, math of elliptic trajectories and all. In all honesty, I borrowed all hard core math from Paul Schlyrer.


Reply 2 years ago

and thn to even think of making something like that :-)

yoh-thereAnirudh Ralhan

Reply 2 years ago

Thank you. This was a really fun project to do. I (re)learned a ton on vector math and astronomy along the way.