So; I’ve been working with 3D Printers as of late, and having a a lot of fun. My latest project is an 18″ moon globe on a stand. Seeing it online made me want one, so out comes my trusty 3D Creality S10 printer, and I was off and running. Here is the result:

I started with the STL model from here available online. From the author: The elevations are exaggerated five times taller and deeper. JAXA data, Kaguya LALT Team is credited. The Moon is presented from the Japanese database. Laser Altimeter is LALT. LALT is one of the instruments on board KAGUYA main orbiter for laser ranging from the satellite to the surface of the Moon in the nadir direction. LALT is able to obtain the range data globally along satellite’s trajectory on the polar orbit. These range data of LALT will enable us for the first time in the world to construct a global, accurate and precise topographic map of the Moon.

This sounded perfect to me!

The only issue I had with the model was it’s original size. At about 150 mm, it was just too small to be an office-sized globe, so I scaled it up about 200% to get it to it’s final 18″ size. Up/Down scaling 3D models is a trivial matter, and I won’t go into it here other than to say I used Simplify3D software to upscale and slice into a gcode file for my Creality Printer.

The globe model is a sphere with a small bottom part that is expected to be glued together, but since I wanted a display – I hopped over to and generated my own globe base. I added a hollow space on the underside to house the electronics, and a post in the middle of the top surface to mound the led’S. Then I printed the globe in glow-in-dark PLA filament and the base in black PLA. It’s a nice result.

To get the moon to “Phase” I used an Arduino UNO and a NeoPixel 12 element ring from Adafruit. (links at the end of the article). Basically the concept was to light several adjacent LED’s on the ring, rotating the lit segments around the entire ring in sequence. Since there is a post ins the middle of the base, the ring snugly fits over it and casts a shadow whenever the lit segments pass behind the post. Because there are several leds lit in the segment, the effect is a curved edge to the shadow which approximates the “Phases” of the moon.

The Arduino code is hacked out of an Adafruit sample code set, I modified to to handle the segments, rotation, and some other parameters associated with this project, such as number of phases to display, color generators and other timing attributes,. The code is well commented and easy to follow.

#include // Library for NeoPixels
#include // Library for NeoPixels
#define pinPix 6 // Pin driving NeoPixel Ring or String
#define numPix 12 // Number of NeoPixels in the Ring or Strip
const byte extra = 2; // how many ahead, and behind, to light up (width of full sunlight)
const int maxOrbits = 5; //Number of orbits ’round the Earth (smnaller = fewer)
const int orbitSpeed = 1000; // Speed of orbit (smaller = faster)
const int R = 255; //Max Red Value (Smaller number = less of this color)
const int B = 255; //Max Blue Value (Smaller number = less of this color)
const int G = 255; //Max Green Value (Smaller number = less of this color)
// Setup NeoPixel Ring
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number driving the strip
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel myNeoPixels = Adafruit_NeoPixel(numPix, pinPix, NEO_GRB + NEO_KHZ800);
// Hacked from code found online at
void setup() {
myNeoPixels.begin(); // Initialize the NeoPixel array in the Arduino’s memory,; // turn all pixels off, and upload to ring or strin
void loop() {
int Red;
int Green;
int Blue;
Red = setColor(R);
Green = setColor(G);
Blue = setColor(B);
//Fade in and out of color selected
breathe(20, 100, Red, Green, Blue); // Pause; Number of steps; Full-on R,G,B values
// and show some lunar phases
for (int t=0; t<maxOrbits; t++) {
//perform maxOrbits arount the Earth
ledTrail(orbitSpeed, Red, Green, Blue, 0,0,0); // Pause; R,G,B foreground; R,G,B background
// Rf, Gf, Bf = RGB “Foreground” values
// Rb, Gb, Bb = RGB “Background” values
int setColor(int color) {
int newColor;
return newColor;
void breathe(int pause, int steps, byte R, byte G, byte B) {
int tmpR, tmpG, tmpB; // Temp values
// Fade up
for (int s=1; s<=steps; s++) {
tmpR = (R * s) / steps; // Multiply first to avoid truncation errors
tmpG = (G * s) / steps;
tmpB = (B * s) / steps;
for (int i=0; i<numPix; i++) { myNeoPixels.setPixelColor(i,tmpR,tmpG,tmpB); }; delay(pause); } // Fade down for (int s=steps; s>0; s–) {
tmpR = (R * s) / steps; // Multiply first to avoid truncation errors
tmpG = (G * s) / steps;
tmpB = (B * s) / steps;
for (int i=0; i<numPix; i++) {
delay(pause * 30);
void ledTrail(int pause, byte Rf, byte Gf, byte Bf, byte Rb, byte Gb, byte Bb) {
int tmpR, tmpG, tmpB; // Temp values
for (int i=0; i<numPix; i++) {
// now go “extra” pixels ahead and behind
for (int s = 1; s < extra + 1; s++)
tmpR = (Rf * (extra – s)) / extra; // Multiply first to avoid truncation errors
tmpG = (Gf * (extra – s)) / extra;
tmpB = (Bf * (extra – s)) / extra;
myNeoPixels.setPixelColor((i + s) % numPix,tmpR,tmpG,tmpB);
myNeoPixels.setPixelColor((i + numPix – s) % numPix,tmpR,tmpG,tmpB);

I hope you like this fun and educational project.
3d Models here:
NeoPixel here:
Arduino here:

Shopping cart

Shipping and discount codes are added at checkout.