December 15, 2022

While I plan to publish some blog posts about this project, like this one talking about how I got started in this project I wanted to use this post to talk more about the build and less about the story. 

The goal is very straightforward, design and build a digital picture frame. Really there are only two main components, a laptop screen (with its driver board) and a Raspberry Pi. For this project, I decided to go with a 1080p 17.3" diagonal screen with HDMI input that I found on ebay. The kit comes with the screen, a driver board, and a panel of screen controls for adjusting the screen. If you're unfamiliar, a driver card sits between your video source and the screen, converting the input signal (and power) and driving the screen to display the actual image. Besides the video signal the screen needs power, and this one requires 12 Volts. For the Raspberry Pi I went with the Pi 3 A+ as this gave me most of the power of its B+ sibling, without the large components that would be sealed away inside the frame anyway. 

Starting with how to power the whole thing I wanted to make it as simple as possible, using only one power cable to power both the Raspberry Pi and the Screen. I tracked down a buck converter that would meet my needs. A buck converter is a small board that takes the power provided and dropping the voltage. My screen required 12 volts but the Raspberry Pi runs off of a 5 volt input. Fortunately the conversion is efficient and doesn't generate much excess heat since this will be enclosed with everything else. Adding some barrel jacks, a 12 volt power supply and some wire to the shopping list and my power was sorted.

I'll add this here, though this is purely extra. Knowing that sometimes extra screen space is handy and that I would be giving these to important people in my life I decided to add an HDMI switcher. The one I bought came in a metal case, has a single button and will simply toggle between the internal Raspberry Pi and an HDMI port that I will be on the back of the screen. While there are currently no plans for building in speakers, I also picked up some 35mm audio plugs and jacks to allow the driver board's audio out to be connected to headphones or external speakers. 

Since this project has dragged on for so long, hardware and software have developed at their own paces. I have had Raspberry Pi Zeros running test code for quite some time so I had a head start. There have been a few changes recently and there's still a lot of clean up to finish but I'll try to describe it the best that I can. When a new screen is turned on, after it boots past the custom boot image. The background is set to black, with the menu bar set to auto-hide and I plan to hide the cursor once development is finished. The PhotoFrame software starts and looks for a WiFi connection. If it doesn't find one it switches over to hotspot mode, allowing the user to connect to the screen directly from another WiFi device (phone or laptop). Once the user connects to the frame's network, a popup asks them to select from a list of nearby networks and enter the password. The frame saves the credentials and tries to connect to the network. If the connection is successful (or the WiFi network has been set previously) the software connects to my webserver where the server looks up the id of the frame, doesn't find it so passes back an image to allow the user the register their frame. On the screen an image is displayed offering a QR code or a URL to complete activation and account setup. Once this is done photos can be added to the frame through the website. The frame will continue to check in every couple minutes to make sure it is up to date with everything that has changed on the website, whether new photos have been added or photos have been edited or deleted.  The frame will also communicate with the website to display information regarding available storage space, display resolution, last connection time as well as giving the user the chance to set the frame's timezone or night mode time. Night mode is when the screen is automatically turned off to prevent the glow from disturbing anyone. 

It's inevitable that as soon as I give these to anyone there will be some problem with the code and as much as I would like to be able to hope over to another state or country to update the software, that's just not possible most of the time. To help with this, there is a separate update script that will run on a routine to check if the software is up to date, and if there are updates, to download and install them. Since the update is only downloading files that have changed these will generally be very small. The frame software is installed with a key that allows the updater to connect to a private github repo to check for updates. 

That is a pretty thorough explanation of what is happening, so just a few notes on how it's happening. When a frame successfully connects to the webserver it sends a list of files for the frame to download. The frame saves this list as well as a copy of the settings so it can tell the next time it downloads the list if anything has changed. The registration image that is displayed when a frame is first connected generates and stores a 5 character string to link the new user account to the frame's id. With PHP's GDLib the QR code is downloaded from the google graph API and added to the registration image along with the 5 character code. The QR code will enter the 5 character code automatically, while using the provided URL asks you to enter the code, like seen on many smart TV registration screens. The actual image display is handled by the Linux package feh which is described as "a lightweight image view aimed mainly at users of command line interfaces." When new images are done downloading the main software will close the previous slideshow and start a new one. 

Getting back to the hardware side, where things are still in progress there are a few tasks to complete but I am getting very close now. A few purchases and a detailed Fusion360 model have helped make the progress possible. A picture frame was found at Jerry's that came with two depth settings for the backing material. The backing material is high quality, and has metal pieces rivited to it that turn and slide into a groove in the frame. This provides compression on the screen contents while still allowing space for all the components. Knowing the frame size and using a model of the screen I was able to print brackets to center the screen in the frame. I also was able to 3D print a bracket that holds the screen's driver board, the buck converter, Raspberry Pi and HDMI switcher. The corner brackets are very close, but some differences between the tabs on top of the screen and those on the bottom meant screw holes didn't line up correctly. I've already printed a second version of the electronics bracket but a version 3 might provide some extra height for the HDMI switcher's push button to extend through the backing material and possibly some adjustment to the screw mounting points. I've also printed some caps to provide better push surfaces for the screen controls. They will require more testing before I know if another version is needed. 

The project has been fun but I am looking forward to completing it. I will add some of the in-progress pictures to the gallery, please ignore the mess in some of them, I generally just try to take a picture on whatever mostly flat surface is handy. Also, once things are done I will edit this post to include some final thoughts and pictures.