Project: jablock
A project to block TV commercials and promotions.
MOTIVATION:
Probably for purposes of survival we are programmed to have our
attention drawn to action in our field of view, especially to
unexpected events. Advertisers take advantage of this to
capture our attention by presenting fast-changing, unexpected
scenes. The purpose of this project is to provide a way for a
viewer to recapture control of their attention by presenting
a relatively static, predictable scene that he or she may
choose to switch to.
In what follows I attempt to describe every detail of the
operations required to implement this project. No doubt there
are better ways to accomplish the various tasks. I would
appreciate any suggestions for improvements. If you find errors
or ways to improve the descriptions in this file, I would like
to hear about them.
HARDWARE DESCRIPTION:
This project uses a Raspberry Pi processor (called RPi in what
follows, www.raspberry.org). A "starter bundle" was purchased
from Newark Element14 (~$60, www.newark.com). It consists of
a Model B (43W5302) processor, case, AC adaptor and an SD card
pre-loaded with NOOBS (New Out Of Box Software), which
consists of various operating system options. The RPi is
augmented with a real time clock from Acme Unlimited (RasClock,
~$13, store.acmeun.com).
TEST CONFIGURATION:
The project requires a TV with an HDMI input port and (possibly)
an analog audio input jack. The TV unit used for testing was a
Samsung model: UN32EH5000FXZA 32" 1920x1080p. If your TV doesn't
have an analog input jack, it may be possible to input audio
via the HDMI port (see: HDMI AUDIO section below). The HDMI
specification supports both digital audio and video interfaces.
In any case you can still implement the video (most important)
part of this project. Also, much of the configuration work was
done over an ssh wired Ethernet connection.
INITIAL SETUP:
It is necessary to connect the RPi to a TV, keyboard and mouse
for initial configuration. A photo on this site shows my setup.
Note that I have placed an anti-static mat (from Radio Shack)
under the setup. I make it a point to touch the metal on the
wristband before touching the RPi. For initial configuration
I did not install the RasClock. An HDMI cable is needed and,
possibly, an analog audio cable (male connectors on both ends).
The SD card reader is needed only if, during testing, the system
hangs during boot (the procedure for using it will be described
in section BOOT HANG RECOVERY).
When you boot for the first time, you will see a menu prompting
you to install one of several operating systems into free space
on the SD card. I chose Raspbian (a Debian variant). After it is
installed, you will then be presented with a menu of config-
uration choices provided by a utility called raspi-config. There
are many RPi tutorials on the web that will walk you through
these options. For example:
http://learn.adafruit.com/setting-up-a-raspberry-pi-with-noobs/
boot-your-pi
The raspi-config utility presents menus using an ncurses GUI.
Some general rules for navigating the menus are as follows: 1)
to move up or down a menu list use the up/down arrows, 2) to
select an item, press the Enter key, 3) to toggle an entry, use
the Space bar, 4) to select an option at the bottom of a menu,
press the left or right arrows (some times multiple times!), 5)
to exit the utility, press the Esc key.
Later you may re-run the tool to make changes. For our purposes
make sure you choose the "boot_behaviour Start desktop on
boot?" option. Also, choose the "Internationalization Options".
The menu presented will contain three options: Change Locale,
Change Timezone, Change Keyboard Layout. Choose all of these
and configure them for your region. Note that Locale and
Keyboard options may need some additional work. See the next
section: MISCELLANEOUS SETUP for details.
MISCELLANEOUS SETUP:
After the initial formal setup. I found that I needed to make
some additional configuration changes: When you first run
LXTerminal and press the '#' key, you will get the symbol for
the British pound (currency), since the default keyboard
mapping is for the UK. If you are not in the UK you will need
to edit file /etc/default/keyboard and change line
XKBLAOUT='gb' to indicate your locale (e.g., 'us' for the US).
Then reboot. The next change I made was to set my default
editor. Since I use vi, I added the following to the end of
file .bashrc in the /home/pi directory:
export EDITOR=/usr/bin/vi.
You may choose the editor of your choice here. Then run:
$source .bashrc
and:
$env
to verify the change.
If you are not in Great Britain you will need to set your
locale (if you didn't do it during the initial configuration).
Run:
$sudo dbkg-reconfigure locales
Use the arrow keys to move down the list of locales. Use the
Space bar to select/deselect a locale (deselect: en_GB.UTF
UTF-8, select: en_US.UTF-8 UTF-8 or one for your locale). Use
the Enter key to select the next screen. Select your locale
with the arrow keys. Select Enter again to start execution.
Use Esc to exit the program. To check the result, run:
$locale
You should see references to your locale. Also look at file:
/etc/locale.conf. It should look similar.
HDMI AUDIO:
If your TV does not have an input audio jack (or if you would
just rather use HDMI audio), you will need to add a line to
file:
/boot/config.txt
The line should be added at the end of the file. The line is:
hdmi_drive=2
You will need to have root access to do this (enter: sudo su).
Note: when I make changes to root files I always back up the
original first:
cp config.txt config.txt.orig
This change worked for the TV described above. If it doesn't
for yours, Google: raspberry pi hdmi audio. Other solutions
are possible.
SCREEN SETUP:
This application requires the screen to stay on all the time.
To do this we need to: 1) deactivate the screensaver, 2)
disable DPMS (Energy Star) features and 3) set the 'noblank'
flag for the video (HDMI) device. To do this, edit (as root,
get to root by entering: sudo su) file:
/etc/xdg/lxsession/LXDE/autostart
and insert the following lines at the end of the file:
@xset s off
@xset -dpms
@xset s noblank
Run the following command before and after rebooting (or
logging out and in) and note the differences: $xset -q
The screen should now stay on indefinitely.
ETHERNET SETUP:
I did most of my work with the RPi disconnected from the TV
and, instead, accessed over an Ethernet connection using ssh.
To set up the connection I edited file /etc/network/interfaces.
Since I prefer to use static connections for wired links I
commented out line: 'iface eth0 inet dhcp' and added the
following lines at the end of the file:
iface eth0 inet static
address 192.168.0.17
netmask 255.255.255.0
gateway 192.168.0.1
where the address was a free static address available from my
router and the router gateway address is 192.168.0.1. Then on
my desktop workstation I added the following line to file
/etc/hosts:
192.168.0.17 raspi
After rebooting, I could then log into the RPi using:
$ssh pi@raspi
The RPi asks for the password (by default: raspberry). If you
want to have a secure connection (and not have to enter a
password), and you have an RSA public key in your
.ssh/id_rsa.pub file, you can copy and paste it into file
.ssh/authorized_keys on the RPI (you will have to create
directory /home/pi/.ssh first). If you don't yet have keys in
your workstation .ssh directory you can generate them with
command ssh-keygen (see the man page or an online tutorial).
It is convenient to be able to run an X11 client (i.e.,
xclock) on the RPi and have it displayed by the X11 server on
your workstation. To do this the RPi file /etc/ssh/sshd_config
must contain these lines:
X11Forwarding yes
X11DisplayOffset 10
After rebooting, you should be able to remotely log in with:
ssh -X pi@raspi
and run xclock there (once we get it installed! See below).
The clock face should show up on your workstation.
At this point you should be able to transfer files to the
RPi with:
$scp <filename> pi@raspi:/home/pi
and from the RPi with:
$scp pi@raspi:/home/pi/<filename> .
RasClock SETUP:
There is a good tutorial on setting up the RasClock real-time
clock at:
http://afterthoughtsoftware.com/products/rasclock
Choose binary package 3.6.11 and follow the "Rev2 boards:"
instructions. You will need to set Linux system time first
and then copy it to the real-time clock. The RPi will get time
from the network using the ntpd daemon if Ethernet port 123
is open for UDP reading and writing. Make sure its open in
your firewall/router. Or you can use the date command to set
system time: #date MMDDhhmmYY. Then run: '#hwclock -w' to set
the real-time clock. Note that, since accurate time is
important for this project, you might want to go through this
update procedure from time to time. The RasClock is battery
powered and very accurate, but it will drift. Note also that
if you have Internet access near your TV and leave the RPi
connected to it, the ntpd daemon will keep system time up to
date automatically and you won't need the RasClock! Finally,
if you find that the 'date' command shows the wrong time zone,
run:
#dbkg-reconfigure tzdata
INSTALL XCLOCK:
The xclock program is included in a package called x11-apps.
To load it, do:
$sudo su
#apt-get update
#apt-get install x11-apps
To check that it is now installed, run:
#which xclock
/usr/bin/xclock <--- you should see this
Then you can exit root and run it:
#exit
$xclock &
The '&' causes it to run in a forked background process. The
process ID (PID) is displayed. You can kill it with:
$kill PID
Note that if you logged in with ssh -X pi@raspi, the clock
face appeared on your workstation.
INSTALL XMMS2:
The xmms2 music player will be used to continuously play tunes
of your choosing while the RPi is running (and the viewer has
selected it!). It can play a wide range of music formats (see
its man page and/or online site). For convenience (and to avoid
violating copyrights) I have included three short mp3 voice
recordings that I made using the Audacity program. You will
definitely want to replace them with your own choices!
The xmms2 program consists of a server, xmms2d, and a client,
nyxmms2. This is a command-line client, which is all this
project needs. There are also GUI clients available. The server
is installed using the following (root) commands:
#apt-get update
#apt-get install xmms2d
Install nyxmms2 with:
#aptitude install xmms2-client-nycli
The server daemon must be launched (only once) using this
(user) command:
$xmms2-launcher
You can check that it did get launched with:
$ps auwwx | grep xmms2d
After starting the client, enter 'help' to see the options:
$nyxmms2
...
xmms2> help
You can load several playlists. The default list is called
Default. See what is currently in it with:
xmms2> list
Clear the Default playlist with:
xmms2> playlist clear
Add the first test audio file with:
xmms2> add /home/pi/audioTestFile1.mp3
Repeat for the other two test recordings (Note: audio files
MUST BE sterio! The TV will not play monaural files!). List
the tunes in the playlist:
xmms2> list
You may remove a file with:
xmms2> remove <finename>
You may select a recording to play with the 'next' and 'prev'
commands. Then to play the selection, enter:
xmms2> play
You should hear the recording on earphones plugged into the
RPi's audio jack. To stop playing, enter:
xmms2> stop
To exit nyxmms2, enter:
xmms2> exit
In the startjablock script for this project there is a
command to select the Default playlist:
/usr/bin/nyxmms2 playlist switch Default
There is another command to cause the playlist to play
continuously in a loop:
/usr/bin/nyxmms2 server config playlist.repeat_all 1
Finally, there is a command to start playing the currently
selected playlist recordings:
/usr/bin/nyxmms2 play
INSTALL USBMOUNT:
The startjablock script has a provision for inserting a USB
flash memory drive to initiate system shutdown (this will
be discussed later). A package called usbmount automaticlly
mounts a USB flash drive when it is inserted. It is installed
using:
#apt-get install usbmount
To confirm installation, enter:
#df -h
Then insert a USB drive (preferably a new one with a vfat
file system on it) and enter the above command again. The
drive should appear mounted on /media/usb0.
THE STARTJABLOCK SCRIPT:
The startjablock script from the project site should be
installed in directory /home/pi. It should then be made
executable:
$chmod +x startjablock
This Bash script will be started automatically at boot and
contains all commands for the project. You can run it
by entering:
./startjablock
We would like it to run automatically at startup.
Normally scripts that must run at startup are placed in
/etc/init.d and soft links are made to them in directories
rcN.d, where N is the run level. These scripts run at root
level. But we would like our script to run at user level.
There is a feature of the cron utility, called @reboot,
that will do this.
When a pi user uses the cron utility a file is created:
/var/spool/cron/crontabs/pi to hold the user commands.
The best way to edit this file is to run:
$crontab -e
The file will be opened using the pi user's default
editor. Enter the following line at the end of the file:
@reboot /home/pi/startjablock &
WARNING! Don't forget the '&'! It causes the script to be run
in a forked off separate process -- so that the boot process
can continue. Without it the boot process will stall in the
script! If this happens to you, refer to section BOOT HANG
RECOVERY: below. There are other useful crontab options:
crontab -l lists entries; crontab -r removes entries. See its
man page for details.
STARTJABLOCK CONTENTS:
This Bash script starts by using the amixer program to set
the audio volume. When you have installed your tunes you will
probably want to alter the volume setting shown. The next
statement assures that the Default playlist is being used. You
may set up several playlists and switch between them. A
statement is then included that tells the server to repeat
playing the playlist indefinitely. Finally, there is an
instruction to start playing the tunes.
The next command starts the xclock on the local display with
a clock update rate of one second. The background color is set
to SlateGray (so that the clock face will not be too bright
during night viewing). You may prefer a different color (for a
list of color names, Google: X11 color set). You will probably
need to adjust the geometry dimensions to suit your TV screen
size (suggestion: adjust it in binary (e.g., 128) pixel
increments).
As indicated in the script it is VERY IMPORTANT not to forget
the '&' at then end of the command. This tells the Linux
scheduler to fork a separate process to run xclock so the
script process can proceed. Without it control will not return
to the script. If the script, itself, was also started without
a '&', the boot process will hang! If this happens, see
section BOOT HANG RECOVERY: below. When xclock is forked, its
process ID is available in Bash variable $!. It is saved for
later use.
Since this is intended to be a system in which no keyboard or
mouse is attached, and the approved way to terminate a Linux
system is to run: '#shutdown -h now', an alternate way to
accomplish this is provided.
The usbmount utility dynamically mounts a USB memory stick on
/media/usb0 when the device is inserted. That insertion may be
used to initiate shutdown. The script runs a while loop that
contains a test for directory shutdownDir on a flash memory
stick mounted on /media/usb0. If the directory is present, the
shutdown process is started. It consists of killing the xclock
program by using its PID saved earlier, stopping audio output
and finally calling shutdown. If the directory is not
detected, a sleep command suspends the loop for five seconds.
You will know when shutdown has completed when a "No Signal"
message appears on the TV screen.
To make this work it is necessary to create directory
shutdownDir on a USB memory stick. With the stick mounted on
your workstation, enter:
$mkdir shutdownDir
I have found that usbmount will mount a memory stick that
contains a vfat file system (as originally formatted). I had
no luck getting sticks with other file systems to work. The
issue of shutdown is discussed further in section HARDWARE
PROJECT: below.
BOOT HANG RECOVERY:
As indicated above, it is possible to hang the boot sequence
if the script is not implemented and called properly. If this
happens, the only solution is to remove the SD card and mount
it on another computer where corrections can be made. A card
reader similar to the one shown in the site photo is needed.
Once mounted, all files will be accessible and you will be able
to make corrections.
HARDWARE PROJECT:
I may be old fashion, but my idea of an "appliance" is a
device that has an on/off switch! That's a possible problem
with a Linux-based system, since the "graceful" way to bring
the system down it so run shutdown. Linux is very robust, no
doubt due to its journaling file systems and other provisions.
I have run systems based on the Vortex86DX SoC for years and
have not experienced any problems just turning them off. Maybe
this is a non-problem or I have just been lucky. But just
turning a system off when it is in the process of writing a
data structure to memory seems like asking for trouble.
I am not a hardware designer, so I would like to suggest a
project for someone who is. The project would consist of an
on/off switch and some logic that, when the switch is turned
off, signals the processor that shutdown should begin. This
might be accomplished by enabling power to an already plugged
in USB memory device. A script would then detect the condition
and start shutdown as described above for the startjablock
script. After a suitable period of time (about ten seconds),
the logic would turn off processor power. Similarly, when the
switch is placed in the on position, the logic would
disconnect power to the USB stript and then apply power to the
processor.
It may be that something similar to this already exists. If so,
I haven't seen it.
Author: Walter S. Heath
Handle: SaberCat
Email: walmarheath@comcast.net