🔥 Raspberry Pi Fireplace 🔥
by peinador in Circuits > Raspberry Pi
1517 Views, 16 Favorites, 0 Comments
🔥 Raspberry Pi Fireplace 🔥
Who doesn't like the warmth and comfort of a fireplace? The fire brigade and my landlord.
When I found out that my new room was going to have an old fireplace I knew I had to do something with it. Using it with real wood was not an option because it is messy, expensive and not allowed where I live. So, I needed an alternative.
Perhaps the most common uses for old fireplaces are candles and ethanol burners. However, they still involve a live flame, which means that you should not fall asleep while they are on. Perhaps more importantly, they miss what I consider to be one of the best components of a real fireplace: the crackling sounds.
So, I had two options:
- Buy LEDs, a speaker and a Raspberry Pi, solder everything together, write code to generate a decent fire simulation and put everything inside a box.
- Put my phone inside the fireplace and play a 10h fireplace YouTube video
Of course I had to choose option 1.
My idea was to build a device that has three main features:
- Flickering flame-like lighting, provided by an LED matrix. The rendering of the flame does not need to be super realistic, because the device is meant to be put inside the fireplace. Hence we will not see the matrix directly, only the light projected onto the fireplace walls.
- A small speaker playing fireplace noises.
- A knob to control the intensity of the light and sound. This is useful when you want the fireplace to be relatively quiet at night, but louder during the evening.
Disclaimer: I will assume a relative familiarity with Python (pip, jupyter, and coding in general) and Raspberry Pi (ssh and headless installation)
Supplies
- Raspberry Pi Zero W2 (+32GB microSD card)
- MAX98357A I2S 3W amplifier by Adafruit
- 3W 4 Ω speaker
- 20 mm Rotary encoder (without breakout board and resistors)
- 5V to 3.3V 4-way bidirectional level shifter (might also work without)
- 8x8 WS2812 LED (Neopixel) matrix
- On-On Miniature Toggle Switch
- USB-C Power connector mount
- 5cm x 7cm perforated PCB
- 159XXSSBK ABS enclosure 121 x 94 x 34
- Wire, block sockets, header sockets, soldering supplies.
- white card and wrapping plastic used as a light diffuser
Starting the Raspberry Pi
If the Raspberry is new, you will need to install the latest version of the Raspberry OS using an SD card. I recommend using the headless installation for the Raspberry Pi 2 W since it avoids having to connect a display and any peripherals to the Pi.
Once the basic OS is up and running, test that you can ssh into the Raspberry. The command for the default name and user is
ssh pi@raspberrypi
You will be presented with the Raspberry command line. You can update the packet manager list by running
sudo apt-get update
Wiring
The next step is to put all the components together using a simple breadboard. This allows us to troubleshoot easily before soldering anything.
Note that the pin layout on the schematic is the mirror image of the usual Raspberry Pi layout. This is because the final assembly has the Raspberry Pi mounted on top of the perforated board, facing down.
Configuration and Dependencies
Before we try to interact with the components, there are a couple of additional steps that we need to follow to configure the Raspberry Pi.
- Follow the MAX98357A documentation to configure the I2S audio output.
- 2 Install the libraries required to control Neopixels using the Pi. The Adafruit NeoPixels on Raspberry Pi article explains this well.
sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
sudo python3 -m pip install --force-reinstall adafruit-blinka
- Finally, we need to install the dependencies to control the rotary encoder:
# library to read GPIO pins
sudo apt-get install python3-rpi.gpio
Coding
Now it's time to load the software onto the Raspberry Pi. You can find my repo on GitHub. The repo is not super well documented, but it contains a notebook that explains more about the flame simulation. I will just say that it uses Perlin noise, which is a procedural noise algorithm. The noise is then passed through a filter that fades out the top to simulate the cooling down of a flame as it rises. Finally, the code converts the single channel of the noise into colour using a linear map.
If you have a Pi Zero 2 W, you could either copy the code over using shh in headless mode or clone the repo directly on the Pi:
git clone https://github.com/peinador/fireplace.git
Once downloaded, you will need to install the package:
pip install -e fireplace
The "-e" flag indicates that you want to install the package in editable mode, so that the changes that you make to the repo will be automatically loaded by pip.
Once installed, you will need to:
- Add audio files (MP3 or WAV) in data/audio_files/. You might need to create the directory if it does not exist. A collection of free fireplace sounds can be found here.
- Generate the noise image files by running python fireplace/lights/generate_noise_files. This creates a series of numpy files in data/perlin_noise.
NB. The code is configured to work with the pin setup explained here. If you have changed the pins, or decided not to use a rotary encoder you might need to edit some files.
Testing
Once the code is on the Raspberry Pi, it is time to check that everything works as intended. The fireplace repo contains a number of test files:
- tests/audio_test.py: tests the ability to play audio. You should hear the noises added to the audio data directory after a couple of seconds. Press "q" to stop it.
- tests/leds_test.py: tests the LEDs. Run this using sudo (needed to control the LEDs). You should see a fire animation on the LEDs after a few seconds. Press "Ctrl+C" to stop it.
- tests/rotaty_test.py: tests the reading of the rotary encoder. You should see numbers on the terminal if you rotate the encoder while running this file. The numbers should increase up to 100 and decrease down to 0. Press "Ctrl+C" to exit.
Running the Simulation
Once all the test are working, you can run the main simulation file, that combines all three. To run the main animation file run:
sudo python fireplace/main.py
The launcher file launcher.sh can be used to set up a crontab automatic execution upon booting.
This can be done by opening crontab
crontab -e
and adding the following line
@reboot sh /home/pi/fireplace/launcher.sh >/home/pi/logs/cronlog 2>&1
changing the directories accordingly. Make sure that the logs directory exists by doing mkdir logs where appropriate.
Assembly
Once everything is working, it is time to solder all the components together and put them inside the enclosure.
I decided to use a one-sided perforated board and solder the component according to the schematic provided above.
For the enclosure, I used an ABS plastic case. I drilled holes for
- the speaker
- the LED matrix wires
- the rotary encoder
- a toggle switch
- USB-C port
I connected the switch and the charging port to the power connection block. I used hot glue to attach the speaker and LED matrix to the case. All the circuitry goes inside. I must say that the components fit quite tightly in the case. I should have used a taller box for extra room.
Finally, I made a simple LED diffuser using some wrapping plastic and white cardboard.
Enjoy Your Fireplace!
All done! ready to enjoy your new fireplace. You can see how mine turned out above. Really happy with the result!
Some room for improvement:
Some things could be improved, although there are no plans to do it:
- Make it battery-operated!
- It takes a minute or two to start the simulation after powering the pi. This is due to the time it takes to boot the system
- The simulation is slow in the first minutes
- Better control over the iteration time
- Better configuration management.
- The speaker makes a popping noise when booting the Pi. This is probably due to the I2S configuration, and the Adafruit article linked below has a troubleshooting appendix. However, it was not very annoying and it was useful for knowing when the pi had booted.
- The enclosure is rather tight. It would have been better to have a taller enclosure (bigger on its smaller axis).
- Better LED simulation
- Make it sound-reactive
- Add additional effects, like additional flickering
- The rotary encoder misses some ticks. There was a tradeoff between de-bounding and missing ticks. Perhaps using additional pull-up resistors could have worked better than the ones installed on the Pi.
The initial idea for this project was to have a small water vaporiser (aka atomiser) connected to the Pi. The water vapour would create the illusion of smoke. However, the feature was discarded, partly because it would have significantly increased the complexity of the build in terms of dealing with waterproofing the component enclosure.