DIY Sun Lamp

by Electro Retro in Circuits > LEDs

1002 Views, 15 Favorites, 0 Comments

DIY Sun Lamp

Gemini_Generated_Image_jautayjautayjaut.png
IMG_20260721_124129.jpg

I always wanted to make a lamp, and there are already so many amazing designs out there. Recently, I came across an blog about nature inspired lamps by Leora Studio. Their lamps use beautiful organic shapes and algorithmic designs that instantly caught my attention. I loved the way they looked and wanted to build something similar.

Then reality kicked in. I quickly realized I didn't have the skills to recreate designs that complex. So instead of copying them, I decided to take inspiration from nature in a much simpler way.

That's when I came up with the idea of a sun inspired lamp. I imagined a warm glowing orange light with flowing wave patterns inspired by the Sun's corona. I wasn't sure if the final result would match the picture I had in my head, but I think it turned out pretty well.

In this Instructables, I'll walk you through the entire process of making this lamp, from the first sketches to the finished build. Things didn't always go as planned, and there were plenty of mistakes and lessons along the way. So let's get started.

Supplies

IMG_20260717_191601.jpg
IMG_20260718_235409.jpg

Modeling the Lamp Shade

Screenshot 2026-07-21 132358.png
Screenshot 2026-07-21 132421.png

Let's start with the most important part of this project, the lamp shade. As I mentioned earlier, I wanted to create a sphere with flowing wavy ridges inspired by the Sun's corona. The goal was to make it look simple and elegant while still capturing the organic patterns you see around the Sun.

For designing the shade, I chose Blender because it's free, open source, and has plenty of tutorials available online. I was a complete beginner, so this project became my way of learning Blender from scratch. After watching a few tutorials and getting a little help from an AI chatbot, I managed to create a few different designs before settling on this one.

Here's how I modeled the final shade.

  1. Sculpting the Base Shape

I started with a high-resolution UV sphere to get smooth curves.

In Edit Mode, I selected the vertical edge loops running from the top of the sphere to the bottom. Using the Checker Deselect tool, I quickly selected every other edge loop.

Then I pressed S to scale them outward. This transformed the smooth sphere into a shape with evenly spaced ridges all around it.

  1. Twisting the Geometry

To give the lamp that organic, sweeping motion I mentioned earlier, I needed to shape the curves. I selected the top section of the sphere and turned on Proportional Editing, which ensures the rest of the mesh follows along smoothly. Then, I pressed R to Rotate and Z to lock that rotation strictly to the Z axis.

  1. Creating the Mounting Hole

The shade needed to fit securely onto the base, so I had to make the dimensions accurate.

I added a cylinder and set its diameter to exactly 100 mm. This cylinder was then used as a Boolean cut to create a perfectly sized mounting hole in the bottom of the shade.

and finally when I was happy with the design, I exported the STL file

Modeling the Base

Screenshot 2026-07-21 143112.png

Next up, we need a simple base for the lamp to house all the electronics and wiring. I decided to model this part in Tinkercad since it is quick and easy to use.

While putting the design together, I thought it would be really cool to add a small clock to the front of the base. I went ahead and cut out a perfect space for the clock display, along with all the necessary holes and mounting slots for the other components.

As always, I am going to attach all the STL files below and include a direct link to my Tinkercad project so you can easily grab the files and make any changes you like.

3D Printing

IMG_20260717_191601.jpg
Screenshot 2026-07-18 202314.png
Screenshot 2026-07-18 202342.png
Screenshot 2026-07-18 204731.png
IMG_20260717_203105.jpg
IMG_20260719_094552.jpg
IMG_20260721_105532.jpg
IMG_20260720_115141.jpg

This was the step where things didn't go as planned.

For the lamp shade, I wanted to print it in Vase Mode, also known as Spiralize Outer Contour in Cura. In this mode, the printer creates a hollow, single-wall model by printing in one continuous spiral from bottom to top.

This is perfect for lamps because the thin wall diffuses light much better. It also eliminates the Z seam, blobs, stringing, and other surface imperfections that become very noticeable once you place a light inside the shade.

To get the best result, I bought a roll of milky white PLA+ filament and started the print before going to bed. Since the print would take several hours, I thought I'd wake up to a finished lamp shade.

Well... that didn't happen.

The print was about 90% complete, but the top section had failed completely, leaving behind a giant blob of filament stuck to the nozzle.

After a bit of frustration, I went back to Cura and checked the layer preview. That's when I found the problem. Near the top of the model, the layers had huge gaps between them in Vase Mode. It was obvious why the print couldn't continue.

I spent quite a while trying to fix it by enabling Adaptive Layers, increasing the layer height, and experimenting with a few other settings, but nothing worked.

If anyone knows how to solve this issue, I'd really appreciate it if you could leave a comment below. I'd love to learn how to print this design properly in Vase Mode.

In the end, I gave up and printed the shade using normal settings instead. It printed successfully, but the result wasn't nearly as nice. You can clearly see the Z seam and other small imperfections when the lamp is turned on. The difference between the two methods is quite noticeable.

Thankfully, all the other parts printed without any problems.

Remove the Supports

IMG_20260720_121208.jpg

This step is exactly what the title says.

Once all the parts were printed, I carefully removed the support material using a pair of flush cutters and pliers.

Hydro Dipping the Base

Screenshot 2026-07-21 153214.png
Screenshot 2026-07-21 153229.png
Screenshot 2026-07-21 153244.png

After printing everything in white filament, I wasn't completely happy with how it looked. The lamp shade looked nice, but the whole project lacked contrast. It was just... white.

My original plan was to simply paint the base black or brown. Then, out of nowhere, I remembered hydro dipping. It was something I had wanted to try for a long time, but I'd only ever seen it in YouTube videos.

So I jumped online and started looking for hydro dipping films. There were so many designs to choose from, including carbon fiber, wood, marble, camouflage, and more.

At first, I couldn't decide between a wood grain finish and a marble finish. Then I started browsing the marble patterns and realized there were hundreds of different designs. Honestly, choosing one was harder than I expected.

After spending way too much time scrolling through options, I finally settled on a simple black marble pattern. I thought it would give the lamp a clean, premium look while making the white lamp shade stand out even more.

link for the film

Preparing the Base

IMG_20260720_123219.jpg

Since this was my very first time trying hydro dipping, I wanted to make sure I understood the process before jumping in. I started by watching a really helpful, straight to the point tutorial video online to get the hang of the basics.

The hydro dipping film I chose required a white base coat for the marble pattern to show up properly. So, I lightly sanded the 3D printed base to smooth out the surface and help the paint stick better.

After cleaning off the dust, I applied a few light coats of white spray paint and let it dry completely.

Cutting the Hydro Dipping Film

IMG_20260720_163843.jpg
IMG_20260720_164023.jpg

Next, I cut a piece of hydro dipping film large enough to cover the entire base. I placed the base on top of the film as a guide and left a little extra material around all the sides to make sure it would wrap around the part completely.

One thing I noticed right away was how delicate the film is. It's very thin and can easily fold, wrinkle, or stick to itself, so you have to handle it carefully. It took a bit of patience, but once the film was cut to size, it was ready for the next step.

Let's Dip It!

IMG_20260720_170640.jpg
IMG_20260720_170726.jpg
IMG_20260720_170734.jpg
vlcsnap-2026-07-21-16h09m08s806.png
vlcsnap-2026-07-21-16h09m37s595.png
IMG_20260720_171232.jpg
IMG_20260720_223859.jpg
IMG_20260721_112633.jpg

Now came the moment I had been waiting for.

I grabbed the largest plastic container I had and filled it with water. Looking back, I probably should have used a slightly bigger container, but this was the best I had available.

I carefully placed the hydro dipping film on the surface of the water. Since the film is very delicate, you have to be gentle or it can easily wrinkle or fold. After placing it on the water, I let it sit for about a minute so it could fully hydrate.

One important thing to remember is that the correct side of the film needs to face the water. Most films have a glossy side that should face down. If you're unsure, you can test a corner with a tiny amount of activator.

Next, I sprayed an even coat of activator over the entire film. Within a few seconds, the film transformed into a floating layer of ink. If you're using a larger container, you can place a simple frame around the film to stop the pattern from spreading too much after applying the activator.

Then came the exciting part. I slowly dipped the base into the water at an angle. Once the part was completely submerged, I moved the remaining film away before pulling the part back out.

Honestly, I had no idea what to expect. I was actually a little skeptical that it would work on my first try.

But the moment I lifted the part out of the water... wow! It looked much better than I had imagined. The marble pattern turned out beautifully. A slightly larger container probably would have given me better coverage around the sides, but for a first attempt, I was really happy with the result.

The final step was to rinse the part under running water to wash away the slimy residue left on the surface. After letting it dry completely, I sealed everything with a few coats of clear spray paint to protect the finish.

Electronics

IMG_20260721_015428.jpg
IMG_20260718_235407.jpg
IMG_20260718_235950.jpg

For the lighting, I chose three different LED strips: cool white, warm white, and orange, though the orange I got actually looks a bit more like amber. The main idea was to mimic real sunlight. As you might know, the true color of the sun is actually white because it emits all the colors of the rainbow almost evenly. It only appears yellow, orange, or red from Earth because our atmosphere scatters away the shorter blue wavelengths of light before they reach our eyes.

At one point, I wondered if I should have used RGB LEDs instead. That would have offered more color options, but it also would have made the control more complicated.

The next main piece of hardware is a 4 digit 7 segment display for the clock. To control the brightness, the light mix, and the time, I am using three touch switches. The rest of the circuit includes three MOSFETs to drive the three LED strips, an RTC module for accurate timekeeping, a 5V voltage regulator, and a few basic passive components.

At the heart of everything is an ATtiny1614 microcontroller. I think it's a perfect fit for projects like this because it's tiny, inexpensive, low-power, runs happily at 5 V, and supports single-wire UPDI programming. I've used ATtiny microcontrollers before in my automatic soap dispenser project, and they have been incredibly reliable. In fact, I still haven't had to recharge the battery in that project.

I'm using the 14-pin version of the ATtiny1614 along with an SMD-to-DIP adapter because I wasn't planning to design a custom PCB for this build. Instead, everything is soldered onto a piece of perfboard.

To make assembly and future maintenance easier, I used connectors for all the major components instead of soldering everything permanently.

Soldering Everything Together

SCH_Schematic1_1-P1_2026-07-21.png
IMG_20260719_001101.jpg
IMG_20260719_002002.jpg
IMG_20260719_002423.jpg
IMG_20260719_004055.jpg
IMG_20260721_000555.jpg
IMG_20260721_000603.jpg
IMG_20260720_235136.jpg
IMG_20260720_235219.jpg
IMG_20260721_000020.jpg
IMG_20260721_000638.jpg
IMG_20260721_001318.jpg
IMG_20260721_014907.jpg

With all the components ready, it was finally time to assemble the electronics.

Since I wasn't using a custom PCB, I built the entire circuit on a piece of perfboard. Looking back, I probably should have chosen a slightly larger board because things got pretty cramped by the end.

I started by soldering the ATtiny1614, voltage regulator, MOSFETs, resistors, and the remaining components onto the perfboard. The RTC module originally came with right-angle header pins, but they didn't fit well inside the enclosure, so I replaced them with straight header pins before soldering it in place.

When soldering the connectors, I found it was a good idea to solder them in pairs or while they were plugged into their matching connector. Otherwise, the plastic can soften from the heat, causing the pins to shift or bend out of alignment.

Next, I soldered connectors for all the external components, including the touch switches, 7-segment display, DC power jack, and the three LED strips. Using connectors instead of permanently soldering the wires makes the lamp much easier to assemble, disassemble, and repair if needed.

To keep the wiring neat, I connected the VCC and GND pins of all three touch switches together since they all share the same power supply. This allowed me to use a single 2-pin connector for power, while each switch had its own signal wire. It reduced the amount of wiring and made the inside of the base much cleaner.

One final tip: double-check the polarity of every connector before soldering. It's also a good idea to label or note which connector goes to each component. It might seem unnecessary at first, but it will save you a lot of confusion during the final assembly.

Programming the Microcontroller

IMG_20260721_014928.jpg
Screenshot 2026-07-21 005932.png
IMG_20260721_014744.jpg

With the hardware finished, it's time to upload the firmware.

Connect the USB-to-UART programmer to the programming header, making sure it's oriented correctly. Then plug it into your computer.

As I mentioned earlier, one of the nice things about the ATtiny1614 is that it only requires a single data pin for programming using the UPDI interface. You can program it with a simple USB-to-UART adapter or even another Arduino acting as a UPDI programmer. In this build, I'm using a USB-to-UART module.

The TX and RX pins of the USB-to-UART module are connected together through a resistor, and that connection goes to the UPDI pin of the ATtiny1614, which is physical pin 10.

For the software, I'm using the Arduino IDE. First, install the megaTinyCore board package if you haven't already. Then select the ATtiny1614 as the target microcontroller and choose "SerialUPDI (Slow - 57600 baud)" as the programmer.

Finally, copy and paste the code I've provided, click Upload, and wait a few seconds for the programming process to complete. Put a CR2032 battery in the RTC. If everything is connected correctly, your lamp should now be ready for the final assembly.


/*
* Sun Lamp Controller
* Hardware: ATtiny1614, DS3231 RTC, TM1637 Display, 3x TTP223 Touch Buttons
*/

#include <Wire.h>
#include <RTClib.h>
#include <TM1637Display.h>

// --- Pin Mapping ---
// Note: Pin numbers reflect megaTinyCore Arduino definitions, not physical leg numbers.

// Display & RTC
#define CLK_PIN 5 // Physical Pin 7 (PB2)
#define DIO_PIN 4 // Physical Pin 6 (PB3)

// Touch
#define BTN_MENU 3 // Physical Pin 5 (PA7)
#define BTN_UP 2 // Physical Pin 4 (PA6)
#define BTN_DN 8 // Physical Pin 11 (PA1)

// LED Channels (Must be hardware PWM pins)
#define LED_CH1 0 // Physical Pin 2 (PA4) - Warm White
#define LED_CH2 1 // Physical Pin 3 (PA5) - Cool White
#define LED_CH3 10 // Physical Pin 13 (PA3) - Amber


RTC_DS3231 rtc;
TM1637Display display(CLK_PIN, DIO_PIN);


enum Mode { NORMAL, SET_L1, SET_L2, SET_L3, SET_HOUR, SET_MINUTE };
Mode currentMode = NORMAL;


int currentHour = 0;
int currentMinute = 0;

// Brightness percentages (0-99 scale for 2-digit display)
int masterDim = 99;
int mixL1 = 99;
int mixL2 = 99;
int mixL3 = 99;


bool lastMenuState = LOW;
bool lastUpState = LOW;
bool lastDnState = LOW;
unsigned long upHoldTime = 0;
unsigned long dnHoldTime = 0;
unsigned long lastStepTime = 0;
unsigned long lastDisplayUpdate = 0;

const int HOLD_DELAY = 400;
const int STEP_SPEED = 20;

const uint8_t CHAR_C = 0b00111001;

void setup() {
// Initialize UI Pins
pinMode(BTN_MENU, INPUT);
pinMode(BTN_UP, INPUT);
pinMode(BTN_DN, INPUT);

// Initialize LED Pins
pinMode(LED_CH1, OUTPUT);
pinMode(LED_CH2, OUTPUT);
pinMode(LED_CH3, OUTPUT);
// Start Display
display.setBrightness(0x02);
display.clear();

// Start RTC (Halt and flash error if missing/miswired)
if (!rtc.begin()) {
while (1) {
display.showNumberHexEx(0xEEEE);
delay(500);
display.clear();
delay(500);
}
}
}

// --- Menu Helper Functions ---
void incrementSetting() {
switch (currentMode) {
case NORMAL: masterDim = min(99, masterDim + 1); break;
case SET_L1: mixL1 = min(99, mixL1 + 1); break;
case SET_L2: mixL2 = min(99, mixL2 + 1); break;
case SET_L3: mixL3 = min(99, mixL3 + 1); break;
case SET_HOUR: currentHour = (currentHour + 1) % 24; break;
case SET_MINUTE: currentMinute = (currentMinute + 1) % 60; break;
}
}

void decrementSetting() {
switch (currentMode) {
case NORMAL: masterDim = max(0, masterDim - 1); break;
case SET_L1: mixL1 = max(0, mixL1 - 1); break;
case SET_L2: mixL2 = max(0, mixL2 - 1); break;
case SET_L3: mixL3 = max(0, mixL3 - 1); break;
case SET_HOUR: currentHour = (currentHour == 0) ? 23 : currentHour - 1; break;
case SET_MINUTE: currentMinute = (currentMinute == 0) ? 59 : currentMinute - 1; break;
}
}

// --- Display Rendering ---
void updateDisplay() {
uint8_t segs[] = { 0, 0, 0, 0 };
bool blinkDigits = (millis() / 300) % 2 == 0;

if (currentMode == NORMAL || currentMode == SET_HOUR || currentMode == SET_MINUTE) {
// Render Clock Time
int displayHour = (currentMode == NORMAL) ? rtc.now().hour() : currentHour;
int displayMinute = (currentMode == NORMAL) ? rtc.now().minute() : currentMinute;
bool showColon = (currentMode != NORMAL) || ((millis() / 1000) % 2 == 0);

segs[0] = display.encodeDigit(displayHour / 10);
segs[1] = display.encodeDigit(displayHour % 10) | (showColon ? 0b10000000 : 0x00);
segs[2] = display.encodeDigit(displayMinute / 10);
segs[3] = display.encodeDigit(displayMinute % 10);

// Blinking effect during time setup
if (currentMode == SET_HOUR && blinkDigits) {
segs[0] = 0;
segs[1] = (showColon ? 0b10000000 : 0x00);
}
if (currentMode == SET_MINUTE && blinkDigits) {
segs[2] = 0;
segs[3] = 0;
}
}
else {
// Render LED Settings (e.g., "C1:99")
int val = 0, ch = 0;
if (currentMode == SET_L1) { val = mixL1; ch = 1; }
else if (currentMode == SET_L2) { val = mixL2; ch = 2; }
else if (currentMode == SET_L3) { val = mixL3; ch = 3; }

segs[0] = CHAR_C;
segs[1] = display.encodeDigit(ch) | 0b10000000; // Display channel & solid colon
segs[2] = display.encodeDigit(val / 10);
segs[3] = display.encodeDigit(val % 10);
}

display.setSegments(segs);
}

// --- LED Gamma Correction ---
// Converts linear percentages into a logarithmic PWM signal for human eyes
int calculatePWM(int master, int mix, int minPWM) {
if (master == 0 || mix == 0) return 0;
unsigned long linearPercent = (master * mix) / 98;
unsigned long curvePercent = (linearPercent * linearPercent) / 100;
// Maps the exponential curve above the physical turn-on threshold of the LED
int pwm = map(curvePercent, 0, 100, minPWM, 255);
return constrain(pwm, 0, 255);
}

void loop() {
// 1. Read Inputs
bool menuState = digitalRead(BTN_MENU);
bool upState = digitalRead(BTN_UP);
bool dnState = digitalRead(BTN_DN);

// 2. Menu Navigation
if (menuState == HIGH && lastMenuState == LOW) {
if (currentMode == NORMAL) { currentMode = SET_L1; }
else if (currentMode == SET_L1) { currentMode = SET_L2; }
else if (currentMode == SET_L2) { currentMode = SET_L3; }
else if (currentMode == SET_L3) {
DateTime now = rtc.now();
currentHour = now.hour();
currentMinute = now.minute();
currentMode = SET_HOUR;
}
else if (currentMode == SET_HOUR) { currentMode = SET_MINUTE; }
else if (currentMode == SET_MINUTE) {
// Save new time to hardware RTC
DateTime now = rtc.now();
rtc.adjust(DateTime(now.year(), now.month(), now.day(), currentHour, currentMinute, 0));
currentMode = NORMAL;
}
}
lastMenuState = menuState;

// 3. Up Button Logic (Tap & Hold)
if (upState == HIGH) {
if (lastUpState == LOW) {
upHoldTime = millis();
incrementSetting();
} else if (millis() - upHoldTime > HOLD_DELAY) {
if (millis() - lastStepTime > STEP_SPEED) {
incrementSetting();
lastStepTime = millis();
}
}
}
lastUpState = upState;

// 4. Down Button Logic (Tap & Hold)
if (dnState == HIGH) {
if (lastDnState == LOW) {
dnHoldTime = millis();
decrementSetting();
} else if (millis() - dnHoldTime > HOLD_DELAY) {
if (millis() - lastStepTime > STEP_SPEED) {
decrementSetting();
lastStepTime = millis();
}
}
}
lastDnState = dnState;

// 5. Update LED Outputs
// Custom minimum thresholds (25 for White, 5 for Amber) prevent sudden shut-offs
analogWrite(LED_CH1, calculatePWM(masterDim, mixL1, 25));
analogWrite(LED_CH2, calculatePWM(masterDim, mixL2, 25));
analogWrite(LED_CH3, calculatePWM(masterDim, mixL3, 5));

// 6. Throttled Display Refresh (20fps to prevent ghosting/flicker)
if (millis() - lastDisplayUpdate > 50) {
updateDisplay();
lastDisplayUpdate = millis();
}
delay(10);
}

Mount the LED Strips

IMG_20260721_015559.jpg
IMG_20260721_015653.jpg
IMG_20260721_023020.jpg

Next, it was time to mount the lights onto the central cylinder. I simply peeled away the protective backing to expose the adhesive on my LED strips and carefully wrapped them around the 3D printed holder.

Since I am using three different colors of LEDs for this project, I made sure to alternate and space the cool white, warm white, and amber strips evenly as I worked my way up the cylinder. Taking a little extra time to arrange them nicely ensures that the different colors will mix together perfectly once the white lampshade is placed over the top.

Making the Display Window

IMG_20260721_110113.jpg
IMG_20260721_111812.jpg
IMG_20260721_111902.jpg
IMG_20260721_112712.jpg
IMG_20260721_113214.jpg

To cover the clock display, I made a small window from a piece of 2 mm thick clear acrylic.

I cut the acrylic to 55 mm × 25 mm by scoring it several times with a utility knife. A scoring or chipped blade works best for this. Once the score line was deep enough, I simply snapped the acrylic along the line to get a clean edge.

To make the display look a little nicer, I applied a piece of cooling window film to the acrylic. This gives the display a darker, tinted appearance when it's turned off while still allowing the digits to show through clearly when it's on.

Finally, I placed the acrylic inside the base behind the display opening and secured it with a few small dabs of super glue. Use only a tiny amount of glue around the edges. Too much super glue can release fumes that leave a white, foggy residue on the acrylic, which is difficult to remove.

Final Assembly

IMG_20260721_113153.jpg
IMG_20260721_113357.jpg
IMG_20260721_114647.jpg
IMG_20260721_115832.jpg
IMG_20260721_120341.jpg
IMG_20260721_122653.jpg
IMG_20260721_122908.jpg
IMG_20260721_120945770_HDR.jpg

Now it's time to put everything together. I started by sliding the three touch switches into their slots in the base. Make sure each switch goes into the correct position. If you accidentally swap them, don't worry, you can easily change their functions later in the code.

Next, I mounted the 4-digit display using M3 screws, followed by the DC power jack. After that, I secured the perfboard inside the base with M2 screws.

With the electronics in place, I mounted the LED holder to the base using two M3 screws and connected all the cables to their matching connectors. Before closing everything up, it's a good idea to power the lamp on and make sure all the LEDs, touch switches, and clock are working correctly.

Once everything was tested, I installed the back cover and secured it with M3 screws.

At this point, the assembly was almost complete. All that was left to do was place the lamp shade on top and enjoy the finished build.

Final Look

IMG_20260721_123306.jpg
IMG_20260721_123700.jpg
IMG_20260721_123746.jpg
IMG_20260721_123935.jpg
IMG_20260721_123941.jpg
IMG_20260721_124322.jpg
IMG_20260721_124327.jpg
IMG_20260721_124316.jpg
IMG_20260721_124129.jpg
IMG_20260721_124144.jpg
IMG_20260721_124716.jpg

With the assembly complete, it was finally time to see the finished lamp.

Since I'm using 12 V LED strips, the lamp is powered by a 12 V, 3 A power adapter. I connected the power supply, placed the lamp shade on top, and turned it on for the first time.

Interestingly, the shade I'm using here is actually the failed Vase Mode print from earlier. Even though the top section is missing, I still think it looks better than the fully printed version because the single-wall print diffuses the light much more evenly.

The lamp has three touch buttons: Plus (+), Minus (-), and Menu. Thy are embossed on the top of the base.

The Plus and Minus buttons adjust the brightness of the lamp. Pressing the Menu button cycles through the available settings:

C1 → C2 → C3 → Hour → Minute

The first three options control the brightness of each LED strip individually. For example, if I want the lamp to glow only in amber, I can simply set the cool white and warm white LEDs to 0% and leave only the amber LEDs on. You can also mix the three colors to create different lighting effects.

The Hour and Minute options are used to set the clock, with the Plus and Minus buttons adjusting the values.

One thing that's missing at the moment is memory for the LED settings. Every time the lamp is powered on, the color levels return to their default values. I might add this feature in a future update.

Overall, I'm really happy with how this project turned out. The hydro-dipped marble base pairs nicely with the glowing lamp shade, and the built-in clock makes it both decorative and practical.

So, what do you think of this simple Sun-inspired lamp? I'd love to hear your thoughts, suggestions, or ideas for improvements in the comments below.

Thanks for reading, and happy making!