The Death Star inspired IKEA PS 2014 Pendant Lamp is a great platform for a connected home hack. Mine is shown in the video below.
Out of the box, the lamp uses a string and pulley system to open and close the spherical shell. It is a relatively simple mechanism where two strings pull a platform up and down a central spine. Ten scissoring arms attach to this moving platform and to a fixed platform near the top of the lamp. Moving the bottom platform up the spine spreads the outer ends of the arms, opening the lamp’s outer shell (see diagram below from the lamp’s assembly manual).
There is a void where the lightbulb normally sits between the top-most position of the moving platform and the upper platform. This provides the space for the stepper motor and LEDs needed for my modifications. The upper portion of the spine which splits in two to accommodates this space also offers a convenient platform to attach these new bits to.
Lastly, there is cap used to cover the wiring where the lamp anchors to the ceiling. This provides a convenient space for electronics. In my case, I’m using an Arduino Uno, an Arduino Motor Shield and a SmartThings Shield.
I replaced the standard wiring with a Cat5 ethernet cable to connect my electronics in that cap to the motor and LEDs in the body of the lamp. Four of the Cat5 wires are used to control the motor and three for the LEDs, leaving one unused wire.
Given the design of the lamp, it seemed easier to directly drive the lamp’s lower platform rather than try to pull the strings that the lamp ships with. I first thought I would attach a threaded rod to a standard stepper motor, but then I found this motor with a lead screw that is long enough to cover the entire length of the lamp’s spine.
I attached the motor using a standard mounting plate and a fiberboard bridge attached to the central spine of the lamp.
Driving the motor was simple once I found a motor shield that could power it. I first tried Adafruit’s Motor Shield, but it does not provide enough power. After realizing this, I did a bit more research and determined that the Arduino Motor Shield should be able to drive the motor. And it is.
The video above shows the motor moving the platform and opening two of the ten arms. When the lamp was finally assembled, I cut off the last few inches of the screw so that it was just a little longer than the spine.
For the lights, I wanted the flexibility to individually control an array of RGB LEDs. I’ve used the NeoPixel rings before in another project and really like how simple they are to use and how the ring format provides very nice visual effects with relatively simple animations.
Given the design of the lamp and the need to work around the motor’s position, I wanted to use the larger 60 LED ring configuration. Unfortunately, the rings could not fit in any one location when the lamp’s arms were both extended and contracted. Luckily, each 60 LED rings is actually made of four 1/4 circle arcs. I ended up using two sets of three arcs in triangular configurations (one triangle facing down and one facing up).
I then added a 24 LED ring to the top of the lamp to add a bit more brightness. This also works to fill some of the shadows cast on the ceiling by the internal LEDs. The results are great, especially when the lights are animating.
I’m using the SmartThings platform to control the lamp. I went this route for two reasons: it is relatively easy to build a controller UI to use within the SmartThings app and I can integrate it with other things in my house connected to the SmartThings platform.
I created the UI by writing a device handler. The handler sends commands as strings to the SmartThings Shield which are then passed as a parameter to a designated handler function running on the Arduino.
I have not yet connected the lamp to other things but this can be done by writing a SmartThings app.
Very early on in the project, it was clear that constrained RAM on the Uno would be an issue. The first indication was that the board kept restarting with all three components integrated (while any two components worked well).
The first step was to do some simple optimizations to the types of variables I use (e.g. uint8_t in place of int). With this I was able to could get the three components working together; however, memory was still maxing out when I sent long strings from SmartThings. “SetColor: 255,255,0” would work but, “SetColor: 255,255,255” would cause problems. Simply shortening these to “sc:255,255,255” did the trick.
Then something quite surprising happened. The .toInt() function that I use to convert the strings to integers would periodically stop working and convert any three color values to 0,0,0 until I restarted the Arduino board.
I tracked this down to what I believe to be another memory issue, but one more complicated than simply running out of memory. Removing the motor code from the project (and freeing a good deal of memory) was not fixing the issue. On the other hand, removing some of the strings from the sketch that were used to parse the commands sent from SmartThings (freeing up very little memory) did fix this new problem.
In the end, the fix was to further shorten all command strings and to reduce the overall number of commands by consolidating related commands into individual commands with enums.
The lamp can be turned on and off from a standard wall switch so it was important to me that I persist some of the settings while the power was off.
Retaining the position of the moving platform is most important since doing so frees me from adding sensors to know when the lamp is fully open or closed (and thus keep the motor from grinding away once it reaches one extreme or the other).
I also save the NeoPixel RGB and brightness values.
I originally planned to use an FRAM memory module but my previously mentioned memory constraints as well as some pin constraints imposed by the motor shield forced me to reconsider. I decided instead to take a shortcut and use the Arduino’s built in EEPROM memory. This is volatile memory rated for 100,000+ writes, but I’m ok with that trade-off for now.
During development I powered the motor and lights through the Arduino with the lights hooked up to VIN. This worked fine as long as I dimmed the LEDs before running the motor.
However, when run at any significant brightness for moderate periods of time, the power would cut off. This is because the 114 NeoPixels pull about 3 amps at full brightness and my 2 amp power source shuts itself off before damage is done (there is a thermal switch that is thrown as it overheats). Using the recommended calculations it was clear that I should be using a dedicated power supply rated for at least 7 amps.
In the final installation, the lamp is powered by two 5V supplies. The first is a 2 amp supply used for the Arduino and motor plugged into the Arduino’s barrel jack. The second supply is a 10 amp supply connected to the LEDs using this barrel jack adapter (with the ground tied to both the LEDs and the Arduino).
Thats about it
All in all, this was a fun project and I’m pleased with the the results. It presented a number of puzzling challenges both with modifying the physical lamp and getting the different electronics working together and I learned a number of new details along the way.
You can find the Arduino and SmartThings code on GitHub.
If you have any questions let me know in the comments and I’ll do what I can to answer them. And, if this you build your own, I’d love to see it.