A $3000 thunder and lightning cloud lamp have gone viral in the DIY community. It was a stunningly beautiful light, but the price tag kept it out of reach for anyone with their sanity intact. The item we'll construct today isn't precisely the same; we're creating something more practical than an art piece, but it will be far more excellent and adaptable.
Because you presumably already have a good pair of speakers in your room that you would want to use, and since putting a speaker in a lamp is sort of strange, I've chosen to exclude speakers. Instead, I'll be including a microphone that will enable the lightning to react automatically to loud sounds, whether they come from a real thunderstorm or a soundtrack played on your computer or stereo.
To reproduce colors other than white and have control over each pixel, we're also going to use a strand of full RGB Neopixel LEDs (WS2812B).
Warning: The power supply I used for this project includes screw terminals that connect to a live AC wire. Be sure you choose a completely enclosed power supply if you don't feel confident wiring a plug. You must, at the very least, secure the PSU within a project box.
Step 1: Introduction
The completed project is shown in this video. So far, I've added a few different modes, ranging from the standard lighting to a trippy acid cloud and a color-fading mood lighting that can be chosen from the remote control.
This GitHub repository offers the full code and libraries needed for download.
Step 2: You Will Need
- WS2812B strand, 5 meters, is typically priced at about $50. Don't worry if you have a different type of Neopixel strand; it's almost definitely supported by the FastLED interface, but your wiring could be different (you may require a sync line in addition to the signal, for example).
- 5V, 10A+ power supply; I paid $11 for several 15A units. They take 120–240V AC input and produce a hefty 5V output, which will be more than enough to power all of our pixels at full brightness and the Arduino.
- Electrical cabling, plug, and inline switch.
- Project enclosure.
- Two Arduinos. $10 Arduino clones are OK. Although the first controls the primary logic and lights, the second is required for remote control.
- Two 2.2k (or roughly) Ohm resistors. The exact value doesn't matter so much; between 1.5K and 47K should work.
- TSOP4838 IR receiver.
- Large microphone module.
- IR remote, I bought them in bulk for about $2 each, but any remote should work with code modifications.
- A jigsaw and scrap MDF wood to cut your base.
- Polystyrene packing material and box inserts.
- Pillow stuffing is made of polypropylene cotton. From a few awful old pillows, I pulled more than I needed. If that isn't an option, you should be able to get some fresh for less than $10 or use cotton wool, which is much less costly. The cotton wool required more work to tease out and wasn't as fluffy, but in a pinch, it would work.
- Chain and hooks to hang the cloud – should hold up more than 5kg.
- Spray glue makes it easier to stick the stuffing onto your cloud with this, but a glue gun could also work.
- Glue gun with low-temperature setting.
Without tools, the total cost is roughly $100; however, most of this was scrounged from around the house. The microphone may be included in a sensor kit or purchased separately. All of the electrical parts are widely accessible.
Step 3: Cut the Base
Cut out a rough base with a jigsaw from a scrap piece of MDF; the precise shape is obviously up to you, although for some reason in my head, a cloud is kidney-bean shaped. This only serves as a solid base to build upon; we'll be attaching some hooks to it for hanging. Make sure you have enough space to set up at least your project container with several hooks surrounding it since the core area will be reserved for the electronics, PSU, and to hang the chain from.
Step 4: Layer on Polystyrene
We're actually just making something solid and kind of cloud-shaped to glue the LED strip onto, which is the most challenging and creative stage. Glue huge chunks of polystyrene packing onto the base (and beneath it), using a low-heat setting on your glue gun. Turn off the heat gun before attempting to glue if it doesn't have a low setting and let it cool down a little. If the temperature is too high, the rough packing material will simply melt.
Make sure each piece is solid before gluing the next, and it's better to use more glue than not enough.
Remember once again to leave a large enough space within the cloud to accommodate the electronics, chain, and hooks.
Step 5: Carve a 3D Cloud Shape
Using a carving knife, neaten up your cloud shape by rounding off the edges and removing any unnecessary material until you have a rough 3D cloud shape. Because we'll be covering everything with stuffing later, it doesn't really matter how rough everything is—mistakes can be easily hidden.
Step 6: Fix Hooks, Tidy Up
From within each corner of the cloud hollow, attach three or four hooks to the MDF base. While MDF is difficult to screw straight into, you will need to drill a small pilot hole.
To guarantee a uniform color base, I also gave everything a simple layer of white spray paint, though I'm not sure that was truly required.
Step 7: Glue LED Strips
When you start applying glue to the LEDs, either count how many you have in total or start from a new strip; you'll need to work out how many you've used later in the programming process. Make a small hole on the side of your cloud and insert the rough wires that make up the start of your LED strip into the cloud cavity. Be extremely cautious and start from the right end; the LED strips are direction-sensitive, so make sure the signal arrows point away from the cavity.
Working slowly, stick the LED pixels in a circular pattern to the polystyrene base before drawing the strip down to cover the bottom. Again, you don't have to be flawless because after we've diluted everything and drowned it in stuffing, it all looks pretty stunning.
I used a total of 85 LEDs, or a little more than 2.5 meters, encircling the main body twice and using a single string of LEDs on the bottom.
Step 8: Wiring Diagram
While the wiring is complex, it may be easily broken down into smaller pieces.
Then, get the separate power supply wired in and secured, preferably in a power supply project case. I'm not going to lecture you on the safety of live AC wires, so I'm going to presume you can handle this component and that you have a 5V and GND line from it.
IMPORTANT: When programming and testing the Arduino, the 5V from your power supply should remain separate from the Arduinos (the GNDs are all linked, however); the Arduino should just be lighting the LED strip. When programming is complete, the USB connector should be removed so that the Arduino is no longer receiving 5V. The 5V rail on the left side of the breadboard should now be connected to the 5V from your supply.
Begin by connecting the ground and 5V pins from each Arduino to the breadboard's left-side rails. Whether it's the external PSU we have or the USB connection to one of them, they will share the same power supply.
Next, finish the I2C wiring portion; this is what enables the communication between our two Arduinos. Connect a 2.2k resistor from that row to the 5V rail by connecting the A4 pins from both Arduinos to a single row on the breadboard. Repeat for A5, connecting them in a separate row with a different 2.2K resistor that is also powered by 5V.
Connect the IR receiver next; if you have a different type, verify the pin setup, but generally speaking, the signal pin on one Arduino should go to D11. Unplug the USB device after uploading the thundercloud_ir_receiver.ino sketch to this Arduino (full code here).
Connect the Data In signal pin from the LED strip's start to D6 on the other Arduino. At this point, the 5V will come straight from the PSU, but the GND from your LEDs should be shared by all Arduinos.
Plug the microphone module into pin A0 on this Arduino as well. As you debug, keep the USB plug plugged in and upload the second thundercloud.ino sketch. Start by correctly altering the NUM_LEDS variable.
Step 9: Glue on the Stuffing
Glue your stuffing on as the last step. There is no specific technique here; just spray the cloud with glue and grab some stuffing. But if you've previously teased out the stuffing to expand the surface area, it's simpler to work with.
The sound-responsive cloud mode is activated by the Strobe button, the trippy color mode is activated by the Flash button, and the slow-fading mood light is activated by the Fade button.
Step 10: Code Explanation
Why are there two Arduinos? Timing is crucial for both the IR receiver programming and the WS2818B pixel driver library; if the timing is off, the IR signal is garbled. We can make sure timing is accurate on each circuit by providing it with its own microcontroller and having them talk through the I2C protocol. Nevertheless, my study revealed that they really cost more than a simple Arduino clone and an IR LED. You may even get separate IR modules with their own microcontroller built in. While you may want to study up on I2C fundamentals beforehand, the thunder cloud receiver shouldn't need an explanation.
We define many operating modes on the main thundercloud controller, including ON (the lightning effects are not sound triggered), CLOUD (the lightning is solely sound activated), ACID (the cloud displays trippy colors), and simple single-color modes. To define a new mode, first, add it to the enum, then open the console and locate a remote control button to map it to. Each time the button is pressed, a line of debugging information should be printed. Add an extra switch statement there, since we map those key presses to a mode in the receiveEvent() function. We then direct those mode options to various display routines in the main loop() method.
I simplified the Adafruit microphone smoothing code for our purposes and added a trigger when a louder-than-average noise is encountered.
Step 11: Lightning Modes
To produce something that is sufficiently realistic, or at the very least aesthetically acceptable, the lightning displays mix three different “types” of lightning. The first type is crack(), in which each LED is briefly turned on for between 10 and 100 ms. The second type is rolling(), in which each LED has a 10% probability of turning on and the loop is repeated 2-10 times with a 5-100ms delay between each cycle. Thunderburst(), the third type, selects two different sections of the strip, each with between 10 and 20 LEDs, and briefly flashes them 3-6 times. Look closely at these techniques to observe how each LED is turned on. White is represented by (so white is H=0, S=0, V=255). using the HSV color wheel. If you create a lightning display you enjoy, I'd invite you to modify it or write new lightning displays and submit them in the comments.
The cloud randomly selects one of the three lightning types each time lightning is triggered or the loop is executed. The reset() method finally turns off all of the lights; otherwise, they would “remember” their former state.
Questions or problems? Please get in touch in the comments, and I'll try my best to assist you. Post bugs and problems to the issue tracker instead if you have a GitHub account. Please share a link to your code on Gist or Pastebin if you have made any changes or written any new lighting routines.