For some time now, my wife and I have had a white rope light above our fireplace mantel. I was already planning to replace it with some neopixels, so when the opportunity came along to use a network-controllable device to drive it, I couldn't refuse.
This is my first Instructable, so please be kind.
Step 1: Gather the Parts
The parts I used are:
- A Spark Core [https://www.spark.io/dev-kits] (thank you Spark.io!)
- Adafruit Neopixel Strip [https://www.adafruit.com/product/1460]
- A 5v Power Supply capable of driving 68 pixels [http://www.radioshack.com/enercell-5v-3-6-amp-ac-adapter-with-usb/2730437.html]
- Laser Cut box for the enclosure [http://www.makercase.com]
- Soldering Iron/Solder
- Wire cutter and stripper
- Shrink tubing
- Third Hand
- Female headers
- The help and guidance from fellow Makerspace members
Step 2: Prep the Parts
The Spark Core is a 3.3v device and the Neopixels are 5v. Also the core pins can't provide enough current to drive all the pixels (68) in my strip, so I was going to need to run power to each separately. Luckily the core can be powered by 5v easily thanks to its internal power regulation.
The power supply I picked up had a standard DC power plug, so I cut off the end and twisted the outside strands into a single wire and, after verifying polarity, used red and black shrink tubing to identify each.
Neopixels can be bought in intervals of 1m strips. Since my fireplace mantel was between 2-3m I measured it out and cut down the 68 pixels I needed. That length fits exactly the distance of the mantel.
The wires and connector that came attached were on the output end to connect to another strip down the line. I'm not too proud to say that I tried using those wires in my initial tests with the strip and an Uno. It took my only a heartbeat longer that I would have liked to understand what I was seeing. Once I realized that I had to add my own wires to the input end of the strip (for the record they are really clearly labeled, I'm just dense) I was back up and running.
I was using solid core wires which are a bit stiff, so my first +5v wire I connected broke the pad off the strip. I connected a new wire to the bottom of the strip and that broke off too. I was hesitant to cut off even a single pixel and feeling frustrated when my fellow member, Chris H., pointed out I could attach to the next junction up for power and still be okay. Luckily it wasn't the data pin or I would have lost a pixel. Once anchored in place I used shrink tubing to hold them fast to the strip and bind the three wires into a single cable of sorts.
On one hand I wanted this to be a permanent fixture in my house when done. On the other, I couldn't bring myself to solder something as multi-talented as a Spark Core into a project. So I decided to compromise and connected female headers onto my perfboard so I could remove the core later if I needed.
Another fellow makerspace member, Pete P., had written a recent blog post on tools to design boxes with the laser cutters we have at the space. He also sold me a nice piece of black acrylic he had on hand to make the box. We added a couple of holes on each of the long end to handle power and data lines. Half an hour and some hot glue later and I had my enclosure.
* Yes, at this point I'm labeling my subheadings just for alliteration purposes.
Step 3: Wire It Up!
This part was the most time consuming but the easiest to describe.
I ran both sets of wires into the holes at each end of the box. I quickly realized I had made the decision to place the core headers in the middle of the board based on personal preference and not based on what would be easier to connect all the lines.
Luckily the height of the headers provided a nice channel to run the wires. You can see from the pictures the kind of mess I made in there, but once the core is in place, most of it is covered.
Of course, once the lid was in place it was all covered up, so...
Step 4: The Code
The Spark.io web page describes the Core as "Pretty Arduino-ish" and that it is. You can program and flash the core through their web-based IDE which already has contributed libraries for the Neopixels and many more.
The code is pretty raw and I'm almost ashamed to post it here, but... here it is.
There are four public functions:
- setMode - Choose between various display modes (below)
- setColor - Set the color using rrggbb two digit values (00-99) which internally map to 0-255
- setSpeed - Used as the delay() time for most of the modes
- setLength - Determines how many pixels should be on at once for many of the modes
The current modes are:
- Chase - A number of pixels (based on setLength) race from right to left
- Solid - All the pixels are a single color
- Pulse - Not finished as of this writing. Will step a given RGB down to zero and back based on setSpeed
- Blink - As you guessed the pixels turn on and off based on setColor and setSpeed
- Wipe - Cycles through the rainbow colors from right to left based on setSpeed and setLength
- Cylon - Since renamed to Larson a number of pixels swipe back and forth based on setSpeed and setLength*
- Alarm - The left and right sides (based on setLength) flash alternating blue and red like a police light. Plan is/was to use it with other triggers in case of emergency. Currently just scares the dogs.
- Frame - I added that little bit to turn the pixels behind and next to our wedding pictures a nice shade of red for effect.
*After reading the linked article about Glen A. Larson's passing, I realized I also need to adjust the code to have the faded pixels on either side.
Step 5: Try It Out!
Like a kid with a new toy, I placed the strip across the top of the fireplace, mounted the box on the side, and plugged it in!
Step 6: Next Steps and Upgrades
Right now I'm "turning it off" by turning the pixels off. Because the core needs to connect to WiFi, the boot sequence is longer than my patience. Also, the code has some defaults, but I don't want to change the code whenever my mood changes.
In future updates I either want to use Spark's "EEPROM" library to store each of the variables for load on the next boot, or add code for the HTTP client I've already included to have it pull defaults from a "control node" web page or something.
Currently I'm just controlling it via HTTP calls on the command line (curl) to a web page I've written on my server that holds the Core's ID and auth code so I can send a single URL and send multiple commands at once. I've already started playing with integrating Spark and SmartThings so I can control it from my phone without building my own app.
I'm thinking about integrating into IFTTT/Zapier and/or an iBeacon I have for controls when I come and go from the house.
There are also a lot more modes and effects I want to add to the current code base.