Software apps and online services
Hand tools and fabrication machines
The PiNG Video Doorbell is powered by a Raspberry Pi and is retro-stylishly cased in a 1986 Intercom and an old Sony cassette player.
When the doorbell button is pressed the Pi makes a high-quality video call using Google Duo, which can be answered on a phone, tablet or computer, letting you see and speak to callers when you're away from home (or at home but trapped under a cat). It works over WiFi and cellular, so you can even answer the door when you're out pounding the streets.
It also sounds a standard wireless door chime inside the house as a fail-safe, in case the call can't be taken.
The setup and code are very straightforward, read on and I'll show how you can make your own video doorbell from scratch in just a couple of hours for well under £50 (or for practically nothing if you already have a Pi and some components lying around!).
There's a full video showing the build and features on YouTube at https://youtu.be/Bn1qj2Uvl0w if you can't see the embedded version.
I've always fancied making a video doorbell using a Raspberry Pi, but until recently I couldn't find an easy way to make video calls that would both work in a project and be straightforward for others to recreate. That all changed on 26th February however, when I read reports that a browser-based version of Google Duo had been released - meaning that it would run without installing a dedicated app.
Having already researched the challenges of making Pi calls with Skype and WhatsApp I was on the point of installing Android to try and use Google Duo, but was put off by not being able to easily integrate the GPIO interface, so the web app news was really encouraging. After devouring the articles I first tested Duo on my windows laptop, and swiftly moved on to try it with Chromium on my workshop machine, a Pi 2. This didn't go so well, the Duo site appeared and let me log in, but didn't display my contacts list or any options to change settings. I decided to look into using other browsers (the write-up said it also worked on Firefox and Safari) and also test it on a more beefy Pi 3.
I hooked up a Logitech webcam to the Pi 3 then fired up Chromium, and to my amazement was able to video call my wife in the living room seconds later, after tweaking a few settings. The webcam I tested had a built-in microphone and even on the first thrown-together test call the quality was great. This was a very exciting moment, unlocking the potential of the video doorbell project as well as many other possibilities.
So video-calling with a keyboard, mouse and screen was a definite go - but how to make this work with a headless Pi and buttons?
Software setup video: https://youtu.be/Bn1qj2Uvl0w?t=1029
Having Duo running in Chromium was great, and I assumed I'd just run it full-screen, but then (literally by accident) I realised it could run "out of browser", in the same way you can "install" web apps on a Windows PC - here's how:
- Go to the Google Duo site in Chromium on the Pi (https://duo.google.com/)
- Log in with the Google account you want to use to make the doorbell calls
- Click on the three dots (hamburger) > Install Google Duo (If you're not using the most recent Raspbian you may need to select More Tools > Add to Desktop
- Click "Add" in the dialogue box that appears
- A Google Duo shortcut appears on the desktop
If you then double-click the icon on the desktop Duo opens, but like an app, without the usual Chromium furniture. I'm not sure if running it in this way uses less Pi resources (seems to make sense?) but it does make for a cleaner interface.
After some testing I set up a separate google account for the doorbell and linked it to a phone number on an android phone - you may not need to do this if you have an existing google account and you're happy to use it for the doorbell.
It doesn't remember your login details at every launch, but it does stay logged in once you've opened it, mine has been running for over a week without having to touch it. Before making a test call you need to make sure the webcam is plugged in and choose the audio sources, by clicking on the "cog" settings icon and "Manage Sources". The mic & speaker options available are straightforward, and you can play a test sound to make sure they're correct - you'll have to grant permission in a popup the first time you do this, and may need to experiment depending on your webcam/audio setup.
With the sources saved it's also a good idea to set the video shape to Wide so that you see as much as possible when the doorbell calls you. To do this click on a contact as if you're about to make a call, then click on the "Show Wide Video" rectangle in the top corner of the video preview, then hit the X to go back. This setting will be remembered until the Pi is rebooted.
If Duo were a full app then command line options might be available, for example to launch the app and immediately call a specific contact. In the absence of this (for now?) I needed to find a way to automatically start a call with a GPIO button press.
To do this I used the Python module PyUserInput which lets you program mouse movements, clicks and keyboard strokes.
The idea was to set up a script to wait for a button press, then move the mouse to the "Contacts" textbox, type the name of the contact, press "Enter" and click "Video Call". Duo remembers the last person contacted and shows them in the centre of the screen, but I didn't want to rely on this in case the doorbell called the wrong person (which happened in testing - sorry Harry)!
It took some trial and error to get the mouse to click in just the right place (having the app full-screen helped) and finding the right keystroke to emulate the "Enter" key was the same, but it was a lot of fun. On the GitHub page there's also a little script called Position.py that displays the mouse co-ordinates, which was very useful.
With this resolved, I then added in some more code to kick off the mouse moves based on a GPIO button click. This worked very well in testing, once the call had been hung up on the phone the Pi went back to its original screen, so when the doorbell button was pressed again it would repeat the same action.
Software setup video: https://youtu.be/Bn1qj2Uvl0w?t=1029
After a lot of experimenting I refined the setup process to the steps below.
With a fresh (full) installation of Raspbian it's best to do most of the setup below with a monitor connected. First enable VNC server, and ideally log in / create a VNC account to make connecting to the Pi as straightforward as possible. With the Pi running headless you need to connect and log in to Duo after booting up, which is easy and just takes a few seconds - I normally just use my phone for this.
VNC can be enabled under Start > Preferences > Raspberry Pi Configuration (Interfaces tab). Because the Pi will be running headless we also need to tell it to assume an HDMI monitor is connected, and manually set a resolution (System tab) so that the mouse commands in the script line up with the elements on the web app. I chose option 19, 1280x720, if you use a different resolution you'll likely need to edit the mouse co-ordinates in the PiNG.py script.
Next we need to install PyUserInput from the terminal:
pip3 install PyUserInput
...and download the PiNG.py script from GitHub onto the Pi, I just popped it in the main Pi folder. To save having to start the script after each reboot it's worth setting it to run automatically once the desktop has loaded, by editing the global autostart file:
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
...and adding in the following line at the bottom to point at the script location:
After a reboot the script should run automatically.
As the Pi will be probably be waiting a while for the doorbell to ring (unless you're really popular) it's also best to disable the default screen dimming, as this could interfere with the mouse clicks. Counter-intuitively the best way to achieve this is to install Xscreensaver:
sudo apt-get install xscreensaver
...as after installation you can configure the screensaver options (Start > Preferences > Screensaver) and set it to Disabled.
The Python code is attached and on GitHub and is very simple - it essentially just programs the doorbell button to perform a series of mouse clicks to control the Duo web app on screen. Except it's not really on screen as the Pi is running headless.
If you've completed the above and the Pi has rebooted, you should be able to disconnect the monitor (if you used one), connect to the Pi via VNC from a phone or PC and log in to Duo, setting it to full-screen, choosing the audio sources and setting the video width as detailed above. Once that's done you can disconnect VNC and the doorbell is ready for use!
I knew that audio would be important for this project, as there's no point talking to the postman remotely if he can't hear you properly! I decided to go with the Pimoroni pHAT BEAT, as I had one handy - though in some ways that was slightly overkill for this project.
I only really needed a single mono output for the doorbell, but the pHAT BEAT offered stereo output to two speakers, as well as a nice LED VU meter.
There's not much to say about the installation & setup, I followed the instructions and was up & running in no time, listening to the hypnotic "Front Left, Front Right" of the test file.
The only complication of using the pHAT for the audio was that it would sit on all of the pins on the GPIO header - and I needed some of these to connect up the doorbell button and LED. To get around this I added in a pico hat hack3r - found in a party bag from last year's Raspberry Fields. It's a tiny but very handy board that essentially splits the GPIO output in two, letting you connect a HAT while still exposing a full set of GPIO pins. Though this is great you do have to be careful not to conflict with pins already in use by the HAT, so I double-checked pinout.xyz and decided on the following:
Doorbell button - GPIO22 (Pin 15) and 3v3 next door (Pin 17)
Notification LED - Positive to GPIO9 (Pin 21, via a resistor), Negative to GND at Pin 25
With the webcam, audio, button and LED connected up and working, I now had a working video doorbell - albeit spread out over an entire workbench. Next I needed to think about how it would be used and what it would look like.
So the setup worked fine on the bench, but what would happen IRL? I wanted to only have a single doorbell outside to save confusing visitors, but at the same time wondered what would happen if someone pinged it while I was unable to answer the call, or if someone else was in the house and didn't hear the Duo call coming through.
The answer to these worries was to include a standard wireless doorbell transmitter in the build, that would pair with our existing chimes in the house. This way the "normal" doorbell would ring even if the Pi part of the build stopped working for some reason.
I ordered a compatible doorbell button from Ebay (used, £2.50) and after some testing soldered two flying leads to the microswitch contacts of its circuit. This meant I could chop down the doorbell's plastic case and connect my own lever switch to trigger the chime.
Having this fail-safe made me feel a lot better about using this project "in the wild" and also added functionality for very little money - some video doorbell vendors will charge you up to £50 if you want an extra chime unit!
Doorbell Unit Video: https://youtu.be/Bn1qj2Uvl0w?t=416
Once I'd proved that the code would work the next thing was to decide on a case for the project. I wanted it to be obviously a doorbell, but didn't like the idea of having a fully-connected Pi hanging outside my house for obvious security reasons.
What I decided was to split the project in two - to have a doorbell unit outside the house, connected to a Pi base station inside. There were a couple of good reasons to go in this direction:
- Fewer components to squeeze into the exterior case and be exposed to the elements
- Much better WiFi signal inside the house, with the added option of Ethernet
- Easier to perform maintenance & upgrades
- Secure my precious Pi 3B+ behind a locked door
Making the decision on the webcam was easy - one of my MotionEye security cameras has been running 24/7 for over two years using a Microsoft Lifecam HD 3000 and a Pi Zero so this was a logical choice - especially as it has an integrated microphone. Many other webcams work well with the Pi, and you could even use a standard Pi camera - though then you'd need a separate microphone to capture the audio.
The exterior unit was also a no-brainer, a 1986 Intercom! I bought a 3-pack of these retro devices a while back and only used one in 2017 for the Google Pi Intercom project so had spares handy - plus I was already familiar with its innards and was confident I could make everything fit.
Base Unit Video: https://youtu.be/Bn1qj2Uvl0w?t=856
For the interior base unit I considered just using a standard plastic project box, but with the local Maplin having closed down it wasn't so easy to choose a suitable match - so I decided to re-use some more old tech and fit the Pi inside an old cassette player. This worked out really well as there was plenty of space - and meant that the VU meter LEDs could display through the tape window, a convenient extra touch. I was also able to connect the cassette player's original speaker to the spare output on the Phat Beat - meaning the ringtone and speech would play inside the house as well as outdoors.
To connect the two units together I decided on 6-core alarm cable, as this is pretty thin and easy to work with, adding a connection block at each end.
As always the cases needed some dismantling & modification before they'd be ready for use, so I set to with the rotary tool to tidy up the insides, once I'd stripped out the original circuits.
The intercom was first, I had to chop out a plastic post to make room for the webcam, cut a hole for the wide angle lens (bought from Tiger) and sand away lots of protrusions to make things like the speaker easier to fit. Once I had a blank canvas I then thought about how to fit in the various components. I needed to make space for:
- A new speaker
- Two lever microswitches
- The wireless doorbell circuit
- The webcam
- The cable connection block
- The small protoboard circuit for the LED
...as well as the original switch and mechanism - this had looked spacious at first but now I was beginning to wonder.
To make the process easier I used a handy tip from my Hitachi Pi TV conversion, and first built a perspex chassis to hold all of the components. Perspex is absolutely ideal for this, as you can see through it when marking where to cut holes. First I cut it roughly to size, then drilled holes so that it would fit onto the intercom's existing screw posts. From here I added components one by one, drilling and cutting holes to either fit or make space for them. The other benefit of doing this was that I was able to test that everything was working before the final assembly!
To make the webcam fit I had to carefully chop away a lot of its plastic case, so that it would glue directly behind the wide angle lens - if you need to do this start by prying the front off it, don't hack away at the back with wire cutters and pliers as I did!
I was less fussy about the cassette player, and ruthlessly stripped out all of the circuits & components leaving just an empty box. Cosmetic parts like the big buttons were just hot-glued in place, and I filled a small broken lamp window hole with a red push-button.
To make the pi sit in the right place behind the tape window I first hot-glued a Lego plate to the underside of an old (obtained at the Pi 3rd birthday party!) Pi case. I then hotglued a matching plate inside the cassette player in just the right position, to make a nice semi-permanent fitting - the GPIO pins would be accessible with the tape door open, but I wanted to make sure I could get the Pi out to swap SD cards etc without any trouble. I've learned the hard way to plan ahead for future disassembly and maintenance! Lastly I chopped some slots in the exterior of the cassette player so that the USB and HDMI ports would still be available after assembly just in case.
Final Assembly Video: https://youtu.be/Bn1qj2Uvl0w?t=2002
Having test-fitted the perspex chassis into the intercom I gave it a coat of paint - I agonised over colours for a while, trying to choose between white, matt black and brown, but went with "Claret Red" for a change.
The final assembly was pretty straightforward thankfully, and I hot-glued the intercom chassis to the case towards the end, also fitting the wireless doorbell circuit inside the back of the unit to make it easy to change the battery. The very last job was to add in a nameplate, which I just printed out in various font sizes - but when I came to add this I realised that disastrously some hot glue had seeped through a tiny hole in the case, spreading all over the fresh paint and blocking the nameplate slot.
Two hours of delicate scalpel-scraping later the glue was gone, but I had to repaint part of the case - a total pain, but really I should have left the paint to harden for another few days - I'll never learn!
To prepare for the installation I painted some thin conduit brown to match the front door, and drilled a hole to poke the cables through, using rubber grommets to fill the gap. I left myself about an hour to fit it, but this wasn't nearly enough time! In theory I just needed to mount the doorbell unit, feed the wires through the door and reconnect the alarm cable to the base unit, which should have been straightforward - it was anything but.
The intercom fixed to the doorframe easily, using strong 3m velcro pads rated for double the weight of the unit. When I came to reconnect the cables I found I'd snapped the stripped ends off two of them, and having them at different lengths needed some delicate work with tweezers to make the connections. Soon enough it was all connected though, and I powered up the Pi to test it. Here came problem number two - very weak WiFi in the porch. Not to worry, I thought, and added in an ethernet cable and powerline adaptor, which fixed the problem.
Next came the real-world test, and I logged in via VNC to set up Duo - this worked fine as before, but while I was setting the audio sources the PyUserInput actions fired as if I'd pressed the doorbell - and again and again, making video calls almost as fast as I could decline them. This set me sweating, and I carefully dismantled everything to check the connections, as it'd been working perfectly on the workbench for nearly a week. After checking the connections and finding nothing amiss I replaced the doorbell lever switch and tested the resistance of the whole unit with a multimeter. Then I tried a different pHAT BEAT. Then a different Raspberry Pi. And lastly a fresh pico hat hack3r. Nothing worked, it was as if someone was outside constantly leaning on the doorbell, the script just kept firing and making calls.
The only thing that was different to the workbench setup was that the cables were now fixed in place inside conduit, and in a much busier environment - and that turned out to be the problem. Interference was causing the GPIO to interpret pretty much anything as a button press. To try and combat this I first added in a 1k resistor between the switch and the Pi - this confirmed my thoughts as it slowed the false positive presses to one or two a minute. Next I shortened the cables inside the base unit as much as possible, and replaced the 1k resistor with a 10k version. This did the trick - I built a simple script to test it and each button press only fired it a single time, with no phantom presses in between.
For a part of the project I'd assumed would be fun & easy this turned out to be a frustrating problem solving exercise lasting over the Easter weekend, but finding the solution was very satisfying. The silver lining to the whole thing was swapping out the Pi - I was now using a Pi 3 B+, and there was a noticeable improvement in both call speed and quality - if you plan to build one of these I'd definitely encourage you to spend the ext
ra few pounds on the highest-spec Pi possible.
With the PiNG doorbell finally working I had a lot of fun with the kids (& cats) making the project video, and started thinking about the other things we could do with it.
As the Python code is so simple to adapt there are endless options here, many of which I hope to try out soon:
- Set the script to take a picture each time the doorbell is pressed, and upload it to Dropbox
- Set the notification LED on the bellpush to light up constantly in the evening, either at a set time or using a Python module like Astral to calculate the local sunset/sunrise times
- Set the ringtone & speech volume to automatically reduce at night (I just flip open the cassette lid and use the buttons on the pHAT)
- Add in an extra button inside the house to cancel the call in case it's ringing but someone answers the door "manually" - it does time out after about 45 seconds however.
- Set the script so that you can call the doorbell back - you could possibly poll the window name or check which window has focus and tell it to click "answer" if it detects the change
- Theoretically you could program in the button & keyboard presses to automatically log in to Google Duo to save having to do this via VNC - this feels a bit unsafe though, and Duo does stay logged in once you've done it, I've left it running for days on end between presses to test it.
There are also lots of hardware adaptations possible:
- Cut the USB cable and extend it using multi-core alarm cable (You can get 8-core quite easily) - I'm not 100% this will work or how long you could go but it would mean a much smaller hole to drill.
- Make a version that uses a PIR sensor to start the call instead of a button - this would need fine tuning to be practical, but would be handy if your child has lost their ball and you can see it behind a chair in the garden.
- Add in some extra LEDs or a separate solar-powered floodlight for night-time illumination
- Make the case more waterproof (ours sits under a canopy so doesn't need it so much)
For receiving calls the phone & PC work really well, but you could potentially build a dedicated receiver unit, say for the living room, that's constantly listening out for calls and displaying photos or something in the meantime.
It could still use PyUserInput to click "Answer" and you could probably even integrate Google Assistant using the AIY Kit, so that on a given voice command the call is answered - that would be very cool.
Another good use of the technology would be to build a super-easy video chat station, with just one big "Call" button - useful for making easy video calls with, say, an elderly or tech-phobic relative.
Conclusion Video: https://youtu.be/Bn1qj2Uvl0w?t=2894
I say this almost every time, but this was the most fun project I've made so far. It has just the right combination of new technology, old hardware and practicality. Maybe my favourite part though is its simplicity and reliability - I initially thought programming mouse moves on a headless Pi would be temperamental if it worked at all, but it works very well.
It was also really satisfying to harness video calling using a Pi, this has been one of my "Holy Grails" for a while, and Google Duo does a great job, especially on the Pi 3B+. The sound quality of the calls is astonishingly good, and the video is certainly smoother than expected. I hope the web version of Duo continues to develop and Google don't mess with the interface too much - although even if they did something like move a button or textbox the co-ordinates in the script could be easily changed. I read this week they may be adding group chat, I'll be interested to see how this works.
I'm now looking back at some of my old TV conversions and wondering whether to update them as video chat consoles, I do have one that already has a webcam built in, it would just need a mouse to control the calls. It'd be great to bring to life the future vision of videophones as imagined back in the 50s and 60s.
I admittedly went a bit overboard with this project, but you could build something similar with very few components, just a Pi, webcam, speaker & button really - we'd love to see any pics or videos if you do make one, you can tweet us @OldTechNewSpec or leave a pic in the comments. How about a nice touchscreen videophone in a dedicated case, or one where you use a rotary dial to choose a contact?
I'm writing this on 1st May and today was a momentous occasion - the first unsolicited "in the wild" call from the doorbell! During a lunch-hour walk in the city centre the doorbell called and I had a great 2-way conversation with an Amazon delivery person. I found out he didn't need a signature, discussed where to stash the parcel etc and the call quality was excellent, even though I was on a busy street with a not-brilliant 4G signal. I've been chuckling to myself ever since.
It'd be ideal if there was a dedicated doorbell HAT for the Pi, with integrated speaker, microphone and button on one board, that could fit into a 3d-printed doorbell case using either a PI camera or webcam - I think that would make a great, low-cost (compared to commercial options) and practical kit, like the wildlife camera kits you can get now.
Thinking about it the Google AIY Projects HAT has all of those things - you'll have to excuse me while I give that a try...