Introduction: A 24 Hour Sundial That Follows the Sun’s Exact Path Across the Sky Using Two Stepper Motors

For most of history, the Sun defined time. A sundial (in Dutch zonnewijzer - literally “sun pointer”) shows the passing hours by the position of the Sun’s shadow across a set of engraved lines. But this project turns that idea around. Instead of using the Sun to tell the time, this reverse sundial uses time to point to the Sun.

By tracking the Earth's rotation and orbit with two small motors, the pointer continuously turns to face the real Sun, wherever it is in the sky.

The core of the mechanism is the central axis. This represents the Earth's daily rotation. It points north and is tilted so it runs parallel to the Earth's own axis, which means it is set at the same angle as the local latitude above the horizontal. As it turns once every 24 hours, it mimics the spin of our planet.

Halfway along this axle is a small bend of 23.4 degrees, matching the tilt of the Earth's axis relative to its orbit around the Sun. At the end of this tilted section sits the arrow, which completes one slow rotation per year. Together, the two motions, daily and yearly, recreate the geometry of the Earth and the Sun, allowing the arrow to always point precisely toward the real Sun in the sky.


More exactly the main axis rotates in 23h56m, the time it
takes for the earth to rotate once. The difference with 24h
is taken up by the movement of the earth around the sun,
and that is the slow rotation of the arrow above the bend.


If sunlight were shining, the shadow of the main axle would move across the 24-hour scale, showing the local time just like a traditional sundial. Even when the Sun has set, the pointer still shows where that shadow would be, telling you the time, day and night. This makes my little art piece a



24 hour sundial








Supplies

  1. Real Time Clock module with DS3231 chip (various places, I got mine from aliexpress )
  2. Seeed XIAO esp32C6 (seeedstudio)
  3. 2 x stepper motor controller TMC2209
  4. 2 x stepper motor with brass gear from aliexpress
  5. 330 Ω resistor
  6. led arrow, also from aliexpress
  7. 8 cm of PTFE tube, 1.6mm outer diameter, 0.8mm inner diameter aliexpress
  8. Gear with 48 T and modulo 0.5. You can print your own or get one ready-made (many sellers on aliexpress, search for 482A gear)
  9. brass tube 3mm outer diameter, 2mm inner diameter, 60-70 mm length
  10. brass tube 5mm outer diameter, 3mm inner diameter 15-17 mm length
  11. brass tube 5mm outer diameter, 3mm inner diameter 5-6 mm length.
  12. spring steel wire 0.4- 0.6 mm diameter 80mm (aliexpress)

and you need a 3d printer for the housing.

Step 1: Electronics

The electronics are built around a Seeed Studio ESP32-C6. There are two TMC 2209 stepper motor controllers and the space in the base is big enough so one can go the right of the esp32 and the other to the left. The Real Time Clock board is small enough to fit anywhere in the base. Except for the esp32, which USB port clicks into place in the base, the other circuits are just "floating" in the base, or you could use some hot glue to fix them. (I didn't, my wires were pretty stiff, and I put some isolating tape around the boards to prevent problems).

Follow the schematic when soldering the connections.

There are special connections to be made to get power to the arrow.

The arrow has two small copper tabs. Clean them lightly before soldering. One tab has a minus sign on it; that is the one that will carry the negative lead. Do not solder the tabs yet, because the arrow has to be assembled into the mechanism first, but this is the right place in the instructable to explain how the power path works.

The positive power of the arrow flows through the brass tube, and you need to connect a wire from 5V to the brass 5 mm tube. (seen in the picture already in place with the printed part of the main frame). The negative return path goes through the steel wire that runs from motor A to the arrow. To make that happen you solder the output of the 330 Ohm resister straight to the metal gearbox of motor A. The other end of the resistor goes to ground (GND).


One last note about the schematic: motor A and its TMC2209 are on the right side of the ESP32, both in the wiring diagram and in the physical layout. Motor B and its controller sit on the left. This matches the orientation shown in the diagram and helps keep the wiring manageable.

Step 2: 3d Print

I have included five STL files.

The first part is the main frame that holds the motors and gears in place. I designed it to be as compact as possible. It consists of two items that slide together. It had to be split this way so you can mount the motor and the gear before closing it up. It has four pins that hold the motor in place. After assembly, you need something hot, and melt the top of the pins to keep the motors securely in place.

The next two parts form the housing: a cylindrical shell with an engraved top, and a separate bottom plate. These are included mainly as examples. You will need to adapt them to your own location, since both latitude and longitude affect the design.

  1. Your latitude sets the tilt of the central axle. The axle must sit at the same angle as your latitude so it stays parallel to the Earth’s axis. Your housing needs enough space and the right geometry to hold the main frame at that angle.
  2. Your longitude defines how far you are from the center of your time zone. This affects the placement of the hour lines on the top plate. If you want your 24h sundial to actually show the local time, look at the decoration step before printing the housing.

Make sure the housing has enough internal clearance for the tilted axle and enough room to slide the main frame into place. When the sundial is in use, the USB port of the ESP32 should point exactly north.

The fourth STL is the gear that links the main axle to the small motor gear. You can print this gear, or use a standard gear. If you use a store-bought gear, drill a 2.9 mm hole in the center. A round file can help fine-tune the fit, but it should have a tight fit on the 3mm axle.

The Final part is just a tool to bend the brass axis at exactly 23.4 degrees.

My original plan was to spray-paint it with a chrome finish (after several layers of spray filler and sanding up to 5000 grit), but after several tries I could not get the desired result. n the end I painted it black, which made me realize I could have saved a lot of work by printing it in black to begin with.


Alternatively, you could just use my design, but then you have to put something underneath it, so the main axle is parallel to the earth axis (the angle should be your latitude). Make sure you point it North.


Step 3: Brass Parts

You need three brass parts for the mechanism.

The first is a piece of 3 mm brass tube (with a 2 mm inner diameter) about 60 mm long. The exact length is not critical. Near the top, this tube needs a bend of exactly 23.4 degrees, matching the tilt of the Earth’s axis. The printed bending tool makes this easy. While bending, I slid the PTFE tube and the steel wire inside the brass tube. This keeps the brass from kinking or collapsing.

The other two parts are short sections of 5 mm brass tube with a 3 mm inner opening. One is about 15–17 mm long and the other about 5–6 mm long. The 3 mm tube must be able to rotate inside these pieces with minimal clearance, because they also act as electrical contacts. In my case the dimensions were not perfect: my 5 mm tube did not have a true 3 mm opening, and the 3 mm tube itself was slightly undersized. I drilled a 2.9 mm hole into the 5 mm tube, then sanded the 3 mm tube very lightly until it turned smoothly while still making good contact.

The shorter 5 mm tube needs a slit on one side. Use a fine jigsaw blade and cut only partway down the tube, not the full length. The center tab on the arrow will fit into this slit during final assembly and it should rotate smoothly when placed on top of the 3mm tube as seen in the picture.

Step 4: Spring Steel Wire

The arrow rotates by means of a spring steel wire that connects directly to the axle of motor A. Start by cleaning the small motor gear with a file or fine sandpaper so the solder has something to grip. Cut a piece of steel wire about 100 mm long and form a tiny hook, roughly 2 mm, on one end. Place this hook over the gear so the wire sits exactly in the center and points straight upward. Once the alignment looks right, solder the hook to the gear.

In one of my early prototypes the arrow flickered while rotating, and the cause turned out to be this very connection. Spring steel wire does not like solder easily (at least not on Fridays), so take your time and make sure the joint is solid.

The arrow receives its power through the brass tube (positive) and the steel wire (negative), so the wire must not touch the brass. Slide a thin PTFE tube over the steel wire to keep it insulated all the way up.

Step 5: Decorations

You can skip this part if you only want a pointer that follows the Sun. But if you also want to read the time from the top plate, you will need hour markings, and those depend on your latitude and longitude.

To find the angles for the hour engravings, use the formula:

θ = atan( sin(lat) * tan( 15 * (T - 12) + (15 * timezone - long) ) )

Where:

  1. θ is the angle of the hour line from the north line (degrees; positive toward the west/afternoon side)
  2. lat is the latitude in degrees (positive north)
  3. long is your longitude in degrees (positive east)
  4. timezone is your time zone offset from UTC (for example, +1 for CET, 0 for UTC, −5 for EST)
  5. T = local time in hours.

Compute this for T = 0 through 23 to get the full set of hour-line angles.

For my location (lat = 53.22, long = 6.57 E, timezone = +1) this gives the following values from 00:00 to 24:00:

−173.23, −160.86, −147.56, −132.81, −116.27, −98.18, −79.52, −61.58, −45.27, −30.72, −17.57, −5.27, 6.77, 19.14, 32.44, 47.19, 63.73, 81.82, 100.48, 118.42, 134.73, 149.28, 162.43, 174.73.

As you can see, at noon (12:00) the angle is 6.77. That offset matches how far my longitude is from the center of the CET time zone.

I glued some 1mm brass rod pieces into the position of the hour lines.


Later I decided to engrave the top in brass, instead of 3d
printing it. I wrote a python script that generates the image
to engrave, based on the longitude, latitude and timezone.
It is attached to this step. edit your location and run it.
It will generate dial.png and dial.svg. Choose whichever you
want to use. North direction is exactly up in these pictures.
The description of the brass version is at the end of this.

Step 6: Assembly

With all the wiring and printing finished, you can start putting everything together.

Put the motors in the main-frame, slide the gear over the spring steal wire. Slide the other part of the main frame over the wire and snap it into place. There is a small hole that lets you lock the frame with a tiny screw.

Next, slide the longer 5mm brass tube over the spring steal wire. Then push everything into your housing. The 5mm brass tube should stick through the hole in your housing and should be at the same angle with the horizontal as is your latitude. The ESP32 should snap fit into the hole on the side of the housing. The edge of the pcb falls into the grove in the housing. (it could be that you need to file to smooth the edge on the hook a little to make the USB port get in place at all).

Put the PTFE tube over the wire. Then put the bend 3mm tube into the 5mm brass part and press it into the gear. It should have a friction fit, otherwise use some superglue. Do not push it all the way through, because it must not touch the solder joint on the spring steel wire.

The center tab on the arrow fits into the slit you made in the shorter 5 mm brass tube. You may need a tiny dab of solder to hold it in place. Slide the arrow assembly on top of the bent 3 mm tube.

Cut the PTFE tube so it ends about 1 mm above the brass. Bend the steel wire 90 degrees toward the other contact tab on the arrow and solder the two together. Make sure the steel wire does not touch any brass surfaces.

When everything is aligned and Working, screw the bottom plate onto the housing to close the unit.

Step 7: Programming

With the wiring complete, the next step is to program the ESP32-C6. If you have not worked with ESP32 boards before, don’t worry — it only takes a few minutes to get the Arduino environment set up.

1) Download and install the latest Arduino IDE from the Arduino website.

2) Add ESP32 support

  1. Open Arduino IDE.
  2. Go to File > Preferences.
  3. In the field Additional Board Manager URLs, paste the ESP32 package link:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

  1. Press OK.

3) Install the ESP32 board package

  1. Go to Tools > Board > Board Manager…
  2. Search for “esp32” and install the latest package from Espressif Systems.

4) Select your board

  1. Go to Tools > Board > esp32 > ESP32C6 Dev Module.
  2. Select the correct port under Tools > Port (it will usually show up after you plug the board in with USB).

5) Upload the code

  1. Download the sketch from this link.
  2. Open it in Arduino IDE.
  3. Edit the code by telling it the longitude you are (line 25)
  4. Click the Upload button (the right arrow in the top left of the window).
  5. The code will compile and transfer to the ESP32-C6.

Once the upload is complete, the board will reset and start running the code immediately.

Step 8: Usage

With the code running, open the serial monitor and type h to see the available commands.

On the first run you will need to set the date and calibrate the mechanism.

Start by setting the date to 21-Dec-2025 00:00 using the d command. This is a convenient reference point because the Sun reaches its lowest declination around that time. Next, use the a command to rotate motor A and the arrow until it points to its lowest position, which should be near the USB port. Then use the b command to point the bend in the main axis toward the USB port as well. Once both are aligned, the calibration is complete. Finally, set the device to the correct current date and time using d again.

To read the time, look at where the shadow of the main axle would fall given the direction of the Sun. If the arrow seems slightly off, use the a command to make a small correction.

The RTC module has a battery backup and remembers the time, so you can safely unplug the device if you need to, but only for a short time as otherwise the calibration gets lost.

The device has two operating modes, switched with the e command. With the equation of time enabled, the arrow shows the true position of the Sun, provided the USB port is pointing north. The equation if time is a small correction that is needed because the earth doesn't move at constant speed along is elliptical orbit. This is the reason why traditional sundials can be off by up to about 15 minutes. If you want the device to tell clock time more accurately, turn the equation-of-time mode off.

Two extra commands show small demonstrations. m1 advances the pointer through a week of motion. m2 shows the Sun’s position at noon for each day over the next four years. After these short animations there is a short pause after which the device resumes its normal operation.

Step 9: Conclusion

That is the whole build. Once everything is calibrated and the housing is closed up, you have a small machine that quietly tracks the Sun day and night. You can use it as a functional 24-hour sundial, or simply enjoy it as a mechanical art project that brings a bit of astronomy into your living room. When it is running, the pointer quietly tracking the Sun has a calm, almost clockwork quality to it. I hope you enjoy building your own version, and if you make improvements or adapt it for your own location, I would love to hear how it turns out.

Step 10: Brass Version

After finishing the basic version, I decided to make a more decorative one with a 1.5 mm brass disk on top and artwork around the base.

For the top, I wrote a Python program that generates toolpaths for the CNC head of my 3-in-1 printer. The machine can swap between print, laser, and CNC heads, so I used the CNC head to engrave directly into the brass. The decoration.py generates dial.png and dial.svg. Initially I had a version that generated hourly labeling from 1 to 24, but this one generates 1 to 12 twice, which is just a bit easier to read.

Because the main axle is tilted and needs to hit the center of the brass disk, the hole in the printed housing had to be shifted slightly. I have included the STL for that part; it is made for my latitude, but it should not be too hard to adapt it for yours.

The side decoration started from an image of two seated figures with their hands raised. I sent that to an AI tool to turn them into a standing pair with an ancient Egyptian look. Another AI pass gave the result the feel of an old engraving. From there I ran the image through two Python scripts: one to handle the thick lines and one for the thin lines. The intend was to let the laser follow the strokes in the image. A third script merged both into a single vector file called "both.svg". Using a fourth script, tile.py, I generated a long strip with seven pairs of these Egyptian-style figures. This strip wraps around the base, so it looks like a ring of standing figures around the sundial holding it up with their hands.


The instructable website didn't let me upload more than one
python file (or so it appears), but you can download them
directly from google drive thick.py, thin.py, merge.py, tile.py


For the engraving on the base I switched to the laser head. As a test, I printed the base in green silk filament, then used a spray can with a primer/filler, sanded it smooth, and finally spray-painted it black. The laser burned through the black and produced a nice warm yellowish image, so that version looked very good. The base I had printed earlier, however, was blue filament. After painting that one black, the laser exposed a much colder white color that I did not like. In the end I reprinted the housing again in green silk filament, repeated the priming, sanding, painting, and lasering, and finally ended up with a brass 24-hour sundial on a nicely decorated base. The extra thick brass you see in the pictures that seems to support the central axle, is just there to cover up a mistake I made during construction. You can do without it.

Took a beauty shot, and asked AI to generate a nice background.