Ever wanted to see check the weather is in Tripoli and read randomized Seinfeld quotes while you’re doing your hair in the morning? Smart mirrors are the DIY project to make that happen. This easy-to-follow tutorial covers how to build a small magic mirror using a Raspberry Pi Zero and a few other bits and pieces.
Smart mirrors (also sometimes known as “magic mirrors”) can display live information right in the reflection on a mirror – it looks cool and is actually kind of useful. You can set them up to display whatever information you want – calendars, weather, quotes, photos, reminders – it’s totally up to you.
Smart mirrors are pretty easy to make, but everyone seems to make big ones, so let’s make a small one for your desk or bedside table instead.
In keeping with the Raspberry Pi Palmtop article, I’ll avoid anything that requires special tools or 3d printers, or exact measurements.
Materials
Hardware
Here’s the hardware used to put our project together. You might recognize some of the parts from the Raspberry Pi Palmtop project – everything gets recycled here.
Here are the must-haves:
- Ikea picture frame
- Raspberry Pi Zero + SD Card
- Small LCD Monitor
- USB, HDMI Cables
- 2-way Mirror Acrylic Sheet (Mine is 3mm thick, A5 size)
- A USB keyboard to get the Pi set up
- Adhesives – double-sided tape, glue, etc. (if Apple are content to make their devices unrepairable by filling them with glue, so are we)
And in the second picture, some optional extras:
- Plastimorph
- Buttons and wire
- If you’re adding a button and wire and don’t have any pre-soldered, you’ll need a soldering iron (but again – optional!)
Everything above can be found on your favorite multi-colored logo bearing online marketplace.
My smart mirror’s innards will also include a USB hub as I don’t have the OG Raspberry Pi Zero and will need an extra USB port for a WiFi adapter. The newer Raspberry Pi Zero W has built-in WiFi and no need for this, so I’ve left it out.
Adhesives Warning
Don’t glue or tape over or near exposed electronics (capacitors, transistors, resistors, chips) on circuit boards – they could short or overheat! Always have the board properly mounted in a plastic case – then stick things to that.
Software
This project will be a good way to explore using Linux packages as well as Bash and Python scripts:
- Raspberry Pi OS Lite
- Bash Scripts
- Python Scripts
- Git
- The apt package manager for other assorted dependencies
- MagicMirror smart mirror software
Layout and Fit
I’ve marked the screen corners, so I know not to place any tape over where it will show through on the other side.
Plastimorph! You put the granules in boiling water (which is what’s in that jar), wait a minute, and in return, you get plastic you can shape, which will set hard. It’s the poor man’s 3D Printer.
The heat melts the plastic granules into a clump, which you can then shape with your hands.
I’ve used the plastimorph to create some brackets to hold the screen onto the perspex sheet, which is simply taped to the shroud, which usually sits inside the picture frame.
Making It Fit
Here it all is put together and sitting in the frame.
As much as I’m a fan of being untidy, this is going a bit too far. Adjustments need to be made.
The plastimorph was regrettably abandoned, and more tape was used instead. Much better.
The plastic riser, which ran around the inside edge of the frame, was removed so that everything can sit flush with the front glass.
Blutack was used to hold the internals (now all stuck together) to the frame. It may not seem like a permanent solution, but it will hold – and be easy to remove if you want to make any adjustments.
Looking svelte!
I’ve kind of skipped over the button you can see in the above photos – it’s just a basic push button with a couple of wires soldered to it.
It’s connected to GPIO pin 21 and ground. My Raspberry Pi only has a few headers soldered because I am both too lazy to solder the ones I’m yet to use and terrible at soldering.
You can buy buttons and Raspberry Pis with pre-soldered headers if you want to avoid soldering at all.
Finally, the back and stand are to be re-attached. You can use the metal fasteners that the picture frame already has built-in, or in my case, because the USB hub makes everything too fat, I used a copious amount of adhesives.
If it works, it works. Just make sure you can still get to the internals to plug in a keyboard for the software setup.
Make sure you leave a space for the button too.
Raspberry Pi OS and SSH
Next task – get an operating system on the SD card and enable SSH so that it can be accessed remotely from the network. You’ll need a keyboard attached to the Raspberry Pi, and you might want to have it connected to your computer monitor, so things are easy to read.
Installing Raspberry Pi OS Lite
Download the Raspberry Pi OS Lite image from:
https://www.raspberrypi.org/software/operating-systems/
I won’t reproduce the steps for flashing the Raspberry Pi OS SD card image – you can follow our article on Installing Ubuntu on a Raspberry Pi and ignore everything but the Setting up your SD Card With the Ubuntu MATE Image section – substitution the Ubuntu MATE image with the Raspberry Pi OS Lite image downloaded earlier.
Connect to WiFi and Enable SSH
Once you’re up and running with Raspberry Pi OS, plug a keyboard into your Raspberry Pi, log in and update your software:
sudo apt update sudo apt upgrade
Then run the configuration tool:
sudo raspi-config
You’ll get the following configuration screens – run through them to connect to your WiFi network by navigating:
System Options -> Wireless LAN
And enter your network name and passphrase.
Connecting via SSH from another computer
Run raspi-config again and navigate to:
Interface Options -> SSH
And enable SSH access.
Follow this guide to get access to the Raspberry Pi over the network.
You can now unplug your pi from the keyboard and re-attach it to the insides of your smart mirror.
Installing MagicMirror Software
The Smart Mirror functionality we seek will be provided by the software package MagicMirror. It’s free, and it works, so let’s use it.
If you’re using a Raspberry Pi 2 or above, you can skip all of this and just use a pre-built SD card image from
https://docs.magicmirror.builders/getting-started/installation.html#magicmirroros
Just scroll down to the MagicMirrorOS option and go from there
There are no pre-built images for the Raspberry Pi Zero, so we’ll have to set things up ourselves – here’s how.
Installing Node JS on a Raspberry Pi Zero
You might have spotted the instructions for Magic Mirror at
https://docs.magicmirror.builders/getting-started/installation.html#manual-installation
and be tempted to try them. Please don’t do it! You’ll hit this error:
You can’t install NodeJS via this method on the Pi Zero, as support for the ARMv6 CPU they use has been dropped, so follow the advice the console spits out and download the binary tarball using wget, and install manually:
wget https://nodejs.org/dist/latest-v10.x/node-v10.23.0-linux-armv6l.tar.gz sudo mkdir -p /usr/local/lib/nodejs sudo tar -xvf node-v10.23.0-linux-armv6l.tar.gz -C /usr/local/lib/nodejs
NodeJS version 10 is the last version to support the ARMv6 processor.
See this article for more information about using wget
Edit your Bash ~/.profile using the *nano* text editor:
nano ~/.profile
…and add:
# Nodejs VERSION=v10.23.0 DISTRO=linux-armv6l export PATH=/usr/local/lib/nodejs/node-v10.23.0-linux-armv6l/bin:$PATH
Refresh profile by running:
. ~/.profile
NodeJS is now installed! Confirm it with:
node -v
You should get a version number printed out to confirm everything is there.
Downloading MagicMirror using GIT
After that diversion, the MagicMirror software can be installed. The code will be pulled directly from Github using Git, so let’s install it:
sudo apt install git
We’re using apt rather than apt-get – here’s why!
If asked if you wish to install -answer ‘yes’!
Clone the MagicMirror repository using Git:
git clone https://github.com/MichMich/MagicMirror
Now run the MagicMirror installation process – this will download all of the dependencies and libraries MagicMirror requires internally. It’ll take a while, and it might complain a bit – but so long as it’s only warning not producing errors, it’s no big deal:
cd MagicMirror npm install -arch=armv7l
Some of MagicMirrors’ dependencies don’t have prebuilt armv6 compatibility – so we’ll trick it into thinking we’re on ARMv7 (using the -arch=armv7l option) just to get through the install process – and deal with compatibility issues later.
If you didn’t include the -arch=armv7l option, you’d get the below error:
Create the configuration file by copying the sample:
cp config/config.js.sample config/config.js
If for some reason you’re still referring to the MagicMirror installation documentation, you’d be tempted to run:
npm run start
Again, please don’t do it! You’ll get more errors. This is because of that ARMv7 trick above – we can’t use the built-in web browser that MagicMirror includes for displaying content because it’s not supported on the Pi Zero.
Installing Chromium Browser
To get around this, use a browser that does work on ARMv6 – Chromium (It’s pretty much Google chrome without some extras). Install it:
sudo apt install chromium-browser xinit xorg matchbox unclutter
Also being installed is the X Windows System, matchbox window manager, and unclutter – a tool to hide the mouse cursor.
Now that we have a browser, we need to set it to start up automatically.
Auto Login
Run the configuration tool again to enable auto-login:
sudo raspi-config
Navigate to:
System Options -> Boot / Auto Login -> Console Autologin
Select finish, no need to reboot yet.
Automatically Launching MagicMirror
This command writes out a configuration file for Chromium to stop it from prompting or throwing up any message boxes when it is launched – just paste it into the terminal (after reading through it to make sure you know it’s not doing anything malicious):
sudo touch /etc/chromium-browser/customizations/01-disable-update-check;echo CHROMIUM_FLAGS=\”\$\{CHROMIUM_FLAGS\} –check-for-update-interval=31536000\” | sudo tee /etc/chromium-browser/customizations/01-disable-update-check
Return to the home directory:
cd ~
Create a Bash script using the nano text editor to start the MagicMirror server:
nano start_magic.sh
Enter the following before saving:
#!/bin/bash cd ~/MagicMirror node serveronly & sleep 30 xinit /home/pi/start_chromium.sh
Create another Bash script to start Chromium in the matchbox window manager, running in kiosk mode (hiding the window border and address bar), and loading the MagicMirror software now running at http://localhost:8080/:
nano start_chromium.sh
Enter the following before saving:
#!/bin/sh unclutter & xset -dpms # disable DPMS (Energy Star) features. xset s off # disable screen saver xset s noblank # don’t blank the video device matchbox-window-manager & chromium-browser --incognito --kiosk http://localhost:8080/ # MagicMirror runs on 8080 by default
Make the scripts executable:
chmod a+x start_*
We have our start scripts, and we have auto login – let’s set the scripts to start after auto login by adding them to the Bash profile.
nano ~/.profile
#Start mirror on profile load, but only if this isn't an ssh session if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then echo "Hello, SSH!" # SSH session, do not try to launch SmartMirror, or it will make configuring things difficult else sh ~/start_magic.sh # Not an SSH session, run SmartMirror fi
Some may say .profile isn’t the best place for that, but it’s convenient, and this isn’t a mission-critical scenario. Now reboot.
sudo reboot
It might take a minute or two for MagicMirror to load.
The default MagicMirror content gives out all sorts of compliments.
Everything is a bit cluttered on this particular screen, but the layout and configuration can be changed later.
Adding a Sleep/Wake Button
You don’t have to wire in a sleep/wake button, but we have, so let’s use it.
Installing Python and Other Dependencies
You don’t have to – Raspberry Pi OS already includes Python and the required libraries to interact with the GPIO pins the button is attached to.
A Bash Script to Toggle The Display
Create the script:
nano display_toggle.sh
And enter the following commands to toggle the display before saving:
#!/bin/bash if [ $(vcgencmd display_power) = "display_power=1" ]; then vcgencmd display_power 0 else vcgencmd display_power 1 fi
Make it executable:
chmod +x display_toggle.sh
Cool, right? Now create the Python script to trigger this Bash script when the green button is pressed:
nano watch_sleep_button.py
Enter the following before saving:
import RPi.GPIO as GPIO import os # Set which pin the button is wired to gpio_pin=21 def buttonFunction(): # Monitor the pin for changes try: GPIO.setmode(GPIO.BCM) # Use GPIO numbering rather than pin position number so the number above points to the right pin GPIO.setup(gpio_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set pin as an input and set it high so it can be grounded GPIO.wait_for_edge(gpio_pin, GPIO.FALLING) # See if the pin has been pressed (ie grounded, connected to ground) os.system("sh ~/display_toggle.sh") print("Display state changed!") GPIO.cleanup() # Revert all GPIO pins to normal state, just in case something else wants to use them except: pass while True: # An infinite loop so this function will just keep on running, continually checking for a button press! buttonFunction()
Make it executable:
chmod +x watch_sleep_button.py
Now to make this Python script execute in the background whenever the Pi starts.
In the Linux shell, adding a & to the end of a command will run it in the background!
Add the following BEFORE starting the mirror in your .profile
nano ~/.profile
BEFORE the line:
sh ~/start_magic.sh # Not an SSH session, run SmartMirror
Add the following line:
python ~/watch_sleep_button.py & # Watch the sleep button
And do a final reboot:
sudo reboot
Configuring Mirror Content
You’ll probably want to change what is shown on the mirror. There’s a lot of different things you can add, covered over on the MagicMirror docs:
https://docs.magicmirror.builders/getting-started/configuration.html
(*Be sure you don’t change the port number or address in the configuration, or nothing will load)
Results!
It’s not going to win any design awards, but it looks alright! It’s a bit hard to get the full effect in photos, but the effect is very cool in person.
Of course, there’s already grit under the glass – living in central London, 86% of the air is diesel particulates, so it’s to be expected.
That’s it! Our smart mirror took a bit of extra hacking to get together, but it’s working. Make one for your mum for Christmas, and check out our other Raspberry Pi project articles!.
Sadly this tutorial ends with localhost refused to connect. ERR_CONNECTION_REFUSED