Build a tiny OLED Planetarium — turn a knob and zoom from Earth to Jupiter!
This pocket-sized planetarium uses an ESP32, four tiny 1.3" OLED screens, and one rotary knob. Turn the knob slowly and watch the zoom glide smoothly across screens — from Earth, to the Moon, to Mars, all the way out to giant Jupiter. Here's exactly how to build it, with the full circuit and code.
How the zoom effect actually works
There's no single giant zoom lens here — the trick is simpler and more fun to build. Four small OLED screens are lined up in a row, each one permanently in charge of drawing one body: Earth, Moon, Mars, or Jupiter. As you turn the rotary knob, code running on the ESP32 smoothly grows the picture on the "focused" screen and shrinks the one before it, so your eye reads it as one continuous zoom flying outward through the solar system.
4 dedicated OLEDs
Each 1.3" OLED is responsible for exactly one object, which keeps the code for each screen simple.
One knob, one position
Twisting the knob changes a single number the code uses to decide how "zoomed in" each screen should be.
Tiny steps, not big jumps
The code redraws each frame with a slightly bigger or smaller circle, which is what makes the zoom look smooth instead of jumpy.
What you'll need
All beginner-friendly parts from hobby electronics stores. Ask a grown-up to help place the order.
ESP32 Dev Board
Runs the code, reads the knob, and talks to all four OLED screens at once.
4× 1.3" OLED (SH1106, I2C)
Small 128×64 pixel monochrome displays — one for each solar system body.
TCA9548A I2C multiplexer
Since all 4 OLEDs share the same address, this chip lets the ESP32 talk to each one separately.
KY-040 rotary encoder
The twisting knob you turn to zoom — it also has a built-in push button.
USB cable or 3.7V LiPo + charger board
Powers the ESP32, which in turn powers everything else through its 3.3V pin.
Breadboard + jumper wires
Connects everything without any soldering.
Cardboard or 3D-printed stand
Holds the 4 OLEDs in a neat row with the knob mounted beside them.
How the circuit works
The ESP32 talks to all 4 OLEDs over one shared I2C "conversation line," but since they'd normally all answer to the same address, the TCA9548A multiplexer acts like a phone switchboard — routing the ESP32's message to only one screen at a time.
ESP32 Dev Board
3V3 -----------------------> VCC rail (OLEDs + TCA9548A + encoder)
GND -----------------------> GND rail (shared by everything)
GPIO21 (SDA) --------------> TCA9548A SDA
GPIO22 (SCL) --------------> TCA9548A SCL
TCA9548A I2C Multiplexer (address 0x70)
SD0 / SC0 -----> OLED #1 (Earth) SDA / SCL
SD1 / SC1 -----> OLED #2 (Moon) SDA / SCL
SD2 / SC2 -----> OLED #3 (Mars) SDA / SCL
SD3 / SC3 -----> OLED #4 (Jupiter) SDA / SCL
KY-040 Rotary Encoder
CLK --------> GPIO34
DT --------> GPIO35
SW --------> GPIO32 (push button, optional reset)
+ --------> 3V3
GND --------> GND
Step-by-step build
Work through these in order — each step sets up something the next step needs.
Lay out the stand
Cut a small cardboard strip (or 3D print one) with 4 slots in a row for the OLEDs, plus a mounting hole for the rotary encoder beside them.
Mount the 4 OLED screens
Place one OLED per slot in this order: Earth, Moon, Mars, Jupiter — matching the order your code will use.
Wire the OLEDs to the multiplexer
Connect each OLED's SDA/SCL to its own channel (SD0/SC0 through SD3/SC3) on the TCA9548A, as shown in the circuit map.
Wire the multiplexer to the ESP32
Connect the TCA9548A's shared SDA/SCL to GPIO21/GPIO22, and power everything from the ESP32's 3V3 and GND pins.
Wire the rotary encoder
Connect CLK, DT, and SW to GPIO34, GPIO35, and GPIO32, following the circuit map.
Install the libraries
In the Arduino IDE, install the Adafruit_SSD1306 and Adafruit_GFX libraries through the Library Manager.
Upload the code
Paste in the sketch below, select your ESP32 board, and click Upload.
Turn the knob and test
Slowly rotate the encoder and watch the "focus" glide from Earth's screen to the Moon's, then Mars, then Jupiter.
The ESP32 code
This sketch reads the rotary encoder as a smooth position value, works out which two bodies you're currently "between," and draws a growing circle on the next screen while shrinking the circle on the previous one — creating the flythrough zoom effect.
// OLED Planetarium — ESP32 + 4x OLED + rotary encoder // Beginner-friendly Arduino sketch #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define TCA_ADDR 0x70 #define SCREEN_W 128 #define SCREEN_H 64 const int CLK_PIN = 34; const int DT_PIN = 35; Adafruit_SSD1306 oled(SCREEN_W, SCREEN_H, &Wire, -1); const char* names[4] = {"Earth", "Moon", "Mars", "Jupiter"}; const int maxRadius[4] = {26, 18, 22, 30}; // relative sizes volatile long encoderPos = 0; int lastCLK; void tcaSelect(uint8_t channel) { Wire.beginTransmission(TCA_ADDR); Wire.write(1 << channel); Wire.endTransmission(); } void IRAM_ATTR onEncoderTurn() { int clkState = digitalRead(CLK_PIN); if (clkState != lastCLK) { if (digitalRead(DT_PIN) != clkState) encoderPos++; else encoderPos--; } lastCLK = clkState; } void drawOnScreen(int channel, const char* label, int radius) { tcaSelect(channel); oled.clearDisplay(); oled.fillCircle(SCREEN_W / 2, 26, radius, SSD1306_WHITE); oled.setTextColor(SSD1306_WHITE); oled.setCursor(10, 54); oled.print(label); oled.display(); } void setup() { Wire.begin(); pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); lastCLK = digitalRead(CLK_PIN); attachInterrupt(digitalPinToInterrupt(CLK_PIN), onEncoderTurn, CHANGE); for (int ch = 0; ch < 4; ch++) { tcaSelect(ch); oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); } } void loop() { // Map encoder ticks to a smooth position between 0 and 3 float position = constrain(encoderPos * 0.05, 0.0, 3.0); int current = (int)position; int next = min(current + 1, 3); float blend = position - current; // 0.0 -> 1.0 between the two for (int ch = 0; ch < 4; ch++) { int radius = 4; // tiny/inactive by default if (ch == current) radius = maxRadius[ch] * (1.0 - blend * 0.6); if (ch == next) radius = maxRadius[ch] * (0.3 + blend * 0.7); drawOnScreen(ch, names[ch], radius); } delay(20); // small delay keeps the zoom feeling smooth }
0.05 multiplier to make the zoom feel faster or slower per turn, or add a 5th OLED and a Saturn ring drawing for an extra planet stop.Frequently asked questions
Do I need to be good at soldering?
No — this project can be fully built on a breadboard with jumper wires. No soldering is required.
Why can't I just plug all 4 OLEDs into the ESP32 directly?
Most 1.3" OLEDs share the same fixed I2C address, so the ESP32 can't tell them apart on its own. The TCA9548A multiplexer solves this by giving each screen its own channel.
Can I show real photos of the planets instead of circles?
Yes — once the zoom logic works, you can swap the circle drawing for small monochrome bitmap images of each body using the Adafruit_GFX drawBitmap() function.
Is this a real telescope or planetarium projector?
No — it's a hands-on electronics project that teaches how screens, sensors, and code work together, using the solar system as a fun, motivating theme.

Comments
Post a Comment