Star Track - Arduino Powered Star Pointer and Tracker




Introduction: Star Track - Arduino Powered Star Pointer and Tracker

About: Try again. Fail again. Fail better

Star track is an Arduino based, GoTo-mount inspired star tracking system. It can point and track any object in the sky(Celestial coordinates are given as input) with 2 Arduinos, a gyro,RTC module,two low-cost stepper motors and a 3D printed structure.

In the first step, I'm going to introduce you to the basics of Positional Astronomy. Next, I'll explain the idea behind this project. I'll give you the Tinkercad links for the 3d printed parts. So you can edit them to your preferences. Also, I'll include a troubleshooting guide based on the problems I encountered during this build. This way you don't have to build the same thing. Maybe you can find a better algorithm to track the stars. Or you can develop the structure and use bigger motors to drive a telescope? Your imagination (and resources of course :')) is the limit. Let me know about your build!


This instructables was featured on,


Arduino's official blog


This project includes laser pointers thus needs safety measures before use. In many countries, it is illegal to point lasers to an Aircraft and to use them near airports. For more information please check:


You can use a cheap red dot sight instead of the laser. This will avoid all the issues with the laser (eye safety, legal issues, airplanes).( thanks for the feedback of Marty on Hackaday)

Step 1: A Little Bit of Positional Astronomy

In order to track the stars, you have to know the basics of the Celestial Coordinate System. Celestial coordinates define positions of objects in the sky. It's based on the observations of ancient astronomers. They believed that the earth was motionless and at the center of the universe. The sky, they thought , was a moving sphere surrounding Earth, a celestial sphere.[1] In its modern sense, as used in astronomy and navigation, the celestial sphere is an imaginary rotating sphere of undefined radius. All objects in the sky can be thought of as lying upon the sphere.[2] Unlike planets, since the distance between stars and Earth is gigantic, we can simplify the positions of the stars by projecting them on an imaginary sphere.

There are differents ways to specify a objects location on the celestial sphere, These differ in their choice of fundamental plane, which divides the celestial sphere into two equal hemispheres along a great circle.

Each coordinate system is named for its choice of fundamental plane:

  1. Horizontal system
  2. Equatorial system
  3. Ecliptic system
  4. Galactic system
  5. Supergalactic system

Equatorial System

I chose the Equatorial system for this project. Because the altitude and azimuth of a star are constantly changing, it is not possible to use the horizontal coordinate system in a catalogue of positions. And since this project will track the objects in the sky based on the coordinates given. we need a coordinate system for cataloguing purposes. One based on the celestial equator and the celestial poles and defined in a similar manner to latitude and longitude on the surface of the Earth. In this system, known as the equatorial coordinate system, the position of an object is defined by the declination and right ascension. And the coordinates of an object in the sky do not change relative to your position.[3]

Equatorial Coordinates on Celestial sphere

Like Earth, the celestial sphere also has an equator, north pole and a south pole called celestial equator, celestial north pole, and celestial south pole. These are just projections of Earths equator,north pole and a south pole on the celestial sphere.

Like coordinates on earth (longitude and latitude), two coordinates define a point on the celestial sphere, Declination, and Right Ascension.


The coordinate indicating where an object is between the celestial poles is declination. Measured from the celestial equator it ranges from 0° to 90° at the north celestial pole and to -90° at the south celestial pole.[4]

Right Ascension

The second coordinate Right Ascension(RA). It is like (but not the same as) longitude. It locates where a star is along the celestial equator. It has a zero reference point like green which, called the Vernal Equinox Point (we will get into locating that later).[4] Unlike Declination, Right Ascension changes with time(rotation of the earth) And the coordinate of Right Ascension is not in degrees but in hours minutes and seconds. The celestial sphere will make a full rotation in 24h sidereal time (ie if a stars coordinates are 20 dec, 5h RA. After 2 hours the coordinates will be 20dec,7hRA.) Since 360/24=15 1 hour of RA is 15 degrees.

Sidereal Time

Sidereal time is different than solar time. A sidereal day is about 4 minutes less than a solar day. Because of the Earths orbit around the sun. I'm not going into details on how to calculate Sidereal time. I will include some links below if you are interested. You can use a Sidereal calculator. Local Sidereal Time (LST) indicates the Right Ascension on the sky that is currently crossing the Local Meridian. So, if a star has a Right Ascension of 05h 32m 24s, it will be on your meridian at LST=05:32:24.[5] In other words, if you face the north at 0h Local Sidereal Time. the Vernal Equinox Point(0h Ra) will be right above you. to understand it more clearly open this animation

select your location and hit start animation, You will see a line rotating. when that line is above the stick figure it is 0h Local sidereal time.

Here is a demonstration of Equatorial Coordinates on Celestial sphere by UNL Astronomy.

Celestial-Equatorial (RA/Dec) Demonstrator

How to Locate the North Celestial Pole

Now we know the coordinate system of the celestial sphere. But how do we locate a reference point to use our coordinate system? The North Celestial Pole will only change with your latitude. And can be located easily by the north star. Here is an interactive demonstration, you can change the latitude and hit the switch so you can see where the celestial sphere is located.

Celestial and Horizon Systems Comparison

Also here you can animate the movement of an object on the celestial sphere:

Coordinate Systems Comparison


I did not get into details since this is something like an introduction to positional astronomy. If you want to learn more I will include the links that were really helpful for me. There are also problems that you can solve to practice what you have learned. This way you will be able to calculate the coordinates of a star with a given latitude and time.

Further Reading:

History -

RA and DEC -

Celestial Sphere -

Coordinate Systems -

Celestial Coordinates -

Finding Astronomical Objects - .

Local Side Real Clock converter -

How to Calculate Sidereal time -







Step 2: The Idea

Many computerized telescopes have a type of telescope mount and related software which can automatically point a telescope to astronomical objects that the user selects. Called GoTo mounts. Like a standard equatorial mount, equatorial GoTo mounts can track the night sky by driving the right-ascension axis[1]

Since laser pointers are a perfect way to point stars, I thought a laser pointer with a GoTo mount would be a perfect tool for locating stars and to track them.

First I had to design a 2-axis mount.

  1. 360-degree rotating axis for RA
  2. A up-down axis for DEC

After aligning the RA axis with the North Celestial Pole, an Arduino connected with an RTC should be able to calculate and track RA with sidereal time. And you can adjust the 2 axes to the user input from a computer via serial.

But first I had to find a way to precisely point the mount to given degrees. The main idea was to use step motors and give them a specific step to take. But after a few tests I found out that the pointing was not accurate(a few degrees).

Instead, I used a gyroscope placed on the laser pointer to track the degrees on the two axes, this way I was able to send a command to the step motor to start and stop the movement if necessary.

Step 3: Tools & Parts

I used two Arduino's in this project(due to the lack of digital pins).One to control the motors, the other to process the gyro data and send commands to the other Arduino(Master-slave) I had an Uno and nano lying around so I used them. You can use other Arduino's as well.

Here are the main parts I used in this project:

5v Stepper Motor(x2) - 3.68$

Arduino Uno r3 clone - 5.80$

Arduino nano clone- 2.18$

3-Axis Gyro - 2.03$

RTC - 1.07$


Total - 14,76$


  • Lots of jumper cables
  • 30x47x11mm thrust ball bearing(again you can use a bearing you like but have to change the dimension on the parts.)
  • (10x) M3 bolts and nuts
  • (4x) 623 2RS bearings (I had these bearings at the moment. You can use any bearing, but you have to adjust the pieces from tinkercad to your dimensions.
  • X-acto knife
  • Superglue
  • A laser pointer(recommended)

Step 4: Designing the Parts

The first part to design is the base. I thought of a delta type base plate so I can attach 3 legs and adjust them. Here is the Base plate You can edit it on tinkercad as you like. I will also include all .stl files in a zip folder.

The Base

Base Screw

Tripod Mount (Attached to the base)

Pitch(DEC) Mount

Gyro Mount

The Base Gear

Note: I'm giving these tinkercad links so you can change the parts to your preferences. All the other files including these are in the folder.

The Gears

Now for the most important part, designing the gears. I tried to create the gears in Autodesk Inventor but later I found a gear generator tool that generates gears to a .stl file. This was a life-saver for me.

I printed the parts with a prusa i3 3d printer.

Step 5: Assembly-Base Structure

Step 6: Assembly - Electronics

Step 7: Code

How Does it Work?

There are two Arduino's working in order. Arduino Uno being master and nano being the slave.

Master module

The master(Uno) module has two inputs,

  1. Gyro data
  2. RTC(Real Time Clock) data

and 6 outputs,

  1. cw(base motor clockwise)
  2. ccw(base motor counter clockwise)
  3. stahp(base motor stop)
  4. cw2(DEC motor clockwise)
  5. ccw2(DEC motor counter clockwise)
  6. stahp2(DEC motor stop)

The RTC is set to UTC time, a function calculates local sidereal time in degrees and rotates the mount to 0h RA position. The loop constantly checks if the gyro data is equal to the user input & sidereal time data. The default is 0,0. If there is a change and the equality breaks the master module send a command to the slave module.

  • If the user value is higher than the gyro value a signal is sent through cw the motor turns clockwise.
  • If the user value is less than the gyro value a signal is sent through ccw the motor turns counter clockwise
  • If the user value is equal to the gyro value a signal is sent through stahp and the motor stops

same for cw2,ccw2,stahp2.

This way the mount will turn to the user-specified coordinates. And update with sidereal time thus it will track the sky.

Note: I could use serial communication between the two Arduino's but since the analog pins are used by the inputs I had to use digital pins.

I uploaded the code to github so I can update it from one place:

Master module code:

This is the source code for the master-module of Star Track.
Required Libraries:

Created 20 July 2016 by Görkem Bozkurt
#include <virtuabotixRTC.h>
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
//define RTC.
virtuabotixRTC myRTC(A0, A1, A2);
double M,Y,D,MN,H,S;
double A,B;
double location =32.88;//your longtitude
double LST_degrees;//variable to store local side real time(LST) in degrees.
double LST_hours;//variable to store local side real time(LST) in decimal hours.
unsigned long timer = 0;
float timeStep = 0.01;
// Pitch and Yaw values
double pitch = 0;
double yaw = 0;
double val = 0;//variable to store the user input DEC
double val2 = 0;//variable to store the user input RA
double temp = val2;//temporary value to store val2
const int stahp=7,stahp2=10;
const int cw=8,cw2=11;
const int ccw=6,ccw2=9;
void setup() {
//set date-time according to (seconds, minutes, hours, day of the week, day of the month, month, year)
myRTC.setDS1302Time(00, 38, 23, 5, 27, 7, 2016);
delay(5000);//wait before starting
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
}//--(end setup )---
void loop()
//this will update the RA degrees with sidereal time 1degree at a time
//this way the object or star on the sky is tracked.
if( floor(LST_degrees)==LST_degrees ){
if (LST_degrees>180){
val2 = temp+(360-LST_degrees);
val2 = temp-LST_degrees;

timer = millis();
Vector norm = mpu.readNormalizeGyro();
//I've put the sensor with a 90 degree angle on the setup due to
//cable connection problems. Because of that the data values from the mpu6050 chip are
//different in this case:
//roll data(X-axis) is pitch.
//pitch data(Y-axis) is yaw.
yaw = yaw + norm.YAxis * timeStep;
pitch = pitch + norm.XAxis * timeStep;
Serial.print(" Yaw = ");
Serial.print(" Pitch = ");
Serial.print(" LST_d = ");
Serial.print(" LST_h = ");
Serial.println(LST_hours);//local sidereal time in decimal hours.
delay((timeStep*1000) - (millis() - timer));//timer for the gyro.
void recvdata(){
//This function receives data from serial as (0.00,0.00)
//splits it to strings by the comma ","
//than converts them to doubles
if (Serial.available() > 0){
String a= Serial.readString();
String value1, value2;
// For loop which will separate the String in parts
// and assign them the the variables we declare
for (int i = 0; i < a.length(); i++) {
if (a.substring(i, i+1) == ",") {
value2 = a.substring(0, i);
value1= a.substring(i+1);
temp = val2;
void pitch_check(){
//check if pitch is high, low or equal to the user input
//send commands to slave-module to start and stop motors
void yaw_check(){
//check if yaw is high, low or equal to the user input
//send commands to slave-module to start and stop motors
void LST_time(){
//Calculates local sidereal time based on this calculation,
M = (double) myRTC.month;
Y = (double) myRTC.year;
D = (double) myRTC.dayofmonth;
MN = (double) myRTC.minutes;
H = (double) myRTC.hours;
S = (double) myRTC.seconds;
A = (double)(Y-2000)*365.242199;
B = (double)(M-1)*30.4368499;
double JDN2000=A+B+(D-1)+myRTC.hours/24;
double decimal_time = H+(MN/60)+(S/3600) ;
double LST = 100.46 + 0.985647 * JDN2000 + location + 15*decimal_time;
LST_degrees = (LST-(floor(LST/360)*360));
LST_hours = LST_degrees/15;

Slave Module:

this is the source code for the slave module of Star Track
Required Libraries:
Created 20 July 2016 by Görkem Bozkurt
#include <AccelStepper.h>
#define HALFSTEP 8
#include <Wire.h>
// Motor pin definitions
#define motorPin1 2 // IN1 on the ULN2003 driver 1
#define motorPin2 3 // IN2 on the ULN2003 driver 1
#define motorPin3 4 // IN3 on the ULN2003 driver 1
#define motorPin4 5 // IN4 on the ULN2003 driver 1

#define motorPin5 A0 // IN1 on the ULN2003 driver 1
#define motorPin6 A1 // IN2 on the ULN2003 driver 1
#define motorPin7 A2 // IN3 on the ULN2003 driver 1
#define motorPin8 A3 // IN4 on the ULN2003 driver 1
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8);

int stahp = 7,stahp2=10;
int cw = 6,cw2 = 11;
int ccw = 8,ccw2=9;

boolean stopped = false;
boolean stopped2 = false;
void setup() {
}//--(end setup )---
void loop()

void motor_roll(){
stopped = true;
}else{ if(digitalRead(cw)==HIGH){
stopped = false;
stopped = false;
void motor_pitch(){
stopped2 = true;
}else{ if(digitalRead(cw2)==HIGH){
stopped2 = false;
stopped2 = false;


The slave module has 6 inputs from the master module with the same names. And drives the motors.

Slave Module code:

Step 8: First Test

We assembled the base and connected the electronics, now for the first test(indoor),

-Upload the master and slave codes to the Arduino's.

master ==> uno

slave ==> nano

-Connect the Arduino Uno to the computer and open the serial monitor .You will see 4 values printed to the serial monitor,

Yaw ==> RA value in degrees

Pitch ==> DEC value in degrees

LST_d ==> Local Sidereal Time in degrees

LST_h ==> Local Sidereal Time in decimal hours

When you first plug in the Arduino it will wait for 5 seconds. Then it will update the RA(yaw) value to your local sidereal time. After it is done it will continue to update the RA value 1 degree at a time.

Let's input 0,0 to the serial monitor.

When you try to move the mount, it will adjust itself to yaw=0, pitch=0.

Now let's try an input like 5.00,5.00(5 degrees DEC,5 degrees RA). The motors should position the mount at 5,5. degrees. If you encounter any problems check the next step.

Step 9: Troubleshooting

-The steppers are just vibrating

Check the connections of your stepper to the Arduino, different steppers have different pin outputs.

-The steppers start to wiggle when they arrive at the specified position

If your stepper speed is too fast it will struggle to stop at the position specified. Edit the speed of the stepper on the slave module(slave.ino) to something like 50-75.

-RA is not updating

Check the coin-cell battery on the RTC or the connections between the Arduino.

-RA-DEC values do not update(stuck at 0).

The gyro is the main cause of his problem (in my case it was). this is why I put 5 seconds of delay, in the beginning, this way there was no problem. If yıu find another way please let me know.

If you encounter any problem during the build let me know(Even if you solved the problem). So I can put it here.

Step 10: Final Assembly & Tracking

After assembling mount it to a tripod and go outside. The tripod will be a major tool because you will use it to align the setup with the north celestial pole.

After going outside away from city lights, adjust the Laser to an upright position by turning the motor with your hand.

Adjust the base gear so the RTC module is faced north.

Adjust the tripod angle while the laser is on and at an upright position, it should point the north star. If you can not see the north star you can use a phone app like sky map.

Plug in your Arduino to the setup. And wait while the RA degrees update.

Now you are all set. The laser pointer is now pointing 90 DEC,0 RA on the celestial sphere.

Tracking a star

There are huge star databases you can use. I will include the links below but for now, I will use Wikipedia for the coordinates of the star Arcturus. the coordinates of Arcturus are 14h 15m 39.7s , 19° 10′ 56″ first we have to convert this data to degrees, so our setup can process it.I used

the result is: RA: 213.9167 DEC: 19.1822

You can put this values into the serial monitor like this 213.9167,19.1822

and the setup will start to point and track that object/star.


Step 11: What's Next

There are lots of things to improve on this project. My main goals for a later version are,

  • Star database integrated into an android app. You will be able to choose a star. The data will be sent through Bluetooth to the Arduino as RA degrees, DEC degrees.
  • Laser on/off switch with a servo. After the user input, the laser will be turned on for 3-5 seconds to point the star(currently you have to press it manually)
  • more powerful motors and a bigger mount for a DSLR camera (maybe?)
  • Bigger gear ratios for precise locations.
  • Getting time and location data from a GPS module(currently, those are entered manually)

I hope you enjoyed this project as I did and learned something from it. If you find a mistake in the code or wrong information of any kind please let me know. All questions are welcome!

You can also contact me at:

Space Contest 2016

Grand Prize in the
Space Contest 2016

Maker Olympics Contest 2016

Participated in the
Maker Olympics Contest 2016

Be the First to Share


    • Chocolate Challenge

      Chocolate Challenge
    • Make It Modular: Student Design Challenge

      Make It Modular: Student Design Challenge
    • Stone Concrete Cement Contest

      Stone Concrete Cement Contest



    Question 14 days ago on Step 9

    quick question, how are you powering this? I've hooked a 5v 3a power supply to the slave board, and connected the uno to my PC. Just wanted to make sure this was the correct way of doing it? Thanks!


    5 years ago

    the master program getting the following error:

    master:42: error: 'class MPU6050' has no member named 'begin'

    while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))


    master:42: error: 'MPU6050_SCALE_2000DPS' was not declared in this scope

    while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))


    Reply 4 months ago

    The link seems to be inaccessible and can you update a new one? Thanks a lot!


    Reply 5 years ago

    Thanks, now works correctly


    Question 5 months ago on Step 11

    Bonjour, est-il possible de pouvoir m’envoyer le fichier DEC_mount. FCStd pour que je puisse le modifier et l’adapter pour un objectif photo merci à vous François


    Question 7 months ago

    When trying to compile the "master" script, I get this "Error opening serial port 'COM5'. (Port busy)". The "slave" script compiled okay. I just can not disconnect the busy port.
    I have tried two different PC's with identical errors.
    The Arduino IDE ver 1.8.16 is being used on a Due board and I have tried to disconnect the various ports that I have tried on both PCs.
    I'm stumped! Any suggestions?


    Question 1 year ago on Step 6

    Hi, do you have the fritzing document? I need to know where do i find the motors in the fritzing parts.


    1 year ago

    Hi, as i live in the southern hemisphere, do i have to change something in the code? Thanks


    Question 2 years ago

    Hello, so I built this on my desk. and it is a cool project, but I am having trouble as I am using Nema17 steppers and Drv8833 stepper controllers. is there any way I can adapt this code to work? Any help would be greatly appreciated.


    Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Uno"
    In file included from C:\Users\Reaper\Desktop\code startracker\Star-Track-master\master\master.ino:11:0:
    C:\Users\Reaper\Documents\Arduino\libraries\MPU6050/MPU6050.h:40:20: fatal error: I2Cdev.h: No such file or directory
    compilation terminated.
    exit status 1

    Error compiling for board Arduino/Genuino Uno.
    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

    Any suggestions with that error? Thanks!


    Reply 2 years ago

    Have you imported the library for the MPU6050? Without that library, the #include line will get confused.


    2 years ago

    I'm using Arduino mega any help on combining the master and slave codes


    2 years ago

    Yes I've built this, but there isn't enough information to understand what's going on. It's great that someone was able to figure this out, really wish someone would take the time to explain it so that it could be used.

    Jose LuisO14
    Jose LuisO14

    Question 2 years ago

    Has anyone attempted to build this project on a non-Arduino device? I am thinking of ESP8266 or ESP32 with Arduino bootloader, so it programmed "as an Arduino" and this code should work. They have higher speed clocks, so timings could be different.


    3 years ago

    Hi! Great Project! But I've a problem: Idon't find the virtuabotixRTC library.

    The site doesn't load.

    Can you help me?

    Thanks for the support


    Question 3 years ago

    I am having problem with the codes for this project need help please


    Question 3 years ago on Step 6

    Where is the power being supplied from