Saturday, December 15, 2012

Raspberry Pi - Daily Deviations Picture Frame



I have been following the progress of the Raspberry Pi with keen interest for a while now and I’ve finally got one of my own to play with. Over the past couple of weeks I’ve been tinkering with it in the evenings and I’m absolutely blown away by this little device. With a $35 dollar price tag, the RPi is a surprisingly capable computer. You obviously won’t be doing some of the CPU intensive tasks you would be used to on your PC, but its a great way to tinker and learn and maybe find a great practical use for it along the way. After a little trial and error I’ve found an interesting application for it that I wanted to share.

I’ve seen a few people contemplating using the Raspberry Pi to power a photo frame for the living room. One of those digital picture frames that cycles through a bunch of pre-loaded jpgs of your friends and family. This gave me the idea of having a piece of art hanging on the wall, with a nice wooden frame, that actually downloads new art everyday and cycles through it. So I’ve come up with a fairly simple way to do this all without ever starting X.

I would just like to clarify a few things first. This solution relies on a few bash scripts, and this is my first experience making them. I’ve really been piecing together bits of commands that I have found all over the web. I am by no means an expert and this method is probably not the best way to achieve the end result. In saying this, if you know of a better way to get this job done, by all means leave me a comment as I would love to hear your ideas.


What it does

When the RPi is turned on it boots up, deletes all jpg’s and png’s in the directory /home/pi/deviant/, downloads the daily deviations from deviantart, deletes any that aren’t a jpg or png (gifs and other files don’t work yet) and begins a slideshow using the framebuffer. At midnight the slideshow is halted, the RPi is rebooted and the cycle starts over.

What I used

Raspberry Pi Model B
8GB SD Card
Rapbian Wheezy

How it works

After you have a fresh install of raspbian wheezy on your SD Card, pop it into your RPi and boot it up. There is a little wizard at the beginning that walks you through a few simple startup options. I chose to expand root partition to fill SD Card, changed the keyboard layout to us, changed my timezone to Edmonton and changed start desktop at boot to no. After a reboot the RPi will take a few minutes to resize the root and then it will ask you to login. The username by default is pi with a password of raspberry. Every time the device is turned on it will ask you to login, and for our purposes this is not ideal. We want the user pi to be automatically logged in upon boot. Here is how we do that:
  • sudo nano /etc/inittab


This will open nano as root, which is a terminal based text editor. Scroll down until you find the following line:

  • 1:2345:respawn:/sbin/getty --noclear 38400 tty1

Add the pound sign to the beginning of this line to comment it out and add the following to the line beneath it:

  • 1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

Please note that I've used the default user "pi". If you are using a different user name use that instead. Press ctrl+x to exit, type Y to save and enter to confirm filename. Now type

  • sudo reboot

The RPi will reboot and if you did everything right, it will now automatically login as user pi. The next thing we will need to do is install fbi (Linux FrameBuffer Image Viewer). To do this type the following:

  • sudo apt-get update
  • sudo apt-get install fbi

The next thing we have to do is create the scripts that will do the work. Make sure you are in the home directory and type

  • mkdir deviant

This will create a new directory within your home folder called deviant. Change into this newly created directory and type

  • sudo nano getart.sh

Once nano is open we will enter the commands to remove any images from the deviant directory.

  • rm *.jpg *.png
  • rm aa.*

The aa.* will make sense later. Next we will enter the commands to download the daily deviations from deviant art:

  • wget -U 'SomeUserAgent/1.0' -O- 'http://backend.deviantart.com/rss.xml?q=special:dd' 2> /dev/null |

  • grep -Po 'http://[^.]+\.deviantart.com/art/[^"]+-\d+' |

  • sed -r 's/.+-([0-9]+)/http:\/\/www.deviantart.com\/download\/\1\/aa/' |

  • wget -U 'SomeUserAgent/1.0' -i-

This will download the files and name them aa.1, aa.2, aa.3, etc. sequentially so we need to now go through each file and rename it or delete it depending on its file type:

  • FILES=~/deviant/*
  • count=0
  • one=1

  • for f in $FILES

  • do

  • file -b $f

  • echo "Checking file number $count"
  • count=$(($count + $one))

  • if [ "$(file $f|grep JPEG)" ]; then
  • mv ${f} ${count%.*}.jpg



  • elif [ "$(file $f|grep PNG)" ]; then
  • mv ${f} ${count%.*}.png

  • elif [ "$(file $f|grep ASCII)" ]; then

  • echo ”Skip Script file”

  • else
  • rm ${f}

  • fi
  • done

This will go through each file in the directory and either rename, skip or delete it depending on if it is a jpeg/png, script, or anything else. The last line will execute the slideshow script we will write next:

  • bash /home/pi/deviant/slideshow.sh

Now type ctrl+x to save. Next we will create the slideshow script. Type the following:

  • sudo nano slideshow.sh

Once nano has opened enter the following command:

  • fbi -noverbose -m 1920x1080 -a -t 10 /home/pi/deviant/*.jpg /home/pi/deviant/*.png

Now type ctrl+x to save and the slideshow script is done but there is one problem. My screen resolution is 1920 x 1080 so I have set the mode to 1920x1080 but this probably won’t actually work right until we add this mode to the system. You can customize this part to whatever works best for your set up. Type the following to add a mode:

  • sudo nano /etc/fb.modes

Now scroll to the end of the page and enter the new mode:

  • 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
  • endmode

Now type ctrl+x to save the file. There is one more script to create before we move on. This one is a simple reboot script. Type the following:

  • sudo nano rboot.sh

Once you are inside nano enter the command:

  • sudo reboot

Crtl+x to save and now we have to make these three scripts executable. Type the following commands:

  • sudo chmod +x getart.sh
  • sudo chmod +x slideshow.sh
  • sudo chmod +x rboot.sh

The purpose of the rboot script is to reboot the RPi at midnight everyday. To accomplish this we are going to use cron which is a handy tool for scheduling tasks. First we must start cron at every bootup. Enter the following:

  • sudo nano /etc/rc.local

When the script opens in nano we want to add the following two lines on the line above exit 0.

  • /etc/init.d/cron start
  • bash /home/pi/deviant/getart.sh

Ctrl+x to save. This will start cron and execute the getart script every time the RPi is booted up. Now the final step is to schedule the unit to reboot at midnight everyday. To do that type the following:

  • crontab -e

We need to enter the following command in nano:

  • @midnight /home/pi/deviant/rboot.sh

Again Ctrl+x to save and we are done. Type:

  • sudo reboot

The system is now up and running. So as I mentioned before, there is probably a better way to do some of this stuff and I’ll keep tinkering with it, but it should give you at least a starting point for creating a really simple image viewer.

29 comments:

  1. Make a note to change the user in the inittab line. Not everybody is named pi :)

    ReplyDelete
  2. Hi Cameron, Sounds like an awesome project. I'd love to include this in a roundup I'm doing for Wired.com. Do you have any pictures? Or could you take one of the project? I'm joseph.flaherty@gmail.com and here is my byline http://www.wired.com/design/author/jflaherty/

    ReplyDelete
  3. Did you use a guide to make this photo frame?

    ReplyDelete
  4. Thanks for the walk through. I was wanting to do a very similar project. Despite never having really used any form of Linux i got this up and going in no time.

    ReplyDelete
    Replies
    1. I'm glad I could help! Thanks for checking it out :)

      Delete
  5. Hey Cameron,
    I made a minor adjustment for the identifying the script, use it if you want. I noticed it was picking up on ASCII in HTML files etc so wasn't behaving as intended. :)

    from
    elif [ "$(file $f|grep ASCII)" ]; then

    to
    elif [ "$(basename $f)" == "$(basename $0)" ]; then

    ReplyDelete
    Replies
    1. Excellent thank you! This one had me scratching my head, I'm glad you figured out a solution.

      Delete
  6. I'm not sure if this is true for all, but FILES=~/deviant/* failed for me; I used FILES=/home/pi/deviant/* since the scripts are chown root

    ReplyDelete
    Replies
    1. Also I put "cd /home/pi/deviant" at the start of getart.sh, because the files were all going into '/'. YMMV

      Delete
  7. I put together something similar that pulls from Twitter. I used chromium-browser in kiosk mode. I had some trouble with the cursor showing up in the center of the screen on reboot and eventually solved it with unclutter. I wrote an on the whole process.
    http://www.altmake.com/2012/12/27/social-frame/

    ReplyDelete
  8. What if you want to use your own library of photos that average 4 MB instead of the art website ? Either in a slideshow type list or just randomly. Over 5000 photos.

    ReplyDelete
    Replies
    1. Follow this guide but skip the part where we create the getart.sh script. When you edit the rc.local file, change the line "bash /home/pi/deviant/getart.sh" to "bash /home/pi/deviant/slideshow.sh" Then put all your image files in the /home/pi/deviant/ folder and you should be good to go!

      Delete
  9. One of those digital picture frames that cycles through a bunch of pre-loaded jpgs of your friends and family. This gave me the idea of having a piece of art hanging on the wall, with a nice wooden frame, that actually downloads new art everyday and cycles through it.7 inch digital photo frame

    ReplyDelete
  10. What hardware setup were you using ie especially the screen?

    ReplyDelete
  11. Great page. Got mine up and running. I am using a local folder for my source, but I am finding that the FBI app is either not looping to start over again or erroring on something.

    I have a new 'B' board running the latest image.

    Since I am running it local I only have the slideshow.sh, which has this in it.

    fbi -noverbose -u -a -t 10 /var/photos/images/*.JPG

    I cannot find an error log, and every page just states it loops automatically.

    Any thoughts?

    Thanks, Phil

    ReplyDelete
  12. I noticed duplicate URLs from the grep. Easily remove duplicates by adding

    sort -U |

    after grep.

    ReplyDelete
  13. What did you use for your screen? As the only hardware you noted was the Model B Raspberry Pi and the 8GB SD Card, of which I'm sure you could also use something smaller, depending on what you choose your input to be. Have you thought about making this work with a video file or multiple screens?

    ReplyDelete
    Replies
    1. Exactly. I assume you use some sort of screen connected via HDMI?

      Delete
    2. I didn't talk about the screen because it wasn't a very elegant solution and I'm sure you guys could come up with something better. I took apart an old monitor (1280x800) and installed it in the picture frame (Mostly duct tape). I then ran the hdmi and power cable through the wall to power it. This involves cutting holes in drywall and keeping the RPi separate from the frame. Like I said, not exactly an elegant solution, but it works.

      Delete
  14. I am having problems with the if statements. They never evaluate to a true condition. I have :

    if [ "$(file $f|grep JPEG)"]; then
    echo "true"
    else
    echo "false"
    fi

    I have tried all manors of spaces, no spaces, etc for the condition, but no luck.

    ReplyDelete
  15. Could someone help me change the filters in the wget lines to use Flickr instead? The feed for it is http://api.flickr.com/services/feeds/photos_public.gne?tags=[search term]


    I can't get my head round what is going on in the example. Many thanks.

    ReplyDelete
  16. Tom, the 4 lines are combined to form a wget filtered for the files he is downloading from deviant art. What specific files on flickr are you interested in? The [search term] isn't specific enough.

    ReplyDelete
  17. Thanks Jerad - I would use (for example) http://api.flickr.com/services/feeds/photos_public.gne?tags=explore or http://api.flickr.com/services/feeds/photos_public.gne?tags=moonrise.

    These return a page of results in the same way as the backend.deviantart.com link - I just can't work out what I need to change the code to to get it to work with the different URL.

    ReplyDelete
  18. This seems to work:

    wget 'http://api.flickr.com/services/feeds/photos_public.gne?tags=explore' -O- | grep -Po 'http://[^.]+\.staticflickr[^"]+(_b.jpg|_z.jpg)' | wget -i-

    ReplyDelete
  19. has anyone had trouble with fbi hanging on certain images? it seems the rPi is locked up when i experience this, i can't hit q or esc to quit.

    ReplyDelete
  20. Great tutorial Cameron! I've had a blast playing with this project. I have had this running on a RPi model B with no problem but when I tried to run it on a model A I started to experience lockups on random pictures. A quick look into the running processes showed that the fbi call was eating up all the system RAM. It was adding each picture to memory without freeing up the resources of the previous image. I rewrote the slideshow.sh file to call each file individually and clean up after itself (had to put the last sleep 5 in to give it time to dispose of its resources correctly). Anyway I hope this helps others with similar issues:

    cd /home/pi/deviant/pics
    FILES=/home/pi/deviant/pics/*.*

    while [ TRUE ]
    do
    for F in $FILES
    do
    fbi -noverbose -m 1440x900 -a -T 2 $F &
    sleep 70
    killall -9 fbi
    sleep 5
    done
    done


    ReplyDelete
  21. Great idea to make a digital frame with raspberry-pi, if you are not a tech savvy, this 10 inch digital picture frame is great for you and your parents.

    https://www.hdgenius.com/10-INCH-WIFI-PHOTO-FRAME-product.html

    ReplyDelete