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 Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • 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
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • 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 10265 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 7 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 7 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 7 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…
Parents
  • bishely
    bishely over 7 years ago

    Frederick

     

    This is a brilliant project! I'm going to give it a go, and possibly roll out a few of these for our family, since we're all scattered around Europe and the US. I've plenty of experience with Raspberry Pis but haven't used resin.io before (looks very cool!).

     

    I had one question though, which (I think) I've found the answer for myself (but would appreciate you confirming!). I'm sharing it here in case anyone else has the same (probably dumb) question. Your documentation shows how to set WiFi up before flashing the SD card, but if I'm setting it up at home and then delivering it to my family member's house, I obviously need to change those details at some point. My initial guess was that I could change it from the resin.io dashboard (obviously before taking it out of my home), or in the worst case (eg a family member changed their router without warning me) maybe get them to mount the SD card on another computer and tweak a config file somewhere (that'd be a fun tech support call with my dad!). Fortunately, resin.io definitely allows the second option (the first one seems a little clunky, but I don't see why it wouldn't work), but best of all it also lets you configure multiple SSIDs/PSKs, as long as you're comfortable editing a json file. The documentation (for anyone else wondering - I'm sure you've got it covered!) is here: (EDIT: I had an old link here because I'm a doofus. As Frederick rightly points out, it should be: https://docs.resin.io/deployment/network/2.0.0/#wifi-setup)

     

    Once again, a wonderful idea and really sweet implementation: I'm ordering the screen and enclosure (already got a spare Pi, or three, to test this out on) right now!

     

    EDIT: Corrected my link.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fvan
    fvan over 7 years ago in reply to bishely

    Hey Tom,

     

    there is a file on the SD card which can be updated with a different SSID and passphrase. See https://docs.resin.io/deployment/network/2.0.0/#wifi-setup

     

    Thank you for your kind words, it's really satisfying to see people picking up the project image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • fvan
    fvan over 7 years ago in reply to bishely

    Hey Tom,

     

    there is a file on the SD card which can be updated with a different SSID and passphrase. See https://docs.resin.io/deployment/network/2.0.0/#wifi-setup

     

    Thank you for your kind words, it's really satisfying to see people picking up the project image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • bishely
    bishely over 7 years ago in reply to fvan

    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, and I stupidly went ahead and assembled everything while Etcher was still doing its stuff)
    • 20 minutes setting up the software
    • 90 or so minutes cropping a bunch of photos down to 4:3 aspect ratio

    I know I said it before, but this really is an excellent project! I'm possibly going to fork the GitHub code, just so I can play with things a bit and see if I can't break it image I've not done anything with Tkinter before, and this looks like a fun place to start!

     

    PS - I really feel I should be giving something back here: have you got any way I can buy you a beer or something?

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fvan
    fvan over 7 years ago in reply to bishely

    Ha! Don't worry about it! If you do make improvements, permission to incorporate them in my project would be great image

     

    This was my first project with Tkinter, so indeed a great place to start. Took some getting used to, especially getting the layout to work, but I think I got the basics covered.

     

    Don't forget to post a pic or 2 when you finish!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • bishely
    bishely over 7 years ago in reply to fvan

    Hey Frederick

     

    Haven't had much time to play with this lately (we're emigrating this week, and for the last month I've been doing an intensive qualification, so tinkering has been off the menu!) but I think I stumbled on one minor improvement to your original - as mentioned above, the thing that took me most time when setting up my own prototype frame was cropping my photos to 4:3 so they wouldn't look horribly distorted. So I (with the help of Google) tweaked the resize_images function and added an add_borders function, which means you can just drop any size/aspect ratio photo into the Dropbox folder and they'll resize to the maximum possible on the frame without distorting. For me, this is a huge time-saver/friction-remover, since there's no admin to put me off putting uncropped pics in the folder as soon as I've taken them - and I can still crop them later if necessary.

     

    Anyway, I've also made other tweaks and modifications on my branch which are probably not as useful and possibly rather pointless (I've been trying to get a auto-rotation function working, because I seemed to be having some problems with rotated images, but I can't get that to work properly), so rather than doing anything on GitHub, I'll simply put my reworked lines here. Feel free to use them, or ignore them, but thanks again for creating this brilliant project!

     

    def resize_images():

         baseheight = 480

         images = list_images()

         for file in images:

              img = Image.open(file)

              hpercent = float(float(img.size[0])/float(img.size[1]))

              neww = int(baseheight*float(hpercent))

              img = img.resize((neww,baseheight), Image.ANTIALIAS)

              img.save(file, "JPEG")

     

    def add_borders():

         images = list_images()

         for file in images:

              old_im = Image.open(file)

              old_size = old_im.size

              new_size = (640, 480)

              new_im = Image.new("RGB", new_size)

              new_im.paste(old_im, ((new_size[0]-old_size[0])/2,

                                                   (new_size[1]-old_size[1])/2))

              new_im.save(file)



    Obviously, also add a call to add_borders() just after resize_images() in initialize().

     

    (Edit: Stupid table messed my indents up!)

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

    thanks for sharing this,  can you please point me to the file that these changes need to be made in ?

     

    is this under connectedframe.py ? *FOUND it.

     

    Now do i put this under  ?

    initialize()

     

     

    left_column = Frame(root, bg='black', width=80, height=480)

    center_column = Frame(root, bg='black', width=640, height=480)

    right_column = Frame(root, bg='black', width=80, height=480)

    • Cancel
    • Vote Up 0 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 © 2025 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