Sunday 24 June 2012

Raspberry Pi Wireless Display Using a Cheap Parrot LCD Photo Frame

One of the first things I've tried with my Raspberry Pi is to get it to use the low cost Parrot DF3120 320x240 picture frame as a wireless display over Bluetooth. These little frames are available on Amazon for under £15!

This builds on the sterling work done here to hack Linux onto the DF3120. When I first saw this post, I bought a few of the frames as they looked like they might come in handy for something.

The basic idea is to set up Bluetooth networking with the Pi, and use SDL VNC viewer to display the X screen on the Parrot. 

Bluetooth Network Setup 

The first thing we need to do is get Bluetooth networking set up between the two devices.

To start off with, on the Pi side, I'm using the standard Debian squeeze image and an Atheros Communications, Inc. AR3011 Bluetooth USB dongle. Install the bluetooth package, and for my atheros dongle, I installed the firmware-atheros package:

apt-get install bluetooth firmware-atheros

On the Pi, you will also need to run bluetooth-agent to allow pairing of the parrot. For testing I just ran this at the command line with no PIN specified. This will allow the Pi to pair with anything that attempts to connect.

bluetooth-agent hci0 

On the Parrot, flash the firmware update using the PFS file and minifs image using the instructions at Hold down the left and center buttons while powering on to boot into Linux. Once booted, connect the Parrot to a Linux machine and set up the USB networking using 

ifconfig usb0 netmask up

More details on connecting to the Parrot over the USB network are here

To bring the network up and connect to the Pi over bluetooth, issue these commands on the Parrot:

pand --connect AA:AA:AA:AA:AA:AA
ifconfig bnep0

where AA:AA:AA:AA:AA:AA is the BD Address of the Pi. You can find this out by running hciconfig on the pi. 

On the Pi in the terminal where you have bluetooth-agent running, you should see something like:

Authorizing request for /org/bluez/1274/hci0/dev_BB_BB_BB_BB_BB_BB

There should now be a virtual network interface created by bluez on the pi, bnep0. You can give this an IP address on the Pi by issuing: (We will automate this process later)

ifconfig bnep0

You should then be able to ping or telnet to the Parrot on from the Pi. To bring Bluetooth networking up automatically on the parrot, I added this to /etc/init.d/rcS, so mine looks like:

#echo "* Starting Bluetooth"
hciattach -s 115200 /dev/ttySAC0 bcm2035 921600 flow 00:00:00:00:00:00 >/dev/null 2>&1
hciconfig hci0 up

bdaddr 84:59:04:04:02:05                                                              
hciconfig hci0 reset                                                                  
#echo "* Starting DUN connection"
#rfcomm bind /dev/rfcomm0 08:00:06:5E:8D:F5 2
#pppd /dev/rfcomm0 noauth defaultroute lcp-echo-interval 10 lcp-echo-failure 12

#echo "* Starting PAN connection"
pand --listen --role NAP
pand --connect 00:02:72:B2:E8:12
sleep 5
ifconfig bnep0

A couple of things to note - I'm using static IPs, but you could run dhcp on the Pi and assign IP addresses like that. The other thing is that for some reason on the Parrot, I was getting a different bd address every time I rebooted. To solve this I use the bdaddr command that is in the bluez test suite to set the bd address every time. 

The bdaddr utility is not included in the pre-built image for the parrot, but you can download a copy I built here - bdaddr.tar.gz

To build a copy of bdaddr, I had to rebuild the bluez package in minifs for the Parrot to include the test apps. To get this to work, you need to follow the instructions on building the DF3120 toolchain/rootfs here using this patch to bring a few package versions up to date where the linked versions are no longer available, and add the dependancies and config option to build the test apps (including bdaddr) in bluez:

diff -rupN minifs.orig/conf/packages/ minifs/conf/packages/
--- minifs.orig/conf/packages/ 2012-06-24 20:26:02.714490989 +0100
+++ minifs/conf/packages/ 2012-06-24 02:10:36.030728699 +0100
@@ -3,7 +3,7 @@
 ## zlib -
 PACKAGES+=" zlib"
-hset zlib url ""
+hset zlib url ""
 configure-zlib() {
  configure ./configure \
diff -rupN minifs.orig/conf/packages/ minifs/conf/packages/
--- minifs.orig/conf/packages/ 2012-06-24 20:26:02.714490989 +0100
+++ minifs/conf/packages/ 2012-06-24 02:14:55.366933145 +0100
@@ -5,7 +5,7 @@ hset libjpeg url "
 PACKAGES+=" libpng"
-hset libpng url ""
+hset libpng url ""
 hset libpng depends "zlib"
 hset libpng configscript "libpng-config"
diff -rupN minifs.orig/conf/packages/ minifs/conf/packages/
--- minifs.orig/conf/packages/ 2012-06-24 20:26:02.714490989 +0100
+++ minifs/conf/packages/ 2012-06-24 12:47:30.981169269 +0100
@@ -15,9 +15,22 @@ deploy-dbus() {
  deploy deploy_binaries
+PACKAGES+=" check"
+hset check url ""
+hset check depends ""
+configure-check() {
+        configure-generic
+deploy-check() {
+        deploy deploy_binaries
 PACKAGES+=" bluez"
-hset bluez url ""
-hset bluez depends "dbus libiconv libgettext libglib"
+hset bluez url ""
+hset bluez depends "check dbus libiconv libgettext libglib"
 configure-bluez() {
  configure-generic \
@@ -43,7 +56,8 @@ configure-bluez() {
  --enable-service \
  --enable-tools \
  --disable-udevrules \
- --disable-usb
+ --disable-usb \
+ --enable-test
 deploy-bluez() {

To automate things on the Pi side, I added the following to /etc/network/interfaces

iface bnep0 inet static

And to automatically start bluetooth-agent for pairing I added this to the bluetooth startup script. Note that this will allow any device to connect with no PIN, so beware!

--- bluetooth.orig 2012-06-24 21:43:17.024405263 +0100
+++ bluetooth 2012-06-24 20:03:45.376014045 +0100
@@ -25,6 +25,7 @@
@@ -164,6 +165,11 @@
  log_progress_msg "compatibily daemons not started, see bluez-compat package"
+        sleep 3
+        for i in `hciconfig | grep hci | cut -f1 -d:` ; do
+ done
  log_end_msg 0
@@ -180,6 +186,9 @@
  start-stop-daemon --stop $SSD_OPTIONS
  log_progress_msg "bluetoothd"
  stop_uarts || true
+ killall $BLUETOOTH_AGENT > /dev/null 2>&1
  log_end_msg 0

VNC Setup

The next step is to get VNC up and running. On the Pi, install a the tightVNC server and viewer:

apt-get install tightvncserver xtightvncviewer 

Then run the server on the Pi - it will ask for a password to connect the first time.

vncserver -geometry 320x240 -depth 8 :1

On the Parrot, run the SDL vnc viewer:


Enter the password you specified earlier, and you should now see your desktop displayed on the Parrot. Yay!

From an X session on the pi, you can run 

vncviewer :1 

To open a vnc session where you can control the desktop on the Pi. Enjoy.