element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi Projects
  • Products
  • Raspberry Pi
  • Raspberry Pi Projects
  • More
  • Cancel
Raspberry Pi Projects
Blog Raspberry Pi Connected Picture Frame
  • Blog
  • Documents
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi Projects to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: fvan
  • Date Created: 28 Aug 2017 7:34 PM Date Created
  • Views 12165 views
  • Likes 20 likes
  • Comments 50 comments
  • rpibeginner
  • raspberrypi
  • display
  • resin.io
  • iot
  • raspberry_pi_projects
  • resinos
  • picture frame
Related
Recommended

Raspberry Pi Connected Picture Frame

fvan
fvan
28 Aug 2017

This project is about a digital picture frame aimed at family members, such as grandparents.

 

The idea is that parents taking pictures of their children, can easily share those pictures with the children's grandparents by making them appear on the picture frame automatically. In turn, the grandparents can "like" the pictures, letting the children's parents know which pictures are their favourites.

 

By making use of a specific software platform called resin.io, multiple instances of this picture frame can be deployed for various family members, without hassle.

 

  • Features
  • Hardware
  • Software
    • resin.io
      • Application Creation
      • Flashing SD Card
      • Configuration & Environment Variables
      • Application Deployment
    • IFTTT
  • Demo

image

 

Features

 

The project makes use of different services. Here's an overview:

 

image

 

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.

 

Hardware

 

The following hardware components are used in this project:

  • Raspberry Pi 3 with 16GB MicroSD cardRaspberry Pi 3 with 16GB MicroSD card
  • Official Raspberry Pi 7" Touch ScreenOfficial Raspberry Pi 7" Touch Screen
  • Official Raspberry Pi 5.1V/2.5A Power SupplyOfficial Raspberry Pi 5.1V/2.5A Power Supply
  • Raspberry Pi Touch Screen EnclosureRaspberry Pi Touch Screen Enclosure

 

Assembly is super easy, following these steps:

  1. Mount the Raspberry Pi 3 to the Raspberry Pi Touchscreen
  2. Connect the jumper wires from the screen's board to the Pi for power
  3. Slide the Touchscreen assembly through the enclosure's front bezel
  4. Screw everything in place

Do not insert the microSD card or power on the frame yet, as the software needs to be

image

 

Software

 

The complexity of the project is in the software. Let's break it down.

 

resin.io

 

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.

 

Application Creation

 

Setting up a project requires two things:

  • application name: ConnectedFrame
  • device type: Raspberry Pi 3

 

image

 

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.

image

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.

image

 

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.

image

 

Another type of variables, are Environment Variables, which can again be defined at application or device level.

 

image

 

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.

 

Application Deployment

 

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 gh_fvdbosch@git.resin.io:gh_fvdbosch/connectedframe.git

 

Finally, push the files to your resin project:

 

git push resin master

 

If all went well, a unicorn should appear!

image

 

In case of problems, a clear error message will appear, telling you what exactly went wrong.

 

IFTTT

 

"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.

image

 

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.

 

Demo

 

Enough with the theory, let's see the frame in action!

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

What do you think? Is this something you could see family members use? Let me know in the comments! image

  • Sign in to reply

Top Comments

  • bishely
    bishely over 8 years ago in reply to fvan +4
    Hooray! My screen and case arrived! Super-quick and (relatively) straightforward setup: 15 minutes assembly (would've been quicker, but the (non-official) case I'm using has no access to the SD card slot…
  • bishely
    bishely over 8 years ago in reply to gadget.iom +3
    I'm not sure it's quite as straightforward as that, unfortunately, Paul. Google Drive links seem to only point to Google Drive's file manager, and not a convenient downloadable .zip file - if you try to…
  • jw0752
    jw0752 over 8 years ago +2
    Hi Frederick, I think it is not only an awesome idea but probably very marketable. Personally I would love to have a picture frame that changed up pictures of the grand kids from time to time. Thanks for…
  • salmanslim
    salmanslim over 8 years ago in reply to bishely

    Hi Tom , Thank you.

    i have the log files but i am not sure if i can post it here , as most site admins dont allow it. But i will post below. can you please go over it and tell me if anything i am doing wrong ? i am suspecting its my sd card.

    Yes, The display was and is working. I have attached an image in my next post. This is my first build with resin.io

     

    07.02.18 23:24:00 (-0800) Updating application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:00 (-0800) Killing application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:00 (-0800) Sending SIGTERM to remaining processes...

    07.02.18 23:24:00 (-0800) Sending SIGKILL to remaining processes...

    07.02.18 23:24:00 (-0800) Unmounting file systems.

    07.02.18 23:24:00 (-0800) Unmounting /sys/kernel/debug.

    07.02.18 23:24:00 (-0800) Unmounting /dev/mqueue.

    07.02.18 23:24:00 (-0800) All filesystems unmounted.

    07.02.18 23:24:00 (-0800) Halting system.

    07.02.18 23:24:01 (-0800) Killed application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:01 (-0800) Installing application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:02 (-0800) Installed application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:02 (-0800) Starting application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:03 (-0800) Started application 'registry2.resin.io/connectedframe/9caa2971ca1e685c0a52daa5bb1daf75fcf35567'

    07.02.18 23:24:03 (-0800) Systemd init system enabled.

    07.02.18 23:24:03 (-0800) systemd 215 running in system mode. (+PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR)

    07.02.18 23:24:03 (-0800) Detected virtualization 'other'.

    07.02.18 23:24:03 (-0800) Detected architecture 'arm'.

    07.02.18 23:24:03 (-0800) Set hostname to <5f3616d>.

    07.02.18 23:24:06 (-0800) hostname: No address associated with hostname

    07.02.18 23:24:06 (-0800) xauth:  file /root/.Xauthority does not exist

    07.02.18 23:24:06 (-0800) xauth: (stdin):1:  bad display name "5f3616d:0" in "add" command

    07.02.18 23:24:06 (-0800)

    07.02.18 23:24:06 (-0800)

    07.02.18 23:24:06 (-0800) X.Org X Server 1.18.4

    07.02.18 23:24:06 (-0800) Release Date: 2016-07-19

    07.02.18 23:24:06 (-0800) X Protocol Version 11, Revision 0

    07.02.18 23:24:06 (-0800) Build Operating System: Linux 4.4.26-v7+ armv7l Raspbian

    07.02.18 23:24:06 (-0800) Current Operating System: Linux 5f3616d 4.9.59 #2 SMP Wed Feb 7 10:31:49 UTC 2018 armv7l

    07.02.18 23:24:06 (-0800) Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=800 bcm2708_fb.fbheight=480 bcm2708_fb.fbdepth=16 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3f000000 vc_mem.mem_size=0x3f600000  dwc_otg.lpm_enable=0 console=tty1 console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

    07.02.18 23:24:06 (-0800) Build Date: 11 November 2016  11:59:59AM

    07.02.18 23:24:06 (-0800) xorg-server 2:1.18.4-2+rpi1 (https://www.debian.org/support)

    07.02.18 23:24:06 (-0800) Current version of pixman: 0.33.3

    07.02.18 23:24:06 (-0800) Before reporting problems, check http://wiki.x.org

    07.02.18 23:24:06 (-0800) to make sure that you have the latest version.

    07.02.18 23:24:06 (-0800) Markers: (--) probed, (**) from config file, (==) default setting,

    07.02.18 23:24:06 (-0800) (++) from command line, (!!) notice, (II) informational,

    07.02.18 23:24:06 (-0800) (WW) warning, (EE) error, (NI) not implemented, (??) unknown.

    07.02.18 23:24:06 (-0800) (==) Log file: "/var/log/Xorg.0.log", Time: Thu Feb  8 07:24:06 2018

    07.02.18 23:24:06 (-0800) (==) Using system config directory "/usr/share/X11/xorg.conf.d"

    07.02.18 23:24:07 (-0800) Traceback (most recent call last):

    07.02.18 23:24:07 (-0800)   File "/usr/src/app/connectedframe.py", line 9, in <module>

    07.02.18 23:24:07 (-0800)     download_interval = int(getenv("DOWNLOAD_INTERVAL_HOURS")) * 60 * 60 * 1000

    07.02.18 23:24:07 (-0800) TypeError: int() argument must be a string or a number, not 'NoneType'

    07.02.18 23:24:07 (-0800) xinit: connection to X server lost

    07.02.18 23:24:07 (-0800)

     

     

    07.02.18 23:24:07 (-0800) waiting for X server to shut down (II) Server terminated successfully (0). Closing log file.

    07.02.18 23:24:08 (-0800)

    07.02.18 23:24:08 (-0800) xauth: (argv):1:  bad display name "5f3616d:0" in "remove"

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • bishely
    bishely over 8 years ago in reply to salmanslim

    That's not a lot of information to go on, I'm afraid - you're more likely to get help if you can give some more details. Was the display working before, or are you building it for the first time? If it's a new build, check all of your cables, especially the ribbon cable connecting the Pi to the display driver board.

     

    Assuming that doesn't fix it, login to resin.io and open the dashboard for your frame. Find the log and see if that offers any clues: if you aren't sure, post it here.

     

    Lastly, a bit more detail on what the display errors look like could help to diagnose your problem - perhaps you could upload a photo of the screen?

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • salmanslim
    salmanslim over 8 years ago

    I am getting bad display error, can some one help me ?

    07.02.18 23:24:08 (-0800) xauth: (argv):1:  bad display name "5f3616d:0" in "remove"

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • bishely
    bishely over 8 years ago in reply to gadget.iom

    I'm not sure it's quite as straightforward as that, unfortunately, Paul. Google Drive links seem to only point to Google Drive's file manager, and not a convenient downloadable .zip file - if you try to wget them, you get a html file with a ridiculous file name. A quick search suggests there might be a way to manipulate Google's API to turn individual file links into direct download links, but I can't find anything on getting a whole folder in a similar way (you may have better Google-Fu than me).

     

    Also, while the service clearly does have the functionality (in any given Google Drive folder, you can click the dropdown on the folder name and pick download, and it'll prepare and download a .zip for you), I did a quick experiment - recording the requests the browser made to perform a download, then reusing the same links to see if any of them would trigger the same download - and couldn't find a way to do this automagically with a simple URL.

     

    On a semi-related tangent, I use Google Photos for the bulk of my photo archiving and sharing, and tried to adapt Frederick's code to download from a chosen album on there, but had similar difficulties - I found it was possible, but the download URL seemed to change at random intervals for no apparent reason, and there'd be no way to fix it easily. I ended up simply setting an IFTTT rule to sync photos added to my chosen Google Photos album over to a Dropbox folder.

     

    Another workaroundey route might be to add a symlink (or similar, depending on what OS you're on) to mirror your Google Drive photos folder to Dropbox - if you're on *nix or MacOS, you can use symlinks without having to worry about the pics using twice the storage on your host device. Alternatively, assuming you have a computer that's more-or-less always on and syncing your Google Drive, you could fairly easily create a script of some sort to .zip the photos up, then either set your frame(s) to download them directly from the Google Drive API (see the first link above) or put the .zip somewhere else that your client frame(s) can download it from (a web server, for instance) - this could be part of the script, so it all happens automatically.

     

    If that all sounds too complicated, your best bet is just copying (or symlinking) the pics over to Dropbox. Oh, if anyone knows of or finds a way to negate all the above and generate a reliable direct download link to a Google Drive (or even better, Google Photos) folder (album) that spits out a .zip file, please let me know how, as my whole Dropbox is now basically full of photos of my daughter for her grandparents!

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • gadget.iom
    gadget.iom over 8 years ago in reply to jammychris

    It looks like you can just change the "DROPBOX_LINK" url to your google drive one. Make sure the file can be downloaded without logging in (publicly accessible).

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
<>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube