Lampe - overengineered desk lamp, part 12018-01-30
So, I love dimmed light. If there's one thing I can't stand, it's bright artificial lights in the evening that fill the entire room. To me, this is the opposite to cozy feeling. Which is why the main light in my apartment will be turned on 5-6 times a year at most.
There's one problem though: my other lights suck as well. But hey, we can solve that with some stupid over-engineering and hardware hacking! I'll start with a desk lamp, which I use most of the time.
I won't settle for less than this:
- 3/8" thread mount. I've got a microphone telescope boom stand attached to the cabinet beside my desk, which Is much more stable and versatile than those flimy desk lamp stands you can buy.
- 5 or 12 volt input. My homeserver has 5v and 12 v outlets with lots of current on reserve, so if I can use these to avoid a wall-wart: awesome.
- fine-adjustable dimming. None of that "3 brightness levels" crap. I need really fine controls!
- adjustable colour temperature. For soldering work, I love a colder colour temperature. For everyting else, I'd prefer a warmer temperature.
- on/off switch that saves the last setting.
- huge dynamic range - very low brightness, very high brightness.
Nice to haves
- party-mode - RGB all the things! For shits and giggles. Art-Net or DMX? :)
- timed brightness & colour temperature. slowly fade in over the course of an evening and reduce colour temperature when it's getting late.
- remote control (web interface?)
- cool looking.
- sturdy and transportable (ready to be thrown in a backpack for remote work or hackercons)
I've had these neat little esp8266 modules lying in a drawer for over a year now, and I thought that this was a really cool small project to start getting familiar with these things. small, very cheap, pretty much no extra components needed, tons of processing power, wifi, just enough pins to do something useful with them. Awesome! For this Ive used the ESP-07 modules which have an optionally attachable antenna and 1MiB flash. I've also got lots of ws2812b RGB LEDs lying around, so I've used a bunch of those as well. And because I'm a really bad C programmer and a bit lazy, I've decided to use the NodeMCU lua firmware.
16 ws2812b LEDs wired to a freestanding 4x4 matrix (remember those cool 3D LED cubes?) with some thick wire. you do not want to see pictures of this, believe me. Also, an AMS1117-3.3 linear voltage regulator to drop the incoming 5 volts from my homeserver to 3.3 volts for the esp8266. I've had a few of these super-cheap rotary quadrature encoders flying around, so I've slapped that on as well. With everything somewhat securely placed in a small candy can (to act as a lampshade) I sacrificed a microphone clip to have a 3/8" thread and some positioning control.
Connect the ws2812b data pin to GPIO2, rotary a&b to GPIO12 and GPIO13, rotary button to GPIO14, and off you go!
That's what I came up with after a bit of fighting with lua. (lua is a really weird language. I don't think I'm going to be a big fan of it!)
ws2812.init() buf = ws2812.newBuffer(16,3) rotary.setup(0, 6, 7, 5, 100, 250) pos = 10000 activated = false brightness = 0 blue = 128 green = 255 pressed_turn = false function set_leds() local i = brightness if not activated then i = 0 end local b = math.floor(blue * i / 255) local g = math.floor(green * i / 255) -- DEBUG: print(string.format("active: %s, brightness: %d, resulting colour: %d %d %d", tostring(activated), brightness, g, i, b)) buf:fill(g, i, b) ws2812.write(buf) end rotary.on(0, rotary.TURN, function (_, new_pos, _) local _, pressed, _ = rotary.getpos(0) local diff = new_pos - pos pos = new_pos if pressed ~=1 then -- contrary to the docs this is not a boolean, but some integer brightness = math.max(0, math.min(255, brightness + diff)) else blue = math.max(0, math.min(255, blue + (diff * 4))) green = math.max(0, math.min(255, green + diff)) pressed_turn = true end set_leds() end) rotary.on(0, rotary.CLICK, function (_, _, _) if pressed_turn then pressed_turn = false else activated = not activated end set_leds() end)
Result so far
This is what I've implemented already with this low effort:
- 3/8" thread mount from an old microphone clip.
- 5 volt dc jack.
- fine-adjustable dimming. Granularity for lower brightness is bad though.
- on/off switch that saves the last setting. doesn't persist through power loss yet.
Huge dynamic range?
Even though I can adjust the brightness level with the rotary encoder, it needs some further work. Especially the lower levels are really coarse compared to the higher levels. Wouldn't call that done. Maybe I can start turning off individual LEDs on lower levels to increase the available resolution? (switching off half of the LEDs would effectively give me one extra bit of resolution - 512 vs. 256 levels)
Also: I could use more brightness. 16 ws2812b do light up plenty in the evening, but at daytime I can use a lot more brightness.
Right now I can adjust the blue-level, but I would not call that adjustable colour temperature. It's more like a "suck less" control. Also, the white from RGB-only LEDs sucks. I would love to switch to a mixture of RGBNW and RGBW SK LEDs. Depending on the brightness level of either RGBNW or RGBW LEDs I can shift the colour temperature in between those values. I would need a lot more LEDs for that though to retain enough dynamic range for either temperature extreme.
If I set the lamp to full brightness the LEDs will warm up quite a bit. I would rather slap on a lot more LEDs and in turn set these to lower levels for the same amount of light output, thus spreading the heat over more components.Maybe add a small optional fan (PWM?) and temperature sensor for a sustainable "ZOMFG SUPER BRIGHT" mode.
DIY LED control?
ws2812b LEDs are really, really easy to implement electronically, but maybe we can get better (and brighter) results by rolling our own PWM control for regular LEDs? I don't really need to be able to control every LED individually, a grouping of 3, with RGBW controls for each would be plenty.
Well, first up I want to get the software polished up. Implement the missing features, especially cool stuff like timed brightness & temperature (NTP?) before shelling out lots of money for custom PCBs and LEDs. Watch this space for future posts!