Monday, February 4, 2013

Jumbo Digital Picture Frame

What do you do with a spare flat panel monitor?  If you are a Raspberry Pi hobbyist, you turn it into a jumbo size digital picture frame.  Photography is another of my hobbies and this is a great way to display my work.

Hardware Part 1 - Modify the Monitor Power Supply

This section requires some knowledge of power supplies and delicate soldering skills.  This step is totally optional and can be skipped.  I didn't want a second wire hanging from the picture frame for the Raspberry Pi power supply, so I tapped 5V off of the monitor's power supply.  You can power the Pi normally.  If you are really lucky you will have a monitor with a built in USB hub and you can power it from there.

I completely disassembled the monitor and located 5V and ground on the back side of the power supply where one of the connectors attached.  The wires in the lower right of this image show the power lines that I attached.

I shouldn't need to say this, but: DANGER.  Make sure the power supply is unplugged when you work on it.  Mains power can kill you!

Hardware Part 2 - The Control Panel

The monitor outputs 5V even if it is turned off, because it isn't really off - just in standby.  I added a power switch and LED as well as a push button to signal the Pi to shut down.  A simple script will monitor the pushpbutton and execute a halt when it is pressed.

If you only want to install the shutdown button, just connect it to a GPIO pin and to ground.  The pinouts that I used are shown here.  Don't be concerned about the inconsistency in the GPIO pin numbers.  This is explained below and is due to differences in the pin numbering used by the Raspberry Pi developers, the native pin numbers on the BCM chip, and the WiringPi library.

Hardware Part 3 -Build a case and put it all together

I used the plastic from the case to an old backup tape.  These are more flexible and a lot less brittle than most plastic CD cases.  I was able to use scissors to cut the plastic to fit the curved shape on the rear of the monitor.  Machine screws hold the case together tightly enough to keep the Raspberry Pi in place.  It is mounted so that the SD card extends a little bit below the monitor.  I would have liked to have it all hidden, but there wasn't room and this does make it easier to remove and insert the SD card.

Both the case and the control panel are held in place with Velcro   This allows me to peel the case loose so that I can plug a network cable in if needed.  Tie wraps are used to hold the HDMI cable and power cable neatly in place.  It is a very tight fit.

A added a short length of rope for hanging which is attached to the top two VESA mounting screws.  My frame is 21 inches and is quite a bit heavier than a typical painting, so I wanted something stronger than a typical picture hanger on the wall.   My work of art wouldn't be happy crashing to the floor.  I was very lucky and found a stud in the wall exactly where I wanted to mount the frame.  If you have to use drywall anchors, then I recommend using two about four inches apart and make the rope long enough to go over both.  If your walls are stucco, then I wish you luck.

System Preparation

Windows only recognizes the first partition on removable media and I wanted a large FAT partition to put the pictures on when the SD card is plugged in to my Windows laptop.  That means I had to use the /boot partition for this purpose.

  1. Load Raspbian as usual. Shut down the Pi and remove the sdcard.
  2. Install "Minitool Partition Wizard Home Edition" on a windows system with an sdcard slot.
  3. Run the partition wizard and move the second partition (the system partition) all the way to the end of the disk space.  You could shrink the partition first but I didn't bother.
  4. Expand the first partition to fill the remaining space.
  5. Put the SD card back into the Pi, boot up, and log in.
  6. Update the apt database using:  sudo apt-get update
  7. Install the Linux Frame Buffer Interface using:  sudo apt-get install fbi
  8. Create a directory to hold the pictures that the frame will display:  sudo mkdir /boot/PICTURES 
  9. Create a new user named "slideshow" which is a member of the "video" group:  sudo adduser slideshow --ingroup video
  10. Change the inittab file to automatically log on the slideshow user:  sudo nano /etc/inittab   Find the line that begins 1:2345:respawn:/sbin/getty --noclear 38400 tty1  Comment out that line by placing a # in front of it and then add this line:  1:2345:respawn:/bin/login -f slideshow tty1 </dev/tty1 >/dev/tty1 2>&1
  11. Create a script to run the slideshow:  sudo nano /boot/  which includes this one line: fbi -noverbose -m 1920x1080 -t 10 /boot/PICTURES/*.jpg   
  12. Some notes about the fbi command line:  The -m option specifies the resolution to use on the monitor.  This may need to be changed to display better for the monitor that you use.  The mode specified must be in the /etc/fb.modes  file.  I had to add the mode I needed, which is shown below.  The -t 10 option causes the program to run a slideshow with a 10 second period for each picture.  The -a option causes the program to automatically resize the images to fit the screen.  When I first tried this I was using 10 mega pixel images (about 3800 pixels across) and the Pi was taking 8-10 seconds to perform the resize.  To prevent this I removed the -a option and used FastStone Image Resizer to resize all the pictures for my slideshow to fit into a 1920x1080 screen.  You can find that utility here:
  13. Make the script executable:  sudo chmod 775 /boot/
  14. Edit the bash login script for the slideshow user:  sudo nano ~slideshow/.bashrc  and add this line to the end:   /boot/
  15. Once all of the above has been done, you can reboot and the system will automatically run the slideshow.  You can stop it by pressing Control-C on the keyboard.
  16. Of course, you have to put some pictures in the pictures directory.  You can do this many ways, but I re-partitioned the sdcard so that I could plug it into my laptop and copy pictures directly to the sdcard.  The fbi command will support formats other than JPG, so don't feel that you are limited to that format.  You do need to realize that Linux is case sensitive with file names, so be sure to rename them all consistently. 

Here is the block that I added to the /etc/fb.modes file:

mode "1920x1080"
    geometry 1920 1080 1920 1080 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0

The default fb.modes file did not include a 1920x1080 resolution so I had to find this example.  Fortunately it  works fine with my monitor.  More information about the fb.modes file can be found here:

Trigger Shutdown Script 

The drawing above shows the shutdown switch connected to GPIO-1.  I normally refer to the GPIO pins using the WiringPi numbering scheme.  However, I am not using WiringPi for this project.  We will access the GPIO pin via the /proc filesystem.  WiringPi GPIO-1 is GPIO-18 to the system.

Create a script to monitor the pin and perform a shutdown: sudo nano /etc/ini.d/   
The contents of the script is this:


# monitor GPIO pin 18 (wiringPi pin 1) for shutdown signal

# export GPIO pin 18 and set to input with pull-up
echo "18" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio18/direction
echo "high" > /sys/class/gpio/gpio18/direction

# wait for pin to go low
while [ true ]
if [ "$(cat /sys/class/gpio/gpio18/value)" == '0' ]
echo "SHUT DOWN NOW *****"
        halt &
        exit 1
sleep 1

First, the GPIO pin is configured for input with a pull-up resistor enabled.  Then the scripts loops once a second and checks if the pin is pulled low from the push button being pressed.  If it is, then it executes the halt command and exits.

This script must be run at startup.  The easiest way to accomplish this is to add it to the end of the local startup script:  sudo nano /etc/rc.local
Add this line at the end of the file:
/etc/ini.d/ &
The & at the end of the line makes the command run in the background.  Without it, the local.rc script would not exit and the system would hang on startup.

All Completed:


  1. Can this be setup to pull pictures that are stored in NAS (freenas)?

  2. Sure. FreeNAS supports NFS and SMB. I haven't used NFS in years, but it is fairly simple to install samba to support SMB (Windows file shares) and then mount a shared folder on the NAS. You could also pull files as needed using FTP or SCP, but I would go the samba route.

  3. Would it be possible to add a push-button to somehow control the picture display? Rather than a slideshow automatically changing the photo every ten seconds, I'm interested in being able to choose what picture I want to display and being able to cycle through the directory of pictures manually and leave it on a picture as needed. (I realize I may have to worry about monitor burn-in if I leave it on one picture for too long)

    I want to use it as a title screen behind me in a video broadcast, on a screen that at other times I use for Skype interviews (from a different PC on a different input) but want to be able to switch to the title screen quickly. I'd have the Raspberry Pi as a constant title screen displayer on this input.

  4. I have experimented a little with trying to call the fbi command using popen (from a C application.) However, the fbi app will fail when called that way. This means that there is no way to pass it key strokes to control it's operation.

    I was able to make a program that calls fbi once for each image displayed and the C application does all the rest of the logic (pause, backwards, forwards.) When the fbi app runs it blanks the screen then displays the image and this did not appeal to me for a slideshow. However, it would probably work fine for what you want. The program doesn't have to be in C - you could do it inthe language of your choice. Also, it doesn't have to run on the console. I edited the /etc/inittab to prevent login from running on /dev/tty1 and then call fbi with the option "-t 0" to make it appear on the console. Then you can control the display from an SSH session.

  5. I have discovered that fbi has a memory leak. If left running for a few days it will exhaust all memory and cause the system to freeze. I will have to add a periodic reboot to the script.

  6. Great, well explained project. You could of course use WinSCP to copy photos from Windows to the Pi card and no need to go through the re-partioning.
    I use this all the time to copy files to and fro, for backups and for working on / editing Python.

    1. Of course. But that is not possible if the system is not on the network. This one hangs on the wall in my office at work and I can not connect it to the network.

  7. while testing this, I commented out the /boot/ line in the .bashrc file and now the PI boots to a command prompt logged in as slideshow user, who does not have SUDO rights. How can I edit the .bashrc file without SUDO rights ?

    1. Easiest way is to type logoff
      then login as the pi user, which does have sudo rights.

  8. Great project, but mostly have to say the idea is far better....

    Have a similar config, just for the record, I'm usig qiv, since it:
    -doesnt have memory problems
    -you could have keypressses( back, pause, ff )
    -fast enough
    but keep in mind you have to start it through lighdm....

    I would rather be interested in how to connect the keystrokes (like buttons: N-next, B-back etc) to GPIO pins ?

    keep on, If you have any ideas how can we improve the PictureFrame, let me know.:)

    here is my 1st ver: --now going to replace the internal parts with pi and linux.

  9. After trying steps 2 through 4 a number of times, the windows app always reports a bad card, but lets me try it again. The image boots fine otherwise. What am I doing wrong?


    1. No way for me to answer that. I suggest starting over with a fresh load of the raspbian image onto the SD card.

  10. Ted, this is an amazing article. I am a photographer and want to build a very similar style frame with a few modifications. I do not have the technical skills to modify this. Is that something you might be willing to help me with? I'd be happy to compensate you for your efforts. Thanks.

    1. Thanks. This is one the most popular posts on my blog.
      Unfortunately, I don't have any time to spare for the many requests that I receive via this blog, and compensation is (fortunately, for me) somewhat irrelevant. However, I am willing to answer questions and give advice. That I give away. It's one of the purposes for this blog. I can't always respond in a timely matter since this is just a hobby and real life has me busy full time.

    2. PS - I am also a photographer (very amateur) and try to focus on wildlife and landscapes. You can see some of my work at

  11. Nice work! And thanks for the reply and offer. I will undoubtedly be in touch with you as I get into it.

    If I can return the favor - I know a little bit about photography.

  12. Great guide. I implemented a solution based on this and made an excellent slide show for a booth at an expo without risking the loss/theft of an entire laptop. Thanks!

    1. Glad to be of help. That is a great application for this project. I have worked many trade shows and know what it's like. Never enough space and always worried about the hardware.

  13. when i make a new user raspberry asks for new UNIX password
    Ive ried to enter something but the keyboard is not responding
    pls help

    1. The keyboard is actually responding, but the characters are no echoed back for security reasons (someone looking over your shoulder)
      Just enter a password and then enter it again when prompted and it will work.

  14. Thank you! I found this useful ;)

  15. Hi. Interesting project. I'm thinking of making a pattern generator for calibrating tvs and this seems like a possible easy way of doing that. Is it possible to change resolutions on the fly?

    1. Add the various resolutions that you need to the file /etc/fb.modes
      Then specify the resolution when you call fbi.
      Instead of photos, you would display your various patterns. It should be straightforward to make a shell script to do all this.

  16. I'm working on a project ( to teach primary school kids how to program and I found this really useful. Thanks.

  17. This comment has been removed by a blog administrator.

  18. An excellent little project, many congratulations. I am in the closing stages of completing my take on this but am a bit stuck on the hardware to shut down the pi.

    I am using GPIO 18 as you are but I am a little lost on the circuit. My thinking is that all I need is a push-to-make switch between GPIO 18 and GND which, when the circuit is closed, shuts the pi down using your software listed above. However, you mentioned "the GPIO pin is configured for input with a pull-up resistor enabled". Looking at internet tutorials on Pi input switches, there are resistors in such circuits which have confused my rather simple hardware brain.

    Could you elaborate on this circuit and let me know if it is any more complex than I have suggested above?

    Many thanks

    1. It really is as simple as it seems. Just a normally open push-button connecting GPIO 18 to ground. The Raspberry Pi has configurable pull-up or pull-down resistors internally, so none are needed externally. The line
      echo "high" > /sys/class/gpio/gpio18/direction
      turns on the pull-up resistor so that the gpio pin will read high until it is connected to ground. Also note that with the script I provide, the pin is only tested once per second, so you need to hold the button down for at least one second for the shutdown to be triggered.

    2. Great, thanks. Just to confirm, am I connecting GPIO 18 to ground with the push to make switch, or to 3.3V?

    3. Yes, connect to ground.
      It could also be done the opposite way - configure a pull-down resistor and a push button connecting to 3.3v. The script would then be changed to look for a high signal instead of a low.

  19. Can you recommend a reliable HDMI to VGA converter?

    1. No. I have never used one. I use HDMI to DVI cables connected to a normal monitor. If you have a fairly recent monitor, you should be able to do this. If your monitor is old and only has VGA, then you must get a converter.

      Try searching the forum for a recommendation

  20. Great write up. Exactly what I want to do.
    I'm getting "undefined symbol" errors with fbi so need to troubleshoot that before I can get it working

  21. This comment has been removed by a blog administrator.

  22. Would it be possible to use a USB flash stick for the images and have the command pointed to it instead? Also, if that is possible, what would be needed to kill the command upon USB flash unmounts (this would be just pulling the stick out)? After that, I'm sure a mount command of some sort could retrigger the command when a new stick is inserted. I'd like to keep images on removable media without the OS and just let the Pi keep running.

  23. Sure. That's actually the way a lot of people want it.
    A good description of how to set up automount can be found here:

    If you define the mount as read-only (ro instead of rw in the fstab line) it should be safe to just unplug it without causing damage to the drive. However, the script running the slide show would probably crash. Some mods would be needed for the script to recover gracefully.
    This is more than I can cover in a comment - sound like a great idea for a new post.
    I will be installing one of my picture frames in the lobby of my company's new office space and I may want it set up like you described.

  24. Ted,

    Thanks for generously sharing your developments. I am a bit stuck with the pushbutton shutdown script. Working backward: 1) switch does nothing 2) ps -ef does not show the script running 3) executing the script from the command line:
    sudo /etc/ini.d/
    gives this error:
    /etc/ini.d/ line 6: echo: write error: Device or resource busy
    Now I am stuck. Thanks for your help

    1. That error on line 6 indicates that the pin has already been exported.

  25. More about the above. Still no executing from boot. If I instead
    sudo /etc/ini.d/, then the RPI hangs, but the push button will trigger a controlled shutdown. So, to repeat, without sudo, I get
    /sys/class/gpio/export: Permission denied
    How to change permissions so that it will execute at boot? Thanks

    1. I have a typo in my post - that script should be in the /etc/init.d directory. Also, I did not mention that it must be made executable with the command: chmod +x /etc/init.d/

      There are ways to make this run as a non root user but that is not necessary. Anything run from the /etc/rc.local script will run as root.

      It sounds like it is not running because it is not executable.

      Another note - the RPI doesn't really hang, but the current shell will appear to be hung since the script is running in a loop waiting for the button press. If you are on the console (as I assume) then you can get to another shell by pressing CTRL-ALT-F2 (or F3, F4, F5) and return to the original shell with CTRL-ALT-F1

  26. Hi Ted,
    I have to tell that I am totally new to use of the Raspberry Pi - and need lots of both knowledge and time to get into al this...
    That also makes it diificult for me to come up with questions about 'How To' - cuz I can see that there are SO many of you who really know SO much about both commands, the Linux system and the RPi itself.! ;-)

    Well - evne though, I carefully want to come up with some questions about this project - and hope that there can be a will to share some ideas with me.!

    I have gone through the setup you show in your documentation - and was hoping I easily could get a picture frame.
    I have excluded the way of 'auto-start' with boot - cuz I wanted to control the start of the slideshow manually.
    I installed the 'fbi' - made the 'dir' on boot for 'Pictures', created the new user name 'slideshow'.
    Created the script to run 'slideshow' which contains the line as described.
    Made the script 'executable'.
    I did not edit the bash login for the slideshow - cuz I thought that had soething to do with the 'autostart' at boot.
    Am I wrong..???

    Anyway - I get a an 'inappropriate ioctl for device - when I try to run the slideshow.
    The message is as follows;
    using "DejaVu Sans Mono-16", pixelsize=16.67 file=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf
    ioctl VT_GETSTATE: Inappropriate ioctl for device (not a linux console?)

    And the slideshow does not start.!

    My idea about this project was;
    I have from before set up a PiClock and that works very fine and want to put all in a frame together with an old lcd-panel (already have the controller).
    Wanted to install ExaGear and Teamviewer so I can connect to the RPi that way and control the programs that way (wireless)
    The PiClock start on boot and can be stopped by CTRL-C.
    Then I wanted to make use of the Slideshow on the same unit - so if I want to use the same 'frame' to a picture frame - I just stop the PiClock, enter new user and start the slideshow, when I want.

    And as I see from other users here - it is higly wished to be able to use an USB stick with the pictures to show.

    But I cannot get the slide show to run and work.!
    So - I wonder if there are anyone who could help me a little on the way - to get it correct 'put in place' the needed commands..??

    Thanks in advance..!!

    With regards

    1. The fbi program tries to display on the frame buffer device mapped to your current virtual terminal device and will only work if you are logged on directly at the console. (i.e. the device plugged in to the HDMI connector.) You can specify the frame buffer device on the fbi command line to get around this.

      You mention an lcd panel and a controller - this leads me to believe that you are probably connected to the Pi via secure shell and the lcd is connected via GPIO (or SPI, I2C, etc.)

      You will need a program that is able to display pictures on the LCD that supports the way you have it connected. If there is a way to provide a frame buffer device for your lcd controller, then you could use fbi.

  27. Hi Ted,

    Thanks for a good project and write-up. You may wish to update your instructions as Jessie Lite no longer uses inittab. After much web prowling and rebooting, I found this to work. Recommend you test it out to make sure I did not leave anything out as I went down many rabbit holes.

    I made this file using nano
    sudo nano /etc/systemd/system/getty@tty1.service.d/autologin.conf

    And put this in it:

    ExecStart=-/sbin/agetty --autologin slideshow --noclear %I 38400 linux

    Please note the use of the username "slideshow" for the auto login. After that, run this command:

    systemctl enable getty@tty1.service

    That should do the trick.

    Two other things I found helpful. I decided to use an extra usb stick for my photos. I find it easier to reload and update with my ever growing database of files. Plus it allows me to use an older 4 gB sd card for the operating system. This site has a good set of instuctions on how to mount a usb stick:

    And if you find black bars around your display then you need to fiddle with the overscan parameters. Here's a simple lesson on how to do that piece of magic: