The project makes use of different services. Here's an overview:
The picture frame offers following features:
- simple user interface to navigate the pictures, start a slideshow or like a picture
- periodically download pictures from a shared Dropbox folder
- send push notifications whenever a picture is liked
- Turn the picture frame's display off every evening, and back on every morning
Let's take a closer look at the software and hardware for this project, and how you can build your own connected picture frame.
The following hardware components are used in this project:
Assembly is super easy, following these steps:
- Mount the Raspberry Pi 3 to the Raspberry Pi Touchscreen
- Connect the jumper wires from the screen's board to the Pi for power
- Slide the Touchscreen assembly through the enclosure's front bezel
- Screw everything in place
Do not insert the microSD card or power on the frame yet, as the software needs to be
The complexity of the project is in the software. Let's break it down.
Resin.io makes it simple to deploy, update, and maintain code running on remote devices. Bringing the web development and deployment workflow to hardware, using tools like git and Docker to allow users to seamlessly update all their embedded linux devices in the wild.
Resin.io's ResinOS, an operating system optimised for use with Docker containers, focuses on reliability over long periods of operation and easy portability to multiple device types.
To know more details about how resin.io works, be sure to check out this page: How It Works
Sign up for a free account and go through the detailed Getting Started guide. From there, you can create your first application.
Setting up a project requires two things:
- application name: ConnectedFrame
- device type: Raspberry Pi 3
After completing both fields and creating the application, a software image can be downloaded for the devices to boot from. The useful part is that the same image can be used for every device involved in the project. Select the .zip format, which will result in a file of about 400MB, as opposed to 1.8GB for the regular .img file.
Before downloading the image, connectivity settings can be specified, allowing the device to automatically connect to the network once booted. Enter the desired SSID and matching passphrase.
Flashing SD Card
Once the image specific to the application is downloaded, it needs to be flashed to a microSD card for the Raspberry Pi to boot from.
There is a tool available for doing just that, by the same people from resion.io, called Etcher. It works on mac, Linux and Windows, is simple to use and gets the job done.
Launch Etcher, select the downloaded image file. Etcher should automatically detect the SD card, all that remains is to click the "Flash" button.
The SD card is ready to be inserted in the Raspberry Pi.
Configuration & Environment Variables
Some raspberry Pi configuration changes are typically made by editing the /boot/config.txt file. Resin.io allows users to do this via the user interface, by defining Device (single device) or Application (all devices) Configuration Variables.
In config.txt, pairs of variables and values are defined as follows: variable=value
Using the Device/Fleet Configuration, the variable becomes RESIN_HOST_CONFIG_variable and is assigned the desired value.
For example, rotating the LCD touch screen is normally done by appending lcd_rotate=2 to /boot/config.txt. As a configuration variable, this becomes RESIN_HOST_CONFIG_lcd_rotate with value 2.
Another type of variables, are Environment Variables, which can again be defined at application or device level.
These environment variables can be used by the operating system, such as "TZ" which is used to set the correct timezone, but also by scripts.
Following environment variables are used by the connected frame Python script:
- DISPLAY: display to use for the Tkinter user interface
- DROPBOX_LINK: link to dropbox shared folder
- IFTTT_KEY: personal IFTTT webhooks key to trigger notifications
- DOWNLOAD_INTERVAL_HOURS: interval in hours to download photos from the dropbox folder
- CAROUSEL_INTERVAL_SECONDS: interval in seconds to automatically switch to the next photo
- FRAME_OWNER: the name of the person the frame belongs to, used to personalise the "like" notification
Most are to be set at application level, though some variables such as FRAME_OWNER are specific to the device.
The link to the shared dropbox folder ends with "?dl=0" by default. This has to be changed to "?dl=1" in the environment variable, to allow the application to download the pictures.
I've been developing a Python application using Tkinter to create the graphical interface for the picture frame.
The layout is simple: four interactive buttons (two on each side), with the picture centralised.
Deploying an application with resin.io requires some additional files, defining which actions to perform during deployment and which command to use to start it. The full code and accompanying files for this project can be found on GitHub.
You can clone the repository for use in your resion.io application, reproducing the exact same project, or fork it and modify it as you desire!
git clone https://github.com/fvdbosch/ConnectedFrame cd ConnectedFrame/
In the top right corner of your resin application dashboard, you should find a git command. Execute it in the cloned repository.
git remote add resin firstname.lastname@example.org:gh_fvdbosch/connectedframe.git
Finally, push the files to your resin project:
git push resin master
If all went well, a unicorn should appear!
In case of problems, a clear error message will appear, telling you what exactly went wrong.
"IFTTT" stands for "If this, then that" and is an online platform that enables users to connect triggers and actions for a plethora of services.
For this particular project, the webhooks service is used to trigger notifications to the IFTTT app on a smartphone.
The trigger is part of the code and needs to remain as is, though the action could be modified to suit your own personal needs.
Enough with the theory, let's see the frame in action!
What do you think? Is this something you could see family members use? Let me know in the comments!