Wini’s Final Project_Stars Lamp

Project Overview

The Starry Sky Table Lamp is a kinetic light sculpture that bridges digital fabrication with traditional craftsmanship. By integrating 3D printing, laser cutting, and woodworking, the project features a custom-built mechanical assembly powered by a rotary motor and Arduino microcomputer. The design is anchored by a central ring-light and crowned with a high-density panel of 684 LEDs, creating a dynamic, rotating visual experience.

Background

For my final project, I am developing a custom star light projector for my upcoming baby. The goal is to create a device that casts a gentle, soothing starlight pattern onto the nursery ceiling. I plan to use an Arduino microcontroller to program and control a series of LED strips, creating a simple and calming visual effect. This project is a way for me to combine new technical skills with a personal, heartfelt gift for my baby.

Materials

  • 15 inch Plywood stick
  • 1/8″ Acrylic Board_black
  • 1/8″ Acrylic Board_white
  • 1/8″ Acrylic Board_Transparent
  • LED strips
  • LED Pad 16*16
  • Arduino Board
  • Wires
  • Automobile bearing
  • Stepper Motor
  • Adafruit STSPIN220 Stepper Motor Driver Breakout Board
  • Cardboard
Overall Design Process

1. Design of mechanical gear system and lamp body ring structure  for laser cutting

2. Testing the Stepper Motor and gears

3. Soldered the circuit and coding the control buttons.

4. Assembled all laser-cut pieces on the wood stick

5. Created the lamp’s base

6. Created the lampshades

Trial and Error

The most significant challenge was power distribution. Driving both the motor and the high-density array of 684 LEDs simultaneously exceeded the current capacity of my initial single-Arduino setup. While the system could handle the ring light and low-speed motor rotation, activating the main LED panel caused a voltage drop that crashed the system (brownout). To resolve this, I isolated the loads by introducing a second Arduino dedicated solely to controlling the LED matrix.

Next Step:

My next steps are to optimize the electrical system and design a housing unit that seamlessly integrates the internal electronics with an external control panel.

Special Thanks 

Becky, Huy& Kyle

Luis and baby

Codes:

#include <Adafruit_NeoPixel.h>

#include <Adafruit_STSPIN220.h>

#ifdef __AVR__

#include <avr/power.h>

#endif

// ==========================================

// CONFIGURATION

// ==========================================

// — LED PINS & SETTINGS —

#define LED_BUTTON_PIN 12

#define LED_PIXEL_PIN 8

#define NUM_LEDS 428

#define RAINBOW_SPEED 10 // Lower is faster (ms between updates)

// — MOTOR PINS & SETTINGS —

// Motor Control Pins

const int DIR_PIN = 2;

const int STEP_PIN = 3;

const int MODE1_PIN = 4;

const int MODE2_PIN = 5;

const int EN_FAULT_PIN = 6;

const int STBY_RESET_PIN = 7;

const int SPEED_PIN = A0; // Potentiometer

const int stepsPerRevolution = 200; // Standard Stepper

// ==========================================

// OBJECTS & VARIABLES

// ==========================================

// Define the NeoPixel object

Adafruit_NeoPixel strip(NUM_LEDS, LED_PIXEL_PIN, NEO_GRB + NEO_KHZ800);

// Define Stepper object

Adafruit_STSPIN220 myStepper(stepsPerRevolution, STEP_PIN, DIR_PIN,

MODE1_PIN, MODE2_PIN, EN_FAULT_PIN, STBY_RESET_PIN);

// LED Variables

int ledMode = 0; // 0=Off, 1=Dim, 2=Bright, 3=Rainbow

int lastButtonState = HIGH;

long firstPixelHue = 0;

unsigned long lastRainbowUpdate = 0; // Timer for animation

// Motor Variables

int currentSpeed = 0;

unsigned long lastSpeedPrint = 0; // NEW: Timer for printing speed

void setup() {

Serial.begin(115200); // Make sure your Serial Monitor matches this number!

// — SETUP LEDS —

pinMode(LED_BUTTON_PIN, INPUT_PULLUP);

strip.begin();

strip.show(); // Initialize off

// — SETUP MOTOR —

// Set microstepping mode to 1/16 steps (smoother)

myStepper.setStepMode(STSPIN220_STEP_1_16);

Serial.println(“System Ready: LEDs & Motor Combined.”);

}

void loop() {

// ==========================================

// 1. LED BUTTON LOGIC

// ==========================================

int currentButtonState = digitalRead(LED_BUTTON_PIN);

if (currentButtonState == LOW && lastButtonState == HIGH) {

ledMode++;

if (ledMode > 3) ledMode = 0;

// Handle Static Modes (One-time update)

if (ledMode == 0) {

strip.clear();

strip.show();

Serial.println(“LED: OFF”);

}

else if (ledMode == 1) {

strip.setBrightness(10);

strip.fill(strip.Color(255, 255, 0)); // Yellow

strip.show();

Serial.println(“LED: Yellow (Low)”);

}

else if (ledMode == 2) {

strip.setBrightness(80);

strip.fill(strip.Color(255, 255, 0)); // Yellow

strip.show();

Serial.println(“LED: Yellow (High)”);

}

else if (ledMode == 3) {

strip.setBrightness(80);

Serial.println(“LED: Rainbow Mode”);

}

delay(50); // Small debounce

}

lastButtonState = currentButtonState;

// ==========================================

// 2. LED ANIMATION (If in Rainbow Mode)

// ==========================================

if (ledMode == 3) {

// Non-blocking timer: Only update if enough time has passed

if (millis() – lastRainbowUpdate > RAINBOW_SPEED) {

lastRainbowUpdate = millis();

drawRainbowHorizon();

}

}

// ==========================================

// 3. MOTOR LOGIC

// ==========================================

// Read Potentiometer

int sensorValue = analogRead(SPEED_PIN);

currentSpeed = map(sensorValue, 0, 1023, 0, 120); // Map to 0-120 RPM

// — NEW: PRINT SPEED EVERY 500ms —

if (millis() – lastSpeedPrint > 500) {

lastSpeedPrint = millis();

Serial.print(“Motor Speed: “);

Serial.print(currentSpeed);

Serial.println(” RPM”);

}

if (currentSpeed > 0) {

myStepper.setSpeed(currentSpeed);

// Take 1 step per loop iteration

myStepper.step(1);

}

}

// — HELPER FUNCTION: RAINBOW —

void drawRainbowHorizon() {

// Update Hue

firstPixelHue += 256;

for(int i=0; i<strip.numPixels(); i++) {

int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());

strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));

}

strip.show();

}

Discover more from Making Studio

Subscribe now to keep reading and get access to the full archive.

Continue reading