Mercator: An ESP32-based spherical persistence-of-vision display

A spinning ring of DotStar LEDs creates a programmable globe.

I’ve been working on this project for the last few months, and finally got to the point where I can finally declare it done. Mercator is a spherical persistence-of-vision display based on a ring of DotStar programmable LEDs and the Adafruit HUZZAH32 ESP32 dev board. As the LEDs spin around, the pattern changes to display pretty much anything:

Parts

Here’s the stuff one would need to buy to build one of these:

  • Adafruit HUZZAH32 dev board, based on the ESP32 processor. I program this using the Arduino IDE. This board drives the LED strip and controls the motor speed.
  • DC motor. I use this big honking 30W motor that runs off of a 12V power supply. This is no doubt ridiculously overpowered but I wanted something with a large shaft that I could mate with.
  • Two ball bearings, such as these, to hold the base and top of the LED ring steady while allowing free rotation.
  • Since the LED strip is rotating but the electronics are housed in the base, I use a slip ring which allows for electrical connections to be maintained between the two. You need one with at least four wires, such as this one from Adafruit.
  • The motor drives the LED ring using an XL timing belt, such as this one. There is a 3D printed pulley connected to the motor shaft which mates with the teeth of the belt.
  • US5881LUA hall effect sensor. This is used to detect the rotation of the LED ring, which has a small magnet attached to the base (more on this below).
  • Three 10kΩ potentiometers, one each to control the rotation speed, display rotation, and LED brightness.
  • A power switch and a pushbutton. The switch simply controls power to the motor, while the button is used to start the motor and switch between display modes.
  • I used a custom PCB to connect all of the parts, the schematic and Eagle files for which are in the Mercator GitHub repo. One could just as easily use a breadboard.
  • You’ll also need a 1kΩ resistor, two 10μF capacitors, a 7805 voltage regulator, a RFP30N06LE power MOSFET (or similar), and a 1N4004 diode. My PCB design assumes a 12V, 1A power supply connected to the PCB using a 2.1mm DC barrel jack. My PCB uses 2.5mm pitch connectors (JST XH connectors being my favorite) to connect to the other external components, such as the LEDs, motor, pots, etc.

Physical design

There are three main components to Mercator: The base, the clear acrylic shield, and the 3D printed LED ring. The base is laser cut out of 3mm thick wood. The shield cut from 3mm clear acrylic. The shield is there for two reasons: first, to prevent injuries (in case one of my kids decided to stick their hands in front of the spinning ring), but also to hold the top axis of the LED ring upright. I use two 12mm shaft diameter ball bearings, one mounted in the top face of the shield, and another in the top face of the base, to hold the LED ring. The shield has notches that align with matching holes in the top face of the base to hold it in place, so it is easy to lift the shield off if needed.

The case and 3D printed components were designed in Fusion360.

Detecting rotation

A key aspect of the design is detecting when the LED ring is in a certain rotational position, so we can adjust the speed at which to update the LED strip to display the desired pattern. For this I use a US5881LUA Hall effect sensor which detects the presence or absence of a magnetic field passing by its face. Small magnets are mounted on the base of the LED ring and the Hall sensor positioned to be a few millimeters away from the end of the magnet. The Hall sensor is connected to an input pin on the microcontroller which goes low when the magnet passes by.

Close-up of Mercator’s mechanics. On the left is the motor shaft with 3D printed XL timing belt pulley attached using set screws. The timing belt connects to a similar pulley on the base of the LED ring, on the right. Mounted to the LED ring is a small magnet, which rotates with the ring. The Hall effect sensor (small black component) is a few mm from the end of the magnet, and mounted to an L-bracket attached to the base using a ziptie.

Electronics

The electronics for this project are fairly straightforward. The ESP32 dev board controls everything and is attached to the LED strip, potentiometer inputs, Hall effect sensor, and the start button. The HUZZAH32 board is powered via a micro-USB cable connected to a standard 5V USB wall wart. The motor uses a separate 12V/1A power supply.

Schematic for the Mercator connector board. See the GitHub repo for the full design files.
The fully-populated Mercator PCB.

Software

Okay, with the hardware and electronics out of the way, let’s get to the software side of things. The ESP32 is programmed using the Arduino SDK and makes use of the Adafruit Dotstar library to control the LED strip. Here’s a direct link to the program source.

You can pack a surprisingly large amount of detail into a 72x36px image.

Demo

Taking pictures and videos of Mercator is frustrating, because the typical phone camera cannot capture the persistence-of-vision effect observed by the human eye. Here’s a GIF made from an iPhone video of the globe as it is spinning:

That’s no moon.

Lessons learned

As usual with my projects, this one took me a lot longer than I anticipated and, after some initial success with the physical design, the project sat on my workbench collecting dust for a while before I got around to writing the software. A few things that tripped me up and which I would have done differently if I started from scratch:

Distinguished Engineer at OctoML.ai, building compilers for fast AI. Ex-Apple, ex-Xnor.ai, ex-Google engineering director. Systems hacker and drinker of beer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store