Set up a Raspberry Pi Zero headless

If you are using the GUI (Raspian full download) and want to connect your RPi Zero to a keyboard and monitor there are probably easier ways to do this. These notes are for people that want to use a headless (no monitor and GUI) setup ready to connect to your RPi after first boot via SSH from another terminal.

Download Raspbian Lite

wget -O

Download link:

Write Image to SD Card

dd bs=4M if=2017-08-16-raspbian-stretch-lite.img of=/dev/sdb

After this step there should be 2 additional mounts (if not mount the 2 SD card partitions manually).

Set up network interfaces

Create a new config file for the wireless interface.

cd etc/network/interfaces.d/
vim wlan0.conf

Add the following to the new file (if you want to use DHCP – change to static if you want to fix the IP):

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Set up connection details for local wireless network

vim etc/wpa_supplicant/wpa_supplicant.conf

Check the file and ensure the network settings are as per the Wireless Network you are connecting to.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

You could use the clear-text PSK passphrase but I prefer not to do that in configuration files. Create a PSK hash using ‘wpa_passphrasethis older article

There could be other config values you might need depending on the network you are connecting to. More info:

Ensure there are DNS Servers configured

sudo vim etc/resolv.conf

Add the following to the new file (or your own nameservers):

# Google's public DNS servers

Enable SSH Access

Create an ssh empty file in the mounted boot partition. This is necessary to enable SSH access as SSH is by default disabled on more recent versions of Raspbian.

cd boot/
sudo touch ssh

Boot RPi

Boot the Rpi by powering up and after ~30secs you should be able to connect to the IP assigned. Check your router or ise ‘nmap’ or similar to check the assigned IP:

sudo nmap -p22 -sV

Default login details are
UID: pi
PWD: rasbperry

My normal further setup steps for RPi 3 are here.

EDIT [2017-08-21]: One of the things necessary on later RPi’s is to turn off power saving mode on the WLAN interface.

sudo iw dev wlan0 set power_save off

RaspberryPi Version 3 SOE

Since there is now a supported Raspbian version without GUI and other unneeded add-ons available as Raspbian Lite the need to use other installers (with sometimes some downsides) is now not a necessity anymore. Below is a list of steps I like to perform before using them for any purpose as my Standard Operating Environment.

Download Raspbian Lite

Download link:

Write to SD Card

dd bs=4M if=2016-05-27-raspbian-jessie-lite.img of=/dev/sdb

Boot RPi

Default login details are
UID: pi
PWD: rasbperry

Regional settings

locale-gen en_AU.UTF-8
dpkg-reconfigure locales
ln -sf /usr/share/zoneinfo/Australia/Adelaide /etc/localtime

System update

apt update && apt upgrade
apt install vim

Setup SSH keys

As a security precausion it’s a good idea to disable password authentications
ssh-keygen -t rsa
vim /root/.ssh/authorized_keys
# --> add RSA public key

Setup Wireless LAN

iwlist wlan0 scan
wpa_passphrase SSID WPA_KEY
vim /etc/wpa_supplicant/wpa_supplicant.conf

Copy the resulting hash from the previous command

Example config

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

Rename default user account

The default Raspbian images use the default user ‘pi’ – I prefer to change this user to another account for security purposes and to be in line with other Linux system I use.

Reboot and log in to the RPi as root – you need to run the following commands as root.

usermod -l NEW_USER_ID pi
usermod -m -d /home/NEW_USER_ID NEW_USER_ID
groupmod --new-name NEW_USER_ID pi
mkdir /home/NEW_USER_ID/.ssh/
vim /home/NEW_USER_ID/.ssh/authorized_keys
# --> add RSA public key
# change owner and permissions on key files
chown -R NEW_USER_ID:NEW_USER_ID /home/NEW_USER_ID/.ssh/
chmod 700 /home/NEW_USER_ID/.ssh/
chmod 600 /home/NEW_USER_ID/.ssh/authorized_keys
rm /etc/sudoers.d/010_pi-nopasswd
echo 'NEW_USER_ID ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/010_NEW_USER_ID-nopasswd

If you are using the desktop version not a headless version you want to make sure you don’t boot into the desktop and if you want to change the autologin ensure you update the username there as well.


Configure Raspberry Pi settings

I generally need to enable SPI, change the hostname and others depending on the purpose of the unit.

EDIT [2017-08-21]: With the update of Raspbian to Stretch you now have the firmware updater as part of the Raspbian repos:

sudo rpi-update

This will update the Pi Firmware to the latest version as well – which is worth it if you use it for later cameras and peripheral usage.

EDIT [2017-12-27]: change annoying vim defaults in Debian Stretch onwards. Visual mode.

sudo vim /usr/share/vim/vim80/defaults.vim

Comment out the following lines:
“if has(‘mouse’)
” set mouse=a

Paperless Office using the Raspberry Pi

This is a follow-up on an older blog using Ubuntu.

r by rosmary, on Flickr
Creative Commons Creative Commons Attribution 2.0 Generic License   by  rosmary 

For this purpose I used a Fujitsu ScanSnap S1300i scanner as I really like the features of this series (full duplex scan as well auto document feeder as well for around $250). It’s document feeder is not a good as the S1500 we have in the office, but very compact and can be powered from USB hub.

Raspberry Pi Prerequisites

Since this will be a purely headless install designed to sit in a corner behind the scanner I am using a Base Raspian (Debian Wheezy) install (I personally like the clean minimal install via the best).

apt-get install sudo vim wget wput libusb-dev build-essential git-core

Add non-privileged user account(s)

adduser USERNAME
adduser USERNAME sudo
groupadd scanner
usermod -a -G scanner USERNAME

Install Sane

The version of sane from the Raspbian repos is not working with the Fujitsu ScanJet range and needs to be built from source.

git clone git://
cd sane-backends
BACKENDS=epjitsu ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
make install

Install S1300i Driver

You need to get the driver file (‘1300i_0D12.nal’) from the CD that came with the scanner. If you still have access to a CDROM drive that is. :(

mkdir -p /usr/share/sane/epjitsu/
cp 1300i_0D12.nal /usr/share/sane/epjitsu/

Check /etc/sane.d/epjitsu.conf and see if the following line is there (in my case it was already created by sane build).

# Fujitsu S1300i
firmware /usr/share/sane/epjitsu/1300i_0D12.nal
usb 0x04c5 0x128d

sane-find-scanner -q

found USB scanner (vendor=0x04c5 [FUJITSU], product=0x128d [ScanSnap S1300i]) at libusb:001:004
found USB scanner (vendor=0x0424, product=0xec00) at libusb:001:003

scanimage -L

device `epjitsu:libusb:001:004′ is a FUJITSU ScanSnap S1300i scanner

Copy libsane rules from the sane build directory to udev rules.
sudo cp sane-backends/tools/udev/libsane.rules /etc/udev/rules.d/60-libsane.rules

Logout and log in a the non-privileged user account previously created.

If the scanimage -L command works as above you have fully configured the scanner to work under that user account.

Start saned on boot-up

Edit the /etc/rc.local file and add the following line before the ‘0’ line to ensure saned is running as the non-privileged user when you have to reboot.

saned -a USERNAME

Installing Conversion Tools

sudo apt-get install imagemagick bc exactimage pdftk tesseract-ocr tesseract-ocr-eng unpaper

You can add other languages such as tesseract-ocr-deu if you require OCR support for those.

Scan to Repository Script

The script is hosted on Github:

# Thanks to Andreas Gohr ( for the initial work
TMP_DIR=`mktemp -d`
FILE_NAME=scan_`date +%Y%m%d-%H%M%S`
echo 'scanning...'
scanimage --resolution 300 \
--batch="$TMP_DIR/scan_%03d.pnm" \
--format=pnm \
--mode Gray \
--source 'ADF Duplex'
echo "Output saved in $TMP_DIR/scan*.pnm"
# cut borders
echo 'cutting borders...'
for i in scan_*.pnm; do
mogrify -shave 50x5 "${i}"
# check if there is blank pages
echo 'checking for blank pages...'
for f in ./*.pnm; do
unpaper --size "a4" --overwrite "$f" `echo "$f" | sed 's/scan/scan_unpaper/g'`
#need to rename and delete original since newer versions of unpaper can't use same file name
rm -f "$f"
# apply text cleaning and convert to tif
echo 'cleaning pages...'
for i in scan_*.pnm; do
echo "${i}"
convert "${i}" -contrast-stretch 1% -level 29%,76% "${i}.tif"
# Starting OCR
echo 'doing OCR...'
for i in scan_*.pnm.tif; do
echo "${i}"
tesseract "$i" "$i" -l $LANGUAGE hocr
hocr2pdf -i "$i" -s -o "$i.pdf" < "$i.html" done # create PDF echo 'Converting PDF...' pdftk *.tif.pdf cat output "$FILE_NAME.pdf" wput $FILE_NAME.pdf ftp://uid:pwd@scanner.domain:21/Alfresco/scans/ cp $FILE_NAME.pdf $OUT_DIR/ rm -rf $TMP_DIR

Thanks go to Andi Gohr @ Splitbrain for the excellent blog that helped me to get over the sane problems and also gave me some ideas to make the scan script better (as unpaper was not doing such a good job):

RaspberryPi real-world control with REST API

Finally found some time playing with a RaspberryPi and an attached PiFace Interface board to control some garden pumps and potentially an Aquaponics setup in the near future.

PiFace board


Base Raspian (Debian Wheezy) Install (I prefer the clean minimal install via

Configure the base system as per my previous base install.

Install Apache & PHP

sudo apt-get install apache2 php5 php5-dev php5-cli php5-mcrypt curl raspi-config

Ensure mod-rewrite is enabled

sudo a2enmod rewrite

Install PHP SPI Extension

More info:

git clone
cd php_spi
./configure --enable--spi
make test
make install

Install PiFace REST API

cd /var/www/
git clone
cd piface-rest-api
curl -sS | php
php composer.phar install

Thanks to Nate Fanaro for the excellent work on the API.

Make sure SPI is enabled on the RPi


Advanced Options –> A5 SPI –> yes

Install PiFace Modules

sudo apt-get install python3-pifacedigitalio python-pifacedigitalio
sudo usermod -a -G gpio www-data
sudo usermod -a -G spi www-data

For more info visit

Apache2 API Configuration

Enable SPI extension

sudo vim /etc/php5/apache2/php.ini
#add the following extension

Apache VHost config

sudo vim /etc/apache2/sites-available/piface

Paste the following VHost config

<Virtualhost *:80>
DocumentRoot /usr/share/piface-rest-api/public_html
ErrorLog /var/log/apache2/piface_error.log
CustomLog /var/log/apache2/piface_access.log combined
<Directory />
AllowOverride All
Order allow,deny
Allow from all

Enable the newly created VHost

a2ensite piface
service apache2 restart


curl http://HOSTNAME/led/test/

Next up will be some modification for securing access to the PiFace REST API via some sort of API Key or digital certificate as it’s open by default at the moment.

SMS Gateway using Sierra Wireless USB Modem on Debian Wheezy

I have been planning to set up a SMS Gateway for sending and receiving SMS messages via a headless utility unit (Raspberry Pi) for a while. Since I had a leftover Sierra Wireless AirCard 880U from Telstra in Australia I wanted to re-purpose this unit with a spare SIM card. Unfortunately it was very hard to find any good setup manual for this particular combination and took some time to fiddle & debug. This is the working setup for future reference and hopefully it helps somebody.

Install dependencies

Note: install usb-modeswitch BEFORE connecting USB Modem
sudo apt-get install usb-modeswitch gsm-utils smstools gammu

Connect the USB Modem

Check if modem is recognised


Bus 003 Device 002: ID 1199:6855 Sierra Wireless, Inc.

Edit smstools config file

vim /etc/smsd.conf

Change the GSM1 entry
init = ATE0;+CPMS="SM","SM"
device = /dev/ttyUSB2
incoming = yes
mode = new
baudrate = 115200
smsc = 61418706700
pin = ignore
#rtscts = yes
#cs_convert = yes
report = yes
sending_disabled = no
memory_start = 1
pre_init = yes
primary_memory = SM
secondary_memory = SM
secondary_memory_max = 40

Troubleshooting the modem

I installed gammu purely to have an easier way to test if the modem actually worked. You can use gammu-config to do a GUI config or create a config file manually

vim /etc/gammurc

port = /dev/ttyUSB2
connection = at115200



; Configuration file generated by gammu-detect.
; Please check The Gammu Manual for more information.

device = /dev/ttyUSB0
name = Phone on USB serial port Sierra_Wireless__Incorporated AirCard
connection = at

device = /dev/ttyUSB1
name = Phone on USB serial port Sierra_Wireless__Incorporated AirCard
connection = at

device = /dev/ttyUSB2
name = Phone on USB serial port Sierra_Wireless__Incorporated AirCard
connection = at

#send sms
sudo echo "sms test" | /usr/bin/gammu --sendsms TEXT +61XXXXXXXX
#check received sms
gammu getallsms

Add your own user account to dialout group if you want to send from your own account for testing (gammu)

sudo adduser $UNPRIVILEGEDUSER$ dialout

Next I will have some fun setting up PlaySMS to allow me to send SMS commands and create some inbound SMS workflows for family.


FreedomBox + RaspberryPi = FreedomPi

I have been watching progress on FreedomBox ever since watching a video of Eben Moglen a few years ago.

Turns out that that they recently announced the availability of their 0.1 preview release. As part of this there is one component that is extremely useful for RaspberryPi users (funnily the co-founder of RasperryPi is also called Eblen by first name – go figure) out there concerned about increasing snooping of private information by governments and corporations for a variety of reasons.

Meet ‘freedombox-privoxy’

freedombox logo

This software combines the functionality of the Adblock Plus ad blocker, the Easy Privacy filtering list, and the (HTTPS Everywhere]( website redirection plugin into a single piece of software to run on your FreedomBox. Combining these different plugins into software for your FreedomBox means that you can use them with almost any browser or mobile device using a standard web proxy connection.

Best of all this has already been made available via the Raspbian repositories ( so the install is extremely simple.

sudo apt-get install freedombox-privoxy

Note: make sure that you have the ‘contrib’ branch in the Raspbian repositories enabled in /etc/apt/sources.list

deb wheezy main contrib non-free
deb-src wheezy main contrib non-free

Kudos to James Vasile for the technical work !

To get some more idea on the usage of privoxy you can check this article.

Enabling the watchdog timer on the Raspberry Pi

Turns out that the Broadcom BCM2708 chip on the RPi has a hardware watchdog. This can be very useful if your RPi is located remotely and locks up. However, this would not the preferred method of restarting the unit and in extreme cases this can result in file-system damage that could prevent the RPi from booting. If this occurs regularly you better find the root cause of the problem rather than fight the symptoms.

Enable Watchdog Kernel Module

echo 'bcm2708_wdog' >> /etc/modules
sudo modprobe bcm2708_wdog

Install Watchdog Daemon

sudo apt-get install watchdog chkconfig
chkconfig watchdog on
sudo /etc/init.d/watchdog start

sudo vim /etc/watchdog.conf
# Uncomment the line watchdog-device = /dev/watchdog
# You might also want to uncomment max-load-1, or add something like "max-load-1 = 24" to reset your Pi if the load average exceeds 24 in any 1-minute span.

sudo /etc/init.d/watchdog restart

The watchdog daemon will send /dev/watchdog a heartbeat every 10 seconds. If /dev/watchdog does not receive this signal it will brute-force restart your Raspberry Pi.

If you are feeling adventurous you can test the setup by launching one of the fork-bombs you can find out there. Just make sure you don’t have anything of importance running.
: (){ :|:& };:

Thanks to gadgetoid for the original tip !

Dropping the wires on the Raspberry PI

Testing the RPi for some remote sensing application I needed to use a wireless connection as it would have been a pain to reach with an Ethernet cable.


  • Raspberry Pi Series B 512MB
  • Raspbian 3.6.11+ Kernel
  • Comfast 802.11n – Realtek RTL8188CUS WLAN Adapter

Install WPA Supplicant

sudo apt-get install wpasupplicant

Check for the USB adapter

sudo lsusb
This should show output similar to this (depending on your USB adapter)
Bus 001 Device 004: ID 0bda:8176 Realtek SemicondRTL8188CUSuctor Corp. 802.11n WL:AN Adapter

Generate PSK Key

If you want to use the cleartext PSK you could probably skip this step.
This should show output similar to this:

Edit network configuration

sudo vim /etc/network/interfaces
auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid "YOUR_SSID"
wpa-psk c885c4288a0c68b989289586cb075c0ccd1729d2c035820d02ed813fc729f317

Finish off

sudo shutdown -h now
Unplug ethernet cable
Power up the RPi and you should see another wireless DHCP assignment on the router

Webserver and database combination on Raspberry Pi

My normal combination on the big-server side would be Apache + MySQL (or PostgreSQL), but on the RPi this seems to be absolute overkill. For data-logging operations I would not use the local system anyway (looking at MQTT as well as Remote MongoDB datastore via REST Webservices).

After some poking around and reading up on the options I decided to go for the following combo: LightHTTPD + SQLite. Both are lightweight replacement of their fully-featured big-server counterparts (Apache HTTP & MySQL) and have very familiar configurations. There would be other options that have even less resource usage, but I really don’t have the time to start from scratch somewhere.

Another reason to go for this combination is that these are very well supported systems with regular security audits. Even though I am not planning to use my RPi’s for anything mission-critical this is always worth a consideration as you don’t need to unnecessarily introduce vulnerabilities to your network.

Install & configure LightHTTPD

sudo apt-get install lighttpd php5 php5-cgi php5-sqlite
sudo lighty-enable-mod fastcgi
sudo lighty-enable-mod fastcgi-php

Further config changes can be also made via the config file.
sudo vim /etc/lighttpd/lighttpd.conf
sudo service lighttpd force-reload

Install & configure SQLite

sudo apt-get install sqlite3
sqlite3 /home/username/database_name.db

All other commands are standard SQL from the ‘sqlite>’ command prompt or via SQL scripts like
sqlite3 /home/username/database_name.db < sql_script.sql

Access Databases from the webserver (using PHP)

< ?php $db = new SQLite3('mysqlitedb.db'); $results = $db->query('SELECT bar FROM foo');
while ($row = $results->fetchArray()) {

See PHP: SQLite3::query – Manual for more details.

Raspberry Pi – Raspbian post install tasks

The Raspbian Install process is fairly well documented using the Raspbian Installer. This is just to document common tasks after the stock install.

Install base utils

apt-get install sudo vim ntpdate git-core binutils make gcc ca-certificates rpi-update

Allow non-root user account access to ‘sudo’

adduser USERNAME sudo
For those Ubuntu users there is no ‘admin’ group in Raspbian (Debian Wheezy).

NTP time update

sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/Australia/Adelaide /etc/localtime
sudo ntpdate -u

Probably best to choose an NTP Server closest to your location or provided by your ISP

Firmware upgrade

EDIT (2014-03-31): rpi-update is now part of the Raspbian repositories and can be installed via apt-get install rpi-update (I have added this to the above line).

Note: unless you want the latest firmware this is not a necessary step as apt-get will update the firmware to the latest stable release.

Using Hexxeh updater.

Install dependencies

wget -O /usr/bin/rpi-update && sudo chmod +x /usr/bin/rpi-update
sudo rpi-update

Install WiringPi

Thanks to the excellent work of Gordon Henderson ( this is a C-based program to read/write to the Raspberry Pi GPIO pins.

cd /usr/share
git clone git://
cd wiringPi
git pull origin


wiringPi Build script

The wiringPi I2C helper libraries will not be built.

WiringPi library
[Compile] wiringPi.c
[Compile] wiringPiFace.c
[Compile] wiringSerial.c
[Compile] wiringShift.c
[Compile] gertboard.c
[Compile] piNes.c
[Compile] lcd.c
[Compile] piHiPri.c
[Compile] piThread.c
[Compile] wiringPiSPI.c
[Compile] softPwm.c
[Compile] softServo.c
[Compile] softTone.c
[Link (Dynamic)]

GPIO Utility
[Compile] gpio.c

All Done.

Testing the install

gpio readall


| wiringPi | GPIO | Name   | Mode | Value |
|      0   |  17  | GPIO 0 | IN   | Low   |
|      1   |  18  | GPIO 1 | IN   | Low   |
|      2   |  21  | GPIO 2 | IN   | Low   |
|      3   |  22  | GPIO 3 | IN   | Low   |
|      4   |  23  | GPIO 4 | IN   | Low   |
|      5   |  24  | GPIO 5 | IN   | Low   |
|      6   |  25  | GPIO 6 | IN   | Low   |
|      7   |   4  | GPIO 7 | IN   | Low   |
|      8   |   0  | SDA    | ALT0 | High  |
|      9   |   1  | SCL    | ALT0 | High  |
|     10   |   8  | CE0    | ALT0 | High  |
|     11   |   7  | CE1    | ALT0 | High  |
|     12   |  10  | MOSI   | ALT0 | Low   |
|     13   |   9  | MISO   | ALT0 | Low   |
|     14   |  11  | SCLK   | ALT0 | Low   |
|     15   |  14  | TxD    | ALT0 | High  |
|     16   |  15  | RxD    | ALT0 | High  |