Adjustable Desk Lamp
A 3D printed articulating desk lamp with an ESP32 controller and WS2812 LEDs, brightness and color temperature set from a rotary encoder.
Components
- ESP32-WROOM-32 dev board
- WS2812B LED strip, 60 LEDs/m, cut to 30 LEDs
- Rotary encoder with push button (KY-040)
- 5V 3A power supply
- M3 heat-set inserts, various lengths
- 608 bearings for the arm joints
Files
- Lamp arm joints (STL) , printed at 0.2mm layer height, 20% infill
- Base plate (STEP)
What I was trying to make
I wanted a desk lamp that could bend into weird angles without the joints going loose after a month, and that I could dim and change color temperature without pulling out my phone. My old lamp was a cheap clip-on that only had one brightness. This is the excuse I used to finally learn how to drive addressable LEDs properly.
Design process
I started in Fusion 360 with a basic two-segment arm, hinged at the base, the elbow, and the head. First attempt used friction-fit joints with no bearings, just PLA against PLA. That held its position okay when new, but after about fifty adjustments the joint surfaces wore down and the arm started drooping under its own weight.
Second version added a 608 bearing at each joint and a nut-and-bolt through the center so I could tune the friction with a screwdriver instead of it being fixed by the print. That fixed the drooping completely, and now I can dial in exactly how stiff each joint feels.
Electronics and components
The LED strip runs through the inside of the arm, which meant routing wire through a hollow channel I had to reprint twice because I made the inner diameter too small the first time and couldn't fish the wires through without them snagging on the joint hardware.
Everything is controlled by an ESP32, mostly because I already had one lying around and wanted an excuse to use it. The rotary encoder sits on the base and controls brightness with turns and toggles between brightness and color temperature mode with the push button. There's no app or web interface, just the knob, which was a deliberate choice: I wanted something my hands could operate without looking at a screen.
Build process
Print time for the full set of arm segments, joints, and base was about 14 hours split across a few print jobs so a failure wouldn't cost me the whole thing. Assembly was straightforward once the joints were dialed in: heat-set inserts in the printed parts, then bolts to clamp the bearings and hold everything together.
Wiring was the fiddly part. I soldered the LED strip data line, 5V, and ground directly to the ESP32 with short pigtails so nothing pulls on the strip terminals when the arm moves.
Problems and failed attempts
The first channel design was too tight and thin filament strands would catch when I tried to pull wire through, which fused the wire jacket to the plastic more than once from friction heat. I redesigned the channel with a bigger diameter and a smoother internal curve at the joint crossing point, and that solved it.
I also fried one ESP32 early on by wiring 5V into a 3.3V logic pin by mistake while half paying attention. Lesson learned: label your dev board pins with tape before wiring anything late at night.
What changed between versions
- v1: friction-fit joints, no bearings, drooped over time
- v2: added 608 bearings and adjustable-tension bolts at each joint
- v2: widened the internal wire channel after the first one melted a wire jacket
- v3 (current): moved the rotary encoder to the base instead of the lamp head, since reaching up to adjust it while the lamp was on felt backwards
Final result
The lamp holds its position reliably now, the knob controls feel natural, and I've been using it as my actual desk lamp for about a month without any joints loosening. Color temperature range is a bit narrow since I'm mixing warm and cool white LEDs on the same strip rather than using proper tunable white LEDs, which is the next thing I'd improve if I revisit this.