A MQTT controlled Raspberry Pi Zero nightlight and white noise machine

Admir Cosic
7 min readDec 16, 2020

--

Resources

To complete this project you will need the following:

  • A Raspberry Pi Zero W
  • A micro SD Card (I used a 32 GB Samsung EVO Select)
  • A micro USB cable (a sturdy one is preferable)
  • A Unicorn pHAT from pimoroni
  • A usb hub
  • A usb soundcard and 2 pc speakers.
  • A UPPLYST childrens led lamp (I went with the one shaped as a cloud)

You will also need a computer to configure the SD Card and Pi.

Getting started

Download the latest image for Raspbian Buster Lite from raspberrypi.org and flash it to the SD Card. There are many ways to do this, Etcher is a popular one. After the image is flashed you have to do the steps below

  • Add a new file to the root directory of the micro SD card (Boot). Create a file named “ssh” with no extension using touch or New — Text Document, and remove the .txt file extension.
  • Create another file in the same location on the card called “wpa_supplicant.conf”, with the following contents:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=SE
network={
ssid="Your network name/SSID"
psk="Your WPA/WPA2 security key"
key_mgmt=WPA-PSK
}

Edit country=, ssid= and psk= with your information and save the file. Safely eject the card from your PC and use it to boot the Pi. If Raspbian finds an “ssh” file it will enable SSH and delete the file. If it finds a “wpa_supplicant.conf” file, it will move it to its correct location and connect to your wireless network.

Now it is time to put together the Pi and Unicorn pHat and the rest of the parts. If you choose the UPPLYST childrens IKEA led lamp route as i then the finished assembled unit might look something like in the images below.

Frontside assembled unit
Backside assembled unit

Once you have assembled the unit plug it in to a power source and give your Pi some time to boot and connect to your network (the first boot always takes a bit longer), then you should be able to SSH into the Pi and configure it how you like. Connect via SSH and run raspi-config to set localization, expand the file system, and set the GPU memory. Reboot.

Configure unicorn pHat

Now that the Pi is setup and booting it is time to configure the system. SSH to the Pi and login with the default username/password. To install the unicorn hat python libs the guys at pimoroni have created a simple one-liner.
“curl https://get.pimoroni.com/unicornhat | bash”
This command downloads an install script from the internet, which should then run automatically through all the steps required to get Unicorn Hat installed and working. Once the install is done, the script will ask if you want to download example code, answer yes.

Configure usb soundcard and set it as default

First of all plug in the usb card and then collect system and soundcard info.

# Check ALSA modules
cat /proc/asound/modules

0 snd_bcm2835
1 snd_usb_audio

# Check sound hardware
cat /proc/asound/cards

0 [ALSA ]: bcm2835 - bcm2835 ALSA
bcm2835 ALSA
1 [Set ]: USB-Audio - C-Media USB Headphone Set
C-Media USB Headphone Set at usb-3f980000.usb-1.5, full speed

# Check info on card-1
amixer -c 1

Simple mixer control 'Headphone',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 151
Mono:
Front Left: Playback 104 [69%] [-8.88dB] [on]
Front Right: Playback 104 [69%] [-8.88dB] [on]
Simple mixer control 'Mic',0
Capabilities: pvolume pvolume-joined cvolume cvolume-joined pswitch pswitch-joined cswitch cswitch-joined
Playback channels: Mono
Capture channels: Mono
Limits: Playback 0 - 32 Capture 0 - 16
Mono: Playback 23 [72%] [34.36dB] [off] Capture 0 [0%] [0.00dB] [on]
Simple mixer control 'Auto Gain Control',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]

Unless you have very good reasons to keep PulseAudio (PA) or additional JACK server software, you should uninstall them, if they are there. They tend to interfere with ALSA, as they take control of many ALSA functions, and all the additional configurations necessary by those, make things incredibly confusing!

sudo apt-get remove pulseaudio

# You can keep `jack*`, but make sure it is not running.
# If it is running you need to stop it, disble it or remove it.
service --status-all
# Disable the running service with:
sudo systemctl disable xxxxx

Disable the internal (Broadcom) sound card the internal soundcard is driven by the kernel module in: /lib/modules/4.9.59-v7+/kernel/sound/arm/snd-bcm2835.ko Unless you are planning to use the audio jack (in 1) or HDMI (in 2), you should disable this kernel module.

# Edit boot config with:
sudo nano /boot/config.txt
# so that:
cat /boot/config.txt
...
# Enable audio (loads snd_bcm2835)
#dtparam=audio=on
dtparam=audio=off
...
# You need to reboot!
sudo reboot now

Configure your ALSA, we need first to fix our user specific config to use card 1. If you have more than one cards shown, then select the index of one you want to be default.

#cat ~/.asoundrc
cat << EOF | tee ~/.asoundrc

pcm.!default {
type hw
card 1
}

ctl.!default {
type hw
card 1
}
EOF

Next, we fix the system config, using the same card index numbers as above. We need to do this, because some system packages would never see your user config file.

sudo nano /usr/share/alsa/alsa.conf
# then replace:
#defaults.ctl.card 0
#defaults.pcm.card 0
# with:
defaults.ctl.card 1
defaults.pcm.card 1

Now reboot for the changes to take effect. You should now have a working audio system.

Install the mqtt controll script

I have uploaded and made available the basic first version of the Python mqtt controller script in the linked repository below.

In the SSH terminal enter the following command.

git clone https://github.com/adodado/mqtt_bnam.git

It should download the source code to a new folder called “mqtt_bnam”. I am currently working on version 2 of the script which i will make available in the same github repository.

The python script allows us to do the following via mqtt

  • Turn on/off the leds
  • Turn on/off the sounds being played
  • Adjust led brightness
  • Adjust volume of currently playing sounds
  • Set led color
  • Set sound that should be played
  • Get unit status/statuses

I recommend to you to read the code for a deeper explanation of what the script does since it is extensively commented. And also to take the code for what it is, it is meant as a base for you to start. This since i am not using a git branching model for this project so don't be surprised if there are “breaking changes” committed.

Autorun the python mqtt controller script using Systemd

Create a service file for the systemd as following. The file must have .service extension under “/lib/systemd/system/ directory”

sudo nano /lib/systemd/system/mqtt_bnam.service

Add the following content in it. Change python script filename and location. Also update the description if you want.

[Unit]
Description=Mqtt bnam Service
After=multi-user.target
Conflicts=getty@tty1.service
[Service]
Type=simple
ExecStart=/usr/bin/python3 /usr/bin/mqtt_bnam.py
StandardInput=tty-force
[Install]
WantedBy=multi-user.target

Your system service has been added to your service. Let’s reload the systemctl daemon to read new file. You need to reload this deamon each time after making any changes in in .service file.

sudo systemctl daemon-reload

Now enable the service to start on system boot, also start the service using the following commands.

sudo systemctl enable mqtt_bnam.service
sudo systemctl start mqtt_bnam.service

Finally check the status of your service as following command.

sudo systemctl status mqtt_bnam.service

Whats next?

That is actually up to you. If you are curious about mqtt the explanation in the link below is actually a good one :)

Since this small project is designed to be integrated into a home automation system such as Home assistant the choice of mqtt protocol for controlling it seemed obvious. I have for example integrated it into my home assistant system.

And i control it via a dashboard that is displayed on several wall-mounted tablets throughout my home. As seen in the following image.

Home assistant dashboard screenshot
Color selection via the dashboard
Nightlight turned on

I hope you enjoyed this and will take a shot at building your own similar unit. Thanks for reading and feel free to comment or reach out if you have questions, feedback or just want a copy of my home assistant config files for an example of how to integrate the unit in home assistant.

--

--

Admir Cosic

I am a developer who is passionate about stuff like IOT and home automation. Few tech that I enjoy working in are .net core, C#, Typescript and Azure.