Servo Origami
Installation
that blooms · tessellates · morphs
Build a living paper wall where Arduino-powered servo motors fold coloured panels into blooming geometry, tessellation waves, and a breathing morphing wall — all in one kinetic art installation.
A Wall That Folds Itself
Origami is the ancient art of folding paper into beautiful shapes. Servo motors are tiny robotic joints that rotate to precise angles on command. What happens when you combine the two? A wall that comes alive!
Each cell of our 3×3 grid holds one coloured paper panel pre-creased with mountain and valley folds. A small SG90 servo is bonded to each panel's fold crease. When the Arduino tells a servo to rotate from 0° to 90°, it pulls the crease open — and the panel blooms, ripples, or breathes, depending on the timing pattern we program.
The result is a kinetic art installation — part sculpture, part robot, part light show — that anyone can build from cheap craft supplies and beginner electronics.
Panels open from the centre outward like a flower waking up at dawn. Magenta inner panels bloom first, then the outer ring follows in a radial wave.
Panels pop open in a diagonal ripple — top-left to bottom-right — like a wave of dominoes falling in slow motion across a crystalline grid.
All nine panels breathe simultaneously in a slow sine-wave pulse. The wall seems to inhale and exhale — like a living organism made of coloured light and paper.
Parts You'll Need
How to Fold the Paper Panels
Each panel needs a special set of creases so that when the servo pulls one edge, the whole panel opens in a beautiful geometric shape. We use a classic water-bomb base modified into a flat fan fold. Here's the 3-step crease process:
Circuit Diagram
Nine servos, three mode buttons, one OLED, one buzzer — all wired to the Arduino Mega. Power for servos comes from a separate 5V rail so the Arduino doesn't burn out.
Complete Wiring Table
⚙️ Servo Signal Pins
| Servo | Panel Position | Arduino Pin (Signal) | Row Colour Theme |
|---|---|---|---|
| S1 | Top-Left | D2 | ● Magenta Row |
| S2 | Top-Centre | D3 | ● Magenta Row |
| S3 | Top-Right | D4 | ● Magenta Row |
| S4 | Mid-Left | D5 | ● Cyan Row |
| S5 | Mid-Centre | D6 | ● Cyan Row |
| S6 | Mid-Right | D7 | ● Cyan Row |
| S7 | Bot-Left | D8 | ● Gold Row |
| S8 | Bot-Centre | D9 | ● Gold Row |
| S9 | Bot-Right | D10 | ● Gold Row |
🔌 Power, Control & Display
| Module | Pin | Connects To |
|---|---|---|
| All 9 Servos | VCC (Red) | 5V Power Rail (adapter, NOT Arduino) |
| All 9 Servos | GND (Brown) | Common GND bus |
| Arduino Mega | GND | Common GND bus (shared with adapter) |
| Arduino Mega | VIN or USB | USB from PC or separate 7–12V for Mega |
| Button – Bloom | D22 | One leg to D22, other leg to GND |
| Button – Tessellation | D23 | One leg to D23, other leg to GND |
| Button – Morph | D24 | One leg to D24, other leg to GND |
| OLED – SDA | D20 | I2C SDA |
| OLED – SCL | D21 | I2C SCL |
| OLED – VCC | 3.3V | Arduino 3.3V pin |
| OLED – GND | GND | Common GND |
| Buzzer + | D11 | Positive leg to D11 |
| Buzzer – | GND | Negative leg to GND |
Step-by-Step Build Instructions
Build the Frame Grid
Cut a piece of foam board (or thick cardboard) approximately 30×30 cm. Draw a 3×3 grid of squares — each cell should be about 9×9 cm. Cut out each cell lightly so there's a visible frame around each opening. This is the "wall" your panels will sit in. You can paint the frame black for a dramatic gallery look!
Pre-fold All 9 Paper Panels
Follow the three paper-folding steps shown in the diagram above for each of the 9 sheets. Use a ruler and bone folder (or a blunt pencil) to make sharp, crisp creases. Important: fold each sheet the same way so all servos rotate in the same direction. After folding, gently unfold each panel back to flat — the crease memory is now set.
Mount Servos to the Frame
For each cell, hot-glue a servo to the back of the frame, centered in the cell opening. The servo horn (the rotating arm) should point toward the bottom of the cell. Let the glue fully cool before moving on — this bond carries all the mechanical load!
Route and Connect All Wires
Each SG90 servo has 3 wires: brown (GND), red (VCC), orange (signal). Connect all 9 signal wires to Arduino D2–D10 per the wiring table. Connect all 9 red wires to the 5V power rail, and all 9 brown wires to the common GND bus. Label each servo connector with masking tape (S1, S2… S9) before plugging in — trust us, you'll thank yourself later!
Wire Buttons, OLED & Buzzer
Push the three mode buttons through small holes in a control panel strip of cardboard attached to the bottom of the frame. Wire each button leg to D22, D23, D24 and GND. Connect the OLED to the I2C pins. Connect the buzzer positive leg to D11. Keep all these wires bundled neatly behind the frame using cable clips or binder clips.
Upload the Code — Test Servos
Upload the code from the section below. In setup(), all servos go to 0° (panels flat/closed). Open Serial Monitor and confirm "ORIGAMI READY" prints. Then press each mode button and watch the servos move! If a servo twitches the wrong way, swap its signal wire to a different pin and update the code.
Bond Paper to Servo Arms
With all servos confirmed working at 0°, place each pre-folded paper panel in its frame cell. Apply a tiny dot of hot glue to the servo horn and press the bottom crease tip of the paper onto it. Hold for 30 seconds. Repeat for all 9. Now press the Bloom button and watch your origami come alive!
Arduino Code
Install these libraries: Servo (built-in), Adafruit_SSD1306 + Adafruit_GFX via Library Manager. The code runs three effect functions selected by the mode buttons.
// ============================================================ // ✦ Servo Origami Installation // Effects: Blooming Geometry · Tessellation · Morphing Wall // Robo Art Studio — Kid-Friendly Commented Version // ============================================================ #include <Servo.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // ----- OLED ----- #define SCREEN_W 128 #define SCREEN_H 64 Adafruit_SSD1306 display(SCREEN_W, SCREEN_H, &Wire, -1); // ----- Servo Objects (S1-S9) ----- Servo panel[9]; // panel[0] = S1, panel[8] = S9 // Signal pins: D2-D10 for 9 servos const int SERVO_PINS[9] = {2,3,4,5,6,7,8,9,10}; // ----- Angles ----- const int CLOSED = 0; // panel flat const int OPEN = 90; // panel fully bloomed // ----- Buttons & Buzzer ----- const int BTN_BLOOM = 22; const int BTN_TESS = 23; const int BTN_MORPH = 24; const int BUZZER = 11; // ----- State ----- int mode = 0; // 0=idle 1=bloom 2=tess 3=morph bool effectRunning = false; // Blooming order: centre first, then ring (panel indices) // 0 1 2 // 3 4 5 ← panel[4] is centre // 6 7 8 const int BLOOM_ORDER[9] = {4, 1, 3, 5, 7, 0, 2, 6, 8}; // Tessellation diagonal order (top-left to bottom-right wave) const int TESS_ORDER[9] = {0, 1, 3, 2, 4, 6, 5, 7, 8}; // =================== SETUP =================== void setup() { Serial.begin(9600); // Attach all servos and close all panels for (int i = 0; i < 9; i++) { panel[i].attach(SERVO_PINS[i]); panel[i].write(CLOSED); } // Button pins pinMode(BTN_BLOOM, INPUT_PULLUP); pinMode(BTN_TESS, INPUT_PULLUP); pinMode(BTN_MORPH, INPUT_PULLUP); pinMode(BUZZER, OUTPUT); // Start OLED display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(10, 20); display.print("ORIGAMI READY"); display.setCursor(5, 40); display.print("Press a button!"); display.display(); // Startup chime — three ascending notes tone(BUZZER, 660, 100); delay(140); tone(BUZZER, 880, 100); delay(140); tone(BUZZER,1100, 120); delay(300); Serial.println("ORIGAMI READY"); } // =================== LOOP =================== void loop() { checkButtons(); switch (mode) { case 1: effectBlooming(); break; case 2: effectTessellation(); break; case 3: effectMorphWall(); break; } } // =================== BUTTONS =================== void checkButtons() { if (digitalRead(BTN_BLOOM) == LOW) { setMode(1, "BLOOMING"); delay(300); } if (digitalRead(BTN_TESS) == LOW) { setMode(2, "TESSELLATION"); delay(300); } if (digitalRead(BTN_MORPH) == LOW) { setMode(3, "MORPHING WALL"); delay(300); } } void setMode(int m, String name) { mode = m; closeAll(); // reset all panels to flat first showOLED(name, "Starting..."); tone(BUZZER, 1200, 100); delay(500); Serial.println("MODE: " + name); } // =================== EFFECT 1: BLOOMING =================== // Panels open from centre outward like a flower blooming void effectBlooming() { showOLED("BLOOMING", "Centre to edges"); // Open panels in bloom order for (int i = 0; i < 9; i++) { panel[BLOOM_ORDER[i]].write(OPEN); delay(250); // staggered delay = ripple effect if (buttonPressed()) return; // allow mode change mid-effect } delay(2000); // hold open for 2 seconds // Close panels in reverse bloom order for (int i = 8; i >= 0; i--) { panel[BLOOM_ORDER[i]].write(CLOSED); delay(200); if (buttonPressed()) return; } delay(1000); // pause before repeating } // =================== EFFECT 2: TESSELLATION =================== // Diagonal ripple wave, open then close void effectTessellation() { showOLED("TESSELLATION", "Diagonal wave"); // Open in diagonal ripple for (int i = 0; i < 9; i++) { panel[TESS_ORDER[i]].write(OPEN); delay(180); if (buttonPressed()) return; } delay(1500); // Close in reverse diagonal ripple for (int i = 8; i >= 0; i--) { panel[TESS_ORDER[i]].write(CLOSED); delay(160); if (buttonPressed()) return; } delay(800); } // =================== EFFECT 3: MORPHING WALL =================== // All panels breathe together in a sine-wave pulse void effectMorphWall() { showOLED("MORPHING WALL", "Breathing..."); // One full breath cycle (open and close slowly) for (int angle = CLOSED; angle <= OPEN; angle += 2) { for (int i = 0; i < 9; i++) panel[i].write(angle); delay(28); // ~28ms per step = ~1.3s to fully open if (buttonPressed()) return; } delay(400); // hold open briefly for (int angle = OPEN; angle >= CLOSED; angle -= 2) { for (int i = 0; i < 9; i++) panel[i].write(angle); delay(28); if (buttonPressed()) return; } delay(600); // pause before next breath } // =================== HELPERS =================== void closeAll() { for (int i = 0; i < 9; i++) panel[i].write(CLOSED); delay(400); } bool buttonPressed() { // Returns true if any mode button pressed mid-effect return (digitalRead(BTN_BLOOM) == LOW || digitalRead(BTN_TESS) == LOW || digitalRead(BTN_MORPH) == LOW); } void showOLED(String line1, String line2) { display.clearDisplay(); display.setTextSize(2); display.setCursor(0, 8); display.print(line1); display.setTextSize(1); display.setCursor(0, 45); display.print(line2); display.display(); }
BLOOM_ORDER lists panel indices from centre outward — so panel[4] (centre) opens first. TESS_ORDER lists them diagonally. By changing just these arrays, you can invent completely new effects without changing any other code!Testing Your Installation
Servo Range Test (Before Gluing Paper)
With all 9 servos wired but paper NOT yet attached, upload the code and press each mode button. All servos should sweep from 0° to 90° and back. If one servo buzzes loudly or shakes, its power supply may be insufficient — make sure you're using a dedicated 5V 3A adapter and not the Arduino's 5V pin.
Paper Alignment Check
After gluing paper to servo arms (Step 7 of build), run the Blooming effect once very slowly. Watch each panel — it should open smoothly in a diamond fan shape. If a panel tears or crumples, the servo arm is glued at the wrong spot. Re-apply to the exact crease tip of the fold.
Adjust Timing for Your Paper Weight
Heavier paper needs more torque — slow down the SG90 by increasing the delay() values in the effect functions. If panels flutter or overshoot, reduce the OPEN angle from 90° to 75° or 60° in the constants section. Origami paper (80gsm) is the sweet spot for these servos.
The Gallery Test — Step Back 2 Metres
The real test is viewing from a distance! Step back 2 metres and run all three effects in sequence. The visual impact of each effect is completely different up close vs. far away. If the Morphing Wall doesn't look like it's "breathing," increase the delay per step to make it slower and more hypnotic.
Upgrade Ideas
RGB LED Backlighting
Add WS2812B LEDs behind each panel and sync their colour to the servo angle — panels glow brighter as they open.
Sound-Reactive Morphing
Connect a MAX4466 microphone module — the Morphing Wall responds to music, breathing to the beat.
Bluetooth App Control
Add an HC-05 module and control effects from a phone — adjust speed, angle range, and create custom sequences wirelessly.
Ultrasonic Gesture Control
Mount an HC-SR04 sensor facing the audience — panels bloom when someone waves their hand in front of the installation!
4×4 Grid Expansion
Scale up to 16 servos (Arduino Mega handles 48) for a mesmerising 4×4 display. Mix panel shapes — squares, hexagons, triangles.
Temperature Bloom
Connect a DHT11 sensor — the installation opens or closes based on room temperature, turning environmental data into art.
Frequently Asked Questions
MY_ORDER[9] = {some order of 0–8} and loop through it with a delay. Try random order, zigzag rows, or opening alternating panels for a checkerboard flicker effect. The code is designed to make this easy to experiment with.
Comments
Post a Comment