Make an interactive graffiti wall
Mar 14, 2013
[caption id="attachment_194" align="aligncenter" width="595"]
Make an interactive graffiti wall using Raspberry Pi and Node.JS[/caption]
In this tutorial we will enable a projector or display to be painted on using connected smartphones. With the setup described, it's easy to implement your own multi-device applications.
This is awesome
A personal note: As a frontend developer, I think it's amazing to be able to leverage such a humble hardware setup. Just using a Raspberry Pi and some accessories, I get a web server that users can connect to with Wi-Fi and the rendering of HTML5 and CSS3 to a display. The software is all open source and all open web standards.
There are however limitations to how much you can do on the rendering side. Most importantly, CSS3 is not hardware accelerated on the Raspberry Pi yet. I've published some performance tweaks if you want to delve into that.
Table of contents
- Hardware setup / Shopping list
- Software setup
- Frontend setup
- Let's get cracking!
- Software installation
- Browser in kiosk mode
- Reboot your Pi
Hardware setup / Shopping list
[caption id="attachment_202" align="aligncenter" width="595"]
Raspberry Pi, SD card, Wi-Fi router, USB cables, network cable, charger, HDMI cable[/caption]
- Raspberry Pi
- Raspberry Pi basics: Case, SD card (4GB is probably sufficient for this project), USB power adapter, USB micro cable (for power)
- network cable and WiFi router (your home router is also fine)
- optional: CopenhagenJS sticker
Software setup
[caption id="attachment_214" align="aligncenter" width="595"]
Software: Debian, NodeJS, Socket.IO, Chromium[/caption]
- OS: Raspbian Node.JS
- Browser: Chromium in kiosk mode
- Server: Node.JS
- Socket library: Socket.IO
Frontend setup
- Module library: Require.JS
- Event capturing library: capture-smartphone
- Absolutely no jQuery what so ever!
There's more to be said about this setup. I will go through the details in a blog post coming up.
Let's get cracking!
First acquire all the hardware in the list above. You probably have most of the things already. If you don't have a case for the Raspberry Pi, don't despair. You can make one in Lego or out of any box of the right size. Download the official Raspbian image and copy it to the SD card. Connect your Pi to your network and power it up. Establish a connection from your working machine via SSH. User pi, default password raspberry.
Tip
Add your local machine's public SSH key if you don't want to type your password every time you connect:
# from localhost, add ssh-key to your Raspberry Pi
# to avoid having to type password all the time
ssh-copy-id -i .ssh/id_rsa.pub pi@raspberrypi
Software installation
Raspberry pi utility
raspi-config is a useful utility for getting started with your Raspberry Pi. It has an easy-to-use graphical (well, ncurses) interface. I recommend doing these things now:
- Expand the disk
- Choose a locale
Enable Turbo mode for greater speedBeware: Only class 10 SD cards seem to be able to take a high overclocking! If too high, it will cause corruption of the data on the SD card.
sudo raspi-config
Update all APT packages
sudo apt-get update
sudo apt-get upgrade
Install GIT
sudo apt-get install git-core
Update firmware
sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update
sudo chmod +x /usr/bin/rpi-update
sudo rpi-update
Install NVM and the latest stable Node.JS
Because of the certification process in Debian Stable, current NodeJS in APT is 0.6. We want to run a more recent version so we have to install it manually.
Update: The official NodeJS site now provides binaries for Raspberry Pi! Simply download the binary at http://nodejs.org/dist/v0.10.5/ (switch the number to whatever is considered latest stable by the NodeJS site.) The filename of your download should be called something like node-v0.10.5-linux-arm-pi.tar.gz.
If you want to be able to easily jump between NodeJS versions and don't mind building it locally (takes hours!) then I still recommend using NVM which is a handy version manager for Node itself.
git clone git://github.com/creationix/nvm.git ~/.nvm
. ~/.nvm/nvm.sh
echo . ~/.nvm/nvm.sh >> .bashrc
nvm install v0.10.5
nvm alias default 0.10.5
Add the boilerplate website
Get the source code for this project and install its dependencies
git clone https://github.com/cybear/capture-smartphone.git
cd capture-smartphone
npm install
Start your site up as a daemon
We want our server to start automatically. For NodeJS, we can use the following script to use a node.js app as a daemon:
Create /etc/init.d/node-app
#/bin/sh
#This script is copied from https://github.com/chovy/node-startup
NODE_EXEC=/home/pi/.nvm/v0.10.5/bin/node
NODE_ENV="production"
NODE_APP='app.js'
APP_DIR='/home/pi/capture-smartphone';
PID_FILE=$APP_DIR/app.pid
LOG_FILE=$APP_DIR/app.log
###############
# REDHAT chkconfig header
# chkconfig: - 58 74
# description: node-app is the script for starting a node app on boot.
### BEGIN INIT INFO
# Provides: node
# Required-Start: $network $remote_fs $local_fs
# Required-Stop: $network $remote_fs $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop node
# Description: Node process for app
### END INIT INFO
case "$1" in
start)
if [ -f $PID_FILE ]
then
echo "$PID_FILE exists, process is already running or crashed"
else
echo "Starting node app..."
NODE_ENV=$NODE_ENV $NODE_EXEC $APP_DIR/$NODE_APP 1>$LOG_FILE 2>&1 &
echo $! > $PID_FILE;
fi
;;
stop)
if [ ! -f $PID_FILE ]
then
echo "$PID_FILE does not exist, process is not running"
else
echo "Stopping $APP_DIR/$NODE_APP ..."
echo "Killing `cat $PID_FILE`"
kill `cat $PID_FILE`;
rm $PID_FILE;
echo "Node stopped"
fi
;;
restart)
if [ ! -f $PID_FILE ]
then
echo "$PID_FILE does not exist, process is not running"
else
echo "Restarting $APP_DIR/$NODE_APP ..."
echo "Killing `cat $PID_FILE`"
kill `cat $PID_FILE`;
rm $PID_FILE;
NODE_ENV=$NODE_ENV $NODE_EXEC $APP_DIR/$NODE_APP 1>$LOG_FILE 2>&1 &
echo $! > $PID_FILE;
echo "Node restarted"
fi
;;
*)
echo "Usage: /etc/init.d/node-app {start|stop|restart}"
;;
esac
Now it needs to have a Run flag and we need to start the service:
sudo chmod +x /etc/init.d/node-app
#start it!
sudo /etc/init.d/node-app start
#if it seems to work, make it start upon boot
sudo update-rc.d node-app defaults
Browser in kiosk mode
Install Chromium
The main display is rendered by the Raspberry Pi. We want it to hide the mouse cursor, disabling the screensaver and to run in full screen mode. The package unclutter hides the mouse cursor and x11-server-utils enables us to disable the screensaver.
sudo apt-get install chromium x11-xserver-utils unclutter
Enable Kiosk mode
For this kind of a device, I'd like the browser to start automatically and in full screen. Create the file /etc/xdg/lxsession/LXDE/autostart
@lxpanel --profile LXDE
@pcmanfm --desktop --profile LXDE
#@xscreensaver -no-splash
@xset s off
@xset -dpms
@xset s noblank
@chromium --kiosk --incognito http://localhost:3000/examples/graffiti.html
Reboot your Pi
You're done! By now you should have your own interactive graffiti wall. Simply connect the Pi to your router, then connect smartphones to your SSID and fire up the web page!
If you're inspired and want to make something of your own, be my guest to fork the code of this project. It should be fairly easy if you know JavaScript! Stay tuned for a blog post describing the web technologies used for this example.
Share