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 B8GB 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.
Make a note to change the user in the inittab line. Not everybody is named pi :)
ReplyDeleteGood call. Fixed
DeleteHi 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/
ReplyDeleteDid you use a guide to make this photo frame?
ReplyDeleteThanks 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.
ReplyDeleteI'm glad I could help! Thanks for checking it out :)
DeleteHey Cameron,
ReplyDeleteI 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
Excellent thank you! This one had me scratching my head, I'm glad you figured out a solution.
DeleteI'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
ReplyDeleteAlso I put "cd /home/pi/deviant" at the start of getart.sh, because the files were all going into '/'. YMMV
DeleteI 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.
ReplyDeletehttp://www.altmake.com/2012/12/27/social-frame/
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.
ReplyDeleteFollow 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!
DeleteOne 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
ReplyDeletethanks for the link
DeleteWhat hardware setup were you using ie especially the screen?
ReplyDeleteGreat 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.
ReplyDeleteI 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
I noticed duplicate URLs from the grep. Easily remove duplicates by adding
ReplyDeletesort -U |
after grep.
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?
ReplyDeleteExactly. I assume you use some sort of screen connected via HDMI?
DeleteI 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.
DeleteI am having problems with the if statements. They never evaluate to a true condition. I have :
ReplyDeleteif [ "$(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.
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]
ReplyDeleteI can't get my head round what is going on in the example. Many thanks.
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.
ReplyDeleteThanks 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.
ReplyDeleteThese 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.
This seems to work:
ReplyDeletewget 'http://api.flickr.com/services/feeds/photos_public.gne?tags=explore' -O- | grep -Po 'http://[^.]+\.staticflickr[^"]+(_b.jpg|_z.jpg)' | wget -i-
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.
ReplyDeleteGreat 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:
ReplyDeletecd /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
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.
ReplyDeletehttps://www.hdgenius.com/10-INCH-WIFI-PHOTO-FRAME-product.html