Electronic LED Fireplace
This is a cheap way to make a realistic-looking electronic fireplace display that you can put in an empty fireplace or anywhere in your home to give you the feeling of having a real log-fire in the room. It just doesn't produce any heat!
This project requires good computer programming skills and some advanced image data analysis. I used Python and the OpenCV, Pillow, Numpy, and Scipy numerical libraries. It's great for someone who is an experienced programmer and wants to use their skills for something creative.
Supplies
- Arduino or similar micro-controller —I used a Teensy but it doesn't matter.
- About 100 5V RGB LEDs wired in a string — I used two strings of 50 WS2811 LEDs with 4cm spacing between each LED.
- 5V power supply.
- Wires to connect the LEDs to the IO pins of your micro-controller.
- PC or laptop computer with the Arduino programming app.
- USB cable to connect the Arduino microcontroller.
- Smartphone with a video camera.
- Cardboard / old cardboard box.
- White and black paper.
- Glue gun.
- Translucent sticky tape.
- Scissors, knife.
Record a Video of a Real Fire or Download One
I used a video I found on YouTube:
This is a really long video. For this project you only need about 5 seconds of video. Depending on the frame rate of the video, 5 seconds is already a lot of video frames. The above video is 25 fps and I used about 150 frames in the end (6 seconds of video).
To download the video and extract the individual frames as images I used the OpenCV Python library.
Build LED Display
I used an old cardboard box and cut the back panel out. I then sketched the outline of the fireplace on the cardboard using the YouTube video as a guide to the position of the flames and the logs. I then punched holes in the cardboard in a random pattern that roughly corresponded to where most of the flames were in the video images. I then pushed the LEDs through the holes, bending the wires so that they fit (this is why you need LEDs on a flexible string with at least 4 cm of wire between each LED).
To create a flame-like effect, I used strips of white paper of equal width, glued to the cardboard panel with the LEDs in and added some black paper shapes to represent the logs. The images above show the front and back of the display panel after fitting the LEDs and the paper strips.
Finally, I covered the front of the panel with one sheet of white paper cut to size and taped it in place.
Switch Each LED on Separately in a Sequence and Film It With a Smartphone
In order to program the display, we need to know the locations of all the LEDs and the shape of the light that they create on the screen. Rather than figure this out by hand, I wrote a script to turn on each LED one-by-one. I set the colour intensities to (64, 64, 64) which is a low-intensity white light at the level of brightness I wanted the final LED display to have.
I then filmed the whole sequence in a dark room using a smartphone camera and uploaded the movie file from the camera to the computer.
Load Video File and Select a Frame to Represent the Effect of Each LED
I used the same technique used in step 1 to extract each frame from the camera video file as an image. Then I selected one image for the light produced by each LED. I call these mask images because they mask out the light from all LEDs except one. The image above is an example of one of these mask images.
You could do this by hand, it wouldn't take long, but I wrote a script that goes through all the video frames and selects the unique images automatically.
Compute LED Intensities to Mimic the Real Fire Video
This is the hardest step. The goal is to find the LED colour intensity values (red, green, blue) that best match each frame from the real fire video.
Before starting this step, you will probably have to crop and scale the images from the smart phone so that the locations of the LEDs in that video, match the locations of the flames and the logs in the fire video you are trying to mimic. The way I did this, was to create composite images showing all the frames blended together and setting them side-by-side. Then I adjusted the size and scale of both until they looked right.
The simplest way to compute the colour intensity values for each video frame is to consider the effect of each LED separately. Starting with the red colour channel, the computer adjusts the brightness of the mask image until it minimizes the squared difference between the true image from the fire video and the adjusted mask image. To do this I used a numerical optimizer—the optimize.minimize function from the Scipy library. I constrained the adjustment factor to the range 0 to 1, so this ensures the colour intensity values are all between 0 and 64.
Then repeat the optimization procedure for each LED, for each colour (red, green, blue), and for each frame in the video you want to replicate. This can be a slow process, depending on the optimization algorithm you use and the speed of your computer. In my case it took 1.5 hours to calculate the LED intensities for 40 frames of video.
The image above shows the LED intensities calculated for an example fire video frame shown on the left.
Adjust LED Intensities and Upload to Microcontroller
I found that the LED intensities calculated in step 5 were not quite right—in my case parts of the fire image were too blue. I think this is due to the non-linear characteristics of the LEDs and probably also the camera used to make the mask images. So I divided all the blue intensities by two (range 0 to 32) and this solved the problem.
Finally, I copied all the LED values to the Arduino script I loaded onto the Teensy to run the display.
All the code for the project is available here for reference:
Nevertheless, I strongly encourage you to write your own code. It might be easier and certainly more rewarding to do that than trying to figure out how I did it.
Updates and Extensions
I just found out that there is an open source code repository for doing the mapping between LED intensities and display output using a webcam:
I haven't tried it but it sounds like it will do the image processing and save you having to write your own code (or figure mine out!). It sounds like the LEDs and the webcam are run in closed-loop with the algorithm, which is a more sophisticated approach than the one I describe above.