The icicles are hanging strips of WS2812B LEDs, controlled by an ATTiny. They have a button for changing mode and brightness. In addition, when power cycled they will change mode as well. This allows for adjustment without having to touch them, and makes them all change synchronized without any communications. The button can be used to re-synchronize if they ever get out of order. They are powered with a waterproof connector, and driven at 5V, so there is no need for any complex circuitry on the units.
The PCBs contain only a few components. The ATTiny84 runs the show. A SMT momentary tactile button adds some functionality. The connector is for standard 5.5mm jacks, but can also be used for pigtail connectors. At the other end of the PCB are pads to solder the WS2812B strip. Make sure the pins are connected properly, as some strips vary the order of the pins.
There is no extra resistor between the ATTiny and the LED strip, and there is no bulk capacitor at the strip. One could be soldered on easily, though.
There are some test pads that make additional pins available if extra circuitry is desired. That makes these PCBs fairly robust. PA0, PA1, PA2, PB0, and PB2 are all exposed for additional functionality.
The connector for programming is available as .1" spaced pads. This makes it easy to build a programming jig with spring pins, or just hold some perfboard with header pins against it.
The PCB can be potted if the button is not necessary. This would be the most secure way to waterproof everything. If the button is required, shrinkwrap tubing might work, but a better seal should be found. I haven't done this yet.
The ATTiny isn't really capable of driving more than 60 LEDs. For the icicles I've decided on between 10-20 LEDs per icicle, so it's fine. The EEPROM has 2 bytes of data; the current mode and the max brightness. A power cycle will change the mode, as will pressing the button. This is stored immediately in the EEPROM. On startup there is a delay to allow for debounce on the power supply before incrementing the mode. Pressing the button and holding increases the brightness.
The different modes have different variables. Changing the mode calls the updateVariables, which updates the variables based on the new mode. These are hardcoded for maximum awesomeness.
For the LED control, I used the Light_WS2812 library. However, when using HSV, it uses a lookup table to adjust brightness, bu this explodes the memory usage, so I disabled that lookup.