Raspberry Pi® Projects For Dummies® Pi Dummies

User Manual: Raspberry Pi Projects For Dummies

Open the PDF directly: View PDF PDF.
Page Count: 498

DownloadRaspberry Pi® Projects For Dummies® Pi Dummies
Open PDF In BrowserView PDF
Raspberry Pi® Projects For Dummies®
Published by: John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 070305774, www.wiley.com
Copyright © 2015 by John Wiley & Sons, Inc., Hoboken, New Jersey
Published simultaneously in Canada
No part of this publication may be reproduced, stored in a retrieval system or
transmitted in any form or by any means, electronic, mechanical, photocopying,
recording, scanning or otherwise, except as permitted under Sections 107 or 108 of
the 1976 United States Copyright Act, without the prior written permission of the
Publisher. Requests to the Publisher for permission should be addressed to the
Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ
07030, (201) 748-6011, fax (201) 748-6008, or online at
http://www.wiley.com/go/permissions.
Trademarks: Wiley, For Dummies, the Dummies Man logo, Dummies.com,
Making Everything Easier, and related trade dress are trademarks or registered
trademarks of John Wiley & Sons, Inc., and may not be used without written
permission. Raspberry Pi is a registered trademark of the Raspberry Pi Foundation.
All other trademarks are the property of their respective owners. John Wiley &
Sons, Inc., is not associated with any product or vendor mentioned in this book.
LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: WHILE THE
PUBLISHER AND AUTHOR HAVE USED THEIR BEST EFFORTS IN
PREPARING THIS BOOK, THEY MAKE NO REPRESENTATIONS OR
WARRANTIES WITH RESPECT TO THE ACCURACY OR
COMPLETENESS OF THE CONTENTS OF THIS BOOK AND
SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
NO WARRANTY MAY BE CREATED OR EXTENDED BY SALES
REPRESENTATIVES OR WRITTEN SALES MATERIALS. THE ADVICE
AND STRATEGIES CONTAINED HEREIN MAY NOT BE SUITABLE
FOR YOUR SITUATION. YOU SHOULD CONSULT WITH A
PROFESSIONAL WHERE APPROPRIATE. NEITHER THE PUBLISHER
NOR THE AUTHOR SHALL BE LIABLE FOR DAMAGES ARISING
HEREFROM.
For general information on our other products and services, please contact our
Customer Care Department within the U.S. at 877-762-2974, outside the U.S. at

317-572-3993, or fax 317-572-4002. For technical support, please visit
www.wiley.com/techsupport.
Wiley publishes in a variety of print and electronic formats and by print-ondemand. Some material included with standard print versions of this book may not
be included in e-books or in print-on-demand. If this book refers to media such as a
CD or DVD that is not included in the version you purchased, you may download
this material at http://booksupport.wiley.com. For more information about
Wiley products, visit www.wiley.com.
Library of Congress Control Number: 2015942453
ISBN 978-1-118-76669-9 (pbk); ISBN 978-1-118-76672-9 (ebk); ISBN 978-1118-76671-2 (ebk)

Raspberry Pi® Projects For Dummies®
Visit www.dummies.com/cheatsheet/raspberrypiprojects
to view this book's cheat sheet.
Table of Contents
Cover
Introduction
About This Book
Foolish Assumptions
Icons Used in This Book
Beyond the Book
Where to Go from Here

Part I: Getting Started with Raspberry Pi Projects
Chapter 1: Getting to Know the Raspberry Pi
Getting a Raspberry Pi
Discovering What You Can and Can’t Do with a Raspberry Pi
Getting Familiar with Your Raspberry Pi
Selecting Your Accessories
Setting Up Your Operating System
Flashing Your SD Card
Connecting Your Hardware
Setting Up with Raspi-config
Starting Up the Desktop Environment
Troubleshooting Your Raspberry Pi

Chapter 2: Setting Up Your Tools and Workbench
Getting Ready to Build Your Projects
Assembling Your Tools
Using Your Tools Safely and Effectively
Getting Ready to Build Raspberry Pi LEGO Projects

Chapter 3: Focusing on Technique
Getting Around Your Raspberry Pi

Using the Command-Line Interface
Programming Like a Pro

Chapter 4: The Raspberry Family
In the Beginning: Looking at the Evolution of the Raspberry Pi
Deciding Which Raspberry Pi to Buy
Figuring Out Which Raspberry Pi You Have

Part II: Working with LEDs and Switches
Chapter 5: The Sauce Bottle Game
The Game
The Software
Taking It Farther

Chapter 6: Stomp!
Getting Acquainted with the LED
Stomp 1
Stomp 2

Chapter 7: The Light Fantastic
Introducing the Light Fantastic
The Circuit
Construction
Bringing It All to Life

Chapter 8: Games for the Light Fantastic
Treasure Hunt
Sliding Block Puzzle
Color Match
Lights Out
Exploring a World of Possibilities

Part III: Developing Advanced Interfaces
Chapter 9: Advanced Interfaces
Converting Analog to Digital
Introducing the Analog-to-Digital Conversion Methods
Building an Analog-to-Digital Converter
Using a Potentiometer to Control the Breakdown Game
Creating an Analog Temperature Sensor
Interfacing with an Analog-to-Digital Microchip

Chapter 10: Raspberry Pi in the Sky
Understanding the Cloud
Storing Data in Google Docs from Your Raspberry Pi
Creating a Dashboard and Temperature Alerts Using PrivateEyePi
Creating a Database Logger

Chapter 11: Webcam and Computer Vision
Setting Up the Webcam or Raspberry Pi Camera Module
Understanding Images
Creating an Image File
Detecting Motion with a Webcam
Working with Image Recognition
Interpreting Color
Building a Connect Four Game Using Computer Vision

Chapter 12: The Raspberry Jazz Glitter Trio
Meeting the Gang
Testing the Webcam
Hacking the Glitter Lamp
Letting the Band Play

Part IV: Making the Raspberry Pi Your LEGO’s Magic Brick
Chapter 13: The Pi Meets LEGO
Exploring the MINDSTORMS Range
Creating a Tug-of-War LEGO Robot
Going on from Here

Chapter 14: The LEGO Dice Game
Introducing the Dice Game
Understanding the Game Theory
Detecting Dice
Looking at the Playing Mechanism
Writing the Code
Customizing the Code

Chapter 15: LEGO Direct
Creating a Reset Button for the Raspberry Pi
Making Batteries Last Longer
Using Connectors and Cables to Control the LEGO Motors and

Sensors
Reading and Commanding
Rolling Your Own Motor Control
Listening to Sensors

Part V: Exploring RISC OS
Chapter 16: Introducing RISC OS
Knowing What Makes RISC OS Unique
Preparing for Action: Getting RISC OS
All Systems Go: Starting Up RISC OS
Handling Graphics with !Paint and !Draw
Connecting to the Outside World
Identifying the Resources That Are Already Installed

Chapter 17: RISC OS Coding
In the Beginning Was BASIC
Hello World
The Insult Generator
Understanding Full Desktop Applications
Working with Graphics in RISC OS

Chapter 18: Transistor Tester
Getting Acquainted with Transistors
Configuring Transistors
Designing the Circuit
Constructing the Circuit
Writing the Software

Chapter 19: The General-Purpose Input/Output Port in
RISC OS
Using the GPIO Pins in RISC OS
Getting an LED to Blink
Mixing Languages

Part IV: The Part of Tens
Chapter 20: Ten Great LEGO Pi Projects
Panobot
MATLAB and Simulink
Raspberry Pi LEGO Case

Book Reader
A Stop-Motion LEGO Movie
SriShooter
browserBot
BrickPi Remote Sentry Cannon
LEGO Digital Clock
The Original LEGO MINDSTORMS

Chapter 21: Ten Suppliers of Components and Tools
Farnell/Newark
RS Components
Rapid Electronics
Mouser Electronics
Digi-Key
Proxxon
Adafruit
SparkFun
Electronic Goldmine
E.M.A. Model Supplies

About the Authors
Cheat Sheet
Advertisement Page
Connect with Dummies
End User License Agreement

Introduction
Raspberry Pi Projects For Dummies is designed for people who are looking for
something exciting to do with the Raspberry Pi. This book contains projects to
amaze and inspire you! It takes you into a world of switches, lights, motors, home
automation, and computer vision. It not only covers the theory behind what you’re
doing, but also gives you examples of putting that theory into practice, so you can
learn to work on your own projects and not just blindly follow a list of instructions.
Sure, we could just give you a list of steps to follow. But we believe that you
should try to understand what you’re doing and why you’re doing it, and that’s what
this book is all about. With this book as a resource, we encourage you to put your
own stamp on projects, which is why many projects in this book aren’t just cutand-dried lists of things to do, but suggestions about how you can customize the
projects and make them your own.

About This Book
The projects in this book all make use of the computer language Python 2. This
book shows you how to use a wide variety of input and output devices, from a
simple switch to a webcam. You can explore LEDs and multicolored LEDs, learn
about a keypad matrix and see how they can be integrated to become part of your
code so you can make these devices do what you want. Reach out with your
Raspberry Pi and become part of the cloud or build your own web server. This
book shows you how.
The Raspberry Pi can interface with other electronic devices, and in this book we
show you how to interact with LEGO’s latest robotic MINDSTORMS set, the EV3.
You can send messages into the LEGO system or do your own thing and control the
MINDSTORMS peripherals directly from the Raspberry Pi. Not only do we show
you how these two systems interact, but we also show you some projects you can
make using the Raspberry Pi and MINDSTORMS set together.
Linux is the staple operating system used in the Raspberry Pi world. However,
there is a major alternative operating system you can run for just the price of
another very small SD card, RISC OS. RISC OS is a mature, well-honed operating
system, designed from the ground up to run on ARM chips, and as such, it’s fast and
compact. This book shows you how you can explore the RISC OS and gives you a
glimpse of another world.

A few final notes about the book: Sidebars (text in gray boxes) and Technical Stuff
paragraphs are skippable. Finally, within this book, you may note that some web
addresses break across two lines of text. If you’re reading this book in print and
want to visit one of these web pages, simply key in the web address exactly as it’s
noted in the text, pretending as though the line break doesn’t exist. If you’re reading
this as an e-book, you’ve got it easy — just click the web address to be taken
directly to the web page.

Foolish Assumptions
In writing this book, we made a few assumptions about you:
You have a Raspberry Pi. You could certainly read this book without a
Raspberry Pi, but you won’t get much out of it unless you have a Raspberry Pi
to play with.
You have a computer other than the Raspberry Pi. You need a computer to
set up the Raspberry Pi. Note: We provide instructions on how to set up your
Pi, but this information isn’t the main thrust of the book. If you need more
information on setting up your Raspberry Pi, a good companion book to this one
is Raspberry Pi For Dummies, by Sean McManus and Mike Cook (Wiley),
which covers in much more detail your first steps with this remarkable
machine.
Your Raspberry Pi has some connection to the Internet. It may not be
connected all the time, but you’re at least able to connect it for setting up the
libraries you need to install.
You don’t mind voyaging into less charted waters and you have an open
mind on what constitutes computing and operating systems.
You’re eager to begin exploring the world of physical computing. Physical
computing takes a fresh look at inputs and outputs to a computer. The computer
produces physical outputs — signals that make lights flash, sounds play, or
robots move. Inputs are more than just typing — they include everything from
simple push buttons to color sensors to webcams.
You have access to some basic hand tools, like a small saw and drill along
with a soldering iron. If you don’t have these tools on hand, we assume you
have the money to buy them — or you have a friend or family member whose
toolkit you can raid!

You don’t mind spending some money on the components you need to make
your projects. Most of these components aren’t very expensive, but you’ll
need to buy them (and we recommend sources in this book).

Icons Used in This Book
In this book, we use a handful of icons (little pictures in the margins) to draw your
attention to key pieces of information. Here’s what those icons mean:

When we give you an especially useful bit of information — something that
can make your life with the Raspberry Pi easier or help you do something
faster — we mark it with the Tip icon.

You don’t need to commit this book to memory — it’s a resource for you to
turn to whenever you need it. But every once in a while, we tell you something
so important that you’ll want to remember it. When we do, we mark it with the
Remember icon.

What can we say? We’re geeks. And as such, we sometimes get a little
technical, telling you more than you really need to know to get the job done.
When we veer into the technical, we mark that text with the Technical Stuff
icon. If you’re short on time, you can skip anything marked with this icon
without missing anything critical to the task at hand.

You’re bound to come across some pitfalls on your journey with the
Raspberry Pi. We’ve walked this road before, so think of the Warning icon as
orange cones in the road, helping you steer clear of those tire-destroying
potholes or open manhole covers.

Beyond the Book
In addition to the material in the print or e-book you’re reading right now, this
product also comes with some access-anywhere goodies on the web. Check out the

free Cheat Sheet at www.dummies.com/cheatsheet/raspberrypiprojects for
information on connecting the Arduino and the Raspberry Pi, GPIO pin alternate
functions, and powering other devices from the Raspberry Pi.
Also, at www.dummies.com/extras/raspberrypiprojects, you can find free
bonus articles on topics like contact bounce and facial recognition.
Finally, throughout the book, we mention files that you can download from the
book’s companion website, www.dummies.com/go/raspberrypiprojects.

Where to Go from Here
If you’re a beginner, you can’t do better than starting at Chapter 1 and making sure
you have your Raspberry Pi and your workspace set up. Even if you’re
experienced, it’s worth reading the early chapters to pick up hints we’ve gathered
from our extensive experience. If you’re champing at the bit to start playing with
your Pi, feel free to dive into the parts of the book that interest you most!

Part I

Getting Started with Raspberry Pi
Projects

For Dummies can help you get started with lots of subjects. Visit
www.dummies.com to learn more and do more with For Dummies.

In this part …
Learn about your Raspberry Pi.
Set up the hardware and operating system and your project-building
workspace.
Learn construction techniques.
Understand the basics of programming.
Install language extensions.
Discover the Raspberry Pi family of computers.

Chapter 1

Getting to Know the Raspberry Pi
In This Chapter
Getting a Raspberry Pi
Finding out what’s possible with your Raspberry Pi
Connecting your Raspberry Pi
Setting up your operating system
Troubleshooting any problems
You probably wouldn’t have picked up this book if you hadn’t already heard about
the amazing, low-cost computer for everyone, the Raspberry Pi. Besides being
inexpensive, what’s made the Raspberry Pi so appealing is that it’s pretty easy to
use. You can even change it to do things its designers never dreamed of. Unlike
most consumer electronics, tablets, and desktop computers, the Raspberry Pi is
designed to let you investigate how it works and change how it operates by writing
your own software programs.
This is all possible because the Raspberry Pi uses an inexpensive but powerful
processor and a free operating system, which is based upon the popular Linux
platform. In this chapter, we take a look at what you need to get going and show
you how to set it up.
We also tell you where to get a Raspberry Pi and the accessories you need to run it.
We explain how to set up the operating system, how to connect the hardware, and
what to do if you run into any problems along the way. Before long, you’ll be able
to make your Raspberry Pi say, “Hello, world!”

Getting a Raspberry Pi
If you’re interested in building projects with a Raspberry Pi, you probably already
have one. But if you don’t yet have your own Raspberry Pi, this is the section for
you! You’ll be glad to know that there are a few places you can pick one up quickly
and cheaply.

The Raspberry Pi comes in several versions: Model A is shown in Figure 1-1, and
Model B is shown in Figure 1-2. There are other versions of the Raspberry Pi,
though — Chapter 4 has a full rundown. The Model A and Model B use the same
kind of processor, but the Model A is cheaper and uses less power; it has a single
USB port and connections for your screen and audio. Model B has everything
Model A has, plus an additional USB port and an Ethernet port for connecting to a
network, so it costs a little more. For the projects in this book, you’ll want to get a
Model B.

Photograph courtesy of the Raspberry Pi Foundation
Figure 1-1: Raspberry Pi Model A.

Photograph courtesy of the Raspberry Pi Foundation
Figure 1-2: Raspberry Pi Model B.

The newest model as of this writing is the Raspberry Pi 2 Model B, which
replaced the Model B+, but we’ve kept all the projects in this book
compatible with Model B and later.
The Raspberry Pi Foundation (which is technically a UK charity, not a business)
created the Raspberry Pi. The Raspberry Pi Foundation licenses the manufacture of
the Raspberry Pi to the biggest names in electronics in the UK, RS Components
(www.rs-components.com) and Farnell, which supports Raspberry Pi under the
brand name element14
(www.element14.com/community/community/raspberry-pi). If you’re buying
a Raspberry Pi for personal or home use, Farnell’s outlet is CPC (order from
http://cpc.farnell.com). In the United States, you can also buy from Newark
(www.newark.com), which is a part of Farnell, and Adafruit (www.adafruit.com).
These suppliers can provide you with everything you need to get your Raspberry Pi
up and going, but you can only buy from them online.
If you simply can’t wait to get your hands on a Raspberry Pi, and you live in the
UK, you can also walk in to any Maplin electronics shop, where they’re usually

kept in stock. You’ll pay a bit more for the convenience of shopping in a store, but
you can get personal advice from the salespeople, which can be pretty useful if you
have questions. At the time of this writing, you can walk into a Radio Shack in the
United States and buy a Raspberry Pi starter kit, but this may change because the
company is restructuring.
You can also find the Raspberry Pi for sale on eBay. There are usually plenty of
listings for just a Raspberry Pi or for bundles that include all the accessories you
need in order to hook it up.

If you decide to buy a Raspberry Pi on eBay, be sure to purchase from a
reputable seller with plenty of good feedback. There are knock-offs out there,
and they can’t be guaranteed to be manufactured to the same standards as the
real thing. We tend to think the cost savings isn’t worth the risk of buying from
eBay.

Discovering What You Can and Can’t
Do with a Raspberry Pi
This book shows you how to get going with Raspberry Pi projects. After you’ve
done some, you’ll have a pretty good idea of what’s possible. But when you want
to go a bit further with your ideas, it’s good to know what you can realistically
expect to achieve.
The first thing you see when you get up and running is a text-based prompt on the
screen. You can do a lot of things just with text, but most people prefer to launch
the familiar graphical user interface (GUI), the desktop environment you’re used to
on any other computer. The operating system supports all the things you’d want to
do in a desktop system, including playing games, browsing the web, word
processing, using spreadsheets, editing photos, and playing audio and video.
But that’s not where the Raspberry Pi really shines. The great things you can do
with the Pi come into play when you write your own programs and hook it up to
electronics or other objects in the real world using the general-purpose input/output
(GPIO) connector. Your Pi is well suited for this because these kinds of things
don’t usually require the beefy processor in your desktop or laptop. Using your Pi
for things you may not do with your usual computer is what makes it really fun —

and that’s what this book is all about!
The Raspberry Pi uses a Broadcom BCM2835 central processing unit (CPU) and a
VideoCore IV graphics processing unit (GPU) and shares the onboard memory
between them. Either 256MB or 512MB of onboard memory is available. The CPU
is an impressive piece of technology that enables fairly complex computing power
at an extremely low price. The trade-off is that the Pi is not nearly as powerful as
the full-fledged CPU in desktop and laptop computers — it’s a bit slower, roughly
comparable to the capabilities of mainstream computers in the ’90s. You shouldn’t
plan to do high-performance computing or run heavily graphics-intensive
applications like gams or 3D modeling software — the Pi will run these, but they
may be unusably slow.
You probably won’t be replacing your main computer with a Pi, but you can do a
lot of experimentation with it that you may not try with your desktop or laptop, and
you can easily connect your Raspberry Pi to sensors and motors in the real world,
which we show you how to do in the projects in this book. And if you make any big
mistakes that damage your Pi, it doesn’t cost a lot to get another one and start
experimenting again!

Getting Familiar with Your Raspberry Pi
The Raspberry Pi is about the size of a credit card and has all the components that
you need onboard so that you can connect it to a TV or display and start using it.
These connections are shown in Figure 1-3.

Figure 1-3: Identifying the parts of the Raspberry Pi (in this case, the Model B).

Going clockwise around the board from the top left, you’ll find the following
connections:
General-purpose input/output (GPIO) connector: This is a port for getting
electrical signals into and out of your Raspberry Pi, such as for reading sensors
and controlling motors. It’s composed of two parallel rows of pins and is
labeled P1 (for “Plug 1”). Different models of Raspberry Pi use these pins
slightly differently due to the way the pins are routed on the board.
Composite video output: This jack is used for connecting your Raspberry Pi
to a composite video (standard TV) connection using an RCA cable.
Audio output: This is a black 3.5mm jack on the upper right of the board.

USB port(s): These ports allow you to connect USB accessories (such as a
keyboard and mouse and external storage devices) to your board. The Model A
has only one USB port to reduce costs. The Model B has two USB ports.
Ethernet port (Model B only): This port is for connecting your Raspberry Pi
to an Ethernet network and for accessing the Internet.
Camera serial interface (CSI) connector: This slim black connector between
the Ethernet jack and the HDMI output is for connecting a small camera such as
a webcam. CSI connectors are available from the Raspberry Pi store.
HDMI output: This port is used for sending digital video to a computer
monitor. The HDMI output also can route your audio, so you may not need to
use the audio output port.
Power input: On the lower-left side is the micro USB power socket. The
power is provided via a micro USB power supply that plugs into this port.
Display serial interface (DSI) connector: In the middle of the left side of the
board is a slim connector for connecting high-speed displays. It’s used for
connecting a small LCD panel directly to your Raspberry Pi. You can use it for
touch-based input as well!

Selecting Your Accessories
You probably have some of the important accessories lying around the house
already, which was exactly what its creators had in mind. You can just use old stuff
that’s gathering dust — you don’t have to buy anything, which keeps the cost down.
You don’t have to get all the accessories shown in Figure 1-4 to complete the
projects in this book. But at a bare minimum, you’ll need a display and a keyboard
to get things going. Here’s what you see in Figure 1-4:
Monitor: The Raspberry Pi’s onboard HDMI output allows you to connect a
high-definition feed to just about any modern computer display. If your display
has an HDMI input, all you need is a cable between the two.
If your monitor doesn’t have an HDMI input, it probably supports DVI, which
has a larger, wider connector. You can buy adapters that convert from HDMI to
DVI that will allow you to use your DVI monitor. You can also use a VGA
monitor (the VGA input contains three rows of holes), though these aren’t
officially supported. If you want to use VGA, make sure to get an adapter that is
specifically meant to work with a Raspberry Pi.

If you don’t want to use a computer display and you have an old TV,
you can use it as a display. Your Raspberry Pi has an RCA connection, which
allows you to use a composite video signal to a TV with a composite video
input. The picture won’t be as sharp as with a display, and text can be hard to
read, so we recommend using a monitor if you can.
Ethernet cable: Some of the projects in this book require connecting your
Raspberry Pi to a network. For these projects, you’ll need an Ethernet cable.
Case: You can use your Raspberry Pi as is, right out of the box. It’s pretty
durable, but accidents happen, so lots of people have fun making cool cases to
protect the circuit board from spills and dust. Some cases are even enhanced
with glowing LEDs. The designer of the Raspberry Pi logo, Paul Beech, has
designed some cool cases — check out http://shop.pimoroni.com to find
them.
Mouse: Any USB mouse will work fine. The Model A only has one USB port,
so if you’re using a Model A, you’ll need to use a USB hub so that you can plug
in both your mouse and your keyboard. You can also plug your mouse into your
keyboard, if the keyboard has an extra USB port on it.
Keyboard: There is a USB port on the Raspberry Pi circuit board, so you can
plug in a USB keyboard. If you have an older keyboard with a round (PS/2)
connector, you can use it, but you’ll need a small adapter plug to convert
between PS/2 and USB.
SD card: Your Raspberry Pi doesn’t have a hard drive, so you’ll need to use
some kind of external storage. An onboard SD card slot is provided for this
purpose. When you plug in an SD card, your Raspberry Pi treats it just like a
hard drive. SD cards are pretty cheap, so go for one with at least 8GB or 16GB
of storage. SD cards have class numbers to indicate how fast they can read and
write data. We recommend you get a Class 6 SD card or better.
USB hub: If you’re using a Model A Raspberry Pi, you may need a USB hub to
connect your keyboard and mouse (see the preceding bullet). If you’re using a
Model B, you don’t need a USB hub, but you’ll probably want extra USB inputs
into your Pi, because your keyboard and mouse will take up the two USB ports.
Make sure to get a USB hub that has its own power source — the Raspberry Pi
can provide only limited power output via USB.
USB memory stick (not shown): Memory sticks (also called memory keys or

flash drives) can provide a great deal of extra storage that is fast and reliable.
They’re also handy for moving files from another computer or laptop to your
Raspberry Pi.
SD card writer (not shown): The Linux operating system for your Raspberry
Pi is stored on an SD card. You can buy SD cards with the operating system
already loaded, but you’ll probably want to write your own at some point, so
you need to make sure your computer has an SD card slot. Most desktops and
laptops have one these days, but if yours doesn’t, you should get an SD card
writer. It plugs into your USB port and allows your computer to see what’s on
the card and write files to it.
Speakers (not shown): Your Raspberry Pi has a 3.5mm audio jack so you can
plug in headphones or external speakers. If you’re using the HDMI connection
and HDMI monitor as a display, the audio is sent over that cable to your
screen.
Micro USB power supply (not shown): Your Raspberry Pi gets its power via
the micro USB connector on the side. You can use just about any power charger
that fits this port, but it needs to supply 700 milliamperes (mA) of current
(check the specifications printed on the side of the charger). Most good mobile
phone chargers will work fine, as long as they supply 5V 700mA (3.5 watts).
We recommend a Raspberry Pi–compatible power adapter, which should be
available from the supplier of your Raspberry Pi.

Figure 1-4: Key accessories.

Setting Up Your Operating System
To do anything useful with your Raspberry Pi, you need to have an operating
system. The operating system provides the basic functions like the GUI, which most
people know as the “desktop environment.” It also supports reading and writing
files, runs general-purpose applications like your word processor and web
browser, and runs the programs you write for your Raspberry Pi projects. Your
Raspberry Pi uses the Linux operating system to do this.
Your operating system is stored on an SD card, not on a hard drive like most
computers. When you turn on your Raspberry Pi, it reads the operating system
that’s on the SD card. If your card isn’t inserted, the Raspberry Pi won’t be able to
start up, so you need to get the operating system onto an SD card before you can do
anything else.

Linux is a free operating system, unlike the ones used on Windows and Mac. It’s an
open-source project, which means anyone can contribute to it — and thousands of
people do. The Linux Foundation (www.linuxfoundation.org) coordinates these
efforts and manages the standard Linux kernel (the core code that makes it work).
All you have to do is download a copy of the operating system (see the nearby
sidebar) and put it on your SD card.

You also can buy premade SD cards that already have the operating system
written onto them. With one of these cards, all you have to do is insert your
card and power up your Raspberry Pi. You can buy them from RS, element14,
Amazon, eBay, or other online outlets. If you already have one, skip to the
section on setting up your hardware, later in this chapter.

Selecting your Linux distribution
Because it’s an open project, many different versions of Linux are out there in the wild. These are
referred to as Linux distributions (or distros), and you can download them for free. The different
distributions are specialized for a variety of purposes. Some are made to be as bare bones as
possible; others are optimized for performance.
The Raspberry Pi Foundation has endorsed a special distribution for beginners called Raspbian
Wheezy, which is a version of the Debian Linux distribution. It includes a GUI called the Lightweight
X11 Desktop Environment (LXDE). It also supports the programming languages that you use to write
code for the projects in this book. Most of the projects use a scripting language called Python; some
use a programming language called C. We assume you’re using Raspbian Wheezy for the projects
in this book. ( Tip: Your operating system is on your SD card, so if you ever want to use something
other than Wheezy, you can load it onto an SD card and pop it into the SD card slot.)
You need to download Raspbian Wheezy so you can copy it to your card. The best place to get it is
from the Raspberry Pi website at www.raspberrypi.org/downloads. Click the Download ZIP button next
to Raspbian Debian Wheezy and save the file on your system in a place that you can easily find it.
After you download Wheezy, you’ll need to unzip the compressed file by clicking it. ( Note: If you have
a Mac, you don’t need to unzip the file before you create the SD card. Just follow the instructions for
Mac later in this chapter.)
There is also a download file called NOOBS (which stands for “new out of the box software”) on the
Raspberry Pi website, which you can use to automate the process of creating an SD card. It’s
designed to be really easy to use. You just download NOOBS, unzip it, and put it on your SD card.
NOOBS then manages the setup of your Raspberry Pi automatically. Even though NOOBS is
supposed to be easy, problems sometimes occur, requiring you to get another program to format
your SD card. We think it’s simpler just to download the Raspbian Debian Wheezy and create your
SD card yourself in a few easy steps.

Flashing Your SD Card

Your operating system is made up of a bunch of files that are run from the SD card
itself. However, when you write the operating system’s files to the SD card,
they’re written in a special format that Linux can read. You can’t just copy them
over as you would with other kinds of files. The Linux distribution you
downloaded is in a special format called a disk image. And you flash the disk
image to the SD card using a special little program. The program you need depends
on whether you’re using Windows, Mac, or Linux.

Flashing an SD card in Windows
To create the image file in Windows, you use a special program called Image
Writer for Windows. It’s free and pretty easy to use. Just follow these steps:
1. Insert your SD card into your computer’s SD card slot or, if you don’t have
one, into your SD card reader.
Take note of which drive letter is assigned to your SD card.
2. Download the files at
www.sourceforge.net/projects/win32diskimager/files/latest/download

.

If you want more information about Image Writer for Windows, go to
www.launchpad.net/win32-image-writer.
3. Double-click the file to extract it, click Extract All Files to unzip the
archive into a folder, and then open the folder.
Note: If the filename of the file you downloaded ends with .exe, when you
double-click the file, an installation wizard may run.
You should see the list of extracted files. Make sure that you aren’t looking at
the zipped files.
4. Click the file Win32DiskImager.exe to open it.
5. Click the folder icon to the right of the long white box and navigate to the
Linux .img file you just unzipped; double-click to select it.
This will put the file path into the long white box for you.
6. From the Device menu, select the drive letter that your SD card has been
assigned.

Be absolutely sure you’ve got the correct drive selected — the one that
contains your SD card. Whatever drive you’ve chosen in the device menu will
be completely erased!
7. After you’ve double-checked that you’ve selected the right drive, click the
Write button to create the image file on your SD card.

Flashing an SD card on a Mac
On a Mac, you can use a simple script called RasPiWrite to do the work of flashing
your image file to your SD card. First, you create a folder that RasPiWrite can use
while it’s flashing your SD card. Then you use the script to create your image file.
You do some of this by typing commands on the command line, using the Terminal
program, which is found in your Applications/Utilities folder.

You need your system password to be able to flash the SD card. Just
follow these steps:
1. In your Documents folder, create a folder called SD Card Prep; in the SD
Card Prep folder, create a folder called RasPiWrite.
2. Go to https://github.com/exaviorn/RasPiWrite to download the zip
file of RasPiWrite.
3. Double-click the file you downloaded and open the resulting folder.
4. Drag the files in this folder to the RasPiWrite folder you created in Step 1.
5. Drag the zip file of your Linux distribution into your RasPiWrite folder.
6. Open the Terminal application, located in Applications/Utilities, and
type cd and then a space.
7. Use the Finder to locate the SD Card Prep folder you created in Step 1;
make sure you can see both the Finder window and the Terminal window,
and then drag the RasPiWrite folder into the Terminal window.
This places that path name of that folder into the command line for you. (It’s
easier than typing it all out.)
8. Press Return.

This switches you to the folder containing RasPiWrite.
9. Type ls and press Return.
The list command produces a list of files in the RasPiWrite folder. You use it
later to tell RasPiWrite where to get the source files for your disk image.
10. Remove any external memory cards, USB sticks, or other pluggable
storage device from your system so that you don’t accidentally erase them.
11. Type sudo python raspiwrite.py to run RasPiWrite.
12. Enter your system password.
You see a progress report as your script creates the disk image. If all goes
well, you should see a raspberry made of text characters.
13. Insert your SD card into your Mac’s SD card slot or to an external SD card
writer and press Return.
14. Follow the prompts to select the disk that corresponds to your SD card.

You can double-check to make sure you’ve selected the correct one by
ensuring that the disk’s size (listed in the size column) corresponds to the size
of your SD card. You don’t want to erase all the data on your main hard drive!
15. You’ll be asked if you want to download a distribution; because you
already did that, type N.
The program asks you to locate the disk image file.
16. Scroll back up to where you used the ls command and copy the filename of
the distribution; then scroll back down and paste this filename at the
prompt and press Return.
The program extracts the image file and prepares it to upload onto your SD
card. It then asks you to confirm that you’re about to erase your SD card. Be
sure you’ve got the right SD card.
17. Type accept to continue installing the image, and press Return.
The flash process can take a long time. You’ll see some dots on your screen as the
process continues. Depending on your system, it can take 30 minutes or even up to
an hour. You can use your computer for other things during this process, but if you
lose power or restart, you’ll have to start all over again.

If you’re presented with a message immediately after typing accept,
there’s a problem. Even though the message may say Transfer Complete,
the immediate response means that the transfer hasn’t been accomplished. This
sometimes happens if the image file isn’t located where you indicated it was
or if the distribution contains just an image file rather than an image file within
a folder of the same name. If it happens, create a folder with the same name as
the image file, drag the image file into it, and try again.

Flashing an SD card in Linux
If you’re using Linux, the process of flashing an SD card for your Raspberry Pi is
pretty straightforward. We assume you’re using Ubuntu, one of the most popular
Linux distributions. If you’re using another distribution, the following steps will be
very similar.
When you download the Raspbian Wheezy distribution, make sure you save it
where you can find it, such as in the Documents directory. Then follow these steps
to flash your SD card:
1. Remove any external drives, USB keys, or other SD cards from your
system and insert the SD card you would like to flash for your Raspberry
Pi.
2. Open a Terminal window.
This is located in the Applications menu under Accessories.
3. Type sudo fdisk –l (the last character of this command is the letter l, not
the number 1).
This starts the fixed disk program, a tool you can use to manage, erase, and
separate disk drives into different logical partitions. It also shows you which
drives are available on your system.
4. Locate your SD card in the device list.
The list gives details about each of the drives on your system, including the size
of each device in bytes and other details such as the number of heads, sectors,
cylinders, and so on. Find the device that most closely matches the size of your
SD card in bytes. For example, an 8GB SD card will be listed as about
8,068MB. Take note of the name of that disk’s directory. For example, on our

system, the SD card is located in the directory: /dev/sdg.
5. Use the cd command (“change directory”) to navigate to the directory
where you saved your Raspbian Wheezy distribution.
For example, if it’s in the Documents directory, type cd Documents and press
Enter.
6. Display the name of your Raspbian Wheezy image file by typing ls *.img.
7. To write the Raspbian Wheezy image to the SD card, use the dd command.
Here’s what we would type on our system:
sudo dd if=mydistribution.img of=/dev/sdc bs=2M

You need to substitute the name of your distribution file where it says
mydistribution.img. Substitute the directory where your SD card is located
where it says /dev/sdc.

The sudo command stands for “super user do” and tells Linux that
you’re issuing the dd command as the administrator of the system. The
operating system assumes you know exactly what you’re doing, and there are no
protections for making any grave mistakes. The dd command is short for “data
description,” but some people have joked that it stands for “destroy disk” or
“delete data,” because if you aren’t careful, it can erase your system’s hard
drive. When these two commands are combined, you can imagine the
consequences of making a mistake. So, be sure you’ve typed everything
precisely!
8. Press Enter to start flashing the image file your SD card.
It should take about two or three minutes to do this operation. You won’t see a
progress update, but you may see the light next to your SD card slot flickering.
When it’s finished, you’ll be advised how much data was copied and how long
the operation took to complete. Pat yourself on the back. You’re ready to fire
up your Raspberry Pi!

Connecting Your Hardware
When you’ve got the essential accessories and the operating system, you can set up
your hardware. This is simply a matter of connecting the right bits together. Figure

1-5 shows you how things are connected using a Raspberry Pi Model B.

Figure 1-5: Hooking up all the hardware.

Follow these steps to set up your hardware:
1. Locate the SD card slot on the bottom of your Raspberry Pi and insert the
newly flashed SD card snugly, with the label facing down.
The card will stick out from the side of the circuit board a little bit.
2. Connect your computer monitor or TV to your Raspberry Pi.
If you’re using a monitor or TV with an HDMI connection, just connect the two
with an HDMI cable. If your monitor has a DVI connection instead, insert the
HDMI cable into an HDMI-to-DVI adapter and then plug it into your monitor. If
you’re using a TV without an HDMI connection, connect a yellow RCA
connector cable to the round RCA jack on the top of your Raspberry Pi and
plug the other end into your TV’s composite video input.

You may need to manually select which input your monitor or TV is

using. Check the manual if you aren’t sure how to do this. Also, make sure the
power to your display is switched on.
3. Connect your USB hub into one of the two USB sockets on the right side of
your Raspberry Pi.
If you’re using a Raspberry Pi Model A, there will be only one socket. Your
hub should have a power adapter — plug it into an electrical socket.
4. Plug your keyboard and mouse into the USB hub.
If you’re using a keyboard or a mouse with an older PS/2-style connector,
you’ll need a PS/2-to-USB adapter. You can also connect them directly to your
Raspberry Pi’s remaining USB socket, but it’s a good idea to use the hub,
which has more available power.
5. Connect your audio.
If you’re using an HDMI monitor with audio, the audio will go through your
HDMI cable. If you’re using external speakers or a TV, your audio output is the
black 3.5mm socket on the top-right edge of your Raspberry Pi. Connect your
speaker cable there.
6. Connect to your network.
If you’re using a Model A, you can skip this step. There is no network
connection available for it.
If you’re using a Model B, connect an Ethernet cable to your Ethernet socket on
the right side of the board. When your operating systems starts up, it will
automatically connect to your home router, as long as it supports Dynamic Host
Configuration Protocol (DHCP). (Most home routers do.) If you have trouble
connecting to the network, see your Internet service provider’s instructions for
setting up new devices using DHCP on your home router. In rare cases, DHCP
may be switched off.
7. Connect your micro USB power supply to your power socket on the
bottom-left corner of your board.
Some power supplies have standard-size USB ports. You connect a USB–to–
micro USB adapter cable from the standard USB output on these power
adaptors to the micro USB input on your Raspberry Pi. There is no power
switch. To cycle the power, you remove the adapter plug and put it back in,
which is a little awkward. If you have an extension lead with a switch, you can
connect your power adapter and use the switch on the lead to cycle to turn the

power on and off more easily.

Don’t connect your Raspberry Pi to your computer’s USB port via a
USB–to–micro USB adapter cable. Your computer’s USB port isn’t designed
to deliver enough power for your Raspberry Pi, via the USB port.
When you power up your Raspberry Pi you should briefly see a rainbow-colored
screen, which confirms that the hardware itself is working. Then the Linux
operating system on your SD card will start to run and you’ll see an avalanche of
text on your screen as all the various parts of the system are started. It can be pretty
fun to watch. This will take a little time to complete. When it’s finished, you’ll be
able to move on to setting up the system in the next section.
You’ll also see a little status light on the board next to the audio jack. The PWR
light should be on. When your Raspberry Pi accesses the SD card to load the
operating system, you’ll see the ACT light activated.

If you’re using an earlier Revision 1.0 board, the ACT light is labeled OK.
The FDX light indicates that you have a good Ethernet connection. The LNK light
will flash whenever there is network traffic on the wire. The 100 light indicates a
high-speed (100 Mbit) Ethernet connection.

Setting Up with Raspi-config
Raspi-config is a little program that automatically loads to help you to get your
Raspberry Pi ready to run, the first time you start up. It gives you a list of the basic
system options in case you want to change them. After it’s set up the first time, it
won’t run again unless you launch it manually. You use the keyboard arrows to
move up and down the menu of options and the left and right arrows to select
options. Pressing Enter confirms your selection.
The options in the menu change from time to time. You may encounter an older
version of the software with different menu items, but here’s a rundown of what
they are and what they do (as of this writing):
Expand Filesystem: When you flash your SD card with your operating system,

it makes an exact copy (an “image”) of the Linux distribution files, and the
formatting of the disk itself is likely to be smaller than the actual available
space on your card. The image files don’t take up much space, and if you have a
large SD card, it will look like your SD card has much less capacity than it
actually does.
To overcome this problem, it’s very important to use this option to expand your
root file system to use all the available space on the card. Otherwise, you could
run out of room! When you press Enter with this option, it runs immediately.
The next time you start your Raspberry Pi, the command will resize your file
system to use all the available room. This can take a few minutes; the screen
won’t respond until it’s done. After it’s finished, all the space will be available
to you.
Change User Password: Lets you set the password for the default user of your
Raspberry Pi, which is the user pi. You don’t need to change this. If you do,
make sure not to forget it because there’s no way to get it back from the system!
Enable Boot to Desktop/Scratch: You can use this option to make your
Raspberry Pi go straight into the graphical operating system at startup.
Otherwise, you have to start it manually (see the next section).
Internationalization Options: This option takes you to a submenu where you
can configure several options depending on where you’re located:
Change locale: Allows you to change your language and character set.
Leave this option alone if you want to use your Raspberry Pi in English.
Change timezone: Tells your Raspberry Pi where you’re located.
Afterward, it detects the time from your Internet connection.
Configure_keyboard: Allows you to select your keyboard model and
layout. When you press Enter, a long list of keyboards will be
displayed. If nothing seems to be happening, be patient. It can take a few
seconds for the list of keyboards to show up. Choose the one you want to
use and then select the keyboard layout you want to use (for example,
UK).
Enable Camera: If you’ve purchased an optional Camera Module, this menu
allows you to set it up to work with your Raspberry Pi.
Add to Rastrack: Racktrack allows you to add your Raspberry Pi to the global
map of users around the world. You can see all the other tracked Raspberry Pis
on their website at http://rastrack.co.uk.

Overclock: Overclocking is a way of speeding up the CPU to perform
calculations faster than the manufacturer intended. The clock speed is the
heartbeat that determines how many instructions your CPU processes per
second. Manufacturers build in a bit of leeway to ensure that they can guarantee
the speed that your CPU is rated to. If you overclock your CPU, your Raspberry
Pi will run faster, but its lifespan may be reduced, and it’s likely to run a bit
hotter. If you change this setting and your Raspberry Pi no longer works, hold
down the Shift key when you power up to return your Raspberry Pi to disable
overclocking.
Advanced Options: Advanced Options contains several settings that are a bit
more involved, so we don’t use them in this book. But they are good to know.
The options are as follows:
Overscan: Allows you to ensure that the picture is centered on your
monitor and uses the available room correctly. If you have a black
border around your image that you don’t want, disable this option.
Otherwise, you can leave it alone.
Hostname: Allows you to set the name of your Raspberry Pi network.
You probably won’t need to modify this.
Memory Split: Your onboard memory is shared between the CPU and
the GPU. Depending on what you’re doing with your Raspberry Pi, your
programs may use one or the other more intensively. For example
graphics and gaming programs make more intensive demands on the
GPU, so you can increase your Raspberry Pi’s performance by giving
more memory to the GPU. Raspbian Wheezy uses 64MB to the GPU by
default, and for most purposes this will be fine. You can experiment
with this setting to see what setting works best for you.
SSH: Secure Shell (SSH) is a secure way of communicating between
computers using an encrypted connection, so that you can control one
computer from another one. Unless you’re familiar with this feature, you
can ignore this option.
I2C: A communication protocol used by some external devices and
sensors. This option allows you to enable or disable the I2C module so
you can use these devices.
Serial: Allows you to enable or disable messages from the system on
the serial interface. You most likely won’t need to change this unless
you’re doing some kind of debugging.

Audio: Allows you to select whether audio is sent via the onboard
3.5mm audio jack or via the HDMI port. It’s set to auto by default,
which means your audio will be routed via HDMI only when an HDMI
screen is connected.
Update: From time to time, you may have to update Raspi-config.
You’ll need an Internet connection to do this, but if you’re using a
recently download distribution, you should be up to date.
About raspi-config: This just describes what the Raspi-config tool does.
When you’re finished making your selections, press the right arrow key twice to get
to the Finish option and press Enter. You may have to reboot your Raspberry Pi,
depending on the options you’ve selected.
If you want to use Raspi-config later, you can start it by typing sudo raspi-config.

Starting Up the Desktop Environment
When you’ve finished configuring your Raspberry Pi with Raspi-config, you’re
ready to start up. After you switch on your power, you may have to enter your
username and password, depending on your settings. For Raspbian Wheezy, the
username is pi and the password is raspberry. Make sure you type these in
lowercase.
After you log in, you’ll see the command prompt:
pi@raspberrypi ~ $

This means you’re up and running and you’ve logged into the operating system.
Give yourself a cheer!
It doesn’t like the graphical operating system you’re used to with a desktop
computer, but the command line is the direct connection to your Raspberry Pi’s
capabilities. You can execute all the main system commands and even do
programming using only the command line interface. In a sense, the graphical
environment is just a way of prettying up the command line and make it easier to
use.
To get pretty, you launch the GUI, LXDE, by entering its startup command on the
command line. To fire it up, type startx. It will take a moment or two to start up,
and the screen will go blank for a bit. After startup, you should see the LXDE and a
lovely red raspberry logo on the desktop wallpaper, as shown in Figure 1-6.

Figure 1-6: Starting up the desktop environment.

When you’ve got the desktop working, you can move on to learning about the
programming tools in Chapter 3 or dive straight into the projects, if you’re familiar
with programming.

We recommend you peruse through Chapter 2 to make sure your
workbench is set up for building the projects in this book. You’ll need a few
tools to get going on many of them, and it’s a good idea to set up your
workspace before you begin.

Troubleshooting Your Raspberry Pi
Things don’t always go according to plan. Here are some common problems and
how you can try to solve them:
No lights on your Raspberry Pi: This can happen if you forgot to connect the
micro USB power connector or if the power supply isn’t capable of supplying
your Raspberry Pi with enough power. Check that it’s rated to at least 5V

700mA (3.5 watts).
Only the red light comes on: Your Raspberry Pi has power, but it can’t read
the operating system on your SD card. First, make sure your SD card is firmly
inserted. Then check that you’ve correctly created the disk image. If that
doesn’t work, you can try testing your SD card on another Raspberry Pi to see
if you get the same problem. If all else fails, try using a pre-imaged SD card.
No output on the monitor: Check your monitor connection and your monitor’s
power connection. Make sure that your monitor is turned on. (Sounds silly, but
we’ve all done this at least once!) Then check that your monitor is using the
correct input source. Use a button on the front of the monitor to cycle through
them or use the monitor’s remote control.
Inconsistent behavior or hang-ups: Your Raspberry Pi uses power at
different amounts depending on what it’s doing. Make sure you have a good
power supply and that it isn’t overtaxed.

If you have a lot of peripherals connected to your Raspberry Pi, they
may be demanding power as well. If your power supply is right at the limit of
its capabilities and your processor needs extra power for computing-intensive
tasks, it could exceed what’s available and cause your Raspberry Pi to hang.
This is particularly common if you try to power your Raspberry Pi from a USB
socket.
If these tips don’t fix the problems you’re experiencing, your next port of call
should be the user forums at the Raspberry Pi Foundation
(www.raspberrypi.org/forums). The user community there is extremely
knowledgeable and very helpful, particularly for beginners. Your problem may
already have been solved in the discussions there. If not, post your problem,
describing exactly the trouble you’re having. More often than not, you’ll get an
answer within a few hours. Making it easy to experiment with your Raspberry Pi is
what the user community is all about!

Chapter 2

Setting Up Your Tools and
Workbench
In This Chapter
Setting up a project-building workspace
Choosing the right tools for the job
Selecting your accessories
Using breadboards and soldering
Finding out about Raspberry Pi LEGO projects
The first thing you need to do to get started with Raspberry Pi projects is to get
your workspace ready. You need a dedicated work area and the right tools so that
you can build the projects quickly and easily. In this chapter, we explain how to
create a good workspace with the right set of tools for the projects in this book.
The project chapters assume that you have the basic workspace and tools ready to
go. After you dive into a project, it can be a drag to interrupt your work to get some
basic tool that you’ve overlooked. But if you have most (or all) of the basics of
your workspace covered, you won’t have to stop what you’re doing to go get a
hand tool or run to the hardware store.

Getting Ready to Build Your Projects
You can start working on Raspberry Pi projects almost anywhere, but it’s best to
have a dedicated spot in which to build them. Completing the projects will take
some time, so you want to choose a place where you can work comfortably and see
what you’re doing. Generally, setting up and taking down unfinished projects is a
hassle — it takes more time and can introduce errors if your connections come
loose. You can avoid this problem by setting aside a dedicated workspace.

Setting up your workspace
You need a dedicated area where you can build and test your projects —

especially the advanced ones in this book, which can take a few hours or more.
You have to connect all the components together, provide power, keep the cables
and connection wires organized, and do some light fabrication. So, find a spot in
your house, apartment, shed, garage, studio, or wherever, where you and your work
will be undisturbed and where you can make a bit of a mess. The workspace in
Figure 2-1 has all these things covered.

Figure 2-1: A good working environment and some basic tools.

You don’t want to get interrupted by distractions hunting for parts, or not
having the right tools, so it’s important to get the work area ready. In our
experience, a good Raspberry Pi workspace has the following:
A solid workbench or desk
A comfortable chair
Dry air and good ventilation (especially for evacuating soldering fumes)

Plenty of power outlets, ideally at desk height
Enough room for the screen, keyboard, and mouse, and some extra workbench
space for assembly and fabrication
A nearby network connection or Wi-Fi router
Shelving and storage for projects you’re working on
Small boxes and drawers for organizing parts and tools
The environment needs to be comfortable to work in for a long stretch. If it’s too
cold or too hot, too noisy, or filled with distractions, it’ll take you longer to
complete the work. Make yourself a sort of hideaway where you can stay focused.
Your Raspberry Pi is a fine computer in its own right, but an extra computer is
sometimes useful during the project-building process, so it’s good to have room for
a desktop or laptop computer on the workbench. Plus, you’ll want to be able to hunt
for references online, look up datasheets, and post questions to forums, so a
reliable Internet connection is vital.

Keeping an eye on safety
A few of the projects in this book deal with low-voltage electronics. Safety is
always a factor when working with electrical circuits. None of these projects
works with wall power, but you should always treat electronic projects as if they
could have potentially dangerous voltages. If children may roam around your work
area, take special precautions to keep them away. Little kids love pulling on cords
and cables and could easily drag everything off your desk with one quick tug. A hot
soldering iron left unattended could cause severe burns, besides being a fire
hazard.
It’s probably best to keep food and drink separate from your workbench. Empty
pizza boxes or soda cans may hide critical parts, and you can waste time hunting
for things. Accidentally spilled drinks don’t do good things for live circuits.

Assembling Your Tools
You need some basic tools to build several of the projects in this book. The tools
basically fall into two categories: electronics tools and physical building and
fabrication tools. You can get most or all of these components from electronics
retailers such as Radio Shack (in the United States) or Maplin (in the UK).
Specialty electronics suppliers on the Internet also stock them and are often

cheaper, so hunt around at places like Farnell (www.farnell.com), Newark
(www.newark.com), Rapid Electronics (www.rapidonline.com), and RS
(www.rs-components.com). Sometimes you can find good deals on Amazon
(www.amazon.com) and eBay (www.ebay.com), too.

Electronics tools
Here are the basic electronics tools you’ll want on your shopping list:
A multimeter: A multimeter is an essential tool for most electronic projects.
You use it to perform basic tests to make sure that you have good connections
in your electrical circuits. With a multimeter, you can measure the
characteristics of an electrical circuit and troubleshoot why something may not
be working. A multimeter is also handy for testing and measuring individual
electronic components. You should have one on hand for testing and
troubleshooting your projects. (See the following section, “Selecting a
multimeter,” for more information.)
A breadboard and jumper wires: Some of the projects in this book involve
wiring up electrical components, LEDs, sensors, or actuators to your Raspberry
Pi. This can be as simple as one or two wires, but some of the projects have
many connections. A breadboard is a simple tool to help you easily make all
these electrical connections. You need jumper wires to make connections when
you’re using a breadboard. Wires come in solid core and stranded versions
(which contain many fine wires). You need solid core jumper wires for
working with breadboards.
A soldering iron: A breadboard is ideal for temporary connections and
prototyping, but for some connections you’ll want something more permanent.
This is where a soldering iron comes in. You use a soldering iron to make
strong, permanent connections between electronic components. If you want to
mount buttons onto an enclosure for your project, you’ll probably want to
solder wires to the buttons and connect these to your Raspberry Pi. You can
even build part of your circuit on a breadboard and use soldered connections
for switches or sensors that are located some distance away. (See the upcoming
section, “Selecting a soldering iron and accessories,” for more information on
what to look for.)
A power supply: None of the projects in this book requires a desktop power
supply, so this is optional. But for general electronics experimenting, you’ll
probably want to have a power supply on hand.

Selecting a multimeter
A multimeter is an essential tool for testing, measuring, and diagnosing problems in
electronic circuits. You use a multimeter to measure several basic attributes of
your circuit, including:
Continuity: Whether there is a good connection between two points
Voltage: The measure of potential electromotive force in a circuit
Current: The measure of the continuous, uniform flow of electrons through an
unbroken pathway in an electrical circuit
Resistance: Opposition to the flow of current within a circuit
With a multimeter, you can also measure the voltage provided by batteries and
power supplies, and the characteristics of discrete electronic components, such as
resistors, capacitors, diodes, and transistors.

Different models have different features, and the more expensive ones have
advanced features you may not need. That said, there are two important
features to look for:
Continuity with audio signal: Checking continuity — making sure that the
things you think are connected really are connected — is the task you’ll use
your multimeter for most often. You touch the two probes to part of a circuit to
see if they’re connected, and the multimeter screen displays a confirmation.
With cheap multimeters, you need to hold the probes in place while looking at
the screen, which can be annoying if the probes slip off. It’s a pain to check
continuity by holding leads on a circuit while you’re also looking at the
display. It’s much easier to just poke around and listen for an audio signal.
Meters with audio output will beep when you test for good continuity so you
don’t have to take your attention away from the circuit. If you can, spend a little
more for a multimeter that has this feature.
Auto-ranging: Inexpensive multimeters require you to estimate the range of
measurement and set the dial accordingly. On auto-ranging multimeters, you
don’t have to set the dial to select the range of measurement that you’re reading.
Auto-ranging is particularly handy and can be worth paying slightly more for.

Older multimeters used a needle and graduated scales for the display, but
modern ones use a digital readout. If you don’t already have a multimeter, we
recommend getting a digital one, like the one shown in Figure 2-2.

Figure 2-2: A digital multimeter is an essential diagnostic tool.

Selecting a soldering iron and accessories
Many of the projects in this book can be built without soldering anything at all, but
you’ll need to do a little bit of soldering for some of the projects, so it’s good to
have a soldering iron on hand.
Soldering involves melting solder (a metal alloy that melts at about 700°F) and
allowing it to cool, creating a strong, conductive joint. You can solder wires to
each other and join wires to components. You can bond wires to circuit prototyping
boards such as perfboards and stripboards. Soldering secures components in place,
while creating a good electrical connection for a more permanent, longer-lasting
project. You can also simply solder certain components (like switches and
displays) to wires that lead to your breadboard. That way, you can mount them in a
project box. On some projects, you may want to move buttons or switches from the

breadboard to the project enclosure, which means you’ll need to solder extension
wires on them.
Your soldering iron provides the heat for creating a soldered joint. Many people
have the impression that you melt solder onto the parts that you want to connect, but
this is actually backward. When soldering, you use a soldering iron to heat up both
the solder and the components that are being joined together. When the components
are hot enough, the solder will flow onto them, at which point, you remove the tip
of the soldering iron and, thus, the heat supply. The solder cools rapidly and, if
done correctly, forms a reliable bond.
Figure 2-3 shows a basic array of soldering tools. The key soldering tools you
need at your workbench are as follows:
Soldering iron: Your main soldering tool. Irons can be very inexpensive, but
the professional ones can set you back hundreds. If you want to save money,
avoid the cheapest ones and aim for a soldering iron that’s at the top end of the
low-range options. You’ll need one that supplies at least 30 watts. A soldering
iron with an adjustable temperature setting can be useful if you need extra heat
for large joints, but it’s not essential.
Solder: A metal alloy you use to create soldered joints. There are both leaded
and lead-free varieties. Some purists prefer leaded 60/40 solder (60 percent
tin, 40 percent lead), but lead is toxic, so unless you have a particular need for
it, we recommend you opt for the lead-free variety, with a rosin core. The rosin
core melts and helps to clean the surfaces you’re joining. Solder comes in a
variety of diameters measured in standard wire gauge (SWG). For most
electronics soldering needs, 18 SWG or 20 SWG diameter is ideal. You can
use 22 SWG for detailed work.

Somewhat counterintuitively, as the wire gauge number goes higher, the
diameter of the wire gets smaller.
Extra soldering tips: Tips do the main work of the iron, directing the heat in
the right place. Tips come in a variety of shapes and sizes. For most electronics
work, you’ll need a cone-shaped tip rather than a chisel tip. Because they come
into contact with molten metal and impurities, tips can degrade over time, so
it’s a good idea to get spares.

Different manufacturers have different tip-mounting systems, so buy a
couple extra tips when you buy your iron to avoid having to hunt for the right
product later.
Soldering stand: A device that holds the wand safely while it’s hot. It may
have a sponge for cleaning the tip. Soldering stands are often included with
soldering iron kits.
Cellulose sponge and brass wire sponge: You use these to clean the tip of
your iron, which you do while the iron is hot. You can use either a cellulose
sponge or a brass wire sponge, depending on your preference. The cellulose
sponge can be any garden-variety kitchen sponge from the supermarket dipped
in a bit of water and wrung out. Using a moist sponge cools down the tip of the
iron, which is something to avoid because your iron will have to work harder
to keep the tip at a constant temperature, and contaminants can build up on the
tip. The brass wire sponge costs a little more, but it doesn’t cool down the tip
of the iron when you’re cleaning it and it doesn’t contaminate the tip. Using
brass wire also means that your tip will last longer.
Desoldering tools: You use these tools to remove unwanted blobs of solder
from your work or disconnect wires, traces, or components that you may have
soldered together by accident. You can find both desoldering wick and
soldering suckers. A soldering sucker is a spring-loaded pen that you can use to
suck liquefied solder away from your work piece. Desoldering wick is simply
braided flat copper ribbon, which you press against your work while heating it.
Capillary action draws the liquefied solder onto the braid and away from your
work. We tend to prefer wick, which is cheaper and usually more effective.
Tip-cleaning paste: Even with careful use, your tip may develop an oxidation
coating, especially if you don’t clean it regularly. This makes it very difficult to
coat the tip and control the way your solder flows. Cleaning paste can help to
remove oxidation and debris.

Figure 2-3: An entry-level soldering iron and essential accessories.

Physical building and fabrication tools
You also need some basic tools for light fabrication. Not all these tools are
essential, but often the one tool you don’t have is the one you need so you may want
to stock up. Figure 2-4 shows some of the essential tools. We’ve listed these
roughly in order of importance, from most to least:
A selection of precision screwdrivers: Both flathead and Phillips-head
screwdrivers are essential.
Helping hands: This is a small clamp with two alligator clips to hold your
work piece; it often comes with an integrated magnifying glass. This tool is
essential for gripping objects you’re working on — unless you have three arms.
Wire strippers: You use these for cutting and stripping the insulation off of
wires. They come in several different styles. Splurge a little here — if they’re

too cheap, they’ll produce poor results and be frustrating to use.
Angled side cutters: You use these for clipping component leads and cutting
wires.
Needle-nose pliers: Use these for holding fine objects. You should have both
small and large ones on hand.
A task light with magnifier: Use these to provide direct illumination and to
make it easier to see fine work. Get one with a spring arm so that you can place
it right over your work, if necessary.
A box cutter/carpet knife with replaceable blades: Use this for cutting
sturdier materials.
A cutting mat: You need this to protect your work surface.
A Sharpie and a pencil: Use these for making cutting marks and permanent
marks. No workbench is complete without a Sharpie!
Hand drill and small hand saw (not shown): For small projects, you can
probably use inexpensive hand tools, which you should be able to get at your
local hardware store. Power tools will also work, but they’re generally more
expensive.

Figure 2-4: Some essential light fabrication tools.

Using Your Tools Safely and Effectively
When you’ve assembled all the tools and set up your workspace, you’ll probably
be eager to dive right in! But before you do, take a few minutes to read the
information in this section so you don’t hurt yourself or those around you.

Working with electricity
In working with electronics, safety is critical. You should take basic
precautions to protect yourself. None of the projects in this book involves
connecting directly to the wall power, but you should use precautions anyway
and develop good safety habits. Even though you may only be working with
low DC voltages, it’s a good idea to follow some basic safety rules when
working with all electronic projects:
Don’t touch metal contacts or leads in a live circuit.
Don’t alter a live circuit. Always disconnect power before removing or
adding components to your Raspberry Pi or breadboard.
Always test with one hand tied behind you back. Well, at least one hand not
on the work piece. If enough stray current flows between both your hands, and
across your heart, it can cause arrhythmia. That’s not likely at the low DC
voltages we’re working with here, but it’s best to be safe and get into the habit.
Sounds crazy, but don’t work barefoot. Maximize the resistance between you
and the floor by wearing good, rubber-soled shoes. A puddle of water is a
great conductor, and you don’t want to be in one, if something goes wrong.
Wear an antistatic wrist strap. Your Raspberry Pi is a tough little computer,
and if it’s in an enclosure it should be well protected. However, it and other
components are sensitive to wayward voltages, including static electricity.
Several thousand volts of static electricity can build up on you, and you may not
even know it, especially on carpeted floors. If it does and you touch your
hardware, you can fry it in an instant. An inexpensive antistatic wrist strap will
guard against unexpected sparks by connecting you at all times to ground, which
diverts any electrical charge from building up on your body.
When fabricating or soldering, wear light, comfortable safety glasses. Wire
offcuts can fly around the room when they’re clipped, and hot solder can

sometimes spit and splutter. You don’t want any molten metal heading for your
eyes.

Laying the foundation for your electronics work
To quickly and easily connect your project circuits, start out by using a breadboard.
All the projects involving electronic circuits in this book can be built on a
breadboard. After testing on a breadboard, you can either put your Raspberry Pi
and your breadboard inside an enclosure or build your circuit permanently on a
stripboard or perfboard, which requires a bit of soldering.

Breadboards
A breadboard is a small block of plastic with lots of rows of holes into which you
can insert jumper wires and electronic components. Underneath the holes are tiny
metal strips forming springs, which grasp wires and the legs of components that are
inserted into the holes. Because the springs are metal, if you connect wires or
components to the same springs, they’re electrically connected together.

Because breadboards use springs to hold the wires, you should always use
solid core wire on them. Stranded wire (which is composed of multiple tiny
wires) will get scrunched by the springs when you try to push them into the
holes on the breadboard. It’s a big pain to use stranded wire, so save yourself
the trouble.
In the main work area on the breadboard, the holes are typically organized into
rows of five and grouped into two columns. There is usually a trough between the
two columns of holes, which allows you to insert an integrated circuit (IC) into the
breadboard so that each of its legs is served by four adjacent holes.
Many breadboards have columns of holes running the full length of either side of
the board. These holes aren’t electrically connected to the main work area, and
they’re often labeled + (positive) and – (negative or “ground”) and may be color
coded. You use these as “rails” for power and ground. You’ll often want to connect
components to power or ground, so you usually need lots of connections to them.
Breadboards come in various sizes, from small (with 400 contact points) to large
(with 830 points or more). You’ll want to have at least a small one on hand for
testing. If you run out of room, you can connect two breadboards using the notches
and fingers on the sides of the boards. But be warned: There’s no standard for

these, so they usually need to be from the same manufacturer in order for you to
connect them.

Stripboards and perfboards
Stripboards and perfboards are similar to breadboards — they have lots of holes to
connect things together — but they’re designed for permanent connections that are
soldered in place. Stripboards are coated with adhesive strips of conductive
copper that run underneath the holes. Electronic components are soldered to the
strips of copper, providing an electrical connection and a strong physical bond.
Perfboards have metallic pads that surround each individual hole, into which you
can solder parts and which you can solder together to create electrical circuits.
Stripboards and perfboards come in a huge range of shapes and sizes (see Figure
2-5), so if and when you’re ready to go for a more permanent solution, shop around
for the size and type you need.

Figure 2-5: Mini and full-size breadboards and a piece of stripboard.

Prototyping boards

A number of manufacturers offer a printed circuit board that has a prototyping area
for soldering electrical components, plus a multi-pin jack that you connect to the
GPIO socket on your Raspberry Pi. This makes it easy to build circuits and
experiment. Our favorite is the Humble Pi prototyping board, available from
Ciseco (http://shop.ciseco.co.uk). If you’re outside the UK, you should be
able to find it from other online retailers, like Amazon (www.amazon.com).
This board stacks right on top of your Raspberry Pi to make a little sandwich, as
shown in Figure 2-6. It comes in a kit form and is easy to put together. You simply
solder the GPIO socket to the board. If you aren’t confident with your soldering
skills, this is a good kit to practice with, because it’s difficult to damage it by
making soldering mistakes.

Photograph courtesy of Humble Pi
Figure 2-6: A Humble Pi prototyping board stacked on top of a Raspberry Pi.

Project boxes and housings
Many of the projects in this book are built on a breadboard because it’s a fast and
easy way to get going. If you want to protect the project, you can transfer it to a
dedicated enclosure.
Potential project housings are everywhere, and almost anything that can be used as

a small box will do. Electronics suppliers usually stock a range of generic
enclosures, in both metal and plastic. When selecting one of these, make sure that
you have the correct tools to fabricate your housing. If you’re going to mount
switches, buttons, or a display on the project box, you’ll need to be able to cut
through the material cleanly. It’s really difficult to drill a hole into thick materials
and metals without the right saws, drills, and bits, so make sure to select a housing
that you can work with.
Another source of project enclosures is one of the new and popular laser cutting or
3D printing services, such as Pololu Robotics & Electronics (www.pololu.com),
Ponoko (www.ponoko.com), and Thingiverse (www.thingiverse.com). You send
off your design to them, and they’ll ship you your finished custom laser-cut design.
Many of these companies also have templates you can download for boxes and
enclosures.

Soldering safely
When you’re first trying your hand at soldering, it’s a good idea to practice on
some throwaway stuff that you won’t mind messing up. It takes a while to get the
hang of soldering — how long it takes to heat up the solder, how to flow it onto
components, and how to make a good solder joint. You can use a piece of
stripboard to do a few test connections, without worrying about damaging things on
your project.
When soldering, follow these basic steps:
1. Secure the main piece of the work (your stripboard, circuit board, or other
components) to your worktable, or use a pair of helping hands to hold the
piece.
2. Unwind a bit of solder from your spool.
3. Hold the iron as you would a pencil and place it in contact with the
elements that you’ll be soldering.
4. After a moment, press the end of the unwound bit of solder against the
surfaces that you want to join.
This should be right near where the tip of the iron is heating up the components.
The solder should begin to melt and coat the components.
5. After the surfaces are well coated, remove the solder you’re feeding into
the joint.

6. Remove the iron and wait until the surfaces are cool.
7. Examine the joint.
The joint should be shiny. On a stripboard or perfboard, the joint should form a
volcano shape around the wire that you’re soldering and should be
mechanically secure. It shouldn’t wiggle around if you press against it.

Try not to take a long time to solder the joint — ideally, only a few
seconds. Excessive heat can damage the components, especially with
sensitive components such as transistors and ICs. You may not even know
they’re damaged until you realize that your project isn’t working and you have
to track down the problem!

Practice soldering on extra bits of wire or on resistors, because they’re
cheap and easy to work with and it doesn’t matter if you overheat them — you
can just throw them away after you’re finished practicing. If you have any
electronics board lying around, you can practice your desoldering skills, too,
using a desoldering wick (see “Selecting a soldering iron and accessories,”
earlier in this chapter). Try to remove parts from the boards. You’ll quickly
see why it’s a good idea to get your soldering skills up to speed — taking
things off a circuit board is a lot harder than soldering things on!
Figure 2-7 shows an example of soldering components to a perfboard. When you’re
soldering, you apply the iron to the components and then flow the solder into the
heated area. You need to ensure that the components are hot enough for the solder
to adhere to them. You don’t heat the solder and drip it onto the parts. The solder
will liquefy around the components and coat them. When they’re coated, remove
the solder and the iron, and allow the parts to cool. The result should be a strong
connection that you can’t pull apart.

Figure 2-7: Soldering components to a perfboard or stripboard.

Here are some soldering tips to keep in mind:
Make sure your parts and surfaces are clean. In particular, make sure you
clean your soldering iron tip using a damp sponge.
When you first use your soldering iron, and periodically thereafter, coat
the tip of your iron with a little solder — just enough to make it shiny. This
is called tinning and will make it easier to solder your connections.
Don’t overheat parts. You should heat the components just long enough to
make a good connection. If you apply too much heat, some sensitive
components could be damaged.
Safety first. Make sure you aren’t soldering over your hands or another part of
your body. If the solder drops off your work, you could be burned. Remember:
Make sure to wear safety goggles — burning solder can sometimes spit and fly
in unexpected directions.
Be careful not to breathe in the soldering fumes. Work in a well-ventilated
area.

Getting Ready to Build Raspberry Pi
LEGO Projects
Chapters 13 through 15 use the LEGO MINDSTORMS system. LEGO has been a
popular toy for decades. Since the 1980s, it has produced a series of products that

can interface with a computer and be programmatically controlled. Recently, the
company has produced products geared toward robotics experimentation called
MINDSTORMS. You can connect your Raspberry Pi to this latest range of
products. We use the MINDSTORMS system to quickly and easily build complex
projects. The modular building system makes the physical work of rigging up a
robot or computer-controlled object very easy.
The core of the MINDSTORMS system is the MINDSTORMS Intelligent Brick,
which contains the processor and memory required to do programmatic control.
You send programs to the Intelligent Brick, which can then execute complex
instructions, such as reading data from sensors or controlling motor drive systems.
The brick has several ports for input and output, along with a display that you can
program, as well as a number of buttons that can be used for input that you can read
with your Raspberry Pi.
Several kinds of MINDSTORMS systems have been developed over the years, and
the latest version is the MINDSTORMS EV3. If you plan on trying out some of the
LEGO projects, you’ll need to get the most recent version. You can buy the LEGO
MINDSTORMS EV3 kit, which contains both the control brick and a bunch of
extras to build several projects. This kit is pretty expensive (around $350), so if
you want to save a little, you can just buy the control brick, which is about half the
cost of the full kit. You can sometimes find the brick for sale on eBay at a lower
price.
In Chapter 13, we provide more information on the EV3 system and using it with
your Raspberry Pi.

Chapter 3

Focusing on Technique
In This Chapter
Getting acquainted with the Raspberry Pi operating system
Using the desktop and the Linux shell
Brushing up on programming
The easiest way to get know your Raspberry Pi is to play around with the Raspbian
Wheezy operating system and familiarize yourself with what it can do. As soon as
your Raspberry Pi finishes starting up, you can interact with the operating system in
two ways:
From the command-line interface, often referred to as the “shell”
With the graphical user interface (GUI), the “desktop environment” people are
most familiar with, called Lightweight X11 Desktop Environment (LXDE)
Raspberry Pi also has software to support writing your own software. The two
software programming environments we use in this book are Python and C.
In this chapter, we cover the basics you need to know to use the Raspberry Pi
operating system using the command line and LXDE and show what you need to
know to get started writing programs in Python and C. We also show you how to
download and install new software to use when you’re writing code.

Getting Around Your Raspberry Pi
If you haven’t yet set up your Raspberry Pi operating system, head back to
Chapter 1, which covers the details.
After you turn on your Raspberry Pi, you see a number of messages on the screen as
various parts of the operating system start up. When your operating system has
finished starting up, you need to log in. The username is pi and the password is

raspberry. (Make sure you type both of these in lowercase.)

If you’ve set up Raspi-config to bypass logging in with the command line,
you start up into the LXDE. But you can access the command-line environment
running “underneath” LXDE at any time by double-clicking the LXTerminal
icon.
After you log in, you see the command-line interface prompt:
pi@raspberrypi ~ $

The prompt is your Raspberry Pi’s way of telling you that it’s ready to accept your
commands. Anything you type after the $ is accepted as an instruction to do
something. Later in this chapter, we discuss using the command-line interface to
interact with the operating system. For now, type startx and press Enter to launch
LXDE.

Using the desktop environment
The Raspberry Pi desktop environment, LXDE (refer to Figure 1-6 in Chapter 1),
is an application that allows you to easily do all the things that you can do with the
command-line shell. But because it’s a GUI, it’s easier to interact with for many
tasks. Like a regular desktop computer or laptop, your Raspberry Pi comes with
graphical applications that support common computing tasks, like word processing,
creating presentations, using spreadsheets, browsing the web, and playing games.
Just as you see on the desktop of a Windows or Mac, you see several icons on top
of the background wallpaper (most likely, a giant red raspberry icon) that provide
quick access to the most commonly used programs. To launch one of these
programs, you double-click the icon. The programs include the following:
Scratch: A programming language that can be used to create simple programs,
animations, and games.
LXTerminal: A program that gives you access to the command-line interface.
This tool is very handy — you’ll use it often when you’re building the projects
in this book.
PI Store: An online store for finding and downloading software for your
Raspberry Pi.
IDLE and IDLE3: Programs for creating software in Python. You use these to

write to applications in Chapters 5 through 15.
Midori: A web browser.
Debian Reference: A collection of web pages stored on your SD card that
gives you a quick reference to the Raspbian version of Linux. It’s essentially a
handbook for your Raspberry Pi.
Wi-Fi Config: A tool for setting up your Raspberry Pi to use a Wi-Fi network.
It requires an external wireless dongle that you connect to a USB port. We
assume you’re using either a Wi-Fi connection or an Ethernet connection for the
projects that connect to the Internet. If you want to use a wireless connection,
you need to set it up first with this configuration tool.
Python Games: A collection of fun games that demonstrate the capabilities of
the Python programming language.
Along the bottom of the LXDE is the taskbar, shown in Figure 3-1, which is very
much like the taskbar in Windows. You can usually access the taskbar no matter
what programs you’re running. It’s different from the taskbar at the top of the Mac
desktop, which is located at the top of the screen and changes, depending on what
program you’re running.

Figure 3-1: The LXDE taskbar.

The taskbar gives you quick access to the Programs menu, where you can access
other applications you may already be running. The leftmost icon in the taskbar
opens a menu containing a number of programs arranged in categories; it works
like the Windows Start menu. You move your mouse over the categories of
programs you want to use, and submenus reveal the available applications.
In LXDE, you can have several different desktops, all running at the same time.
You can have many programs running on the different desktops, and you can
quickly switch between them using the window icons on the taskbar. In practice,
you probably won’t be using multiple desktops very much because your Raspberry
Pi just isn’t up to the job of running lots of program simultaneously. However, to
keep things consistent with beefier computers that are the cousins of your
Raspberry Pi, you still have the capability of using multiple desktops, just like
other Linux-based systems.

Using the File Manager
You manage files on your Raspberry Pi and any connected storage devices using
the File Manager. The most common operations you need to do involve opening,
closing, saving, moving, copying, and deleting files. You open the File Manager by
clicking the File Manager icon, which is the second icon in the taskbar, shown in
Figure 3-2.

Figure 3-2: The key parts of the File Manager.

The menu items at the top of the window — File, Edit, Go, Bookmarks, View,
Tools, and Help — contain all the operations that you can perform on files on your
system. If you get lost while you’re working with your files or you can’t figure out
how to do something, these menus list all the functions you may need to perform.
Like the Windows File Manager or the Mac Finder, you see a view of the files and
directories on your system (refer to Figure 3-2). You double-click a folder to open
it and double-click files to open them with their default programs.

The left side of the File Manager window contains a list of special types of files
and directories called Places. If you click one of these, the right pane displays the
directories and items that are in that Place. The standard Places you see are as
follows:
folder: The pi folder is where you should store most of your files, including
files that you create for the projects in this book. If you try to store files outside
this folder, you’ll encounter problems, because normal user accounts can save
files only in this folder. You can create any directories you need to in the pi
folder to keep your projects organized.
pi

folder: The Desktop folder contains anything you can see on your
desktop. Any file or folder you place on the desktop appears here.
Desktop

Rubbish Bin: The Rubbish Bin is a temporary holding area for directories and
files you want to delete. You can highlight any file or folder and press the
Delete key to send that file or folder to the Rubbish Bin. If you need the file or
folder later, you can open the Rubbish Bin to get that file (assuming you haven’t
emptied the Rubbish Bin yet). After you’ve emptied the Rubbish Bin, any files
that you placed there will be permanently deleted and you won’t be able to
recover them.
folder: The Applications folder contains the same items that
are listed in the Programs menu.
Applications

Any connected external drives will also appear in Places. Click the triangular
Eject button to safely remove a drive from your system before you physically
disconnect the device.
Beneath the external drives is the Bookmarks pane, which contains a column of
frequently used directories and files. If you have any directories that you use often,
you can drag them into the pane. You can also add a bookmark using the
Bookmarks menu.

You may also notice other items in the Bookmarks pane, depending on how
your Raspberry Pi is configured and whether any additional drives are
connected.

Using the Command-Line Interface

Underlying the LXDE is the command-line interface. Unless you configured your
Raspberry Pi to automatically start up in LXDE, you were in the interface, also
called the shell, right after you turned on your system and logged in.
When you’re in LXDE, you can access the shell by clicking the LXTerminal icon.
This opens a console in which you type your commands. You can even have
multiple shell consoles open at the same time.

If you exit the LXDE, you find yourself at the command line, but with no
desktop, no icons, and no use of the mouse. So, most people access the shell
from within the LXDE and use a console to do things using the command line.
In the shell, you type text instructions at the command-line prompt. Your Raspberry
Pi faithfully executes your commands, such as running programs, managing files,
sending emails, and browsing the web. But like the commands you type, all the
interaction is strictly text based.

You can change the color and size of the text in the console and even adjust
the background color to suit your preferences. Just choose Edit ⇒
Preferences.
The easiest way to get familiar with the shell is to do a few things in the shell and
learn some basic commands. That’s what this section is all about.

The command prompt
The shell shows you it’s ready to do something by displaying the command-line
prompt:
pi@raspberrypi ~ $

The prompt shows you your username followed by an at symbol (@), the system
name, a tilde (~), and the dollar sign ($), which means the system is ready for input.
The tilde means you’re in the “home” directory of the user you’re currently logged
in as, which by default is the user pi.

The default directory for each user account is often referred to as the user’s
“home directory” or “user directory,” which is the directory you see when you

open the File Manager. This can be a bit confusing because there also is a
system directory called “home,” which contains all the default directories for
the user accounts on your system. The home directory for each user account is
labeled with that person’s username and every one is stored in the system
home directory.
If you were in another directory, it would be shown here. The dollar sign means
you’re logged in as an ordinary user and not a superuser; if you were a superuser,
you would see a hash symbol (#).

The directory tree
Like your operating system, all the files and directories are stored on your SD card.
Linux users talk about organizing files into “directories,” rather than “folders,” but
they mean the same thing. They’re just containers to put your files and other
directories into. Just about any directory or file can be put into other directories or
files. But there are thousands of files on your Raspberry Pi, so as with any Linux
system, they’re organized in a sensible way.
Linux file systems are organized as a hierarchy. This hierarchy is often thought of
metaphorically as a tree, because a tree starts with a trunk from which everything
else branches off. Part of this directory tree is shown in Figure 3-3.

Figure 3-3: Part of the Linux directory tree.

At the top level is a single root directory (indicated by /), under which everything
else is organized. Within the root directory are 20 subdirectories in which all your
Raspberry Pi’s files are organized. The most important among these subdirectories

is your user folder, where all your files are stored. Your user folder is called pi by
default; when you open a console in LXTerminal, you can look at all the files in
your pi folder.
You do this with one of the most handy shell commands: list (ls). To show the
files in any directory, type the ls command at the command prompt (what you need
to type is shown in bold):
pi@raspberrypi ~ $

ls

Then press Enter.
A listing of the directories in your home folder is displayed:
Desktop ocr_pi.png python_games
pi@raspberrypi ~ $

The shell prompt shows the default username before the at symbol, which
is why the prompt says pi@raspberrypi. If you change your user or log in with
a different username, it will show that name before the at symbol.
You see the command prompt again, indicating that the system is ready for your
next request. The names of directories are color-coded in blue. If you have any
files in your home folder, they’re shown in purple.
You can take a look at one of the other directories using the ls command, as well.
Try listing the files in your python_games directory:
pi@raspberrypi ~ $

ls python_games

You see a long list of all the files and directories within the python_games
directory. Because it’s below the pi folder in the directory tree (refer to Figure 33), it’s referred to as a subdirectory of your pi directory.
To see the full list of 20 Raspberry Pi directories stored in your root directory
(represented by a forward slash /), type the following:
pi@raspberrypi ~ $

ls /

A full list of the directories is displayed, along with the subdirectories that are
immediate subdirectories of the root.

Any Linux command can also be issued with a number of options. Options
are indicated by a dash and a letter or letters. For example, you can get further

details about a file listing with the long listing option (-l), which formats the
output as a single list and provides further detailed information about each
file. Try it:
pi@raspberrypi ~ $

ls –l python_games

The resulting output shows each file or directory on a separate line and gives
details about who can access it, how large it is, and when it was last modified.
There are dozens of options you can use with the ls command.

You can get more information about any of the Linux commands and their
options by using the Unix Programmer’s Manual, which is always available at
the command line by typing man and the name of the command. Try getting
information about the options available with the ls command:
pi@raspberrypi ~ $

man ls

A description of the ls command is provided, along with all its options. The
information is very detailed and is presented as several pages of text. You use the
up and down arrows to scroll through the text; you can skip forward or backward a
page by pressing the Page Up and Page Down keys on your keyboard (the spacebar
also works to skip forward). Type h to get help; to quit the manual at any time,
simply type q.
Just as with the File Manager in LXDE, you can manipulate files and folders in the
shell. Generally, using the File Manager to do these operations is easier, but
sometimes examining and working with the files in the shell is useful.

You’ll notice that above your pi directory is a directory called home. This
is a bit strange, because the pi directory is your home directory. That’s
because the default username is pi, and you are in the home directory for the
user pi. But along with your pi directory, the home directories of any other
user accounts are also located within the /home directory.
The commands you issue at the command prompt are executed from the directory
you’re located in. Remember: Your home directory is represented with a tilde (~)
in front of the dollar sign ($) prompt. You can move to another directory with the
change directory (cd) command. Try it:
pi@raspberrypi ~ $ cd python_games
pi@raspberrypi ~/python_games $

You’re now within the python_games directory, and the prompt has changed to
show the directory you’re currently in: ~/python_games $. Type ls, and you get
the same listing of files and folders as shown earlier.
The pi directory is above python_games in the directory tree and is referred to as
its parent directory. To go back to the parent directory, type cd with a space and
then two dots after it:
pi@raspberrypi ~/python_games $
pi@raspberrypi ~ $

cd ..

The prompt now shows that you’re in your home directory (pi) with a tilde (~).
The two dots (..) are a sort of shorthand to tell the system to go up a level without
your having to type out the full name of the parent directory. Keep going up the
hierarchy, and you can go right up to the root directory that everything branches off
from.

The file path
To tell the system to do something with a file or directory, you either need to be in
the same directory as the file or folder you’re working with, or you need to specify
the file path of the file that you want to work with. The file path is the full location
of the file within the directory tree, separated by forward slashes (/). For example,
the file path of your python_games directory from the root directory is
/home/pi/python_games

You can use the file path to work with files in any part of the system, no matter
where you’re currently located. For example, from your home directory, you can
get information about a file in another directory with the file (file) command.
To try this, change to your home directory. (If you aren’t in your home directory,
you can get back to your home directory from anywhere, by typing cd ~.) From your
home directory, you only need to specify the file path as you would reach it, from
home. Try it, by looking up the details about the cat.png image file that is located
in the subdirectory python_games:
pi@raspberrypi ~ $ file python_games/cat.png
python_games/cat.png PNG image data, 125 x 79, 8 bit color RGBA, non-interlaced

The system responds with details about the cat.png image file that is located
below your current home directory.
Just about any command can be used in this way. In fact, you already used this with
the ls command earlier.

Directories
You’ll want to organize your stuff into directories so you can find and use it.
Creating new directories is easy. Try creating a directory in your home directory
called stuff with the make directory (mkdir) command:
pi@raspberrypi ~ $

mkdir stuff

If you do a directory listing, you see a new folder:
Desktop python_games stuff
pi@raspberrypi ~ $

You can easily make multiple directories by separating their names with a
space.
Because you’re currently in your home directory (pi), the stuff directory was
created in it. If you wanted to create a new directory in python_games, you would
need to move to that directory, or specify its file path when you used the mkdir
command. For example, you could create a stuff directory in python_games even
if you’re currently in your home directory by typing the following:
pi@raspberrypi ~ $

mkdir python_games/stuff

To make sure it worked, you type:
pi@raspberrypi ~ $

ls python_games

Your new stuff folder will be listed (highlighted in blue) among the other files
and directories.
Getting rid of directories you don’t need is also important, and easy. Use the
remove directory (rmdir) command to delete the folder you just created in
python_games. Type the following:
pi@raspberrypi ~ $

rmdir python_games/stuff

A directory listing of the directory will confirm that stuff is gone.

Be careful when using the rmdir command. After you’ve deleted a
directory, there’s no way to easily recover it. To prevent a disaster, rmdir
won’t delete a directory unless it’s empty. You have to remove the contents of
a directory before deleting it (although there is a way around this: using the -ignore-if-non-empty option).

Files
The file command shows you information about files in your directories. You can
also move and remove files from the system. To try it out, create a dummy text file
to play around with.
It’s easy to create new files from the command line. This is something you may do
when you’re writing short bit of text or you want to try out a quick snippet of code.
To create a new text file, you use a text editor.
There are legendary arguments in the Linux community about which is the best
command-line text editor. One of the simplest and easiest editors is nano (which is
a version of its ancestor, pico). Create a new dummy file using the nano editor by
typing the following:
pi@raspberrypi ~ $

nano dummy.txt

The nano editor is a full-screen text editor that takes up the entire LXTerminal
window while you’re using it, as shown in Figure 3-4.

Figure 3-4: Creating a dummy file in the nano editor.

Type in some text for your new file; it appears on the first line of the editor:
This is a dummy text file.

Along the bottom of the screen are the commands available to you. The ^ character
means to use the Ctrl key on your keyboard, so to exit the editor you press Ctrl+X.

When you do so, you’re asked if you want to save the file. In the status bar along
the bottom of the screen, nano asks the following:
Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES)

Because you want to save your changes, type y and press Enter to confirm. Now, if
you do a directory listing you’ll see your new dummy.txt file.
One of the most popular commands for reading files is the concatenate (cat)
command. You can use it to display the contents of any file on the screen. Take a
look at your dummy file by typing the following:
pi@raspberrypi ~ $ cat dummy.txt
This is a dummy text file.
pi@raspberrypi ~ $

You can use the cat command to display the contents of any file, but unless
it’s a text file, you’ll probably see gibberish on the screen.
Now you can move your shiny new dummy text file to the stuff folder. To do so,
use the move (mv) command. You follow the command by the name of the file you
want to move, a space, and the location where you want to put the file. Move it to
your stuff folder by typing the following:
pi@raspberrypi ~ $

mv dummy.txt stuff

Do a directory listing of stuff to confirm it’s there:
pi@raspberrypi ~ $
dummy.txt
pi@raspberrypi ~ $

ls stuff

Removing a file is just as easy as moving it. You use the remove (rm) command.
Deleting files can be risky business, so one way to ensure you’re removing the right
file is to use the confirmation option (-i) and set output to verbose mode (-v). You
don’t have to use the - sign before each option:
pi@raspberrypi ~ $ rm –iv stuff/dummy.txt
rm: remove regular file 'stuff/dummy.txt'? y
removed 'stuff/dummy.txt'
pi@raspberrypi ~ $

Type y to confirm the deletion. Your file has now been deleted, and you’ve
received confirmation. Safe and easy!

Be careful when using the rm command. After you’ve deleted a file, there’s

no way to easily recover it. This is a good reason to make the confirmation
option a habit.

Programming Like a Pro
To get the most power and flexibility out of your Raspberry Pi, you’ll want to write
your own programs, which is what this book is all about! We use two programming
languages — Python and C — as a way to get you started with your own Raspberry
Pi projects. We cover these languages in this section, and provide some basic tips
on how to use text editors to write and update your code.

Python
Python (named after the popular Monty Python comedy series) is a powerful
programming language that is relatively easy to learn and is widely used by big
companies like Google and Amazon. It’s easy to use and, unlike many programming
languages, easy to read. We use Python for several of the projects in this book, so
you need to know the basics, even if you’re only going to copy the code we provide
for you.
Python is an interpreted language, meaning that the code is written in a manner
that is easy for humans to read rather than in native machine code. When the
program is in the process of being executed, the Python command interpreter
translates it into machine code for your operating system. By contrast, C is a
compiled language and uses a compiler to prepare your code in advance for the
operating system
To write programs in Python, you can simply create a text file using the commands
that Python understands and save the file with the filename suffix .py. You don’t
have to have the .py suffix, but it’s a good reminder that the file is a Python
program. You can run the program within the Linux shell at the command prompt by
sending your file to Python’s interpreter. The command interpreter (which is, itself,
an application) reads through the code and executes the instructions you’ve
programmed. You do this by simply typing python and then the filename.
Your Raspbian Wheezy distribution comes with a couple versions of Python:
versions 2.7 and 3. Python 3 contains a number of modifications of the syntax and
capabilities of Python 2.7, and programs written for it may not by entirely
compatible with Python 2.7. All the programs in this book are compatible with
Python 2.7.

You can figure out which versions of Python you have from the command
line by typing python –V.
The classic way to start learning a programming language is to create a simple
program to print the phrase “Hello world!” The code to do this would be the
following:
print("Hello world!")

If you were to save this instruction in a text file called hello.py, you could run it
with Python’s command interpreter.

Refer to the “Files” section earlier in this chapter to review how to create
a text file from the command line.
To run the program with Python’s command interpreter, you would type the
following on the command line:
pi@raspberrypi ~ $
Hello world!
pi@raspberrypi ~ $

python hello.py

This statement tells your operating system to use the Python interpreter to read
through the file and follow the instructions. The result is printed on the screen.
You can also use the interpreter (sometimes referred to as the shell) in interactive
mode. Just as you can use the system shell to issue commands for the system to act
on, you also can use the Python shell to issue commands for the Python interpreter.
This can be a bit confusing, because both the system shell and the Python shell are
text based. When you’re using the desktop, they’re in different windows.

To avoid confusion between the system shell and the Python shell, pay
attention to the command prompt. If the prompt is pi@raspberrypi ~ $ (or
any other username before the @ symbol), you’re in the system shell. If the
prompt is >>>, you’re in the Python shell.
You open the Python shell by typing the following:
pi@raspberrypi ~ $

python3

You see version information followed by the interpreter’s prompt (>>>):

Python 3.2.3 (default, Mar 1 2014, 11:53:50)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Type the same command above and observe the output. Note that the commands you
type are case sensitive:
>>> print("Hello
Hello world!
>>>

world!")

The shell executes your command. Then the prompt returns and is ready for your
next instruction. To leave the interpreter, press Ctrl+D.

IDLE
Writing programs as text files is very easy, but when your programs start to get
more complicated, it’s helpful to have a tool to support the code-writing process.
In this book, we use a special programming application called IDLE (short for
Integrated DeveLopment Environment), which provides a sort of sandbox where
you can write code and test it to see if it works correctly. IDLE is an interactive
graphical editor, so you have all the benefits of using your keyboard and mouse in
LXDE.
There are two versions of IDLE on your Raspberry Pi. (IDLE3 is for Python 3,
which is what you use for programs in this book.) Their icons are on the desktop.
Start the IDLE Python shell by clicking the IDLE icon. The display looks much the
same as the interactive shell (see the preceding section), as shown in Figure 3-5.

Figure 3-5: Using IDLE as an interactive Python shell.

IDLE offers several benefits over a text editor:
It checks that your code is correctly formatted.
It highlights key commands.
It checks your syntax.
By design, Python is picky about the position of text in your code and IDLE checks
this, too.
Try out the “Hello world!” program again, this time using the IDLE editor. Type
the following:
>>>

print("Hello world!")

Then press Enter. Notice that as you type the program, key instructions are
highlighted in orange, and the text between quotes is made green. This is handy if
you forget to type commands in the correct case. For example, if you type Print
with a capital P, the command won’t turn orange, and you’ll know you have a
problem. Functions (such as print) are in purple; other known terms (such as for)
are in orange.
To create a runnable Python program in the shell, you change from interactive mode
to script mode. Change to script mode by choosing File ⇒ New Window. A blank

window opens and is ready for your code, as shown in Figure 3-6.

Figure 3-6: Using IDLE to write Python programs.

Start your program with a description of what it is. You enter this as a comment on
the first line, using a hash symbol (#). Anything after the hash symbol is ignored by
the interpreter, so it’s used for making remarks about your code.
# New Python program
print("Hello world!")

Save your new program by choosing File ⇒ Save As. Use the name
helloworld.py and save it in your home directory. You can run the program by
choosing Run ⇒ Run Module. Alternatively, you can press F5.
You can also run this in a shell console by typing the following:
pi@raspberrypi ~ $

python helloworld.py

Finding out more about Python
You know the basics you need for creating the projects that use Python. Chapter 4 covers important
programming concepts for both C and Python, but this book isn’t remotely big enough to
comprehensively cover how to learn Python. For that, you can take a look at Python For Dummies, by
Stef Maruch and Aahz Maruch (Wiley), which is an excellent, in-depth guide. The ultimate resource
for anything to do with learning and using Python is the project’s website (www.python.org). If you want
to get started exploring what you can do with Python, there are a number of online learning tutorials at
Codeacademy (www.codeacademy.com) that provide exercises and interactive help.

C
Some of the programs in this book are written in C. Unlike Python, C is a compiled

language, which means that the human-readable code is converted to machine code
in advance and saved as a binary file. As with Python, you can create code in a text
editor and then run it from the command line. Alternatively, you can use an
integrated development environment (IDE) to write your code; many people use
one called Geany (see “Using apt-get,” later in this chapter).
Compiling C programs entails working with four kinds of files, each with a
different filename suffix. The suffix helps you determine what a file is without
having to open it. The file types are as follows:
Source code: The files you work with to write your code. Source code
filenames end in .c.
Header files: Files that contain declarations of functions and references to
functions that may be outside the source code, and information for the C
compiler’s pre-processor. Header filenames end with .h.
Object files: The output of the compiler; they contain function definitions in
binary form, but they aren’t executable. Object filenames end in in .o.
Binary files: Also called executables, these contain the runnable code that is
ready to be used. They don’t usually have a suffix. These are the same .exe
files on Windows systems.
When you finish writing the source code, you compile it, which generates a binary
file. You can then run this file from the command line.
Try using nano to write a quick “Hello world!” C program called (not so
creatively) hello.c, as shown in Figure 3-7. Create it in your /stuff directory so
that it isn’t jumbled with your other directories and files. Type the following:
cd stuff
pi@raspberrypi /stuff $

nano hello.c

Figure 3-7: Writing a C program using nano.

The nano editor launches and is ready for your program. Type the following:
#include 
void main(int argc, char *argv[])
{
printf("Hello world!\n");
return;
}

The first thing you notice is that nano understands when you’re typing C commands
and highlights them in different colors for you.
In the first line, you instruct the compiler to use a header file called Standard IO
(stdio.h). Unlike Python, the hash symbol (#) is an instruction for the compiler’s
pre-processor to use the standard external header file that handles input and output.

The stdio.h header file is one of many built-in header files that contain
common and useful functions. It has all the code needed to send your output to
the screen — that way you don’t have to write this! The pre-compiler knows
where to find the built-in set of header files on your system. It locates them
automatically when you compile your program. If you need to include other
header files when you compile your code, you usually need to place these
files in the same folder as your source-code file.
The next section of your source code creates a function called main that does the

work of printing “Hello world!” It’s not important to understand exactly how this
works for now, because we’re focused on compiling the code. Save the code by
pressing Ctrl+X and typing y to save the changes.

Compiling and running your C code
On the command line, you can compile the code. Type the following:
gcc hello.c –o hello

After a very short delay, you see your command prompt again, and your file is
compiled. Do a directory listing to confirm it’s there:
pi@raspberrypi /stuff $
hello hello.c
pi@raspberrypi /stuff $

ls

Notice that the executable binary file is highlighted in green and the source code is
not. The gcc command launches a program called the GNU C compiler. (GNU is
the open-source software project that eventually led to the creation of Linux.) The o hello option indicates that the binary executable file is to be called hello.
Now you can run your program. To do so, type the following:
pi@raspberrypi /stuff $
Hello world!
pi@raspberrypi /stuff $

./hello

Congratulations! You’ve just written, compiled, and run your first C program!
You usually need to use the dot-slash (./) to execute your programs.
You don’t need to know more about C to get the projects in this book running. C is
one of the granddaddy programming languages, and learning it is a huge topic. C
For Dummies, by Dan Gookin (Wiley), is a great starting point.

You may want to use an IDE to write your C programs, just as you can with
Python, using IDLE. Geany is an IDE included with your Raspbian Wheezy
distribution that many people use. To use it, you need to use a program called
apt-get (see the following section).

Using apt-get
Sometimes you need to install other libraries of code (also called packages) or
add new programs to your system. There’s an easy way to do this from the
command line using a tool called apt-get. Apt-get is a simple command line
interface tool for managing, downloading, and installing packages and updating

source code for packages from their repositories on the Internet. To use apt-get to
update source files, you must have your Raspberry Pi connected to your network
and have a connection to the Internet.
To install the Geany IDE, type the following:
pi@raspberrypi ~ $

sudo apt-get install geany

The superuser do (sudo) command is required for certain operations that need
special privileges — in this case, accessing files in a directory that’s only
accessible to administrators. The next instruction launches apt-get and instructs it to
install the Geany package on your system.
You see various status messages as apt-get prepares for the installation, checks the
Internet for updates to the source files, downloads them, and installs the program.
When it’s finished, you can find Geany in the Programming folder, as shown in
Figure 3-8. Installing other packages and code libraries is done in a similar way.
Geany is a very powerful IDE, and there is a lot to learn — too much to explain
here. You can find more information on the Raspberry Pi website.

Figure 3-8: The Geany IDE is installed in your Programming folder.

When apt-get is needed for the projects in later chapters, we provide
instructions on which packages you need to download and how to install them.

Troubleshooting
You’ll be writing and copying a lot of code in the process of building these
projects. As you do, there’s always a chance that something can go wrong. In the
case of the projects that involve building something, the problem could be with
your software or your hardware. Here are a few things you should check:

Your code: Make sure you type the code correctly. The color coding in your
IDE can help you make sure you haven’t introduced any errors. If you cut and
pasted or downloaded the code from this book’s companion website, make sure
there weren’t any typos introduced in the process.
Your connections: If you aren’t able to download a file or can’t get apt-get to
work, check your network connection. You may think you’re online, but there
could be a problem.
For the projects that require physically building something, there is likely to be
a lot of wiring or soldering. Make sure none of your connections came loose
while you were working.
The Raspberry Pi forums (www.raspberrypi.org/forums ): The Raspberry
Pi forums are where the whole Raspberry Pi community shares their
knowledge, experience, problems, and solutions. Here, you should be able to
find the answer to your problem. Because Raspberry Pi is aimed at newcomers
to programming, people are very friendly on the forums and no question is too
basic. Newbies are welcome.
Stack Overflow (www.stackoverflow.com ): One of the best resources you
can find online. Here, thousands of experienced programmers who have trouble
with their code post their questions to the community. People vote on the
quality of answers, and the better answers rise to the top of the list. You can
search the forums for postings related to your problem or post a new question
about it. People within the community will likely answer your question quickly.

Chapter 4

The Raspberry Family
In This Chapter
Understanding the evolution of the Raspberry Pi
Exploring the options of the general-purpose input/output (GPIO) port
Discovering the secrets of the revision number held in your Pi
Finding the impact of your Raspberry Pi model on projects in this book
In the beginning was the Raspberry Pi, and all was good. Then the Pi begat the
revision 2 with more memory, which begat the Model A, which begat … well, you
get the idea. With all this begating, we want to introduce you to what the Raspberry
family looks like and how what you have may affect the projects you want to do. In
this chapter, we show you how to understand the differences in the versions of
Raspberry Pi that have been produced. By looking at the memory, GPIO, and video
and processor variations that have been produced, you can see how the Raspberry
Pi has improved over the years.

In the Beginning: Looking at the
Evolution of the Raspberry Pi
The original Raspberry Pi, like so many firsts, did not need a qualifier to its name,
but it had one. It was known as the Raspberry Pi Model B. The second version was
known as the Model A. It’s impossible for end-users to complete their own
upgrades, so the two versions are separate models.
The Model A has no Ethernet socket, only one USB connector, and typically less
memory; as a consequence, it’s about $10 cheaper than the Model B. Also, the
Model A consumes about one-third less power than the Model B, which can be
important for battery-powered standalone applications.

Model B was first?

It might sound odd that the first Raspberry Pi was the Model B (not the Model A), but here’s the story
behind that name: Most of the people who made up the driving force behind the Raspberry Pi grew up
in the UK, where another Cambridge-designed computer — the BBC computer, designed by Acorn
Computers — was ubiquitous in education. Originally, there were two versions of the BBC computer:
the Model B, and a cut-down version called the Model A.
From the start, the makers of the Raspberry Pi wanted to produce two models. They figured that
most people would want the Model B version, as they did with the old BBC computer, so that’s the
one they produced first.

The Raspberry Pi Foundation, the creator of the Raspberry Pi, is a registered
charity with the aim of promoting computer literacy. They worked for many years
developing prototypes before they released anything. The original Raspberry Pi 1
Model B set the benchmark for what a Raspberry Pi was, and it’s great credit to the
developers that each new variant on the Raspberry Pi had improvements but did
not break the compatibility with the previous models.
One confusing aspect of the Raspberry Pi is that changes and improvements to the
Pi were not always accompanied by a change in name, so users are never quite
sure what they’re buying. We want to try to clear that confusion: There have only
been three basic named versions of the Raspberry Pi to date — the original (or 1),
the plus (+), and the 2. Given that there is a Model A and a Model B variant for
each model, that means there are six named types of Raspberry Pi (see Table 4-1).

Table 4-1: Named Types of Raspberry Pi
Name

Release Date

Memory

Notes

Raspberry Pi
1 Model B

February 19,
2012

256MB

The original Raspberry Pi.

Raspberry Pi
1 Model B
Revision 2

September 5,
2012

512MB

Changes in the thermal fuses on the USB. Addition of unpopulated
connector P5 for accessing more GPIO pins. Three changes to the
GPIO pins on connector P1.

Raspberry Pi
1 Model A

February 4,
2013

256MB

The first cut-down version of the Raspberry Pi.

Raspberry Pi
1 Model B+

July 14, 2014

512MB

More I/O pins than previous models and a micro SD card.

Raspberry Pi
1 Model A+

November 10,
2014

256MB

Same number of I/O pins as the B+.

Raspberry Pi
2 Model B+

February 2,
2015

1GB

The first version with a quad-core processor.

Raspberry Pi
2 Model A+

Not expected Not known
until sometime as of this Cut-down quad-core Raspberry Pi.
in 2016
writing

Deciding Which Raspberry Pi to Buy
Only immediately after the launch of a new version of the Raspberry Pi do you
have any choice in what to buy. With backward compatibility and no change in
price, there is little demand for older models. So your only real choice is whether
to get a Model A or a Model B. In most cases, this is a no-brainer — the Model B
is the obvious choice. You should only buy a Model A if you have some specific
reason for doing so (for example, the cost, smaller form factor, or lower power
consumption).

Memory
The memory chip used on every Raspberry Pi 1 was in an unusual form factor in
the field of computers. It was the so-called chip-on-chip system — the processor
chip had contacts on both sides (one set on the base to connect to the printed circuit
board, and another set on the top for the memory chip). The memory chip was then
soldered directly onto the processor chip to give a very compact design, only 1mm
thick. This technique is more usually found in smartphones where space is at a
premium. With the Raspberry Pi, it had the unfortunate effect of limiting the amount
of memory that could be fitted, because this sort of memory chip was only
available in a few memory sizes, with 512MB being the biggest.
The latest Raspberry Pi 2 versions have discontinued that trend and allowed a
larger memory chip to be fitted. The Raspberry Pi 1 Model B+ and the Raspberry
Pi 2 Model B+ look almost identical from the top, but on the underside you can
clearly see the separate memory (the large black block), as shown in Figure 4-1
and Figure 4-2.

Figure 4-1: Raspberry Pi 1 Model B+ (left) and Raspberry Pi 2 Model B+ (right), top view.

Figure 4-2: Raspberry Pi 1 Model B+ (left) and Raspberry Pi 2 Model B+ (right), bottom view.

General-purpose input/output (GPIO)
The plus models have 40-pin dual-row header pins to allow access to the generalpurpose input/output (GPIO) port pins. Some of these pins are needed to turn the
processor into a computer system by accessing the SD card and Ethernet and USB
peripherals; others of the spare pins are brought out for the user. The GPIO pins
carry logic signals that the computer can control or read and are how you can get
the Raspberry Pi to switch outputs and sense inputs. Not all these pins are GPIO
pins; there are several instances of 5V, 3V3, and ground. The pre-plus models had
only a 26-pin connector and fewer pins were brought out. Figure 4-3 shows the pin
out of this connector.

Figure 4-3: The GPIO connector pin out.

With the exception of the original Issue 1 of the Raspberry Pi, the GPIO pins have
remained on the same physical pin of the connector through subsequent revisions.

Each GPIO pin can be switched inside the processor to perform a different
specialist function. This has led to some people designating these pins to these
functions, and then labeling the remaining pins as GPIO from 0 upward. In our
opinion, this is stupid because it adds an extra, pointless, totally artificial
layer of obfuscation that you have to wade through. Another form of confusion
arises when some people label these pins with the physical pin number on the
connector. So, for example, they refer to pin 3 in the software and that gets
translated internally to GPIO 2. That’s a little more understandable, but it’s no
substitute for referring to GPIO pins as what they are in the processor.

Connection choice
There is an almost bewildering number of commercial boards, allowing you easy access to the GPIO
contacts. Also, there are many designs you can make yourself. These designs tend to fall into two
broad categories: those that mount a board directly on the Raspberry Pi’s board, and those that
connect to the connector with ribbon cable.
Using a direct connector limits the size of the attached board, whereas using ribbon cable does not.
However, the ribbon cable connector is specific to the number of pins you have. A 26-way ribbon
connector won’t fit on a 40-pin header, whereas a 26-way direct connector will.

Video
All models of the Raspberry Pi have high-definition multimedia interface (HDMI)
video as a standard output. If you have a monitor that takes a VGA connector,
you’ll have to get an HDMI-to-VGA adaptor. If you have a normal TV, you can
connect the Raspberry Pi to it using the RCA connector.

This RCA connector seemed to have disappeared in the plus models and
the Issue 2, but it’s still there. It’s hidden in what looks like the audio jack, in
a TRRS (Tip, Ring, Ring, Sleeve) system. Not all TRRS leads are wired the
same, so you have to check if the wiring is compatible with the Raspberry Pi.
Go to www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-model-b3-5mm-audiovideo-jack for details.

Processor
There is a big leap in the performance of the Raspberry Pi when going to the
Raspberry Pi 2 from the Raspberry Pi 1. This is because of a change in the
processor chip. The Raspberry Pi 1 used a processor with an ARM6 core; the
Raspberry Pi 2 uses a processor with an ARM7 core. The difference between these
two processors, as far as performance is concerned, is mainly due to the efficiency
with which high-level language instructions, like the C language, can be translated
into the machine code instructions the processor actually performs. This
performance difference is further boosted by the fact there are four cores in the
Raspberry Pi 2 processor, potentially allowing it to run four independent
processors at the same time. In addition, the ARM6 was run at a 700 MHz clock
speed, and the ARM7 runs at 900 MHz.
The processor in the Raspberry Pi 2 also has a larger level-2 cache. This is an area
of very fast on-chip memory where machine code instructions are queued up
waiting to be processed. Instructions are transferred to the on-chip memory from
the slower off-chip memory in bursts, which are more efficient than single memory
accesses, which can speed up processing, in some cases considerably.
The bottom line: The Raspberry Pi 2 runs faster than the Raspberry Pi 1. How
much faster depends on many factors, but faster by one and a half to six times is the
sort of range you’re looking at. This definitely elevates the Raspberry Pi into a
useable replacement for a desktop machine.

When the Raspberry Pi 2 was launched, a lot was made about the
backward compatibility, but this didn’t apply to any code that accessed the
GPIO pins — all that kind of code stopped working. The reason was that in
the new architecture, all the peripherals — including the GPIO — were
located at different addresses in the processor’s memory map. Fortunately,
most users access these peripherals through one of a number of libraries, so
when the library you used was updated, the original programs worked again.
However, because most libraries are maintained by individuals, some of the
libraries didn’t get updated. The situation is very fluid, so check to make sure
that any library you want to use has been updated for the Raspberry Pi 2. If it
has, it should work with both models of Raspberry Pi.

Figuring Out Which Raspberry Pi You

Figuring Out Which Raspberry Pi You
Have
You may not know exactly which Raspberry Pi you have. You can easily see if you
have a 26-way or a 40-way GPIO connector, but how can your program tell which
pins are available?

In Linux, everything is a file, so there is a way of finding out exactly what
you have. Just go to a command-line prompt and type the following:
cat /proc/cpuinfo

On a Raspberry Pi 1 system, you see the following:
Processor: 0
model name : ARMv6-compatible processor rev 7 (v6l)
Features : swp half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture : 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2708
Revision : 0010
Serial : 00000000a5fb87e8

The interesting thing is the revision number, which tells you a lot about your
Raspberry Pi. Table 4-2 tells you what the revision number means. The words in
parentheses are the factories where the Raspberry Pi boards were made.

Table 4-2: Raspberry Pi Revision Numbers
Revision Number Raspberry Pi Version
0002

Model B Revision 1.0

0003

Model B Revision 1.0 + Fuses mod and D14 removed

0004

Model B Revision 2.0 256MB (Sony)

0005

Model B Revision 2.0 256MB (Qisda)

0006

Model B Revision 2.0 256MB (Egoman)

0007

Model A Revision 2.0 256MB (Egoman)

0008

Model A Revision 2.0 256MB (Sony)

0009

Model A Revision 2.0 256MB (Qisda)

000d

Model B Revision 2.0 512MB (Egoman)

000e

Model B Revision 2.0 512MB (Sony)

000f

Model B Revision 2.0 512MB (Qisda)

0010

Model B+ Revision 2.0 512MB (Sony)

0011

Computer Module (Sony)

0012

Model A+ Revision 2.0 256MB (Sony)

You may notice that revision 0011 is the Computer Module, a Raspberry Pi with a
very different form factor. This is a Pi built on a small printed circuit board (PCB)
with all the connections brought out on PCB edge connectors. This then plugs into a
base board of your own design and is meant for industrial or commercial
applications. There is also a blank breakout board to do your development on.
If you look at the CPU info on the Raspberry Pi 2 system, you see four processor
blocks in much the same format as the Raspberry Pi 1 — one for each core. The
last three entries look like this:
Hardware : BCM2709
Revision : a01041
Serial: 000000001664c635

The revision number is in an entirely different format with different groups of bits
having specific meanings. A collection of bytes is known as a word, and the
processor in the Raspberry Pi uses words that are four bytes or 32 bits long. Bit 23
in the revision word tells you if the revision number is in the old format or the new.
For a new format revision number, this bit will be a 1. The interpretation of the
revision number under the new format is given by splitting the word up into bytes
in this manner:
SRRR MMMM PPPP TTTT TTTT VVVV

Where
S

is one bit giving the revision scheme (0 = old, 1 = new).

is three bits indicating the RAM size (0 = 256MB, 1 = 512MB, 2 =
1,024MB)
RRR

is four bits giving the manufacturer (0 = Sony, 1 = Egoman, 2 = Embest, 3
= Unknown, 4 = Embest).
MMMM

PPPP

is four bits giving the processor (0 = 2835, 1 = 2836).

is eight bits giving the type (0 = A, 1 = B, 2 = A+, 3 = B+, 4 = Pi 2
B, 5 = Alpha, 6 = Computer Module).
TTTT TTTT

VVVV

is the four-bit version or revision (0–15).

So, the hex number a01041 in the preceding readout gives the following bit pattern
when you write it out in binary:
1010 0000 0001 0000 0100 0001
SRRR MMMM PPPP TTTT TTTT VVVV

For a quick hexadecimal-to-binary converter and a conversion table, check
out www.binaryhexconverter.com/hex-to-binary-converter or search
the web for “convert hexadecimal to binary.”
So, breaking this down:
S

is 1, which means it’s the new revision scheme.

R

is 010, which is 2 in binary, and that means the RAM is 1,024MB.

M

is 0000, which is 0 in binary, and that means the manufacturer is Sony.

P

is 0001, which is 1 in binary, which means the processor is 2836.

T is 0000 0100, which is 4 in binary, which means it’s a Raspberry Pi 2 Model
B.
V is 0001, which is 1 in binary, which means it’s version 1.

For information on how to read binary, check out www.dummies.com/howto/content/digital-electronics-binary-basics.html.

There is a warranty bit that gets set if you attempt to overclock the system.
This is to prevent people from overclocking the Raspberry Pi, breaking it, and
then claiming it was faulty. This warranty bit is bit 24, but when the
Raspberry Pi 2 was introduced, the faster clock and higher voltage required
for the processor’s core was automatically setting this bit, so the warranty bit
has been changed to bit 25 for the Raspberry Pi 2. If you’re buying a
Raspberry Pi secondhand, check this bit before parting with your cash.

For all the projects in this book, you can use any of the versions of the
Raspberry Pi. Newer models will run faster, but this shouldn’t have much of
an impact because physical computing is heavily involved with human
interaction. If you find that something runs too fast, a simple small sleep
command will throttle back the speed.
On the upside, faster speed is useful if you’re using graphics programs like Gimp to
prepare graphics for your programs. And a quad-core machine holds out the
possibility of running several programs simultaneously at full speed.

Part II

Working with LEDs and Switches

Find out how to recognize and deal with contact bounce in a free
article at www.dummies.com/extras/raspberrypiprojects.

In this part …
Make projects using LEDs and switches.
Build a sauce bottle simulator.
Construct a bug stomp simulator.
Learn to drive the WS2812b multicolored LED.
Hack a PCB to make the Light Fantastic interface.
Program four full-color games with the Light Fantastic.

Chapter 5

The Sauce Bottle Game
In This Chapter
Making a sauce bottle simulator
Reading a digital input
Creating realistic graphics
Understanding the beginnings of the Pygame framework
The project in this chapter is just about the most fun you can have with a single
contact input. Whether you call it catsup, ketchup, or sauce, it’s a thixotropic fluid,
which means it changes its viscosity (runniness) according to the agitation of the
fluid.

The Game
The game is simply an interactive sauce bottle where shaking can be sensed by the
Raspberry Pi. This is mirrored on the screen by a graphic of the same bottle.
However, on the screen, the sauce bottle can be seen to slowly empty in response
to the shaking. The idea is to get the bottle emptied in the shortest possible time.
This game is a great introduction to the interaction of hardware and software.
Figure 5-1 shows the hardware bottle next to a monitor showing the graphic bottle.

Figure 5-1: The finished game.

Parts
The parts you need for this project are simple, and you can substitute a wide
variety of objects if you don’t have exactly the same parts we use. Here are the
parts you need:
Plastic sauce bottle: We used a Heinz Tomato Ketchup bottle, but you could
use another similar plastic bottle.
6½ feet (2 meters) of twin core cable: We used microphone shielded cable.
Tilt switch: The tilt switch consists of a metal ball in a small tube. When the
ball rolls down one end, it shorts out the two wires leading into it.
2 single-pin header sockets: You can use any method of connecting to the
general-purpose input/output (GPIO) pins.
Hot melt glue: You’ll need a hot melt glue gun to apply this.
Silicon sealant

Schematic
The schematic of this circuit (shown in Figure 5-2) is almost trivial, so it’s easy to

follow.

Figure 5-2: The sauce bottle schematic.

Always make a schematic whenever you make anything electronic, so you
have something to check your construction against.

It doesn’t matter which way around you wire the connections on the switch.
They just connect and disconnect the GPIO pin 2 to ground. This pin is
normally used for the I2C interface. On the board, it’s connected to a resistor
connected to the 3V3 supply. This is known as a pull-up resistor. It ensures
that the logic level on this pin is normally a logic 1, unless the pin is
connected to ground, in which case it becomes a logic 0.

Construction
To build this project, follow these steps:
1. Drill a hole in the top of the bottle for the wire to go in.
Our wire was 1.5mm in diameter so we drilled a 2mm hole.
2. Push the wire through the hole into the bottle.
This step is critical. Pushing in the wire from the outside of the bottle is easy.
Pushing the wire through the hole from the inside of the bottle is impossible.
3. With silicon sealant, glue the tilt switch onto the small flexible membrane
on the bottle lid, which normally holds back the sauce.
Allow the sealant to set.
4. After the sealant sets, wire the screened cable to the tilt switch, as shown
in Figure 5-3 .

If you haven’t used screened cable before, just know that you need to
strip off the outer insulation and twist the screen wires together between your
fingers. Then tin them by applying a touch of solder, and watch it soak in
between the wires. Then trim off the screen a bit to make it tidy. Now strip the
inner insulation off the core, twist the wires together, and tin them again. Then
make the soldered joints with the switch.
5. Apply some hot glue over the tilt switch and run it around the base of the
cap.

Don’t overfill it or you’ll never get the screw bottle back on the cap.
6. Screw the cap back onto the bottle and then put a blob of hot glue where
the cable comes out of the bottle to fix it.
Make sure you leave enough slack in the bottle to remove the cap if any repairs
are needed.
7. Attach the other end of the cable to your Raspberry Pi.
You can do this in a variety of different ways with various breakout boards.
Because there are only two wires, we used two single-pin sockets and shells
and connected them directly to the GPIO connector, as shown in Figure 5-4. We
soldered the end of the cables to these two wires and covered the joint with
some heat-shrink cable, but you can use insulating tape if you prefer. Then we
carefully placed them on the GPIO connectors before booting up the Raspberry
Pi.

As a rule, you should never connect anything to your Raspberry Pi
while it’s powered up.

Figure 5-3: Wiring the screened cable to the tilt switch.

Figure 5-4: Connection to the GPIO pins.

Testing
After you’ve assembled your project, it’s time to test the switch. In order to access
the GPIO pins, you need a special library. There are a few of these around, but one
of our favorites is WiringPi, by Gordon Henderson. There is a Python front end,
and it’s easy to install.
From the desktop open up a command-line prompt, and type the following:
sudo apt-get install python-dev python-pip
sudo pip install wiringpi2

That should be it. You can test that it’s installed correctly by typing the following:
sudo python
import wiringpi2
wiringpi2.piBoardRev()

You should see the revision number of your board. However, notice that you have
to use the sudo command to access things as the root user. You can still program in
the IDLE environment by opening it up and typing the following from a commandline prompt:
gksudo idle

Then everything you do is as a root user. Get into IDLE like this, open up a new
window from the file menu and then type the program in Listing 5-1.

Listing 5-1: Switch Test
#!/ #!/usr/bin/env python
"""
Sauce bottle switch test
"""
import wiringpi2 as io
print "if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetup()
io.pinMode(8,0) # Physical Pin P1,3 GPIO 2
print "Pin test - Ctrl C to quit"
lastPin = 0
while True :
pin = io.digitalRead(8)
if pin != lastPin:
print "Pin now ", pin
lastPin = pin

This is a very simple program and shows the basis of reading a GPIO pin. It starts
off by importing an instance of the wiringpi2 library. Then there is a little
warning about being a root user. (If the program crashes on the next instruction, it
shows that you aren’t the root user.) Then the io.wiringPiSetup() function is
called, which initializes the library. This sets up the pins to use some pin mapping
that automatically takes care of the swapping about of pins on this header, which

has occurred in the different editions of the board.
Here, GPIO 2 (or GPIO 0 on a Raspberry Pi 1 board) is on connector P1 on pin 3,
but it’s referred to as pin 8 in the software. It may sound complex, but the point is
that pin 8 will access the same pin on the GPIO connector no matter what board
revision of the Raspberry Pi you have.
Then the io.pinMode(8,0) call makes this pin an input and finally
io.digitalRead(8) returns the logic value on this pin. A variable called
lastPin holds the previous value on the pin and prevents it from being printed out
if it hasn’t changed. Run the code and see how the pin state changes with the tilt of
the switch. If you don’t see any changes, check the wiring and chase down your
fault.

The Software
What makes this project really exciting is the combination of good graphics and
hardware. In the early days of computers, you had to write code for every line and
pixel displayed, but today you can work wonders with digital photographs and
image manipulation packages.
In this section, we describe how you can make your own graphics — but there is no
need to do this if you don’t want to. You can simply download our graphics from
the book’s companion website (www.dummies.com/go/raspberrypiprojects) if
you want to copy exactly what we have.
The idea is that there is a picture of the empty sauce bottle and the software fills it
with sauce and then slowly empties it according to how you shake the bottle. You
do this by drawing a rectangle of translucent sauce over the bottle and then
removing or masking out areas where the sauce should not go. Finally, the label
and cap of the bottle are layered over the top to give the illusion that the sauce is
actually inside the bottle.

Preparing the graphics
If you want to go it alone and make your own graphics to match your bottle, you
have to do a bit of playing about with a graphics application, like Adobe
Photoshop (on your desktop or laptop computer) or Gimp (on the Raspberry Pi).
Here are the steps to preparing the graphics yourself:
1. Using the best digital camera you have access to, take a photograph of

your bottle against a white background.
Make sure the bottle is at an angle of about 60 degrees.
2. Save the picture as a high-resolution PNG file.
Many cameras create JPGs, so you may have to export the image from your
camera and import it onto your computer and then save the image as a PNG
using an application like Photoshop.

All images in the following steps should be saved as PNGs because the
JPG image format does not support transparent masks. Also, working at high
resolution means any mistakes are minimized when you reduce the picture size
later.
3. Remove any background surrounding the image and replace it with a
uniform flat gray.
4. Save this image as your base image and call it Bottle.png.
5. Make a copy of Bottle.png, and select the gray background.
6. Invert the selection and make the selection transparent.
7. Save the image and call it Mask.png.
8. Make another copy of Bottle.png and paint the same color gray as the
background for all of the bottle except the label and the cap.
9. Select the gray area and make it transparent.
10. Save the resulting image as Label.png.
11. Make copies of Bottle.png, Label.png, and Mask.png and place them in
another folder called Graphics.
12. Reduce the image size of all three of the images in the Graphics folder so
that all three pictures are exactly 500 pixels wide.
13. Copy the Graphics folder to the folder you want to have the game in on
the Raspberry Pi.
The trick is to layer these three images along with a rectangle of sauce to build up
the image of the half-full sauce bottle, as shown in Figure 5-5.

Figure 5-5: Building up the bottle image.

You start with the picture Bottle.png, which is the first to be drawn. Then a
rectangle of semitransparent sauce is drawn; the height of this rectangle
corresponds to how full the bottle is. This rectangle will cover areas outside the
bottle image, so in order to remove this, Mask.png is drawn on top of it. This mask
has a transparent area in the shape of the bottle, so it removes any sauce outside
this area. Finally, Label.png is drawn so it looks like it isn’t being covered by the
sauce, which gives the impression that the sauce is inside the bottle. Drawing the
sauce as a semitransparent color also adds to this illusion because things like the
light reflections off the bottle can still be partly seen through the sauce on the
bottom layer, and they’re fully seen when the sauce retreats from those reflections.
This gives the strong illusion that the sauce is in the bottle.

The rules
The game itself is simple: The bottle starts off full of sauce, and on each shake, a
certain amount of sauce is removed and the picture is redrawn. When the bottle is
empty, that round of the game is over, and the time it took to empty the bottle is
displayed, with a record being kept of the fastest score. There is one more feature
that, although it sounds simple, does add quite a bit of code: the game reset, which
is triggered by pressing the spacebar. The game reset abandons any current run and

refills the bottle.
The game uses the Pygame framework, which allows for easy handling of the
keyboard, pictures, and windows. It’s included in the standard Raspberry Pi
distribution. The code for the game is shown in Listing 5-2.

Listing 5-2: The Sauce Bottle Game
#!/usr/bin/env python
"""
Sauce bottle game by Mike Cook
"""
import time, pygame, os, sys
import wiringpi2 as io
print "if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetup()
io.pinMode(8,0) # Physical Pin P1,3
pygame.init() # initialise graphics interface
os.environ['SDL_VIDEO_WINDOW_POS'] = 'center'
pygame.display.set_caption("The Sauce Bottle")
pygame.event.set_allowed(None)
pygame.event.set_allowed([pygame.KEYDOWN,pygame.QUIT,pygame.MOUSEBUTTONDOWN])
screenWidth = 500
screenHeight = 542
screen = pygame.display.set_mode([screenWidth,screenHeight],0,32)
sBottle = pygame.image.load("Graphics/Bottle.png").convert_alpha()
sLabel = pygame.image.load("Graphics/Label.png").convert_alpha()
sMask = pygame.image.load("Graphics/Mask.png").convert_alpha()
# define the colors to use
cBack =(60,60,60)
pygame.draw.rect(screen, cBack, (0,0,screenWidth, screenHeight),0)
cSauce = (166,30,0) # color of the sauce
returnKey = False ; restart = False
def main():
global returnKey,restart
print "Sauce bottle game by Mike Cook"
full = 100.0 # percent the bottle is full
highScore = 60.0 # Record time
while True:
drawScreen(full)
print "shake when ready"
start = time.time()
while full > 0 :
while io.digitalRead(8) == 0 and restart == False:
checkForEvent()
while io.digitalRead(8) !=0 and restart == False:
checkForEvent()
if restart == True :
full = 0
print "Reset"
else :
full = full - 5.0 #change this number for a faster / slower game
if full < 0:
full = 0
drawScreen(full)
drawScreen(full) # empty

if restart == False:
runTime = time.time() - start
print"You took ",runTime," to empty the bottle"
if runTime < highScore:
print "A new record!"
highScore = runTime
print "The record is ",highScore
else:
drawScreen(100)
print "return key for a new game"
returnKey = False
while returnKey == False :
checkForEvent()
returnKey = False
restart = False
full = 100.0
def drawScreen(p) : # draw to the screen
screen.blit(sBottle,(0,0))
sauce = pygame.Surface((425,p*4.53)) # maximum sauce
sauce.set_alpha(170) # transparency of sauce
sauce.fill(cSauce)
screen.blit(sauce,(61,11+((100.0-p)*4.53)))
screen.blit(sMask,(0,0))
screen.blit(sLabel,(0,0))
pygame.display.update()
def terminate(): # close down the program
print ("Closing down please wait")
pygame.quit() # close pygame
sys.exit()
def checkForEvent(): # see if we need to quit
global returnKey,restart
event = pygame.event.poll()
if event.type == pygame.QUIT :
terminate()
if event.type == pygame.KEYDOWN :
if event.key == pygame.K_ESCAPE :
terminate()
if event.key == pygame.K_RETURN :
returnKey = True
if event.key == pygame.K_SPACE :
restart = True
if event.type == pygame.MOUSEBUTTONDOWN :
print pygame.mouse.get_pos()

if __name__ == '__main__':
main()

The best way to understand this is to look at the functions individually, starting
with the last one, checkForEvent, which looks to see if anything has happened that
the Pygame framework has picked up in the background. For example, a QUIT event
can be the user clicking the close box of the window; if this occurs, the terminate
function is called, shutting down everything. Next are the KEYDOWN events, which
are picked up if a key is pressed. For example, the Escape key calls the same
terminate function as the close box click. The other keys that are of interest

simply set variables to indicate that they’ve been pressed. The way the code works
is that this checkForEvent function should be called constantly, as often as
possible. If you were in a loop and not calling it, then the program might have
thought to have hung. The last event is just for debugging, but we’ve left it in in
case you’re adding your own graphics. It simply prints out the x- and y-coordinates
of where the mouse is clicked, which you need to know in order to align and size
the sauce rectangle correctly.
The drawScreen function is where all the graphics magic happens, it draws the
elements of bottle, sauce, mask, and label just as we describe in the preceding
section. It takes in a variable, p, which is the percentage of how full the bottle is,
and uses this variable to calculate the size of the sauce rectangle’s height. The
width is fixed by the maximum extent of the visible area of the bottle. The
transparency is set as a value of 170; this is where 255 is fully opaque. You may
want to change this value and see how it looks. The rectangle is then drawn with
the top representing the top level of the sauce.

Note that in Pygame’s windows, the (0,0) coordinate is at the top-left
corner and the y value increases as you move down the window, which is the
opposite of more conventional systems.
The lines at the start of the listing initialize various aspects of the program. It first
sets up the hardware GPIO input. Then it sets up the Pygame system and defines the
window size. The window size must match your photographs’ size. Next the photos
are loaded in and the colors are defined. Again, this is an opportunity to change
them if you like.
Finally, the main function actually plays the game. After setting initial variables
and printing out the title, it enters an infinite loop with the while True: line. It
then draws the picture of the bottle, prints out an invitation to start, and makes a
note of the current time so it can calculate the time taken to empty the bottle. The
code enters another loop, which repeats as long as the bottle is not full with the
while full > 0: line. This loop waits for the input to be low and then to be high
before removing a bit of the sauce. You can change the amount it removes per
shake to make the game longer or shorter. When the bottle is empty, the run is over.
The time taken is printed out and checked to see if it’s a new fastest score. You can
press Return to start again.
Note that the feedback is given in the Python console window, but the game

window must have the focus (be the top window) in order for the program to “see”
any key presses.

Taking It Farther
You can do even more with this project if you like. Here are some examples:
You can add sound effects (maybe a squelch for each shake and a fanfare for
finishing, with a special one for a new high score). Chapter 13 has a project
that uses sound with Pygame so you can see how it’s done.
You can make it so that the timing begins on the first shake of the bottle.
You can add graphics of the sauce actually squirting out of the bottle.
You can make the game a two-player game where the players race each other.
To do this, you need two bottles and a bigger window.
You can make the high score permanent by writing it to a file.
When you get more advanced with handling hardware, you may want to add
some flashing red LEDs in the bottle that match the shaking.
What ever you do, there will be a whole lotta shakin’ goin’ on!

Chapter 6

Stomp!
In This Chapter
Driving LEDs directly from the Raspberry Pi
Using all the GPIO outputs on a Raspberry Pi Model B+
Making an addictive game of stomping out bugs
Discovering modern multicolor LEDs with built-in electronics
Converting the bugs game to color
No matter how complex a project is, the first step is to get an LED flashing. That
flashing LED confirms that so much of your system is operating, and then you have
a platform to build on.
In this chapter, we show you how you can control LEDs from your Raspberry Pi.
There has recently been a big advance for people who want to use a lot of LEDs in
their projects: LEDs with built-in controllers, allowing you to easily create
colorful projects. We show you how to take advantage of these LEDs in your
projects.

Getting Acquainted with the LED
The light emitting diode (LED) was first made available in the mid-1960s and
emitted invisible infrared light. An application for LEDs was quickly found in TV
remote controls. LEDs work by exciting electrons in a crystal lattice; then, as the
electrons lose energy, they emit a photon of light. The wavelength of this light
depends on the crystal lattice material, so the drive for visible colors was a drive
to find and manufacture semiconductor materials other than silicon and germanium.
An alloy of the metals gallium and arsenic allowed red LEDs to be produced,
which was followed slowly over the years by other colors. It wasn’t until the
1990s that it was possible to produce a material for blue LEDs. Then about ten
years later, you could get a hold of white ones, which work by having an ultraviolet
LED shining on a phosphor.

In electronics terms, the LED is a bit of a curiosity in that it isn’t a linear device.
That means that it doesn’t follow Ohm’s law, which says that the current increases
in proportion to the voltage. With an LED, the situation is like the sauce bottle from
Chapter 5: You increase the voltage and the current doesn’t increase much; then a
threshold is reached, after which a tiny increase in voltage produces a very large
increase in current. This means that you can’t connect an LED directly to a voltage
without it either not working or self-destructing. You have to provide some form of
current control, and the simplest way of doing that is to use a resistor in series with
the LED.
The value of the series resistor you need to use depends on two factors:
The amount of current you want to push through the LED
The voltage that is pushing this current
The more current you push through an LED, the brighter it will get. However, there
is a limit to how much the LED can take without being fried. For most indicator
LEDs, this is 20 mA. So, this is a normal design current to use, but the increase in
brightness with current is not proportional.

Well, the increase in brightness with current actually is proportional, but
the snag is that the eye doesn’t perceive brightness linearly, so the perceived
difference between an LED current of 10 mA and 20 mA is not that it is twice
as bright but more like only one-third as bright. It is a logarithmic
relationship. However, many modern LEDs are high efficiency, which means
you can get much brighter for the same amount of current or you can get just as
bright for less current.
Calculating the resistor value is simple, but it can be confusing at first. Consider
the circuit shown in Figure 6-1, which shows an LED and resistor connected to a
voltage source. If you take a meter and measure the voltage across the resistor and
the voltage across the LED, both readings will add up to the voltage produced by
the voltage source. This sort of thing is known as a potential divider.

Figure 6-1: A basic LED circuit.

Now, you want the voltage across the LED to be enough to light it up. It has to be
the threshold voltage, known as the forward voltage drop. You find this voltage
quoted in the data sheet of the LED. (If you don’t have a data sheet, you can guess it
from the color or, even better, use a nominal resistor of something like 510 R
[ohms] and actually measure it with your meter.) Normally, the forward voltage
drop for each color LED is roughly the same, with red having the lowest voltage
and white having the highest.
Once you know the voltage drop across the LED, what’s left of the voltage from the
supply (that is, the supply voltage minus the LED voltage) is what’s across the
resistor. If you know what current you want to let flow through the resistor and you
know what voltage is across it, you can rearrange Ohm’s law and calculate what
value the resistor should be. The circuit is a series circuit, so whatever current is
flowing through the resistor has to be flowing through the LED, so you can
calculate what resistor you need for what current. This can be summarized in the
following formula:
Resistance = (Supply Voltage – LED Voltage Drop) ÷ Required Current
When you do this, you’ll almost certainly get a value of resistance that is not
manufactured. Resistors come in a series of “standard” values, and in this case you
pick the standard value that is closest to but higher than the one you calculated.

This gives you slightly less current than you designed for, but you won’t be able to
tell the difference.

You’re deciding what current you want to flow and, hence, the brightness.
Given that, you calculate the resistance. The actual current is not very critical
— don’t get hung up on getting exact resistor values. Modern white LEDs are
very efficient, and you can get quite a bright output for a few mA, so if you
just want an indicator, you don’t need much current.

Stomp 1
This project uses LEDs connected directly to the GPIO port. It’s a ring of LEDs to
play a game we call Stomp. (If you’re in the UK, think of this as Stamp.) You can
see the finished unit on top of a Raspberry Pi in Figure 6-2.

Figure 6-2: Stomp 1 LED ring.

Stomp is a game where lots of bugs are running around, and you have to stomp on
them when they pass under your foot. But if there isn’t one under your foot when

you stomp down, a new bug pops up. The object of the game is to clear all the
LEDs in as short a time as possible. The creatures are represented by a ring of
white LEDs and the stomping foot by two red LEDs on either side of the ring (red,
of course, for blood). You do the actual stomping on a momentary foot switch.

Parts
This project requires a lot of GPIO pins, so you need a Raspberry Pi Model B+, a
Raspberry Pi Model A+, a Raspberry Pi 2 Model B+, or a Raspberry Pi 2 Model
A+ — in other words, you need a Raspberry Pi with a 40-pin GPIO header. If you
have an earlier Pi, Stomp 2, later in this chapter, is for you — it can be run on all
models.
Here’s what you need to make Stomp 1:
A Raspberry Pi with a 40-pin GPIO connector
A 2½-x-3¾-inch (60-x-95-mm) stripboard
Twenty-four 3mm white LEDs
Two 3mm red LEDs
A foot-operated momentary switch
Twenty-four R1 value resistors for the white LEDs (we used 330R)
Two R2 value resistors for the red LEDs (we used 220R)
A two-pin header strip
A two-pin header socket
A thin 0.5m flexible twin core cable
A 40-way surface mount header socket

Schematic
This is a simple circuit, but a lot of the impact requires a clean-looking board. That
means we’ve done all the wiring on the underside of the board to make the top side
clutter free. You can even use surface mount resistors on the underside of the board
if you want, for the ultimate in anti-clutter. The basic schematic is shown in Figure
6-3.

Figure 6-3: The Stomp 1 schematic.

You can see that the bulk of the circuit is simply an LED connected through current
limiting resistors connected to the GPIO pins repeated 24 times, with a different
GPIO pin for each LED. The association between the GPIO pin and the LED was
partly dictated by the physical layout and the need to make the wires as short as
possible, but it isn’t important because in software the relationship is defined by a
lookup table in the form of a list. The two red LEDs can be driven from the same
GPIO pin because you only ever want to turn both of them on at the same time.
Finally, the foot switch is connected directly to GPIO 3, which has an onboard
strong pull-up resistor so the switch can be on a long length of wire and not suffer
from interference pickup.

Design
The only thing to design here is the two values of the LEDs’ current limiting
resistor. The exact value will depend on the type of LEDs you have and what
current looks good. You don’t want to pull too much current directly from the GPIO
pins. Although 16 mA is the maximum you should draw per pin, there is a rough 55
mA limit on the total current draw from the chip, so we designed the white LED
limiting resistor for 1.7 mA. With the 3V3 voltage of the GPIO pins and the 3.0V
forward voltage drop of the LEDs we had, this give a resistor value of 330R. For
the red LEDs, we gave them 7.5 mA each and used 220R resistors, so they had a
1.7V forward voltage drop.

Check with the LEDs you have to see if the brightness is right before

building the circuit.

Construction
The circuit is simple, but if you want to copy exactly what we’ve done, you need to
take some care. We built the prototype on stripboard. Many beginners think that you
have to make as many connections as possible with the strips, but this isn’t the
case. It’s fine if some connections work out like that, but don’t go overboard trying
to make it work this way.
Our main design consideration was to get the LEDs to look as much like a circle as
possible, despite being laid out on a 0.1-inch square grid. That was our starting
point. Then to fix it to the Pi, we used a twin-row pin header socket. It needs to
mount on the underside of the stripboard, so we used a surface mount socket. In
fact, we didn’t have a 40-pin strip so we cut down a length of 52-pin strip we had.
A saw cut to the first waste socket and a quick clean with a fine file were all that
was needed.
The circuit laid out is shown in Figure 6-4. We’ve numbered the columns and rows
of the stripboard so we could build up a cutting and wiring list for you to follow.
Note the position of the LEDs. There is a very subtle flat on the cathode side of the
LED, which is normally the lead that is the shorter of the two. We recommend you
make a note of which way around your LEDs are before you get very far with the
construction.

Figure 6-4: The top side of Stomp 1.

Construction should start on the underside of the board, which is shown in Figure
6-5. This shows all the tracks you need to cut. Note that all but two tracks are cut at
the hole. A simple circular motion left and right, either side of the hole, with a
scalpel is all you need to cut the track. The two red LEDs require a small strip
being cut out of the track between the holes. Make two cut lines as close together as
possible, and peel off the copper track in between.

Figure 6-5: The track side of Stomp 1.

On the book’s companion website
(www.dummies.com/go/raspberrypiprojects), there is an image file of Figure
6-5 so that you can print it out full size and lay your board over it. Then you can
easily identify the columns and rows. Instead of picking out tracks to cut from the
diagram, we’ve produced a spreadsheet containing a list of tracks to cut. This
spreadsheet also contains a list of component placements and a list of wiring links.
The first step is to cut the tracks on the underside of the board. This might take
about 30 minutes and requires a bit of concentration. After it was cut, we used the
continuity testing function on our multimeter to check that they had been broken and
there were no thin whiskers of copper still making a contact.
Next, mount the 40-pin header socket on the board. It should cover the column with
the cut tracks and have the small legs covering the track until it almost reaches the
hole. Make sure it’s placed evenly so the legs on each side are the same distance
away from the holes. Then tack one corner with a blob of solder. Check again that
it’s placed correctly because at this stage it’s easy to correct any misalignment by
simply melting the one joint. When you’re satisfied that it’s straight, tack the leg on
the other side and check again.
Next is the point of no return, solder all the remaining legs. Flip the board over and
solder all the resistors in place, and then carefully add the LEDs, soldering them in

one at a time. First, solder one LED and then look to see that the LED stands
straight up. If it’s crooked, place your iron on the joint and push the top of the LED
so it’s square and upright. Then you can solder the second leg and snip off the
excess wire. You have to make sure that the LEDs are in the right holes, and that
they’re the right way round. Finally, add the small two-pin header to the board.
All that remains is to wire it up. We’ve devised the wiring so that it always goes
between two points on the board that already have a component in them. We used
thin 28 AWG insulated solid core wire for the wiring. Strip just the smallest
amount you can from the wire, no more that 2mm or so. Apply your soldering iron
to the solder on the component already on the board and push the wire in.
Beginners tend to strip too much insulation back. Be constrained, and always cut
what you think is too little.

A list of the point-to-point connections is in the spreadsheet on the book’s
companion website. Also on the website is a multicolored diagram showing
all the wiring. This can look like a bit of a mess, but the colors should enable
you to pick out the connections one at a time. However, we think it’s best just
to use the wiring list. You can print it out and cross off each connection as you
make the link.
A two-pin header strip is attached to the top end of the board. We made an
extension lead with thin flexible microphone wire and finished it off with a two-pin
header socket.

Software
While working on another of our Raspberry Pis — one of the types with a 26-way
GPIO socket — we ran the following code and it froze out the keyboard and
mouse. This is because it was playing about with GPIO pins that shouldn’t be
altered on earlier revisions, so we put a check in the code to test that it was the
right board before the code would run.
Basically, the presence of a bug is held in a list called critters. If a list value
contains a 1, that represents a bug; if it contains a 0, that means no bug. The list is
rotated each step, and the new list of LEDs is displayed. This gives the appearance
of the lights going around in circles. The program is shown in Listing 6-1.

Listing 6-1: Stomp 1 Game

#!/usr/bin/env python
# Stomp 1
# Author: Mike Cook
import time, random, sys, re
import wiringpi2 as io
from collections import deque
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
numLEDs = 24
stompPos = 18
critters = deque([ 0 for i in range(0,numLEDs) ])
direction = True # direction to run round the ring
#GPIO LED pin numbers for LEDS 0 to 23
pinLED = [20,21,19,26,13,5,11,7,17,4,18,15,14,22,23,24,25,27,8,10,9,6,12,16]
pinRed = 2 #GPIO
stompSwitch = 3 #GPIO
sTime = 0.2
random.seed()

def main():
if getrevision() < 0x10:
print"You can only run this on a Pi with a 40 pin GPIO connector"
sys.exit()
initGPIO()
wipe()
lastSwitch = 0
print"Stomp on the bugs"
while True:
setup()
startTime=time.time()
while critters.count(0) != numLEDs:
switch = io.digitalRead(stompSwitch)
if lastSwitch != 0 and switch == 0:
stomp = True
if critters[stompPos] >0 :
critters[stompPos] = 0
else:
critters[stompPos] = 1
else:
stomp = False
showCritters(stomp)
moveCritters(direction)
lastSwitch = switch
time.sleep(sTime)
wipe()
print "all gone in ",time.time() - startTime,"seconds"
print"have another go"
time.sleep(3)
def moveCritters(wayRound):
global critters
if wayRound:
critters.rotate(1)
else :
critters.rotate(-1)
def showCritters(stamp):
for p in range(0,numLEDs):

io.digitalWrite(pinLED[p],critters[p])
if stamp :
io.digitalWrite(pinRed,1)
else:
io.digitalWrite(pinRed,0)
def setup():
global critters,direction,stompPos
for c in range(0,3):
choice = random.randint(0, numLEDs -1 )
while critters[choice] != 0 :
choice = random.randint(0, numLEDs -1 )
critters[choice] = 1
if random.randint(0,1) == 0:
direction = True
stompPos = 19
else:
direction = False
stompPos = 18
def wipe():
for i in range(0, numLEDs ):
io.digitalWrite(pinLED[i],0)
io.digitalWrite(pinRed,0)
def initGPIO():
for i in range (0, numLEDs ):
io.pinMode(pinLED[i],1) # to output
io.pinMode(stompSwitch,0) # to input
io.pinMode(pinRed,1) # to output
def getrevision():
revision = "unknown"
with open('/proc/cmdline', 'r') as f:
line = f.readline()
try:
m = re.search('bcm2708.boardrev=(0x[0123456789abcdef]*) ', line)
revision = m.group(1)
except:
m = re.search('bcm2709.boardrev=(0x[0123456789abcdef]*) ', line)
revision = m.group(1)
return revision & 0xff

# Main program logic follows:
if __name__ == '__main__':
main()

A fundamental requirement of the program is that a list should be able to be quickly
rotated, clockwise or counterclockwise. To do this, we used Python’s doubleended queue (deque) module, and initialized the empty critters list at the start of the
code. Each LED in the ring is numbered 0 to 23, and the GPIO pin corresponding to
the number is given in the pinLED list. Some global variables are declared before
entering the main function.
The first thing the function does is check to make sure the revision number is large
enough to have a 40-pin GPIO connector (see Chapter 4). Then the GPIO pins are
initialized. (Because GPIO 3 has an external pull-up resistor on the board, there is

no need to enable the software one.) Then the wipe function turns off all the LEDs
— both those in the ring and the red ones. Finally, an infinite loop is entered that
defines a game or round. In this loop, the setup function defines the initial
population of bugs by choosing three random locations to place a 1 in the
critters list. There is some code to make sure that three different positions are
chosen. Then the code chooses a direction to march the bugs for this game and
defines the stomp position for each direction. You need to have the “killing field”
located just in front of the boot, or red LEDs as you may like to call them.
A record of the system time is made so that the time taken to squash all the bugs can
be printed out at the end. Then, a while loop plays the game, continuing until the
critters list is full of zeros. The game loop consists of looking at the stomp
switch and comparing it to what the switch state was the last time around the loop.
This ensures that only the first time the switch is pressed counts as a stomp. The
code then looks at the stomp position in the critters list and removes a critter if
there is a number 1 in this location; otherwise, it adds a 1 to the list.
The showCritters function is called, which lights up the LEDs corresponding to
where the bugs are in the list. The red LEDs are also lit up if the stomp switch has
just been activated. Next, the moveCritters function is called, which rotates the
critters list. Finally, a delay is called; the sTime variable set up at the start of
the code defines how fast the game runs.
When all the bugs have been stomped on, the time taken to clear the ring is printed
and a new game is started.

How it plays
In practice, the game plays very well, with a good mixture of tension and reaction.
It takes some concentration to rid the circle of bugs. Sometimes we didn’t keep our
feet on the switch for long enough to register a stomp — we were being far too
jittery. All in all, a most enjoyable game — and it was a surprise that we found it
easer to clear a ring moving clockwise than counterclockwise.
You may want to take things further, like introducing a small random jitter into the
sleep delay to break up any rhythm a player builds up. You may want to add sound
effects or keep a high score. You could have more initial bugs in the list or you
could reverse the direction of rotation after a fixed time or even after each stomp.
If you only have a Raspberry Pi Model B, you could modify the design to use only
15 LEDs and an input.

Stomp 2
The Stomp 1 game with discrete LEDs is great, but you need a lot of GPIO pins on
your Raspberry Pi, and each LED is only one color. Plus, it takes a bit of skill to
make. Stomp 2 uses much more ready-built components and is a multicolor game.
It’s slightly different from Stomp 1 in that it takes three stomps to kill the bugs; each
stomp on a bug changes its color, until the last one removes it. In order to get a fine
range of colors, you need to know how you control the brightness of an LED (see
the nearby sidebar).

Controlling brightness
Although the resistor value sets the maximum brightness for an LED, it’s possible to control or fade
the brightness down from this maximum. There are two ways of doing this:
By altering the voltage of the supply: Unfortunately this approach isn’t very satisfactory,
because of the nonlinear nature of the LED’s current flow. Imagine you can control the
voltage smoothly between 0 and 5 volts. For the lower part of the range, below the forward
voltage drop, the LED will not be lit. Then, as the voltage is increased past this point, the LED
will get brighter very quickly. The increase in brightness will drop off as the voltage
approaches the maximum. So, the useful range of control over the brightness is very small.
By using pulse width modulation (PWM): This approach simply involves flashing the LED
on and off very rapidly. If you do this faster than 32 flashes per second, you can’t see the
LED flashing due to your persistence of vision. The time you keep the LED on relative to the
time it is off is known as the duty cycle. Changing this duty cycle changes the apparent
brightness of the LED.
Many microcomputer chips have outputs that can automatically generate the PWM signal when you
give it the duty cycle you want. The chip in the Raspberry Pi has only two such outputs, and one is
used for the sound output, so there is only one output free. So, although it’s easy to fade one LED, it
isn’t that easy to control more than one without extra hardware.

Design
The snag with using a lot of LEDs is that they can take a lot of current. Each
WS2812b (see “The WS2182b,” later in this chapter) can take about 66 mA, and
when you add that up for 24 of them, you get just over 1.5 amps. This is way more
than the Raspberry Pi can provide, even if you have a big power supply. So, you
need another 5V supply.
The other snag is that the Raspberry Pi is only a 3V3 system; ideally, the LEDs
need a 5V data signal, which is just outside the reach of the GPIO lines. However,
if the supply voltage is not 5V but just under at 4.8V, this is often enough to allow
the Pi’s GPIO pin to drive it directly, as long as you put the data signal through a

470R series resistor. This improves the signal shape by damping down ringing on
the GPIO signal and preventing reflections on the line.
The LEDs themselves can be driven with 3V3, but they aren’t as bright. Besides,
3V3 external power supplies can be hard to come by. The better solution to the
driving problem is to use a level shifting circuit. This is a good solution and is
guaranteed to give you the best results.

Parts
Here are the parts you need for this game:
Any Raspberry Pi
A 2-x-½-inch (48-x-12mm) stripboard
A 24-pixel WS2182b LED ring
A foot-operated momentary switch
Two 5K6 resistors
A two-pin header strip
A five-pin header strip
A two-pin header socket
A thin 0.5m twin core cable
A 2.1mm power jack socket
A 5V power supply with at least 2A capability
A 2N7000 FET
A push-button switch
Five header pin socket leads and shells

The WS2812b
Recently, a component has been introduced that is a game changer as far as hobby projects are
concerned. It’s the WS2812b or, as branded by Adafruit Industries, the NeoPixel. This isn’t just one
LED but three in one package — a red one, a green one, and a blue one. But what makes it
remarkable is that each package contains not only the three LEDs but also a controller chip that can
alter the brightness of each LED. This makes it possible to make an almost unlimited range of colors
by mixing these three primary colors in varying amounts. What’s more, the controllers are chainable
— a serial output of one device feeds into the serial input of the next device. So, you can have several
hundred LEDs, all controlled from a single GPIO pin.
The big snag with using the WS2812b with the Raspberry Pi is that the LED requires feeding with a

very precisely timed stream of data. Normally, the interrupts that Linux gives to any program would
disrupt the timing, and the system wouldn’t work. Fortunately, there is a very clever way around this.
Unfortunately, the details are very complex and way outside the range of this book. To the rescue
comes Jeremy Garff, who has produced a library along with a Python wrapper that makes it very
easy to use these LEDs. Under the hood, it uses a DMA channel, direct memory access, which
allows simple operations like moving memory from one place to another without the intervention of
the computer’s processor. This, coupled with the pulse width modulation (PWM) register and an
internal FIFO (first in, first out) memory buffer, allows the precisely timed data stream to be
generated.
The WS2812b comes in many different products. There are single individual surface mount
packages, or you can get them mounted on a tiny PCB for easy soldering. They come in ready-built
configurations like an 8-x-8 square matrix or a ring of LEDs. The LED rings are interesting — you can
get a small 12-LED ring, a 16-LED ring, or a 24-LED ring. If you want to go even bigger, you can get a
ring quadrant so that four together gives you a 60-LED ring. You can even get them in conventional
5mm and 10mm LED packages.
For Stomp 2, we use a 24-LED ring. These have a 66mm outside diameter and are just about the
smallest diameter you can get 22 LEDs into.

Schematic
Figure 6-6 shows how this is put together. The level converter is mounted on a
small piece of stripboard and connects to the Raspberry Pi through header socket
leads. Make sure that your power jack socket matches your power supply output
lead.

Figure 6-6: The Stomp 2 schematic.

The wiring is quite simple, and there is an additional switch on this version to act
as a reset button. We found it was easy for things to get out of hand with this
version of the game with far too many bugs being generated. So, instead of quitting
and restarting the program, we thought it would be a good idea to have a simple
push button to clear out all the bugs. You can leave out the reset switch altogether if
you want. It will have no effect being left open circuit.

The 2N7000 FET acts as a noninverting level converter, boosting the 3V3 signal
from the Raspberry Pi to a 5V signal for driving the LED’s controller. The only
GPIO pin you can use on the Pi is GPIO 18, because that’s the only one capable of
having the PWM register switched to it. The resistor values aren’t too critical.
Anything between 1K and 10K should be fine.

Construction
There is not too much to the construction — the only tricky bit may be mounting the
power jack on the stripboard. The thing is, it simply won’t fit on the 0.1-inch pitch
of the holes. What we did was put a small router bit in our drill and cut three slots
in the stripboard so the connections would fit in. If you don’t have a router bit, you
can make do with some fine needle files to cut the slots; use the point of the round
one to get you started.
When the power jack fits snugly on the stripboard, the rest of the circuit can be
built around it. The layout we used is shown in Figure 6-7, and a photograph is
shown in Figure 6-8. The power jack has three connections. You need to use only
the two in the middle; the one on the side is just used for mechanical stability.
Solder it to some tracks, but electrically don’t go anywhere with it.

Figure 6-7: The physical layout of the level shifting board.

Figure 6-8: The level shifting board.

Note that the copper strips run vertically. Make sure you get this right when you cut
your stripboard to size. The reset push button we used was a two-wire one. There

is room to put a four-connector switch here if you want.

Using opposite corners when wiring these is simplest. The board can be
wired to the GPIO connector any way you want. We used two six-way shells
to make up a short connector between the GPIO header pins and the five-pin
connector on the level shifting board.
Finally, we stuck the board and LED ring to a piece of plywood with a generous
helping of hot glue. A few coats of medium oak wood staining varnish beforehand
made the whole thing look a lot more upmarket than it sounds. A photograph of the
finished unit is shown in Figure 6-9.

Figure 6-9: The finished Stomp 2 game.

Software
Before you can start using these awesome WS2812b devices, you need to
download and install the library to drive them. Do this by typing the following from
the command line:
wget https://github.com/tdicola/rpi_ws281x/raw/master/python/dist/rpi_ws281x-1.0.0-py2.7linux-armv6l.egg
sudo easy_install rpi_ws281x-1.0.0-py2.7-linux-armv6l.egg

Note: armv6l ends in the letter l and not the number 1.

Then you need to connect the circuit and run the code in Listing 6-2.

Never plug anything into the Pi while it’s powered up. Always shut down,
disconnect the power, attach the device, and reconnect the power.

Listing 6-2: Stomp 2 Game
#!/usr/bin/env python
# Stomp 2
# Author: Mike Cook
import time, random
import wiringpi2 as io
from collections import deque
from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
numLEDs = 24
strip = Adafruit_NeoPixel(numLEDs,18,800000,5,False)
sTime = 0.2
critColor = [Color(0, 0, 0),Color(0, 0, 32),Color(0, 32, 0),Color(32, 32, 32)]
stompColor = Color(32, 0, 0)
stompPos = 12
stompSwitch = 3 ; resetSwitch = 2
critters = deque([ 0 for i in range(0,numLEDs) ])
direction = True # direction to run round the ring
def main():
initGPIO()
strip.begin()
wipe()
lastSwitch = 0
print"Stomp on the bugs - three stomps to kill"
while True:
setup()
startTime=time.time()
while critters.count(0) != numLEDs:
if io.digitalRead(resetSwitch) == 0 :
resetGame()
switch = io.digitalRead(stompSwitch)
if lastSwitch != 0 and switch == 0:
stomp = True
if critters[stompPos] >0 :
critters[stompPos] -= 1
else:
critters[stompPos] = 3
else:
stomp = False
showCritters(stomp)
moveCritters(direction)
lastSwitch = switch
time.sleep(sTime)
wipe()
print "all gone in ",time.time() - startTime,"seconds"
print"have another go"
time.sleep(3)

def moveCritters(wayRound):
global critters
if wayRound:
critters.rotate(1)
else :
critters.rotate(-1)
def showCritters(stamp):
for p in range(0,numLEDs):
strip.setPixelColor(p, critColor[critters[p]])
if stamp :
strip.setPixelColor(stompPos, stompColor)
strip.show()
def setup():
global critters,direction
for c in range(0,3):
choice = random.randint(0,23)
while critters[choice] != 0 :
choice = random.randint(0,23)
critters[choice] = 3
if random.randint(0,1) == 0:
direction = True
else:
direction = False
def resetGame() :
global critters
for i in range(0,numLEDs):
critters[i] = 0
print"Game restarted"
while io.digitalRead(resetSwitch) == 0:
pass # wait until switch released
def wipe():
for i in range(0,strip.numPixels()):
strip.setPixelColor(i, Color(0, 0, 0))
strip.show()
def initGPIO():
io.pinMode(stompSwitch,0) # input
io.pinMode(resetSwitch,0) # input
# Main program logic follows:
if __name__ == '__main__':
main()

The overall structure of the code is the same as the Stomp 1 game, but there are
some changes needed to drive the WS2812b LEDs. The driver builds up data in a
buffer, so whenever you want to change an LED’s color, you put the data in the
buffer with the setPixelColor method. Nothing will change on the LEDs until you
transfer that buffer out to the LEDs using the show method of the library. The data
buffer object is set up using the Adafruit_NeoPixel call. The numbers in the call
are explained in the files that came with the library, if you’re interested, but it just
tells the library how many LEDs to drive, on what pin (you can’t change this), and
on what frequency. The False at the end allows you to invert the output signal in

case you use an inverting buffer as a level shifter.
The major change here is that the critters list holds a number, and that number
defines the color of the LED. Each time a bug is stomped on, this number is
decremented until it reaches 0. Because the LEDs can change color, there is no
need for a red stomp LED — you just set the LED at the stomp position to red.

The two games are virtually identical to play, but these LEDs can be too
bright to look at directly. This is reflected in the color definitions, but you may
want to do what we did and add a diffuser over the LEDs. We used some
0.5mm styrene sheet and cut out a circle with scissors, but a sheet of white
paper works nearly as well. You may want to mark the stomp position if you
do that.
Have a stomping good time!

Chapter 7

The Light Fantastic
In This Chapter
Building an illuminated button pad
Making your first PCB hack
Seeing stunning multicolor effects
Exploring alternate color models
Learning how a keyboard scanning matrix works
This project is about producing a universal 4-x-4 illuminated switch matrix. Why?
Because it’s a great base for so many projects with physical interfaces. This
chapter shows you how to build and test it, as well as produce a light show with it.
In Chapter 8, we show you how to make four games using this interface, as well as
a whole host of other uses you can put this to. A photograph of the final project is
shown in Figure 7-1.

Figure 7-1: The finished Light Fantastic.

Introducing the Light Fantastic
This interface can be described as an undedicated controller. It consists of 16 push
switches, each illuminated by an RGB LED. In Chapter 6, you see how you can use
LEDs and, in particular, a long strip of LEDs, all controlled by a single Raspberry
Pi pin. Those LEDs in the strip are also available in a normal 5mm LED package,
and they’re used to create this project.
Before the availability of WS2812b LEDs, constructing a project like this was
complex. The multiplexing required meant that it couldn’t be done with a
Raspberry Pi, because of the time-stealing nature of the Linux core. But with this
revolutionary LED, this project is comparatively easy.
There are many ways to build this project, but the one we show you here is simple
because it makes use of a readymade printed circuit board. This printed circuit
board wasn’t designed to use the WS2812b LEDs; instead, it was designed to use
the more conventional common anode or common cathode RGB LEDs. We show
you how to hack the printed circuit board in order to take this new component.
Here are the components you need:
Button Pad 4x4–LED Compatible (www.sparkfun.com/products/7835)
Button Pad 4x4–Breakout PCB (www.sparkfun.com/products/8033)
16 WS2812b 5mm LEDs
16 1N4148 or similar diodes
16 0.1uF ceramic capacitors
470R resistor
0.5 meter of 26-way ribbon cable
26-way IDC socket (or 40-way if you’re using a Raspberry Pi Model B+)
Four 15mm hexagonal M3 tapped pillars or spacers
13 M3 10mm pan-head screws
12 M3 10mm countersunk screws
21 M3 hex nuts
For the enclosure we used:

Scrap PCB boards for the side (you can also use ABS or thin plywood)
3mm ABS sheet for the base, top cover, and light baffle
200mm of 7mm (or so) angle aluminum

The Circuit
There are two parts to the circuit of the Light Fantastic: One is for the switches and
is called a switch matrix; the other is for the switch illuminating LED. We start
with the LEDs.

LEDs
This is a very simple circuit. It consists of a single string of 16 WS2812b LEDs,
chained together, with the data output of one going into the data input of the next.
Each LED has a connection to a 5V and ground of a power supply. In most cases,
this can be driven directly off the general-purpose input/output (GPIO) pins of the
Raspberry Pi, as long as the Pi’s power supply can handle an extra amp of current.
The only other component is a 0.1uF ceramic decoupling capacitor across the
power supply of each LED. The circuit is shown in Figure 7-2.

Figure 7-2: The LED schematic.

Note: Figure 7-2 shows just 4 of the 16 LEDs for clarity; the other 12 LEDs are
wired just the same between the broken doted lines.

Switches
The switch circuit is a bit more complex. It’s based around the 4 x 4 silicone button
pad sold by SparkFun Electronics, composed of 16 switch covers that have a ring
of conduction carbon at the base. The idea is that it fits over a dual ring and spoke
track on a PCB; when the cover is pressed, the conducting ring makes contact and

shorts out the inner and outer PCB track rings, completing a circuit.
In theory, you could just wire up each switch to a separate GPIO pin, but when you
use a lot of keys, you use a lot of inputs, so switches are often arranged in a matrix,
as shown in Figure 7-3. In a matrix, there are rows of switch inputs feeding into
column outputs. Each switch is isolated with a diode. This component lets the
electric current flow only one way; it’s important to stop the production of phantom
key presses when more than one switch is pressed at once. You can see that
although there are 16 switches, only 8 GPIO pins are used. In general for a square
matrix, the number of switches you can have is the square of half the number of
GPIO pins you use. As you use more GPIO pins, the saving becomes greater.

Figure 7-3: A switch matrix.

The price you pay for this efficiency in hardware is that you need to be clever with
the software. Basically, the software scans the matrix. It puts one row line high and
the others low. Then it looks at each column input in turn, and if an input is found
with a logic 1 on it, you know what key is being pressed on that first row. If nothing
is found, then that row is made to output a 0 and the next row is set high. Then the
inputs are scanned again. This process is repeated until the whole matrix has been
scanned. Suppose switch SW9 is pressed. Only when Row 3 is high will there be a
high on Column 2.

Here’s a small trick to save time seeing if any key is being pressed: Put all
the rows high and then if you see a logic high on any column, you know that

some key is being pressed. Although this isn’t the only way to read a keypad
matrix like this one, it’s by far the most common and is the method used on the
board we’re going to hack.

The PCB
In addition to reading switches in a matrix, you can light LEDs in a similar manner,
and that’s what the board you’re going to hack was originally designed to do. In
each row, all the red LEDs are connected together, as are the green and blue
components of the RGB LEDs. This is shown in Figure 7-4, along with the pin out
of the RGB LEDs used. Also shown are the connector numbers for the rows and
columns. Note the switch matrix circuit in addition to the LED circuit on the board.
The switch row inputs are marked as S on the connector pads labeled JP.

Figure 7-4: The original LED matrix circuit.

To convert this into a circuit suitable for the WS2812b LEDs, you need to cut some
tracks and add some links in order to convert it into the circuit shown in Figure 75. Note how similar it is. What was the blue LED connection on the original board
will now be the positive 5V power line. For each row, the green connection is the
data input to the first LED, and the red connection is the output from the last LED in
the row. Each LED has its data output linked to the data input of the next LED in the
row with a wire link.

Figure 7-5: The modified LED circuit.

So, first, you need to make 25 cuts in the tracks of the PCB. The trick is making the
correct 25 cuts (see the X’s in Figure 7-6). These cuts should be done with a sharp
knife or scalpel. Make two cuts in the track close to each other, and then use the
blade to remove the small section of track between the two cuts.

Figure 7-6: PCB track cuts.

The only tricky cut is the one on the data output of the first LED on row 1, next to
the label Switch 1. This must be between the LED and the track going off to the
connector. This is shown in detail in Figure 7-7.

Figure 7-7: Close-up of the bottom-left cut.

Construction
The next step is to solder in all the diodes, which are marked on the board as
rectangles with a line at one end. Make sure this line coincides with the line
marked on the diode itself.
Now, normally you would insert the diode and solder the other side of the board.
However, in this board, the silicone rubber switches will be placed on this track
side of the board, so you want as little height on the joints on this side as possible.
The technique we used was to fit the diode, and then trim off the lead on the track
side flush with the level of the board with a pair of side cutters. Then solder from
the component side, letting the solder be sucked down into the hole by capillary
action. Be careful not to put too much solder on the joint because you’ll get a dome
on the wiring side. The silicone rubber can take some distortion, but try to keep it
to a minimum. Figure 7-8 shows the three steps in mounting the diodes.

Figure 7-8: Soldering the diodes and track-side wires.

At the next stage, you add the LEDs, pushing them through the other side of the
board to the diodes and bending the legs so that the LEDs lie as close as possible
to the board. Notice that there’s a very subtle flat on the side of the LED that marks
the data out connection. The data out and the ground connections are also longer
than the other two pins. It’s critical that the LEDs are put in the board the right way
around. You’ll see an exaggerated flat on one side of the legend where the LEDs
are to be inserted, as shown in Figure 7-9.

Figure 7-9: The mounting of the LEDs.

Notice the holes showing in Figure 7-9 with the component wires soldered from
the track side and the solder filling the hole but not seeping through. Also, notice
the two circles with interleaving spokes that surround the LEDs. These are the two
contacts of the switch; the conducting rubber ring on the silicone cover makes
contact between the inner and outer ring when the switch is pressed. Keep your
fingers off these rings or at least wipe them down with a grease solvent before you
fit the silicone cover.
Now that the LEDs are in place, you can wire up each row of LEDs so that the data
out of one LED goes into the data in of the next. We used some thin insulated wire
to do this. There are three links on each of the four rows.
Finally, you need to solder a ceramic capacitor across the middle two wires of the
LEDs. These wires are decoupling capacitors and ensure a smooth power supply
for each controller chip in the LEDs. We used a small surface mount capacitor and
held it close with fine tweezers while we soldered it onto the pins. If you like, you

can use small leaded capacitors — just make sure you bend the leads so that
they’re as short as possible when soldered up. A photograph of this is shown in
Figure 7-10.

Figure 7-10: Linking up the LEDs.

Now the rows and columns can be commoned up to complete the circuit. Figure 711 shows a diagram of these, as well as where they should be connected to the
Raspberry Pi’s GPIO pins.

Figure 7-11: Linking up the board connectors.

Connecting to the Raspberry Pi
We decided to use a flying lead from the Light Fantastic board to the Raspberry Pi
through a ribbon cable. This allows you to easily attach and detach it. If you have a
Raspberry Pi Model B+, you’ll need a 40-way IDC connector; otherwise, you need
a 26-way one. Either way, you need about half a yard of 26-way ribbon cable;
clamp it to the connector, ensuring that the red wire on the cable is pierced by the
connector marked with a triangle, as shown in Figure 7-12. Now squeeze it up in
the vice and add any strain relief clamp that came with the connector. The red wire
is now pin 1 on the GPIO connector and will be the wire in the ribbon connector
closest to the edge of the Raspberry Pi board when you plug it in.

Figure 7-12: Clamping up one end of the ribbon cable.

Having fitted the connector at one end, you can proceed to wire up the other end to
the Light Fantastic board; the connections are shown in Figure 7-13. Strip back the
individual wires and cut short those that aren’t used. Connect them to the back of
the PCB in Figure 7-11. Note the two 5V and two ground connections — wire them
both up to reduce any resistance from the connectors. If you don’t have a spare amp
in your Pi’s power supply, connect an external 5V supply to the board and don’t
connect the 5V on the ribbon cable. When we were finished, we used a doublesided foam pad to stick the ribbon cable to the PCB and stop any mechanical strain
from being put on the individual joints.

Figure 7-13: The flying lead to the Raspberry Pi.

To finish it off, we put the silicone cover over the LEDs. We fastened it to the PCB
with a nut and bolt in the center and middle positions. Don’t tighten the nuts too
tight, or the silicone will distort. Finally, we attached a 15mm M3 tapped pillar to
each corner of the board so that it stood up on the desk while we tested it.
At this point, the electronic construction is complete, and you can use the project
just as it is. However, the project looks much better if you surround it with a box.
Also, the colors of the LEDs look so much stronger with a black background, and
putting light baffles between the keys stop colors from interfering with each other.
We describe one way of doing this in the next section, but if you’re making this,
you may want to skip to the testing stage to see if it works before committing to
making the box.

Boxing the Light Fantastic
The project looks much better if it’s finished off by putting it in a box. Not only
does it look neater, but there is much less glare and the buttons’ colors are better
defined. The trickiest part about putting a box around it is making the top bezel.
Although you can buy four 2 x 2 bezels for the switch cover, they’re quite
expensive, so we decided to make our own. It would’ve been simple to laser-cut
some thin plywood, but we didn’t have access to a laser cutter. If you do have
access to one, there is a PDF on the book’s website

(www.dummies.com/go/raspberrypiprojects) that contains the cutting file.
We used this file to print out the size and position of the 16 square holes and sprayglue mounted it onto some 3mm-thick ABS plastic sheet. Then we used a drill to
rough out the holes and a file to give them as neat an edge as we could. It took us
about four hours to do this, but a file and a drill is all you need. The only file we
had that fit the square holes was a triangular one. Figure 7-14 shows our progress
partway through the process.

Figure 7-14: Cutting out the top bezel.

The final fitting process involves carefully enlarging the holes one at a time and
testing that the button tops slip snugly over the top.

Don’t be too worried about the straightness of the edges to the holes.
Visually, any small imperfections are masked by the contrast of the two parts,
and it looked a lot more precise than it actually was.
We made the base from exactly the same template as the top, only we didn’t need to
cut out the holes for the switches.
You can make the sides of the box from thin plywood if you like, but we used some
scrap fiberglass PCB material, which is strong and thin and machines easily
(although it will blunt your tools faster). We think it gives the box a “geek tech”
feel. We used strips 26mm wide so that the button tops protruded just 2mm above
the top bezel. These were mounted on the base by some 50mm lengths of angle
aluminum held in place by two pan-head screws and nuts (see Figure 7-15). The
right side had this bracket offset so that the ribbon cable could come out of the side;

a small recess in the side was cut in with a file to allow the ribbon cable to go
underneath.

Figure 7-15: The side brackets.

We applied a little epoxy to fix the nuts to the brackets so they could be fastened
without having access to the inside of the box. On the underside of the top bezel,
we fitted some strips of the same ABS plastic we used for the top to shield the lit
buttons from each other. They were held in place by model airplane glue (see
Figure 7-16). In the central strip, we put a small notch in the center and each end to
clear the head of the rubber key fixing screws. Then we carefully painted the top
bezel a flat matte black. If we had used plywood for the sides, we would’ve
painted them as well at this stage.

Figure 7-16: Light baffles on the underside of the top.

In theory, the next step is simple: Drill four holes in the base to take the pillars of
the PCB assembly. In practice, though, you don’t know exactly where to drill them
and still have the top bezel square. So, we removed the side panel with the ribbon
cable slot, put the bezel on the buttons, and aligned everything nice and square.
Then we put some hot glue around the base of the two pillars; when it had set, we
disassembled the sides and unscrewed those pillars from the PCB. This left just the
base with two pillars glued to it in exactly the right place. Then we took a 2.2mm
drill (a 2mm one will do if you haven’t got a 2.2mm) and drilled through the pillars
into the base. Then we picked off the pillars and the hot glue and drilled out the
hole to 3mm. This meant that the two holes were in exactly the right place. So, we
assembled it again with screws through the base into the two pillars — only this
time, we left the opposite side off and repeated the glue and drill trick to get the
other two pillars in exactly the right place.
Finally, we assembled the box again, left both sides off, and tacked the top bezel to
the two remaining sides at the corners, again with hot glue. Then we removed the
two sides and the top bezel, now attached to each other, and put a heavy glue fillet
around the inside of the sides and top.

Make sure you leave a small unglued area for the other two sides to fit in.

Bringing It All to Life
Now you need to write some software to read the switches and light the LEDs. If
you’ve done the project in Chapter 6, you’ve installed the NeoPixel Library; if not,
turn back to Chapter 6 to see how that’s installed.
Because both the NeoPixel library and the reading of switches require access to the
GPIO, you need to be in root mode, so open IDLE with gksudo idle from the
command line. Then type in the code in Listing 7-1 to test them both.

Listing 7-1: Switch and Lights Test
# NeoPixel Light Fantastic
# Switch & lights test
# Author: Mike Cook
import time, random
import wiringpi2 as io
from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
# LED strip configuration:
LED_COUNT
= 16
# Number of LED pixels.
LED_PIN
= 18
# GPIO pin connected to the pixels
LED_FREQ_HZ = 800000 # LED signal frequency in hertz
LED_DMA
= 5
# DMA channel to use for generating signal
LED_INVERT
= False
# no need to invert on the Light Fantastic
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT)
def main():
initGPIO()
strip.begin()
print"Keyboard to LED test - Ctrl C to quit"
print"pressing key will light up the LED"
wipe() ; key = 1
while True:
while keyPressed() == False :
pass
newKey = getKey()
if newKey != -1 :
key = newKey
wipe()
while keyPressed(): # wait for release
pass
strip.setPixelColor(key, Color(255, 0, 0))
x = key % 4
y = key / 4
print"key ",key," X=",x," Y=",y
strip.show()
def initGPIO():
for pin in range (0,4):
io.pinMode(pinList[pin],0)
io.pullUpDnControl(pinList[pin],1) # input enable pull down

for pin in range(4,8):
io.pinMode(pinList[pin],1) # output
io.digitalWrite(pinList[pin],1) # all high
def keyPressed(): #is a key being pressed>?
pressed = False
for pin in range(0,4):
if io.digitalRead(pinList[pin]):
pressed = True
return pressed

def getKey():
key =-1 # -1 = no key
for outPin in range(4,8):
io.digitalWrite(pinList[outPin],0) # all low
for outPin in range(4,8):
io.digitalWrite(pinList[outPin],1)
for read in range(0,4):
if io.digitalRead(pinList[read]):
key = ((outPin-4) * 4) + read
io.digitalWrite(pinList[outPin],0) #remove active row
for outPin in range(4,8):
io.digitalWrite(pinList[outPin],1) # leave all high
return key
def wipe():
for i in range(0,strip.numPixels()):
strip.setPixelColor(i, Color(0, 0, 0))
strip.show()
# Main program logic follows:
if __name__ == '__main__':
main()

The setting up of the NeoPixel library should be familiar to you if you read Chapter
6; the difference here is that there are only 16 LEDs. The pinList list is the GPIO
pin numbers used for the switch matrix. The first four are the input columns, and the
last four are the output rows of the matrix. These pins are initialized in the
initGPIO function. Note that the inputs have their pull-down resistors activated so
they’ll read a steady zero in the event of no key being pressed. The row outputs are
all set high in preparation for the next function, keyPressed.
This function’s job is just to return a True if a key is being held down and a False
if it is not. It assumes that all the rows are high, which they will be after that first
function. It does this by initializing a variable pressed to be False and then
looking at each column in turn and setting this variable to True if a logic 1 is seen
on any of the input columns.
Although sometimes you just want any key indication, when the program knows a
key is being held down, it’s normal to want to know which key. This is where the
getKey function comes in. It starts off by setting all the row outputs to 0. Then a
for loop will put them high one at a time. Inside this for loop is another for loop,

which reads each column in turn. If a logic 1 is detected, it sets a variable called
key to be the index of this inner loop plus four times the index of the outer loop —
in other words, the key number. Before the function exits, the code sets all the row
outputs high (to a logic 1) for the next time the keyPressed function is called.
The wipe function simply sets each pixel color to black. So, all that remains is the
main function. This calls the functions that initializes the key’s GPIO pins and the
LEDs and sets them all to black. Then it enters an infinite loop where it waits until
there is a key press; then it goes off to read the key, wipes the LEDs, and waits for
the key to be released. Then the LED corresponding to the key being pressed is set
to green and both the key number and its x- and y-coordinates are printed out before
the pixel buffer is transferred to the LEDs with the strip.show function call.
Now, you may have spotted that we said the LED to light up would be green, but
we set this up with the line strip.setPixelColor(key, Color(255, 0, 0)),
which, as you may expect from Chapter 6, would be red. It turns out, for no
explained reason we can tell, that the 5mm version of the WS2812b has the red and
green data packets swapped over when compared to the surface mount package
used in the LED strips and rings. So, you need to swap red and green in the function
call to get the color you expect.

A bit of a show
Now that we have everything working, we finish off this chapter with a bit of a
light show. Basically, it consists of eight sequences that you can use to turn on the
LEDs and a way of generating a random color. The LEDs turn on one at a time with
a small interval between them and then rapidly turn off. This repeats until another
key is pressed — the keys are looked at only after the sequence ends, so you have
to press a key and hold it until all the lights are off before you can change the
sequence.
For each sequence, there are two ways of generating the color: one changing every
four steps in the sequence and the other changing every step. The top eight keys
evoke the first changing method; the second eight keys evoke the second step.
The way colors are generated here is worth a mention. If you want to generate a
random color, setting the red, green, and blue components may seem to be what you
would want to do, but that’s not the case. Although it will produce random colors,
they’ll mostly turn out to be fairly washed out.
What you need is another way of representing color. The red, green, blue (RGB)
method is often called a color cube, with each color component representing a

coordinate in a cubic space. There are several other color models as well; one
popular one is known as hue, saturation, value (HSV). The hue is what you would
describe as the basic color; the saturation is how intense that color is; and the value
is the brightness of the color.

Saturation and value are quite different, although they sound like they may
be the same thing. If you were to deal with mixing paints, the hue would be the
basic pigment, and the saturation would depend on how much white you
added. For a fully saturated color, you would add no white, and for a pale,
washed-out color, you would add a lot. Similarly, the value would be how
much black paint you added — no black for the full brightness and a lot for a
very dim, dark color. This representation of a color is often known as hex
cone space because the space bounded by these coordinates represents a
hexagonal cone. We use a simple function to generate a full-brightness, fully
saturated color that is very useful for generating a reasonable set of random
colors.
The code for the light show is shown in Listing 7-2. Because this has the key
reading functions identical to those in Listing 7-1, to save space they aren’t printed
here — just copy the function from the previous listing you typed.

Listing 7-2: The Light Fantastic Light Show
# NeoPixel Light Fantastic
# Light sequence
# Author: Mike Cook
import time, random
import wiringpi2 as io
from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
order =[ [ 0,1,2,3,7,6,5,4,8,9,10,11,15,14,13,12 ],
[ 0,4,1,5,8,2,12,3,9,6,13,7,10,14,11,15 ],
[ 9,10,6,5,4,8,12,13,14,15,11,7,3,2,1,0 ],
[ 12,9,6,3,0,5,10,15,4,8,13,14,11,7,2,1 ],
[ 12,8,4,0,1,2,3,7,11,15,14,13,9,6,10,5 ],
[ 0,8,1,9,2,10,3,11,7,15,6,14,5,13,4,12 ],
[ 12,3,15,0,9,6,10,5,8,7,4,11,13,2,14,1 ],
[ 12,15,0,3,8,11,4,7,13,1,14,2,9,6,5,10 ], ]
strip = Adafruit_NeoPixel(16,18,800000,5,False)
def main():

initGPIO()
strip.begin()
print"Use the light fantastic keyboard to:-"
wipe() ; key = 1
print"press key for demo ",
print"press and hold until lights go out to change demo"
while keyPressed() == False :
pass
while True:
newKey = getKey()
if newKey != 16 :
print "New sequence ",newKey
key = newKey
wipe()
while keyPressed(): # wait for release
pass
if key < 8:
fill(key, True)
elif key < 16:
fill(key-8, False)
def initGPIO():
# see Listing
def keyPressed():
# see Listing
def getKey():
# see Listing
def wipe():
# see Listing

7-1 for this function
7-1 for this function
7-1 for this function
7-1 for this function

def colorH(angle): # Color returned H=angle, S=1, V=1
while angle <0 : # get angle in range 0 to 255
angle += 256
while angle > 255:
angle -=256
if angle < 85:
return Color(255 - angle * 3, angle * 3, 0)
elif angle < 170:
angle -= 85
return Color(0, 255 - angle * 3, angle * 3)
else:
angle -= 170
return Color(angle * 3, 0, 255 - angle * 3)
def fill(seq, col):
startH = random.randint(0,360)
incH = random.randint(7,35)
color = colorH(startH)
for i in range(0,strip.numPixels()):
if col :
if (i % 4) == 0 :
color = colorH(random.randint(0,360))
else:
startH += incH
color = colorH(startH)
strip.setPixelColor(order[seq][i], color)
strip.show()
time.sleep(0.3)
time.sleep(1.0)
for i in range(0,strip.numPixels()):
strip.setPixelColor(order[seq][i], Color(0, 0, 0))
strip.show()
time.sleep(0.05)

# Main program logic follows:
if __name__ == '__main__':
main()

The sequence is defined as a list of lists or two-dimensional array called order.
This sets the order of what lights to turn on in any sequence. Following that, the
call to the Adafruit_NeoPixel function is the same as the previous listing, except
the parameters are placed in the call directly leading to another saving of lines in
the listing. The main function is very similar to the previous listing, only this time,
at the end, the fill function is called. It’s called with the second parameter either
True or False, depending on whether the key number is less than eight. This
defines the color-changing strategy. The first parameter defines the sequence and,
because there are only eight of them, it’s kept below eight for key numbers above
seven by subtracting eight.
The functions fill and colorH are the new ones here. The fill function does all
the work driving the LEDs, and colorH does the setting of the color given a
number representing the angle H. To make matters simpler, angles are given in
1/256th of a circle to match the resolution of the color in RGB space.
The fill function takes in two values: the sequence to use and the way to change
the color, either a random color in groups of four, or a chain of blending colors.
The color is defined by the H or hue number and is first set to be a random number;
then the increment of this number (that is, the amount it’s changed each time you
want a new number) is set to a random number between 7 and 35.
Next, a for loop steps through each position in the sequence in turn, and sets the
pixel color, updates the strip, and delays for a short time. Depending on the way the
color is changed, either the startH variable is incremented or every fourth time
around the loop a new color is set. The % operator gives the reminder from a
division, so i % 4 is zero every fourth loop.
Before that, the loop index is examined to see if the color needs changing; if it
does, it updates the colorH variable startH calls colorH function.
The colorH function may look a little strange, but it isn’t so bad when you know
what’s is doing. First, it ensures that the given angle is within the range of 0 to 255.
Then it splits the range of possible angles into three, representing the three basic
primary colors. Then it generates a color from this primary color and the next one
in the sequence. Note that there is always a color component that is zero and a mix
of the other two components. The times by three in the color setting statement maps
one-third of the circle to the range of the individual color components.

Things to try
You can tinker with this for variety. For example, you might alter the sequence of
lights or add more sequences. You can run the original demo from the NeoPixel
library. We’ve added some changes to this and incorporate reading the keyboard to
select a sequence and also swapped the red and green to make the colors to be as
they were originally intended; that listing can be found on the book’s website
(www.dummies.com/go/raspberrypiprojects). You could make it so that you
show a whole frame of pixels at once or show a sequence of them to make an
animation like a firework exploding. You could even read the sequence of frames
from a file.
In the next chapter, we show you how to play some games with the Light Fantastic.

Chapter 8

Games for the Light Fantastic
In This Chapter
Making more projects with the Light Fantastic keypad
Finding hidden treasure and learning the resistor color code
Making a color sequence sliding block puzzle
Trying your skill at matching colors
Battling logic to get all the lights out
Having built the Light Fantastic in Chapter 7, you’re ready to have some fun with it.
This chapter presents four games, along with ideas for variants and more complex
puzzles. Each one is colorful fun.

If you haven’t built the Light Fantastic yet, be sure to turn back to Chapter
7. You won’t get very far in this chapter otherwise.
A few notes before we begin: The Light Fantastic consists of illuminated push
buttons. Each one can be set to a range of colors too subtle for your eye to
distinguish. In scientific terms, this is known as better than a “just noticeable
difference.” The color of each LED is defined by writing a value of the red, green,
and blue components of the color into a buffer. When the buffer has been set to
what you want to display, it’s transferred to the LEDs with the show call. The push
buttons and LED positions should match up, as shown in Figure 8-1.

Figure 8-1: Light Fantastic position mapping.

The sequence numbers start at 0 and go to 15, but there is an alternative way of
describing a position: with a pair of x- and y-coordinates. This is quite a handy
thing to do when you’re looking for an adjacent position rather than just the next
one in the sequence. In Figure 8-1, you can see how we can convert a sequence
number to x- and y-coordinates and back again. You may not have come across the
% operation before, but in Python (and many other languages), it’s the modulus
operation. That means, “Do an integer division, but just give the remainder.” Note
that the divide operator (/) returns just an integer; if the two numbers involved are
integers, it throws away the reminder.
Finally, in order to save on your fingers some functions that are the same in all
programs are not repeated. Instead, after the function definition is a note saying
where the function can be copied and pasted from. All these programs require you
to enter the IDLE editor by using gksudo idle from a command-line window. The
programs interact with the user through the Python console window, so keep that
the active window (the one with the keyboard focus). All the programs run in an
infinite loop, so when you want to quit one, press Ctrl+C. If that doesn’t appear to
work, click with your mouse on the Python console window to give it the keyboard
focus.
Let the games begin!

Treasure Hunt
Treasure Hunt (see Figure 8-2) is a simple game with an educational motive. A
treasure has been hidden in one of the squares, and you have to find it. If you guess
right and press the right square, it flashes. If you press the wrong square, the square

lights up in a color that tells you how many squares you are away, in terms of
horizontal plus vertical distance (diagonal distances don’t count).

Figure 8-2: Treasure Hunt.

Notice in the diagram that the distance of every square has a number in it. On the
Light Fantastic, there are only colors, so the colors that light up are the distance
numbers in the resistor color code colors. So in addition to playing a game, you’re
learning the resistor color code (well, at least up to six).
Resistors have their values marked in colored bands, with each color representing
a number. They are as follows:
0
1
2
3
4
5
6
7
8
9

Black
Brown
Red
Orange
Yellow
Green
Blue
Violet
Gray
White

You need to learn these codes if you’re going to work with electronics.
Unfortunately, LEDs aren’t good at producing brown and orange, and brown can be
confused, exactly as it can be with real resistors. It’s easy enough to fiddle around
with the numbers if you don’t like our rendering of the colors.
The code for this game is given in Listing 8-1.

Listing 8-1: Treasure Hunt

#!/usr/bin/env python
# NeoPixel Light Fantastic
# Treasure Hunt
# Author: Mike Cook
#
import time, random
import wiringpi2 as io
from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
# black=0, brown=1, red=2, orange=3, yellow=4, green=5, blue=6
distanceC = [ Color(0,0,0), Color(45,139,0), Color(0,255,0),
Color(120,255,0), Color(255,255,0), Color(200,0,0),
Color(0,0,200) ]
treasure = 0 # location of the treasure
strip = Adafruit_NeoPixel(16,18,800000,5,False)
def main():
initGPIO()
strip.begin()
print"Treasure hunt - find the hidden treasure"
print"pressing a key will show the distance to the treasure"
wipe() ; key = -1
while True:
setBoard() # set up colors to use
while key != treasure:
while keyPressed() == False :
pass
newKey = getKey()
if newKey != -1 :
key = newKey
while keyPressed(): # wait for release
pass
makeMove(key)
print"puzzle complete - any key for new game"
while keyPressed() == False :
pass
while keyPressed(): # wait for release
pass
time.sleep(0.5)
print"play"
def initGPIO():
# see Listing
def keyPressed():
# see Listing
def getKey():
# see Listing
def wipe():
# see Listing

7-1 for this function
7-1 for this function
7-1 for this function
7-1 for this function

def setBoard():
global treasure
wipe()
treasure = random.randint(0,15)
#uncomment to cheat
#print" treasure at",treasure
#strip.setPixelColor(treasure, Color(128, 128, 128))
#strip.show()

def makeMove(move):
distX = abs((move % 4) - (treasure % 4))
distY = abs((move / 4) - (treasure / 4))
distance = distX + distY
if move != treasure:
strip.setPixelColor(move, distanceC[distance])
strip.show()
else:
print"found it"
flashTreasure()
def flashTreasure():
for i in range(0,7):
strip.setPixelColor(treasure, Color(0,0,0))
strip.show()
time.sleep(0.3)
strip.setPixelColor(treasure, Color(0,255,255))
strip.show()
time.sleep(0.3)
# Main program logic follows:
if __name__ == '__main__':
main()

The Colors are defined in a list called distanceC. For these 5mm packaged
versions of the WS2812b LEDs, the Color function takes in the color components
green, red, and blue. Note that black is defined even though it isn’t used in this
game, so all the other colors have a list index, which is the same as the color’s
value in the resistor color code. The main function sets up the LEDs and the
switches and prints the instructions to the console.
The setBoard function picks a random square to hide the treasure in. Note that
there are some cheat lines commented out with # that will show the square number
in the console and even light up the treasure square as a light gray color.
When the main function has a key press, the key number is passed to the makeMove
function. This function first calculates the distance to the treasure by adding up the
x displacement and the y displacement; then it checks to see if the move has found
the treasure. If it has, the flashTreasure function is called. True to its name, it
alternates the treasure square between black (unlit) and magenta (a color not
otherwise in the game).
If the treasure hasn’t been found, the key you pressed is illuminated with a color
equal to the distance. The important point here is the use of a list to define a color
whose index is the distance color.

You can do more with this game if you like. For example, you could make
a more elaborate win celebration, maybe taking the elements of the demo in

Chapter 7. You could keep a total of the best score — that is, the fewest
moves. You could play the game with a time element, where the score is not
simply the number of moves it took you but a measure of the amount of time it
took. Because this is such a simple game, you could change it so that you
played a number of games — say, six — and it gave you an average score.
Finally, you could extend it to a Battleship type of game.

Sliding Block Puzzle
This game is a colorful twist on the sliding-block puzzle game. Normally, you have
to get numbered squares into an ascending order, but here it’s much trickier. You
have to get the colors in the right sequence according to the H value in the HSV
color space (see Chapter 7). The correct color sequence is shown at the start; then
the colors are scrambled up. Normally, you would have no chance of remembering
15 colors from just one showing, so here there are two ways you can get a hint:
Press the blank square, and all the colors that are not in the correct order
will blink. This is great for keeping track of how well you’re doing.
Press a key that is not in line horizontally or vertically with the blank
space. This move would normally be invalid, but here it’s a request to repeat
the display of the final sequence you’re aiming for.
In a normal move, if you press a key that’s adjacent to the blank space, it swaps
position as you would expect. However, if you press a key that’s on the same
column or row as the blank, all the colors are pushed up from where you pressed
into the blank space, and the blank appears where you made the move.
Listing 8-2 shows the code for this game.

Listing 8-2: Sliding Block Puzzle
#!/usr/bin/env python
# NeoPixel Light Fantastic
# Sliding block puzzle
# Author: Mike Cook
#
import time, random
import wiringpi2 as io
from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "

pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
gameOrder =[ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,14 ] # working order
lightC = [ Color(0,0,0) for i in range(0,16) ]
strip = Adafruit_NeoPixel(16,18,800000,5,False)
def main():
initGPIO()
strip.begin()
print"Sliding block puzzle - get the lights in the right order"
print"pressing the unlit block will blink blocks in the wrong place"
print"pressing a key that does not result in a shift will show the right order"
wipe() ; key = 1
while True:
setBoard() # set up colors to use
while not finished():
while keyPressed() == False :
pass
newKey = getKey()
if newKey != -1:
key = newKey
while keyPressed(): # wait for release
pass
makeMove(key)
showSet()
print"puzzle complete - any key for new game"
while keyPressed() == False :
pass
while keyPressed(): # wait for release
pass
def initGPIO():
# see Listing 7-1
def keyPressed():
# see Listing 7-1
def getKey():
# see Listing 7-1
def wipe():
# see Listing 7-1
def colorH(angle):
# see Listing 7-2

for this function
for this function
for this function
for this function
for this function

def setBoard():
global gameOrder,lightC
random.shuffle(gameOrder) # mix up the board
h = random.randint(0,255)
hInc = random.randint(16,35)
for i in range(0,15):
lightC[i] = colorH(h)
h += hInc
showSol()
def showSol():
for i in range(0,16):
strip.setPixelColor(i, lightC[i])
time.sleep(0.08)
strip.show()
time.sleep(1.0)
showSet()
def showSet():
for i in range(0,16):
#print"game order ",gameOrder[i]
strip.setPixelColor(i, lightC[gameOrder[i]])
strip.show()

def finished():
done = True
for i in range(0,16):
#print i," Game order ", gameOrder[i]
if gameOrder[i] != i:
done = False
return done
def showCorrect(): #blink incorrect squares
for blink in range (0,3):
for i in range(0,16):
if gameOrder[i] != i:
strip.setPixelColor(i,Color(0,0,0))
strip.show()
time.sleep(0.5)
showSet()
time.sleep(0.3)
def makeMove(move):
if lightC[gameOrder[move]] == Color(0,0,0):
#blank key pressed
showCorrect()
else:
#print"not blank"
x = move % 4
y = move / 4
blank = findBlank()
if blank[0] == x:
shuffle(4,blank[1],y,blank[2],move)
elif blank[1] == y:
shuffle(1,blank[0],x,blank[2],move)
else:
#print" no alignment with blank"
wipe()
showSol() # show what you are aiming for
def shuffle(incSize,distance,target,blankPos,move): #move into blank
global gameOrder
inc = incSize
if distance > target:
inc = -incSize
while blankPos != move:
temp = gameOrder[blankPos]
gameOrder[blankPos] = gameOrder[blankPos + inc]
gameOrder[blankPos + inc] = temp
blankPos += inc
def findBlank():
blank =(-1,-1,-1)
for i in range(0,16):
if lightC[gameOrder[i]] == Color(0,0,0):
blank = (i % 4, i / 4, i)
if blank == (-1,-1,-1):
# this should never happen
print"error blank not found"
return blank
# Main program logic follows:
if __name__ == '__main__':
main()

The code follows the overall structure of the previous game in terms of

initialization. Here, there are two lists: gameOrder defines the order you have to
arrange the colors in, and lightC defines the current colors. At this initial stage,
it’s set so that they’re all black.
The setBoard function first mixes up the gameOrder list, which defines the initial
startup position. Then the lightC list is populated by a succession of colors
defined by a randomly chosen initial h angle and incremented by a randomly
chosen value, incH. When that’s finished, the showSol function shows the solution,
by simply showing the pixels in the order of the lightC list.
The while not finished( ): line calls the finished function, which returns a
true when the puzzle is complete. It does this by checking that the gameOrder list
matches the sequence 0 to 15. If any entry in the list fails, the logic variable done is
set to false, and it’s this variable that is returned by the function.
So, assuming the puzzle is not complete, the main function waits for a key press.
When it gets one, it calls the makeMove function, which looks to see what sort of
move has been made. If it’s the blank key, it will call the showCorrect function
and blink the positions that don’t contain the correct color. It does that by
alternately blanking the pixels that don’t correspond to the right order and then
showing the current state of the board with the showSet function.
If the move wasn’t the blank key, it works out the x- and y-coordinates of the move
key and then calls the findBlank function, which, as its name implies, returns a
tuple (a list of numbers in one variable) of the x- and y-coordinates of the blank
space. If the blank space is at the same x value as the move, the shuffle function
is called. This takes the colors between the blank space and the move and shuffles
them up one. This function copes with moving the colors along both the x-axis and
the y-axis, depending on what’s needed. We started out by writing two functions —
one to shuffle in the x-axis and the other for the y-axis — but they looked so
similar. So we combined them into one and let the axis be defined by the
parameters passed to it. This make for very efficient use of code, but it can be a bit
tricky to follow at first.
If there is no alignment in either the x- or y-coordinate between the blank space and
the move, this is an invalid move and the code responds by showing the solution —
that is, the sequence of colors you’re aiming for.
When the puzzle is complete, a message is output to the console. On pressing any
key, a new game is set up.

You can experiment with changing the range of numbers used for the incH
variable. Making it a small number makes the game much more difficult, with
blue colors starting to look very similar. Making this value too big means you
lose any sense of blending between adjacent colors.
Because this is a much longer game than the first one, we suggest that you base any
scoring on time rather than the number of moves made. You may want to
incorporate an “I give up” combination of keys.

Color Match
Mike Cook wrote this game specifically to annoy someone in an online forum. He
was using LEDs without any form of current control and claimed that the intensity
of the LEDs had not diminished in three months of continuous operation. It turned
out he wasn’t measuring it in any way but claimed he could tell by looking. Mike
said he couldn’t remember the brightness over three seconds let alone three months,
so he designed this game to prove it. This is a Light Fantastic version that deals not
only with brightness but also with color.
The way this game works is that the center four switches light up for just over a
second. Then all goes dark, and two seconds later the perimeter lights are lit up
and you have to press the one of the same color as the one lit up in the center. Then
the center color, the matching perimeter color, and your guess, if different, flash. If
you got it right, there is only one perimeter light flashing — your choice. If you got
it wrong, you can see the difference between the color you chose and the central
colors. Just to confirm things, a console message is produced as well. If you want
to have another look at the colors, you can press one of the central four keys for a
sneaky reminder.
The code for this program is shown in Listing 8-3.

Listing 8-3: Color Match
#!/usr/bin/env python
# NeoPixel Light Fantastic
# Color Match
# Author: Mike Cook
#
import time, random
import wiringpi2 as io
from neopixel import *

print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
colorOrder = [0,1,2,3,7,11,15,14,13,12,8,4]
colorRange = [ Color(0,0,0) for i in range(0,12) ]
strip = Adafruit_NeoPixel(16,18,800000,5,False)
cheat = False ; target = 0
def main():
initGPIO()
strip.begin()
print"Color Match"
print"the center four lights will flash a single color"
print"then you press the match on the outside"
wipe() ; key = 1
while True:
guess = True
setBoard() # set up colors to choose from
while guess:
while keyPressed() == False :
pass
newKey = getKey()
if newKey != -1:
key = newKey
while keyPressed(): # wait for release
pass
guess = makeMove(key)
print"another go"
time.sleep(1.5)
def initGPIO():
# see Listing 7-1
def keyPressed():
# see Listing 7-1
def getKey():
# see Listing 7-1
def wipe():
# see Listing 7-1
def colorH(angle):
# see Listing 7-1

for this function
for this function
for this function
for this function
for this function

def setBoard():
global colorRange,target
wipe()
h = random.randint(0,255)
hInc = 8 # sets how hard it is
for i in range(0,12):
colorRange[i] = colorH(h)
h += hInc
target = random.randint(0,10)
showReminder()
if cheat :
print target
def showSet():
for i in range(0,12):
strip.setPixelColor(colorOrder[i], colorRange[i])
strip.show()
def showTarget():

strip.setPixelColor(5, colorRange[target])
strip.setPixelColor(6, colorRange[target])
strip.setPixelColor(9, colorRange[target])
strip.setPixelColor(10, colorRange[target])
strip.show()
def showReminder():
wipe()
time.sleep(0.4)
showTarget()
time.sleep(0.9)
wipe()
time.sleep(1.5)
showSet()
def makeMove(move):
guess = True
if move == 5 or move == 6 or move == 9 or move == 10:
showReminder()
else:
guess = False # flash guess and color and right color
if colorOrder[target] == move:
print"Yes right"
else:
print"No wrong"
for t in range(0,6):
wipe()
time.sleep(0.2)
strip.setPixelColor(move, colorRange[colorOrder.index(move)])
strip.setPixelColor(colorOrder[target], colorRange[target])
showTarget()
time.sleep(0.4)
return guess
# Main program logic follows:
if __name__ == '__main__':
main()

Again, following the same template as before, the colorOrder list has in it the
keypad’s numbers for the perimeter of the Light Fantastic display. The colorRange
list is used to hold the colors to display. The main function starts by initializing
things and printing out the instructions. The setBoard function generates a range of
colors to act as the potential target and then chooses one of them at random.
Although the initial point in the HSV color space is chosen at random, the hInc or
increment value is fixed. This effectively controls the change between adjacent
colors; a value in the listing is one that we found to give a just noticeable
difference over the whole range, with blue color changes being the hardest to
detect. Make this value bigger for an easier game.
After the colors have been defined, the setBoard function calls the
showRemainder function. This clears the key colors, shows the target color with
the showTarget function, wipes that, and then shows the colors around the outside
of the keypad with the showSet function.
After all that, back in the main function, the program looks for a key press. There

are two actions that can happen as a result of pressing a key: One is to make a
guess as to the correct color, and the other is to request a review of the target color.
This is decided in the makeMove function. If the move is one of the central keys, it
calls the showRemainder function just like at the end of the setBoard function.
Then it returns a True value to inform the main function that this round has not yet
finished.
If, however, your move is one of the outer keys, that’s taken as a valid answer, and
a check is made to see if the key you pressed is where the target color was in the
colorOrder list. Then your success in matching the color is printed out to the
console. Finally, the target color, your guess, and the correct result are flashed.
Note that there are two lines that define your guess and the correct color. These
are:
strip.setPixelColor(move, colorRange[colorOrder.index(move)])
strip.setPixelColor(colorOrder[target], colorRange[target])

If you’re correct, these two lines will result in setting the same pixel number to the
same color. The use of colorOrder.index(move) is a reversal of how you
normally use lists. This returns a number that gives the position of where the value
of move is in the list.

There are a few things you can tinker with in this program. First, you can
alter the sleep delays so you have longer to wait before you see the choice of
colors. Unsurprisingly, the longer you have to wait, the harder the game. The
order of the color choice also is constantly increasing around the perimeter in
order of increasing H color value. You can scramble that by applying a
random shuffle to the colorOrder list.
Perhaps the biggest change you can make is in the generation of colors. The eye is
much less sensitive to the amounts of blue in a color than to red or green. You
could change the H increment value according to the initial H starting point so that
if H were clear of the blue content — that is, below a value of 170 — then the hue
increment could be smaller. You could change the way the choice colors are
generated so that it gets harder as more and more correct answers are given and
drops down to easy if a mistake is made. Each degree of difficulty could be marked
with a level number. Then you could introduce an element of competition in how
high a level you can get.

Lights Out

Lights Out
Lights Out is a fantastic puzzle. We normally implement it on a 3 x 3 grid, but here
it’s on the 4 x 4 grid of the Light Fantastic. The idea is to turn out all the lights by
pressing keys. The snag is that when you press one key, not only is that key inverted
but those surrounding it are also inverted. It basically inverts a cross pattern of
adjacent keys, but that’s clipped if the key is close to the edge. This is shown in
Figure 8-3.

Figure 8-3: Lights Out logic.

The game works on two levels: First, it’s about getting all the lights out. But when
you get better, the aim is to get the lights out in the minimum number of moves.
You can’t just generate any random collection of lights — it has to be a pattern that
is solvable. To do this is remarkably simple: You start off with a finished
representation of the board and make a number of random moves to generate the
start position. The number of moves it took to generate the start position is the
number of moves you need to get back to the end position. Each move is fully
reversible, so if you press a key twice, you get back to your original position. That
applies no matter what keys you press and in what order. Any sequence of key
presses is reversed by the same keys in a different order. All you need to do in
order to make sure you’re getting the minimum number of moves when you’re
setting up the board is not use any key twice. You can set up a board that is
solvable in any number of key presses you like. It turns out that for one or two
moves, it’s trivial but for three or more moves it becomes increasingly difficult.
The code for the Lights Out game is shown in Listing 8-4.

Listing 8-4: Lights Out
# #!/usr/bin/env python
# NeoPixel Light Fantastic
# Lights Out
# Author: Mike Cook
#
import time, random
import wiringpi2 as io

from neopixel import *
print"if program quits here start IDLE with 'gksudo idle' from command line"
io.wiringPiSetupGpio()
print"OK no crash" ; print" "
pinList = [9,24,10,23,7,8,11,25] # pins for keyboard
litColor = Color(255,0,0)
lightC = [ Color(0,0,0) for i in range(0,16) ]
strip = Adafruit_NeoPixel(16,18,800000,5,False)
cheat = True
def main():
initGPIO()
strip.begin()
print"Lights Out - remove all the lights"
print"pressing a key will invert the light and others surrounding it"
playLevel = int(raw_input("Enter the level 3 to 8 "))
if playLevel < 3 or playLevel > 8 :
playLevel = random.randint(3,8)
print"Setting level to ",playLevel
wipe() ; key = 1
while True:
turn = 0
print"this can be completed in",playLevel,"moves"
setBoard(playLevel) # set up colors to use
while not finished():
while keyPressed() == False :
pass
newKey = getKey()
if newKey != -1:
key = newKey
while keyPressed(): # wait for release
pass
makeMove(key,True)
turn += 1
print"You have had",turn,"turns"
if turn > playLevel:
print"taking more than you should"
if turn == playLevel:
print"Well done - minimum number of turns"
print"puzzle complete - any key for new game"
while keyPressed() == False :
pass
while keyPressed(): # wait for release
pass
def initGPIO():
# see Listing 7-1
def keyPressed():
# see Listing 7-1
def getKey():
# see Listing 7-1
def wipe():
# see Listing 7-1
def colorH(angle):
# see Listing 7-1

for this function
for this function
for this function
for this function
for this function

def setBoard(level):
global lightC,litColor
for i in range(0,strip.numPixels()):
lightC[i] = Color(0, 0, 0)
h = random.randint(0,255)

litColor = colorH(h)
moves = [random.randint(0,15)]
move = moves[0]
makeMove(move,False)
for m in range (0,level-1):
while move in moves:
move = random.randint(0,15)
moves.extend([move])
makeMove(move,False)
showSet()
if cheat :
print moves
def showSet():
for i in range(0,16):
strip.setPixelColor(i, lightC[i])
strip.show()
def finished():
done = True
for i in range(0,16):
if lightC[i] != Color(0,0,0):
done = False
return done
def makeMove(move,play):
toggleColor(move,play)
y = move / 4
if move -4 >= 0:
toggleColor(move -4,play)
if move +4 < 16:
toggleColor(move +4,play)
if ((move -1) / 4) == y:
toggleColor(move -1,play)
if ((move +1) / 4) == y:
toggleColor(move +1,play)
def toggleColor(led,play):
global lightC
if play: # playing the game
if lightC[led] == Color(0,0,0):
lightC[led] = litColor
strip.setPixelColor(led, litColor)
else:
strip.setPixelColor(led, Color(0,0,0))
lightC[led] = Color(0,0,0)
strip.show()
time.sleep(0.2)
else: # setup the board
if lightC[led] == Color(0,0,0):
lightC[led] = litColor
else:
lightC[led] = Color(0,0,0)

# Main program logic follows:
if __name__ == '__main__':
main()

You should be seeing a pattern in these programs by now. Many of the functions
have the same names but do different things, depending on the game. This time, the
state of the board is represented by the list lightC. This needs checking to make

sure they’re all out. One difference here is that you need to type in the game level
on the keyboard at the start of the game. Once it’s set, it’ll be the same for all
subsequent games.
The loop in the main function that plays the game prints a reminder as to how many
moves the board can be completed in. Then the setBoard function is the one that
plays the reverse game to generate the starting position. First, the lightC list is
cleared. Then a random color for the game is chosen. Next, a list of moves is
generated. Notice that after the first move, the while loop keeps generating random
numbers until it finds one that is not in the list of moves. This ensures that the same
key is never used more than once. After each unique move has been generated, the
makeMove function is called. This takes two parameters: one containing the move
and the other containing a logic variable that determines if the game is being played
or set up.
The makeMove function further identifies which positions need to be inverted (or
“toggled” as it’s called in electronics). These positions are the move, and the
positions above, below, left, and right if they’re places on the board. Each one
identified calls up the toggleColor function, which in the setup phase simply sets
the move position lightC list to the opposite of what it is already. Finally, the
setBoard function calls the showSet function to display the board. Then if the
cheat variable has been set to true, it prints out a list of moves you have to make.
When the main function has set up the game, the code loops reading the keys and
checking for completion. After each key press, a reminder is given of how many
turns you’ve had. Then when all the lights are out, a congratulation message is
printed if you did it in the minimum number of turns.

As always, there are a number of improvements and changes you can make
to this basic game. For example, you may want to add a reset button so you
can restart the same pattern if you’ve exceeded the minimum number of turns
and want another shot at the same pattern. You need to add an extra list to
permanently store the start position in order for this to work.
The biggest change you can make is to change the logic. One such change is that you
can restrict the keys you’re permitted to press to just the keys that are currently lit.
This changes the whole feel of the game.

When generating moves, to get to the starting position you need to filter out
those moves that land on a lit position. This is exactly the opposite of how you
would play the game. It needs to be opposite so your play can undo what the
setup has done.
In addition to restricting what can key be pressed, you could change the patterns of
inversions depending on the key pressed. For example, a corner key could invert
all four keys in the corner and a side middle key could invert the whole row or
column. This can be as asymmetrical as you want. As long as the setup function
follows the play logic, the whole concept will work. If you make it too complex,
though, you’ll have a hard time explaining the rules to the players.
Finally, you could define an ending state to the board, which is not all the lights
out. Some of them could be, say, red. Then play in another color — say, green —
and have the red lights toggle between blue and red and the others between green
and off. Although it may sound complex, it’s exactly the same game, just much
harder to play.

Exploring a World of Possibilities
There is no need to stop with these four games — there are a whole host of uses
you can put the Light Fantastic to. The options we present in this chapter are just a
few to give you some inspiration.
The Light Fantastic interface lends itself well to all sorts of variations of the
“Whack-a-Mole” game, where lights come on and you have to press the keys as
quickly as possible to turn them off. You could have some colors the player should
whack and other that the player shouldn’t.
You can also make a colorful version of a plumbing game where you have to
unblock a drain by maneuvering pipe blocks into place to make the water flow.
How about a snake game that wraps around top and bottom, as well as left and
right, of the playing area?
Then there’s tic-tac-toe. Normally it’s played on a 3-x-3 grid, but there’s nothing
stopping you from using a 4-x-4 grid. In fact, how about four in a row?
Finally, you don’t have to stop at games. You can use the keys to control just about
anything, from media players to musical instruments. You have the tools now. Let

your imagination flow!

Part III

Developing Advanced Interfaces

Find out about facial recognition in an article at
www.dummies.com/extras/raspberrypiprojects.

In this part …
Find out how to read analog signals into the Raspberry Pi and get analog-todigital conversion techniques.
Build a brick in the wall game control.
Build a temperature measuring module.
See how the Raspberry Pi can interact with the cloud and find out about
databases and web servers.
Make a data logger.
Make a computer vision monitored Connect Four game.
Build the Raspberry Jazz Glitter Trio.

Chapter 9

Advanced Interfaces
In This Chapter
Converting analog to digital
Building an analog-to-digital converter
Using a potentiometer
Creating an analog temperature sensor
Interfacing with an analog-to-digital microchip
The Raspberry Pi general-purpose input/output (GPIO) pins are capable of
detecting digital signals — either high or low. The problem is, the world we live
in is a lot less black-and-white than that. For example, what if you want to detect
light, sounds, temperature, or pressure? A digital signal isn’t going to cut it.
Instead, you need the ability to detect a range of electronic signals, and that’s
where analog signals come in.
One of the shortcomings of the Raspberry Pi is that it doesn’t have any analog
inputs. But you can easily solve this problem by using an analog-to-digital
converter. In this chapter, you build your own converter, learn about different
conversion methods, and write software for each. Toward the end of the chapter,
we look at a high-precision analog-to-digital converter microchip.

Converting Analog to Digital
The Raspberry Pi’s digital inputs can detect binary signals, which are either high
or low represented by either 0V or 3.3V. However, an analog signal consists of a
range of voltages. A 5V analog sensor, for example, may output voltages from 1.5V
to 5V. An analog-to-digital converter (sometimes known as ADC, A-to-D, or A/D)
converts the variable voltage to a reading that can be interpreted by the digital
microprocessor or, in our case, the Raspberry Pi.
But how do you determine a variable voltage when all you have is a digital input
that has only two states?

One method that is frequently used by microprocessors is to treat the analog sensor
like a resistor connected to a capacitor and time how long it takes to charge up a
capacitor. Capacitors don’t charge instantly; the amount of time they take to charge
varies depending on the voltage. Unfortunately, this method isn’t very accurate on
the Raspberry Pi, because the Linux operating system can’t accurately measure
clock cycles, so your results would be inaccurate. Additionally, this method works
only on analog devices that act as resistors like potentiometers, temperature
sensors (thermistors), and photocells.
Another method is to compare the analog voltage to a known reference voltage.
Using a device called a comparator, we can determine if one voltage is greater
than the other. Even though you don’t know the analog voltage level, the
comparator will tell you when your reference voltage is greater than the analog
voltage. By comparing one voltage to the other, you can make a series of calculated
guesses to determine the analog voltage.
Figure 9-1 demonstrates how you can increase your known reference voltage and
perform series of tests using a comparator. When you receive a positive result from
the comparator, you know the analog voltage is somewhere between the current and
previous levels.

Figure 9-1: Use a comparator to compare a known voltage to an unknown voltage in order to determine
the unknown voltage.

Comparators are often associated with analog-to-digital conversion because of
their ability to compare two voltages. A comparator compares the voltage of two
inputs and outputs a digital signal indicating which is larger. Figure 9-2 shows a
diagrammatic representation of the LM339 comparator, which has four analog
inputs and 14 pins in total — 8 inputs, 4 outputs, and 2 pins for +VE and GND.
(The LM339 is available from electronics stores or online, and it’s very
affordable.) The comparator is one of the components you use to build an analogto-digital converter later in this chapter.

Figure 9-2: A diagram of the LM339 comparator chip.

The pulse width modulation (PWM) is the component that enables you to vary the
voltage going into the comparator, which makes the method shown in Figure 9-1
possible on the Raspberry Pi. PWM works by regulating energy using a succession
of pulses, known as the pulse train. By increasing or decreasing the pulse width,
you can regulate energy flow. PWM is often used to regulate the brightness of an
LED by making the LED blink on and off at different frequencies, which makes it
look bright or dim. As long as it blinks faster than the persistence of our vision, you
don’t see it flickering. The analog-to-digital converter uses PWM to alter the DC
voltage of the reference voltage going into the comparator.

Figure 9-3 shows how you can alter the voltage by changing the waveform of the
signal. If the average high state of the pulse train is high, then the voltage will be
high; if the average high state of the pulse train is low, then the DC voltage will be
low.

Figure 9-3: Pulse width modulation can be used to alter DC current.

GPIO 18 on the Raspberry Pi can be configured for PWM. In order to create a
digital pulse train, you connect GPIO 18 to the positive end of a comparator and a
test voltage to the positive end of the comparator. When the test signal is higher, the
comparator will output a positive digital signal; when it’s lower, the comparator
will output a negative signal.
We will use a low-pass filter on the PWM signal, which has a smoothing effect and
produces a DC output that is connected to the –VE side of the comparator. The
filter attenuates the high frequencies and lets through the lower ones. A common
method to create a low-pass filter is to use a resistor and a capacitor in series to
smooth the signal. The test voltage is connected to the +VE side of the comparator.
As shown in Figure 9-4, the output from the comparator tells us whether the test
signal is greater or less than the PWM. We can alter the DC current of the input
using PWM from the Raspberry Pi, which gives us a method of guessing the test
voltage. Later in this chapter, we examine three commonly used methods of
guessing the test voltage. You use PWM, a comparator, and a low-pass filter to
build an analog-to-digital converter later in this chapter.

Figure 9-4: Use a comparator to convert the PWM waveform into a digital pulse train.

Considering the accuracy of analog-to-digital conversion
The intersection of the analog voltage (A) and the reference voltage (B) is
approximate (refer to Figure 9-1). You can get very close to the analog voltage
reading, but you’ll never get the exact reading. Analog-to-digital converters are
usually described by their resolution, which represents the range of readings
they’re capable of producing. For example, an analog-to-digital converter that has
a resolution of 8 bits can produce a range of 256 readings (28 = 256). A 10-bit
converter has a resolution of 1,024 (210 = 1,024). An analog signal is a range of
electronic signals, so the higher the bit rating of the converter, the bigger the range
of analog signals it can support.

The resolution gives you the range of readings it can support, but it isn’t an
indication of the converter’s accuracy. The data sheet of most analog-todigital converters tells you the converter’s accuracy ratings, which describes
the potential variance between the analog signal and the digital reading.

These variances are usually given in the unit of least significant bits
(LSBs). The LSB is the rightmost bit of a number. For example, a 10-bit
number is represented in binary as a ten-digit number of ones and zeroes (for
example, 1111111000). The three zeroes are the least significant bits. If a 10bit analog-to-digital converter has an accuracy of 2 LSB, that means its actual
accuracy is 8 bits.
This explains an important difference between an analog-to-digital converter’s
resolution and its accuracy. The accuracy of an analog-to-digital converter is

nonlinear. The extent of the variance changes depending on the voltage. This is
called nonlinearity, meaning the accuracy is nonlinear to the voltage.
Another aspect of accuracy is repeatability. You see during the course of this
chapter that all the analog-to-digital converters and methods we use produce a
reading that is very close to the analog signal, but that reading is constantly
fluctuating. (We explore methods to minimize — or even eradicate — the
inaccuracy.) This constant change is called the analog-to-digital converter’s
repeatability. Any analog-to-digital converter can only give a reading of +/–1
LSB.
In this chapter, we compare the accuracy of different conversion methods and make
tradeoffs between conversion time, resolution, and the filter to design an analog-todigital converter that suits your need.

Making sense of a digital reading
You may be wondering, “What does the digital reading mean?” We’ve explained
that analog-to-digital converters can have different resolutions and can produce
readings within the range of the resolution. But what does a reading of 524, for
example, out of a possible 1,024 actually mean?
In order to make the reading meaningful, you need to understand its relationship to
the analog signal. One way to do this is to convert the reading into a value
representing the analog voltage. The analog-to-digital converter has a maximum
reference voltage. The reference voltage gives you a yardstick to calculate the
analog voltage value from the digital reading.
For example if a 10-bit analog-to-digital converter has a reference voltage of 5V
and produces a reading of 310, then the analog voltage is
(311 ÷ 1,024) × 5 = 1.519V
However, knowing the analog voltage doesn’t always mean that much. For
example, a potentiometer connected to a 10-bit analog-to-digital converter will
produce a reading of 0 when turned all the way to the left and 1,023 when turned
all the way to the right. Having a reading between 0 and 1,023 for a potentiometer
probably makes more sense to you than a voltage from 0V to 5V, for example. It all
depends on what information you require from the analog device.

Understanding the relationship between the digital data you receive from
the analog-to-digital converter back to the sensor is an important aspect of
your design.

Introducing the Analog-to-Digital
Conversion Methods
In this section, we introduce you to three commonly used methods for analog-todigital conversion. Later in the chapter, we walk you through each method in
greater detail.
Each of these methods uses a comparator to compare two voltages and make a
series of guesses to try to get as close as we can to discovering the analog voltage.

The ramp method
If an analog sensor has a voltage of 1.75V and you compare it to a known reference
voltage that starts at 0V and increments until the reference voltage is greater than
the analog voltage, you know that the analog voltage is somewhere between the
reading just before 1.75 and after 1.75. This method is known as the ramp method.
The reference voltage in the ramp method starts at zero and increases in small
amounts until it’s greater than the analog voltage (shown as the trip point in Figure
9-5). To increase accuracy, you can make each step as small as possible, but this
adds to the amount of time needed to produce a reading — taking smaller steps
means doing more tests on the comparator, which takes time.

Figure 9-5: The ramp method.

The successive approximation method
The successive approximation method uses a series of calculated guesses to home
in on the answer. The starting point can be half of the maximum voltage and is
either increased or decreased depending on whether the comparator has tripped.
The increment or decrement value is halved with each guess, as shown in Figure 96. As with the ramp method, you can increase the amount of guesses to get a more
accurate result, which takes more time.

Figure 9-6: The successive approximation method.

Successive approximation may look much faster than the ramp method because you
can get a very accurate answer in 8 guesses, whereas with the ramp method you
could make 1,023 guesses. But successive approximation requires more filtering
time — the signal is changing so much between guesses that the filter needs more
time to settle. The ramp method takes small increments in one direction, which
enables the filter to produce an accurate result with much less settling time. When
designed with a fast and accurate filter, successive approximation is faster than the
ramp method. Many analog-to-digital conversion chips (like the MCP3008, which
we use later in this chapter) use this method for conversion.

The tracking method
The tracking method uses the ramp method to determine the first value and then
tracks the analog voltage using the previous reading as a starting point for the next
search, as shown in Figure 9-7. The comparator tells you which direction to search
for the analog voltage. Using the previous reading as a starting point reduces the
number of steps you need to take. This method is fast if the analog voltage doesn’t
change very frequently (for example, because you have a temperature sensor that
changes fairly slowly over time).

Figure 9-7: The tracking method.

Building an Analog-to-Digital Converter
In this section, you build an analog-to-digital converter and write the code for each
of the three conversion methods explained in the previous section. The converter
uses a comparator (refer to Figure 9-2) and pulse width modulation on the
Raspberry Pi, as explained earlier in this chapter, to convert the analog signal to a
digital reading on the Raspberry Pi.

Finding the parts you need
To make this project, you need the following parts:
Five 3K3 ohm 0.5W carbon film resistors ±5 percent

One 10k ohm 0.5W carbon film resistor ±5 percent
One 1k ohm 0.5W carbon film resistor ±5 percent
One 1uF/50V radial electrolytic capacitor
Two 0.1uF/50V radial electrolytic capacitors
One LM339 quad comparator (a device used to compare voltages and output
the result in a digital signal)
One Humble PI prototyping board (a prototyping board for the Raspberry Pi
from CISECO) or one solderless breadboard (a prototyping board where parts
and wires can be connected by clipping them into the board; used for
prototyping electronics without having to solder parts together)
Three 2-pin 0.2-inch (5mm) screw terminals
Assorted jumper wires for the prototyping board or for the solderless
breadboard ( Note: If you’re using a breadboard, use male-to-male for
breadboard connections and male-to-female for connecting the breadboard to
the GPIO pins. Jumper wires usually come in packs of various quantities,
colors, and sizes. Any size will do for this project, but shorter male-to-male
[10cm] and longer male-to-female [20cm] are best.)
One 10K breadboard trim potentiometer
All these parts are readily available from electronic stores or online. We use a
Humble PI breakout board from CISECO because it attaches right to the Raspberry
Pi GPIO header and has a center power rails and holes arranged in threes, making
it a very convenient layout. You can substitute it for a regular prototype board with
center rails or a solderless breadboard, but you’ll need to make the necessary
adjustments because a breadboard has the power rails running down the outside
and not down the center.

Since the release of the Raspberry Pi 2 A++, and B++ models, the shape of
the board has changed, so some breakout boards (like the Humble PI) no
longer fit the Raspberry Pi. However you can use an extra-tall stacking header
Raspberry Pi that allows you to connect the Humble PI to the new shape of the
Raspberry Pi.

Constructing the circuit

The difficulty level of the prototype board construction will be difficult for
a complete beginner because there are around 50 solder points. If you’re a
total beginner, you may want to opt for the breadboard. However, even if
you’re a soldering novice, you should be able to construct this prototype.
As with all prototyping, make sure you understand each part before you begin
construction. This understanding will help you troubleshoot and test different parts
of the circuit during or after the build. Figure 9-8 is the circuit diagram for the
analog-to-digital converter.

Figure 9-8: A circuit diagram for the analog-to-digital converter.

Take note that in later revisions of the Raspberry Pi, GPIO 21 changed to GPIO 27,
but the Raspberry Pi pin number using the in code remains the same.

Understanding the circuit

The left side of the circuit in Figure 9-8 controls the voltage going into pins 6, 8,
and 10 of the comparator. You configure the Raspberry Pi pin 18 to the PWM mode
and adjust its value from 0 to 1,023. This variable voltage is known as the
reference voltage. This moves the voltage going into pins 6, 8, and 10 in small
increments from 0V to 5V. The 1uF capacitor and 10K resistor are the low-pass
filter (refer to “Converting Analog to Digital,” earlier in this chapter, for more
details), which converts the PWM pulses into DC current.
The three analog inputs shown in Figure 9-8 can be connected to your analog
sensors. We only use one of the analog inputs in this chapter, but we’ve designed
the converter with three inputs to give you more options if you need them for other
projects. Later in this chapter, you test this circuit using a potentiometer and a
temperature sensor. The comparator compares the voltages of the reference voltage
to the analog voltage. When the comparator pins 1, 14, and 13 flip from low to
high, you know the reference voltage is greater than the analog voltage. When this
happens, the input pins on the GPIO (pins 17, 21, and 4) go high. Each of these pins
has a 3K3 pull-up resistor connected to it. Lastly, the comparator is powered by 5V
going to pin 3 and is grounded on pin 12.

Constructing the circuit
Figure 9-9 shows a grid of the Humble PI prototype board with the x- and ycoordinates of each connection. Each hole in the board is identified by the row and
column numbers given at the top and on the left side of the diagram. The positive
and negative center rails are labeled as + and –. For example, there is an R1
resistor connected from position E5 to position +5. Table 9-1 shows the position of
every component, including jumper wires.

Figure 9-9: Analog-to-digital prototype board schematic.

Table 9-1: Analog-to-Digital Converter Components
Component

From To

LM339

I11

H11

LM339

I12

H12

LM339

I13

H13

LM339

I14

H14

LM339

I15

H15

LM339

I16

H16

LM339

I17

H17

R1

+19

J19

R1

–20

K20

C1

–21

K21

Jumper

K21

K20

Jumper

K20

K19

Jumper

M9

M8

R2

N4

N8

R3

J8

M8

Jumper

I8

B14

Jumper

M4

N3

C1

–4

L4

C2

–9

I9

Jumper

B14

J9

LM339 pin 1 (GPIO17)

C7

B3

LM339 pin 1 (R1)

J11

D5

LM339 pin 2 (R2)

K12

L8

LM339 pin 3 (5V)

K9

K13

LM339 pin 4 (R1)

K19

K14

LM339 pin 5 (GPIO18)

J15

B4

LM339 pin 6 (R2)

L3

J16

LM339 pin 7 (T2) (analog 1)

L20

J17

LM339 pin 8 (R2)

M3

G17

LM339 pin 9 (T3) (analog 2)

L22

G16

LM339 pin 10 (R2)

N3

G15

LM339 pin 11 (T3) (analog 3) L24

G14

LM339 pin 12 (GND)

G13

-22

LM339 pin 13 (GPIO4)

C5

B10

LM339 pin 13 (R1)

G12

D7

LM339 pin 14 (R1)

G11

D6

LM339 pin 14 (GPIO21)

C6

B5

T1 (+3V)

L14

B14

T1 (+5V)

L16

B14

T2 (GND)

L18

–24

Jumper

G16

L22

PWR Center Rail (+3V)

+26

B13

GND Center Rail (GND)

–26

–VE

First, place all components onto the prototype board without solder. Double-check
that they’re all in the right position and then begin soldering. Be careful not to spill

solder over to any adjacent holes. When all the components are soldered in place,
solder in the jumper wires. We recommend placing the jumper wires underneath
the board and the electrical components above the board, as shown in Figure 9-10.
Some of the jumps can be completed just by using solder to bridge two adjacent
pads (for example, M3 to M4).

Figure 9-10: The Raspberry Pi analog-to-digital converter.

Before powering it up, use a circuit tester to test each connection. Circuit testers
can be bought or constructed using an LED circuit. Some multimeters have a circuit
tester built in. They consist of a battery connected to a light or a buzzer that indicate
when the circuit is closed. The tester has two leads that, when joined, close the
circuit and activate the light or buzzer. You can use the circuit tester to test each
connection of the analog-to-digital converter. For example, the right side of the 10k
resistor should be connected to pins 6, 8, and 10 of the LM339 comparator. In
order to test these connections, place one of the circuit tester leads on the right side
of the 10k resistor and then touch pins 6, 8, and 10 of the comparator. Your circuit
tester will indicate if each of these three circuits is soldered correctly. Use this
method to test every connection.

The Humble PI can be powered by external power (refer to the pads on the
top-right corner of the board), but we’ve chosen to power the board directly
from the Raspberry Pi by connecting the 3V (A13) to PWR and connecting
GND to the negative power rail (–).
The six screw terminals can be used to connect to an analog sensor. There is a
screw terminal for the three analog sensors — 5V, 3V, and GND — as shown in
Figure 9-9.

Connecting an analog sensor
Now that you have your analog-to-digital converter built, you can connect it to an
analog sensor. To start, connect it to a potentiometer (also known as a pot or a
trimpot). Connect the left pin of the trimpot to the 3V screw terminal, the middle
pin of the trimpot to the Analog 1 screw terminal, and pin 3 of the trimpot to the
GND screw terminal (see Figure 9-11).

Figure 9-11: Connecting a potentiometer to the analog-to-digital converter.

Writing the software

In this section, you write code for each of the analog-to-digital conversion methods
explained earlier in this chapter. You use C code for the interfaces because it’s
faster than Python, but we also show you how to call a C program from Python so
you can write Python programs to interface with your analog sensors.

Installing WiringPi
You use a GPIO access library called WiringPi to control the PWM and monitor the GPIO digital pins.
WiringPi was written by Gordon Henderson and is a GPIO library for the Raspberry Pi. You use it to
control the GPIO digital pins and PWM. You also use WiringPi’s Serial Peripheral Interface (SPI)
library later in this chapter. For more details on WiringPi you can visit Gordon’s webpage
(www.wiringpi.com).
To install WiringPi, type the following command at the command prompt:
$ sudo apt-get install git-core

If you get any errors here, make sure your Pi is up to date with the latest versions of Raspbian:
$ sudo apt-get update
$ sudo apt-get upgrade

Install WiringPi:
$
$
$
$

cd ~
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

If you aren’t able to use git or you’re using an operating system other than Raspbian or Debian, you
can follow the instructions to install WiringPi. Go to https://git.drogon.net/?p=wiringPi;a=summary.
Then look for the most recent (topmost) entry in the shortlog, and click the rightmost link (marked
“snapshot”) for that entry.
This will download a tar.gz file with a name like wiringPi-98bcb20.tar.gz. Note that the numbers and
letters after wiringPi (98bcb20, in this case) will probably be different. They’re a unique identifier for
each release.
Then enter the following command from the Raspberry Pi command line:
tar xfz wiringPi-98bcb20.tar.gz
cd wiringPi-98bcb20
./build

Remember: The actual filename will be different. You have to check the name and adjust it
accordingly.

Software for the ramp method
The software for the ramp method is in Listing 9-1. Type the program in and save it
to a file called ramp.c.

Listing 9-1: Analog-to-Digital C Program for the Ramp
Method
/*
* ramp.c
* Raspberry Pi Projects For Dummies: Analog-to-Digital Converter

* Ramp Method
*/

#include 
#include 
#include 
#include 
float to_volts(int reading, float analog_volts);
int main (int argc, char *argv[])
{
int one_reading;
int ramp, reading0, reading1, reading2;
unsigned char gotReading0, gotReading1, gotReading2;
const unsigned char A0 = 17, A1 = 21, A2 = 4, pwm = 18;
if (argc!=2){
printf ("usage : ramp [single_reading 1/0]\n");
exit(1);
}
one_reading = atoi(argv[1]);
if (wiringPiSetupGpio () == -1)
exit (1);
pinMode (A0,INPUT);
pinMode (A1,INPUT);
pinMode (A2,INPUT);
pinMode (pwm, PWM_OUTPUT) ;
pwmWrite(pwm, 0);
delay(40);
for (;;)
{
reading0 =-1;
reading1 =-1;
reading2 =-1;
gotReading0 = 0;
gotReading1 = 0;
gotReading2 = 0;
for (ramp = 0 ; ramp < 1024 ; ramp+=4) // in effect 8 bit
{
pwmWrite (pwm, ramp);
delayMicroseconds(200);
if(gotReading0 == 0 && digitalRead(A0)== 0){

gotReading0 = 1;
reading0 = ramp;
}
if(gotReading1 == 0 && digitalRead(A1)== 0){
gotReading1 = 1;
reading1 = ramp;
}
if(gotReading2 == 0 && digitalRead(A2)== 0){
gotReading2 = 1;
reading2 = ramp;
}
if(gotReading0 && gotReading1 && gotReading2) break;
}
printf("Reading Ch0 = %d (%2.3fV) Ch1 = %d (%2.3fV) Ch2 = %d (%2.3fV)
\n", reading0, to_volts(reading0,5), reading1, to_volts(reading1,5)
, reading2, to_volts(reading2,5));
if (one_reading) {
return(0);
}
pwmWrite (pwm, 0);
delay(40);
}
return 0 ;
}
float to_volts(int reading, float analog_volts)
{
float volts;
volts = ((float)reading / 1023) * analog_volts;
return(volts);
}

The program sets GPIO 18 to PWM mode and then loops through each PWM
setting starting at 0 and ending at 1,023. To speed it up, we set it to increase in
steps of 4. Looping 256 times instead of 1,024 will make the program faster but
sacrifice 2 bits of resolution. With each loop cycle, you check the GPIO digital
pins to see if one of the comparators has flipped from low to high and, if so, save
the reading for that sensor. When all three sensor values have been read or you
reach the end of the loop, the program writes the results to the screen and goes
again into the loop to get the next reading.
Compile the program using the following command:
$ sudo gcc -o ./ramp ramp.c -l wiringPi

You pass a parameter of 0 or 1 to the program that determines whether the program
will print only one reading or multiple readings. If it’s the latter, you press Ctrl+C
to quit. Now run the program from the command line using the following command:
$ ./ramp 0

You see the output printed to the screen for each of the three analog channels.
Adjust the trimpot by turning the knob left and right, and watch the value of channel
0 move up and down. Then stop adjusting the potentiometer and observe the
results. Notice that even though the potentiometer is not changing, the reading
fluctuates. The spread between the minimum and maximum reading we get is about
8, as shown here:
Reading Ch0 = 540
Reading Ch0 = 536
Reading Ch0 = 544

Our goal is to try get to a steady reading with little to no fluctuation. One way you
can reduce the fluctuation is to refine the granularity of the PWM cycle. The
ramp.c program loops through 0 to 1,023 PWM setting in increments of 4 as per
the following line of code:
for (ramp = 0 ; ramp < 1024 ; ramp+=4) // in effect 8 bit

It will loop 256 times, which equates to 8-bit accuracy (28 = 256). With the
fluctuation, we’re losing around 3 bits, so our converter is, in effect, a 5-bit
converter. You can improve this by taking smaller increments and increasing the
loop cycle to the full 1,024 settings available on the Raspberry Pi PWM. Change
the following line to:
for (ramp = 0 ; ramp < 1024 ; ramp+=1) // in effect 10 bit

Recompile and run the program. You should now see a more accurate result. Our
results are as follows:
Reading
Reading
Reading
Reading
Reading
Reading

Ch0
Ch0
Ch0
Ch0
Ch0
Ch0

=
=
=
=
=
=

197
198
199
202
197
197

The spread of the fluctuation is now 5. We’ve improved the accuracy of the analogto-digital converter, but we paid a price in time. The converter is now half the
speed it was originally, and it’s noticeable.
Another change you can make to improve accuracy is to adjust the settling time
given to the circuit with every change of the PWM cycle. The first of the following
two lines changes the PWM value and the second pauses the program for 200

microseconds while the circuit settles.
pwmWrite (pwm, ramp);
delayMicroseconds(200);

Change the 200 to 500 and recompile and run again. Our results improved to a
spread of only 2. However, there is an even more noticeable degradation to the
performance of the conversion.
Reading Ch0 = 178
Reading Ch0 = 178
Reading Ch0 = 180

A third modification that could be made is to fine-tune the low-pass filter by
reducing the cut-off frequency. The settling time is governed by the action of the
filter. Again, there’s a performance trade-off to be made because the lower the cutoff frequency, the longer it takes for the resulting voltage to ramp up to the final
value. This would mean changing the 1uF capacitor and the 10k resistor, which
would require a change to the circuit, so for the purposes of this chapter we won’t
go into the different options here.

Software for the successive approximation method
Listing 9-2 is the code for the successive approximation method. The program
performs eight guesses at the analog voltage. With each guess, the comparator tells
you if you’re higher or lower than the analog voltage, and then the next guess is
either increased or decreased by half the previous increment. With each guess, you
home in on the answer. Type the program in and save it to a file called succ.c.

Listing 9-2: Analog-to-Digital C Program for the
Successive Approximation Method
/*
* succ.c
* Raspberry Pi Projects For Dummies: Analog-to-Digital Converter
* Successive Approximation Method
*/
#include 
#include 
#include 
#include 
int successive(char ch);
float to_volts(int reading, float analog_volts);
int main (int argc, char *argv[]){
int one_reading;
int reading0, reading1, reading2 ;

const unsigned char A0 = 17, A1 = 21, A2 = 4;
if (argc!=2){
printf ("usage : succ [single_reading 1/0]\n");
exit(1);
}
one_reading = atoi(argv[1]);
if (wiringPiSetupGpio () == -1)
exit (1) ;
pinMode
pinMode
pinMode
pinMode

(A0,INPUT);
(A1,INPUT);
(A2,INPUT);
(18, PWM_OUTPUT) ;

for (;;){
reading0
reading1
reading2
reading0
reading1
reading2

=-1;
=-1;
=-1;
= successive(A0);
= successive(A1);
= successive(A2);

printf("Reading Ch0 = %d (%2.3fV) Ch1 = %d (%2.3fV) Ch2 = %d (%2.3fV) \n",
reading0, to_volts(reading0,5), reading1, to_volts(reading1,5),
reading2, to_volts(reading2,5));
if (one_reading==1)
return(0);
}
return 0 ;
}
int successive(char ch){
int reading = 512; // start at the midpoint
int x = 256,i,pwm = 18;
for(i=0; i<8; i++){
pwmWrite(pwm,reading);
delayMicroseconds(3000); // settling time
if(digitalRead(ch) == 0){
reading=reading-x;
}
else {
reading=reading+x;
}
x=x/2; //narrow the search
}
return (reading);
}

float to_volts(int reading, float analog_volts)
{
float volts;
volts = ((float)reading / 1023) * analog_volts;
return(volts);
}

Compile the program using the following command:
$ sudo gcc -o ./succ succ.c -l wiringPi

You pass a parameter of 0 or 1 to the program that determines whether the program
will print only one reading or successive readings. If it’s the latter, you press
Ctrl+C to quit. Now run the program from the command line using the following
command:
$ ./succ 0

Using this method, you can obtain the same result as the ramp method, except with
the ramp method you could potentially have to make 256 guesses as opposed to 8
using this method. One major disadvantage of this method is the settling time (3,000
microseconds) that the circuit needs before it takes a new reading. This is due to
the fact that we’re making large jumps in voltage with each guess. The ramp
method, however, increments the voltage in small increments in the same direction
so you can dramatically reduce the settling time (75 microseconds).
Here’s is a comparison of the total potential settling time of each method:
Total settling time for the ramp method:
256 × 75 = 19,200 microseconds
Total settling time for the successive approximation method:
3,000 × 8 = 16,000 microseconds
Even though the ramp method takes many more guesses, it’s only marginally slower
than successive approximation.
As with the ramp method, a number of factors will affect the accuracy of the
conversion. In the preceding section, we explain how you can fine-tune the settling
time, the granularity of the PWM settings, and the low-pass filter. The same applies
with this method.
You can increase or decrease the amount of guesses it makes by adjusting the 8 in

this form loop statement to your desired value:
for(i=0; i<8; i++){

Software for the tracking method
The tracking method starts by using the ramp method (or successive approximation,
it doesn’t matter which) to find and track the analog voltage. Then it uses the
previous reading as a starting point to search for the next reading. This way, it can
track the analog voltage and reduce the number of overall readings, which can
make this method faster than the other methods.
The software for the tracking method is shown in Listing 9-3. Type the program and
save it to a file called track.c.

Listing 9-3: Analog-to-Digital C Program for the Tracking
Method
/*
* track.c
* Raspberry Pi Projects For Dummies: Analog-to-Digital Converter
* Tracking Method
*/

#include 
#include 
#include 
#include 
// Declare functions
int track(char ch, int direction);
int main (int argc, char *argv[])
{
int one_reading;
int reading0 = 0, reading1 = 0, reading2 = 0;
const unsigned char A0 = 17, A1 = 21, A2 = 4;
if (argc!=2 && argc!=3){
printf ("usage : ramp [single_reading 1/0]\n");
printf ("
[previous_reading1 (0-1023) (optional)]\n");
printf ("
[previous_reading2 (0-1023) (optional)]\n");
printf ("
[previous_reading3 (0-1023) (optional)]\n");
exit(1);
}
one_reading = atoi(argv[1]);

if (argc>=3){
reading0=atoi(argv[2]);
}
if (argc>=4){
reading1=atoi(argv[3]);
}
if (argc>=5){
reading2=atoi(argv[4]);
}
if (wiringPiSetupGpio () == -1)
exit (1);
pinMode
pinMode
pinMode
pinMode

(A0,INPUT);
(A1,INPUT);
(A2,INPUT);
(18, PWM_OUTPUT) ;

for (;;)
{
reading0 = track(A0, reading0);
reading1 = track(A1, reading1);
reading2 = track(A2, reading2);
printf("Reading Ch0 = %d Ch1 = %d Ch2 = %d \n", reading0, reading1,reading2);
if (one_reading==1)
return(0);
}
return(0);
}

int track(char ch, int reading)
{
int gotReading, direction, digital_read;
pwmWrite (18, reading);
delayMicroseconds(4000);
if (digitalRead(ch)==1){
direction=1;
}
else{
direction=-1;
}
gotReading=0;
while (!gotReading){
reading=reading+direction;
pwmWrite (18, reading);
delayMicroseconds(500);
digital_read=digitalRead(ch);
if ((digital_read==1 && direction==-1) ||

(digital_read==0 && direction==1)){
gotReading=1;
}
if (reading<0){
reading=0;
gotReading=1;
}
if (reading>1024){
reading=1023;
gotReading=1;
}
}
return(reading);
}

Compile the program using the following command:
$ sudo gcc -o ./track track.c -l wiringPi

The program takes up to four parameters. The first parameter determines whether
the program will print one reading and quit or continue forever printing readings to
the screen until you press Ctrl+C. The second to fourth parameters are the starting
points for each analog sensor (which is a value between 0 and 1,023). You can use
these parameters if you want to call this program from a Python program where the
Python program stores the previous reading and passes it to this program to obtain
a new reading. This is used in the Breakdown game, later in this chapter.
The program calls the track routine for each of the three analog sensors passing the
previous reading as a parameter. The track routine first sets the PWM cycle to the
previous reading and tests the comparator. This determines which direction you
track to find the next reading. If the comparator is positive, the PWM cycle needs to
increase until the comparator flips negative; if the comparator is negative, the
search heads in the other direction until the comparator flips positive (refer Figure
9-7).
We set the wait time on the first read to 4,000 microseconds so you give the circuit
enough initial settling time. When the tracking starts, we decrease the wait time to
500 microseconds because the changes between readings will be smaller.
As with the other two methods, you can fine-tune the accuracy by changing the wait
times, speeding it up by increasing the increment/decrement value between
readings and reducing the cut-off frequency of the low-pass filter.
Now that you’ve completed the software for the three methods, compare the results
and speeds of each method. Fine-tune them using the parameters we describe to try
get the most accurate readings. In the next two sections, you use the analog-to-

digital converter on two different projects. The first project uses a potentiometer to
control the paddle of the Breakdown game. You use the reading of the
potentiometer to control the horizontal positioning of the paddle. The more the
reading fluctuates, the more unstable the paddle will appear. Speed is also an
important factor for the Breakdown game. You don’t want the digital conversion to
slow down the game and make it unplayable.
In the other project, you use the analog converter to read the temperature from a
thermistor (temperature sensor). In order to calculate the temperature, we need an
accurate voltage reading across the sensor. In this project, speed is less important,
but accuracy is very important.

Using a Potentiometer to Control the
Breakdown Game
In this section, you use a potentiometer to control the paddle (or blocker) of the
Breakdown game, a legendary game from the 1970s. The objective is quite simple:
You use the blocker that moves left and right to deflect a ball and send it back up to
eliminate some more bricks. The objective is to clear all the bricks.
Use the potentiometer circuit you construct earlier in this chapter to move the
paddle left and right. This shows a good visual representation of the accuracy of
your analog-to-digital converter. If your reading fluctuates, you see the paddle jump
or shake. If your analog-to-digital conversion takes too long, the game will slow
down and become unplayable. Use this game as an exercise to determine which
conversion method best suits the game’s needs.
Listing 9-4 is configured to call the ramp program you develop in the “Software for
the ramp method” section, earlier in this chapter. However, you can change it to
call the successive approximation or tracking programs as follows:
If you want to change methods, then change the METHOD constant at the top of the
program to T for tracking or S for the successive approximation method.
You can set the minimum and maximum boundaries of your analog readings
using the MIN_PADDLE and MAX_PADDLE variable settings at the beginning of the
program. Depending on which potentiometer you’re using, you could have
different boundaries within the 0 to 1,023 PWM range.
Type the following program in to a file called breakdown.py and save it in your

user directory of your Raspberry Pi. The program calls the analog-to-digital
conversion C programs, which should also be in your user directory.

Listing 9-4: Breakdown Game Using a Potentiometer to
Control the Game Paddle
#!/usr/bin/env python
"""
Raspberry Pi Projects For Dummies: breakdown game
using a potentiometer to control the paddle
for the Raspberry Pi
"""
import os
import sys
import subprocess
import re
import pygame
# Color constants
BLACK = (0,0,0)
WHITE = (255,255,255)
YELLOW = (200,200,0)
BRICK_COLOR = (0,200,0)
# Game State Constants
STATE_BEGIN = 0
STATE_PLAYING = 1
STATE_WON = 2
STATE_GAME_OVER = 3
PADDLE_DELAY=5
METHOD = "R"
MIN_PADDLE=0
MAX_PADDLE=850
class breakdown:
def get_paddle_position(bo):
if METHOD=="T":
output = subprocess.check_output(["~/track","1",str(bo.reading)])
elif METHOD=="R":
output = subprocess.check_output(["~/ramp","1"])
elif METHOD=="S":
output = subprocess.check_output(["~/succ","1"])
elif METHOD=="M":
output = subprocess.check_output(["~/mcp3008", "1"])
s = re.search("Ch0 =\s+([0-9a-f]+)", output)
if s:
x = (float(s.group(1))/float(MAX_PADDLE-MIN_PADDLE)*615)
bo.reading = int(x)
def display_message(bo,message,x,y):
txt_format = bo.font.render(message,False, WHITE)
bo.screen.blit(txt_format, (x,y))
def run(bo):
pygame.init()
bo.screen = pygame.display.set_mode([640,480])
pygame.display.set_caption("Raspberry Pi Projects For Dummies")
bo.clock = pygame.time.Clock()

bo.font = pygame.font.Font(None,30)
bo.reset_game()
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit
bo.clock.tick(50)
bo.screen.fill([0,0,0])
if bo.paddle_no>PADDLE_DELAY:
bo.get_paddle_position()
bo.paddle.left=bo.reading
bo.paddle_no=0
else:
bo.paddle_no=bo.paddle_no+1
#If you want to use the keyboard to control the paddle
#uncomment the following lines
keys = pygame.key.get_pressed()
#if keys[pygame.K_LEFT]:
#
bo.paddle.left -= 5
#if keys[pygame.K_RIGHT]:
#
bo.paddle.left += 5
if keys[pygame.K_SPACE] and bo.state == STATE_BEGIN:
bo.ball_direction = [5,-5]
bo.state = STATE_PLAYING
elif keys[pygame.K_RETURN] and (bo.state == STATE_GAME_OVER or bo.state
== STATE_WON):
bo.reset_game()
if bo.state == STATE_PLAYING:
bo.ball.left += bo.horizontal
bo.ball.top += bo.vertical
if bo.ball.left <= 0:
bo.ball.left = 0
bo.horizontal = -bo.horizontal
elif bo.ball.left >= 624:
bo.ball.left = 624
bo.horizontal = -bo.horizontal
if bo.ball.top < 0:
bo.ball.top = 0
bo.vertical = -bo.vertical
elif bo.ball.top >= 464:
bo.ball.top = 464
bo.vertical = -bo.vertical
for brick in bo.bricks:
if bo.ball.colliderect(brick):
bo.vertical = -bo.vertical
bo.bricks.remove(brick)
break
if bo.ball.colliderect(bo.paddle):
bo.ball.top = 442
bo.vertical = -bo.vertical #If ball hits the edge
of the paddle send it back in the same direction
if bo.ball.left < bo.paddle.left or bo.ball.left >
bo.paddle.left+45:
bo.horizontal = -bo. horizontal
elif bo.ball.top > bo.paddle.top:
bo.state = STATE_GAME_OVER
if len(bo.bricks) == 0:
bo.state = STATE_WON
elif bo.state == STATE_BEGIN:
bo.ball.left = bo.paddle.left + bo.paddle.width / 2
bo.ball.top = bo.paddle.top - bo.ball.height
bo.display_message("PRESS SPACE TO START",180,200)
elif bo.state == STATE_GAME_OVER:
bo.display_message("GAME OVER - PRESS ENTER TO PLAY AGAIN",100,200)
elif bo.state == STATE_WON:

bo.display_message("WINNER! PRESS ENTER TO PLAY AGAIN",100,200)
for brick in bo.bricks:
pygame.draw.rect(bo.screen, BRICK_COLOR, brick)
pygame.draw.rect(bo.screen, YELLOW, bo.paddle)
pygame.draw.circle(bo.screen, WHITE, (bo.ball.left + 8, bo.ball.top +
8), 8)
bo.display_message("Paddle
Position: " +str(bo.reading),200,10)
pygame.display.flip()
def reset_game(bo):
bo.reading = 0
bo.state = STATE_BEGIN
bo.paddle = pygame.Rect(300,458,60,12)
bo.ball = pygame.Rect(300,442,16,16)
bo.vertical=-5
bo.horizontal=5
bo.paddle_no=0
y = 35
bo.bricks = []
for i in range(7):
x = 5
for j in range(9):
bo.bricks.append(pygame.Rect(x,y,60,12))
x += 70
y += 17
if __name__ == "__main__":
breakdown().run()

To run the program, type startx from the Raspberry Pi command line and open an
LXTerminal window. At the command prompt, type the following commands to
start the game:
$ cd ~
$ python breakdown.py

The program will start up as shown in Figure 9-12. The paddle isn’t very stable so
you need to fine-tune your analog-to-digital conversion methods and experiment to
find one that best suits the game. Your goal is to find a conversion method that’s
fast and that has an acceptable level of fluctuation.

Figure 9-12: The Breakdown game being controlled by a potentiometer connected to the analog-to-digital
converter.

Creating an Analog Temperature Sensor
In this section, you use the analog-to-digital converter you construct earlier in this
chapter to tell the temperature. The analog temperature sensor you use is a TMP36,
shown in Figure 9-13.

Figure 9-13: TMP36 thermistor.

The TMP36 is a low-voltage, centigrade temperature sensor. It provides an analog
voltage output that is linearly proportional to the temperature. It’s very easy to use.
Just connect 2.7 to 5.5 VDC, and it produces the analog voltage on the output pin.
In this project, it’s important for your digital converter to produce an accurate
reading. Depending on how frequently you want to read the temperature, you can
increase the settling time of the low-pass filter of the converter to improve
accuracy. The speed of the conversion is probably less important to you than it was
with the Breakdown game. The software that you wrote earlier in this chapter
provides you with a reading between 0 and 1,023. You can calculate the voltage
using the following formula:
Analog Voltage = (Analog-to-Digital Reading ÷ 1,023) × 5

where Analog-to-Digital Reading is the reading from the analog-to-digital
converter and 5 is the reference voltage we’re using with the analog-to-digital
converter.
The temperature formula for the TMP36 sensor is as follows:
Temperature = (Sensor Reading Millivolts – 500) ÷ 10
A volt is equal to 1,000 millivolts, so for our purposes, we use the following
formula:
Temperature = ([Analog Voltage × 1,000] – 500) ÷ 10
For example, if the analog-to-digital converter gives you a reading of 144, the
calculation is as follows:
Analog Voltage = (144 ÷ 1,023) × 5
Analog Voltage = 0.70381
Temperature = ([0.70381 × 1,000] – 500) ÷ 10
Temperature = 20.831°C

Constructing the circuit
Here are the parts you need to build this circuit:
A TMP36 sensor: This is a wide-range, low-power (between 2.7V and 5.5V)
temperature sensor that outputs an analog voltage that is proportional to the
ambient temperature.
A solderless breadboard: A solderless breadboard is a prototyping board
where parts and wires can be connected by clipping them into the board. It’s
used for prototyping electronics without having to solder parts together.
Assorted jumper wires for a solderless breadboard: Use male-to-male for
breadboard connections and male-to-female for connecting the breadboard to
the GPIO pins. Jumper wires usually come in packs of various quantities,
colors, and sizes. Any size will do for this project, but shorter male-to-male
(10cm) and longer male-to-female (20cm) are best.
As per Figure 9-13, connect pin 1 (left) to 3V, pin 2 to the analog-to-digital

converter (refer to “Building an Analog-to-Digital Converter” section of this
chapter), and pin 3 (right) to ground.

Writing the software
Listing 9-5 is the Python software for the TMP36 that uses the successive
approximation method program built in the “Software for the successive
approximation method” section of this chapter.

Listing 9-5: Python Code for the TMP36 Analog Sensor
Using an Analog-to-Digital Converter
#!/usr/bin/env python
"""
Raspberry Pi Projects For Dummies: TMP36 thermistor
using successive approximation and an analog-todigital converter
for the Raspberry Pi
"""
import os
import sys
import subprocess
import re
output = subprocess.check_output(["~/succ","1"])
s = re.search("Ch0 =\s+([0-9a-f]+)", output)
if s:
x = float(s.group(1))
analog_voltage=(x/1023)*5
temperature = ((analog_voltage * 1000) - 500) / 10
fahrenheit = temperature*1.8+32
print "Temperature = " + str(round(temperature,2)) + "C " +
str(round(fahrenheit,2)) + "F"
else:
print "Invalid reading"

Run the program and check that the reading is correct:
$ python tmp36.py
Temperature = 19.4C 66.93F

The program prints both Celsius and Fahrenheit temperature values. If your reading
is high, make sure that the reference voltage on the analog-to-digital converter is
exactly 5V. Use a multimeter to make sure that you’re getting exactly 5V from pin 2
of the Raspberry Pi. When you have an accurate reading, pinch the TMP36 with
your fingers and watch the temperature rise as the sensor warms up from your body
heat.

Compare the results of the successive approximation method to the ramp
and tracking methods by changing the following line of code:

output = subprocess.check_output(["/home/succ","1"])

Change succ in the preceding line of code to ramp for the ramp method and track
for the tracking method.

Interfacing with an Analog-to-Digital
Microchip
In this section, you use a high-precision analog-to-digital converter that performs
the digital conversion external to the Raspberry Pi. The microchip you use is the
MCP3008. It performs the analog-to-digital conversion and outputs a digital
reading to the Raspberry Pi. The MCP3008 is an 8-channel 10-bit converter and is
capable of conversion rates of up to 200 kilo samples per second (ksps), with a
conversion time of 10 microseconds.
Figure 9-14 shows the pin allocation of the MCP3008 and how it maps to the GPIO
pins on the Raspberry Pi. Use the semicircular indentation on the MCP3008 to
orient yourself to the diagram. The eight pins down the left side are eight analog
inputs. And the pins down the right side provide the chip with power, ground, a
reference voltage, and the various connections required for the serial peripheral
interface (SPI). The communication between the Raspberry Pi and MCP3008 is
handled by SPI, which is a full duplex serial communication link. The Raspberry Pi
supports the SPI protocol and has pins assigned for it on the Raspberry Pi GPIO
header.

Figure 9-14: Pin assignment for the MCP3008 and Raspberry Pi GPIO.

In this section, we show you how to interface a temperature sensor and a
potentiometer so you can compare the readings you get from the MCP3008 with the
analog-to-digital converter you build earlier in this chapter.

Assembling the parts you need
Here are the parts you need:
An MCP3008: This is a high-precision 10-bit 8-channel analog-to-digital
converter. You could also use the MCP3004, which has four analog inputs
instead of eight.
A TMP36: This is a wide-range, low-power (between 2.7V and 5.5V)
temperature sensor that outputs an analog voltage that is proportional to the
ambient temperature.
A 10K breadboard trim potentiometer

A solderless breadboard: A solderless breadboard is a prototyping board
where parts and wires can be connected by clipping them into the board. It’s
used for prototyping electronics without having to solder parts together.
Assorted jumper wires for a solderless breadboard: Use male-to-male for
breadboard connections and male-to-female for connecting the breadboard to
the GPIO pins. Jumper wires usually come in packs of various quantities,
colors and sizes. Any size will do for this project, but shorter male-to-male
(10cm) and longer male-to-female (20cm) are best.

Constructing the circuit
Construct your circuit as shown in Figure 9-15. Be careful to orient the TMP36
thermistor the right way around (refer to Figure 9-13 for pin assignment). The
potentiometer in the diagram uses the middle put as the analog output. The two
outer pins of the potentiometer connect to +3.3V and Ground. The temperature
sensor is connected to channel 1, and the potentiometer is connected to channel 0 of
the MCP3008.

Figure 9-15: How to connect the MCP3008 to your Raspberry Pi GPIO.

Writing the software

In order to enable SPI on the Raspberry Pi, you need to edit the following file and
comment out the spi-bcm2708 line as shown in Figure 9-16.

Figure 9-16: Enable SPI by removing it from the blacklist.

From the Raspberry Pi commend line type the following:
sudo nano /etc/modprobe.d/raspi-blacklist.conf

Press Ctrl+X, then press Y, and finally press Enter to save and exit. Then reboot
your Raspberry Pi by typing the following:
$ reboot

If you haven’t already installed the WiringPi library, refer to the “Installing
WiringPi” sidebar earlier in this chapter. You use the mcp3008 subroutine within
WiringPi to interface with the MCP3008 chip.

Listing 9-6: C Code for a Potentiometer and Temperature
Sensor Connected to an MCP3008
/*
* mcp3008.c
* Raspberry Pi Projects For Dummies: MCP3008
* Analog-to-Digital Converter
* Potentiometer and temperature sensor
*/

#include 
#include 
#include 
#include 
#include 
#define BASE 100
#define SPI_CHAN 0
int main (int argc, char *argv[]){
int tmp,pot, one_reading;
float analog_voltage, temperature, fahrenheit;
if (argc!=2){
printf ("usage : msp3008 [single_reading 1/0]\n");
exit(1);
}
one_reading = atoi(argv[1]);
mcp3004Setup (BASE, SPI_CHAN);
while (1) {
pot = analogRead (BASE+0);
tmp = analogRead (BASE+1);
analog_voltage=((float)tmp/1023)*3.3;
temperature = ((analog_voltage * 1000) - 500) / 10;
fahrenheit = temperature*1.8+32;
printf ("Ch0 = %d Ch1 = %d Temperature = %2.2fC %2.2fF \n",
pot, tmp, temperature, fahrenheit);
if (one_reading) return(0);
}
}

The code obtains an analog reading from channels 0 and 1 and then calculates the
temperature based on the analog reading in the tmp variable. For more details
regarding the theory behind the TMP36 sensor, please refer to the “Creating an
Analog Temperature Sensor” section, earlier in this chapter . Compile and run the
program from the Raspberry Pi command line as follows:
$ gcc -o ./mcp3008 mcp3008.c -l wiringPi
$ ./mcp3008 0

The program should print to screen something similar to this:
Ch0=92 Ch1=216 Temperature = 19.68C 67.42F
Ch0=92 Ch1=216 Temperature = 19.68C 67.42F
Ch0=92 Ch1=216 Temperature = 19.68C 67.42F

The Ch0 and Ch1 values are the raw readings from the MCP3008 chip. These
readings are values in the range 0 to 1,023. The temperature is calculated using the
reading from Ch1.
If you created the Breakdown game (refer to “Using a Potentiometer to Control the
Breakdown Game,” earlier in this chapter), you can configure the Breakdown game
to use the potentiometer reading from the MCP3008. Change the METHOD constant to

M

as follows:
$ cd /home
$ sudo nano breakdown.py

Edit the METHOD constant as follows:
METHOD = "S"

Exit and save by pressing Ctrl+X, pressing Y, and then pressing Enter.

Chapter 10

Raspberry Pi in the Sky
In This Chapter
Understanding the cloud
Storing data in Google Docs from your Raspberry Pi
Creating a dashboard and temperature alerts using PrivateEyePi
Creating a database logger
Sensors can generate enormous amounts of data that need to be stored, monitored,
and analyzed. In this chapter, we explore Internet service providers that do just
that. Later in the chapter, we show you how to log temperature data into a database
and view it through a web browser.

Understanding the Cloud
An abundance of services are available through the Internet that can be used by the
Raspberry Pi. Increasingly, we’re seeing everyday appliances and sensors
connecting to a network providing us with real-time information from and control
over those devices. The Raspberry Pi is very good at interfacing with sensors
through the general-purpose input/output (GPIO) ports. Its small form factor,
processing capability, and simple connectivity to the Internet makes the Raspberry
Pi the perfect fit for this new world of connected devices called the Internet of
Things.

Connecting to the cloud
Storing sensor data on the Internet requires a connection of some kind to the service
provider. Each service provider specifies how to connect to its service and how to
send sensor information. The service provider usually requires you to apply for an
account or create a user profile, and some charge a fee depending on what services
you choose.
In this chapter, we show you the following two free options for storing and viewing
sensor data on the Internet:

Storing data in a Google Docs spreadsheet
Creating an online dashboard and alerts using PrivateEyePi
For each of these projects, you use the DS18B20 temperature sensor to collect
temperature readings. In the next section, we describe how to interface to the
DS18B20 sensor that will be used for the basis of the temperature reading you’ll
send to each service provider.

Assembling the parts you need
In this project, you use the readily available DS18B20 temperature sensor. Here
are all the parts you need to construct your temperature sensor and link it to your
Raspberry Pi:
A DS18B20: This sensor looks like a transistor, but it’s actually a highly
accurate one-wire temperature sensor.
A 4.7k ohm 0.5W carbon film resistor ±5 percent
A solderless breadboard: A solderless breadboard is a prototyping board
where parts and wires can be connected by clipping them into the board. It’s
used for prototyping electronics without having to solder parts together.
A variety of jumper wires: You need male-to-male for breadboard
connections and male-to-female for connecting the breadboard to the GPIO
pins. Jumper wires usually come in packs of various quantities, colors, and
sizes. Although you need only 6 for this project, having 20 to 30 of each should
see you through most projects. Any size will do for this project, but shorter
male-to-male (10cm) and longer male-to-female (20cm) are best.

Constructing the temperature sensor
Besides the power and ground connections, all you need to do is connect the 4.7k
ohm pull-up resistor between the signal and power, as shown in Figures 10-1 and
10-2.

Figure 10-1: A wiring diagram for a DS18B20 temperature sensor connected to a Raspberry Pi.

Figure 10-2: A breadboard diagram for a DS18B20 temperature sensor connected to a Raspberry Pi.

Be sure to use pin 7 on the Raspberry Pi for the sensor connection. The
software you use to interface with the DS18B20 is hard-coded for pin 7, so
you can’t use another pin for this sensor.

Writing the software
The software required to interface with the DS18B20 has already been written and
is built into your Raspberry Pi kernel. You’ll be using an application called
modprobe to retrieve the temperature value.

Log into your Raspberry Pi using the root user for this chapter so you don’t
run into permission issues during installations. If you don’t have a root user or

don’t know whether you have one, you can easily create one using the
following command:
sudo passwd root

It’s also a good idea to protect your Raspberry Pi by disabling root access via
Secure Shell (SSH). SSH can be used to connect to your Raspberry Pi from a
remote location. Edit the SSH configuration file by typing the following command:
sudo nano /etc/ssh/sshd_config

Then look for a setting called PermitRootLogin and change it to no as follows:
PermitRootLogin no

Save the file by pressing Ctrl+X, pressing Y, and pressing Enter. Then log out or
restart your Raspberry Pi and use the root user and password you just created.
In the next few sections, you edit files on your Raspberry Pi. If you don’t know how
to work with editors on the Raspberry Pi, use Table 10-1 and practice creating
new files, editing content, and saving files.

Table 10-1: Useful File-Editing Commands Using the nano
Editor
Description

Sample Linux Commands

Navigate to the desired directory cd /home
Create a new file

nano newfile.py

Edit the file

Use the keyboard to create the content of the file.

Save the file

Press Ctrl+X, press Y, and then press Enter.

Create a new folder (directory)

mkdir /home/temp

Copy the file

cp newfile.py /home/temp

Change directory

cd /home/temp

Delete the file

rm newfile.py

At the Raspberry Pi command prompt, type the following two commands:
modprobe w1-gpio
modprobe w1-therm

One of the nice features of the DS18B20 sensor is that it has a unique number that
allows you to use multiple sensors and uniquely identify the temperature of each
sensor. The preceding command interfaces with the sensor and retrieves the

temperature, which it then writes to a new directory on the Raspberry Pi. This
directory can be found in /sys/bus/w1/devices/. In order to check whether this
file was created, you can do a directory listing by typing the following command:
ls /sys/bus/w1/devices/

You should see a directory that correlates to the unique number of your sensor.
Every sensor has a unique number, so it won’t be the same as our file, but it will be
similar to this:
28-0000040be5b6

Take note of this number for use later in this chapter. If you don’t see a directory
with lots of numbers and letters like this one, do the following:
1. Check your circuit wiring.
2. Make sure that you have the correct resistor.
You need to have a 4.7k ohm resistor (sometimes written as 4k7 ohm). Check
your resistor by looking at the colored bands on it. If there are four bands, your
resistor should have bands in this order: yellow, violet, red, and gold. If there
are five bands, look for: yellow; violet; black; brown; and brown, red, gold, or
silver for the fifth band.
3. Feel the temperature gauge with your finger.
If it feels hot, you have it wired back to front.
If you see the new directory, navigate into it and view the contents of the w1_slave
file, which will contain the temperature value. (Remember to replace our number
with yours.)
cd /sys/bus/w1/devices/28-0000040be5b6
nano w1_slave

You see the contents of the w1_slave file, which contains the temperature data in
Celsius. In our example (shown in Figure 10-3), the temperature is 20.812°C. Press
Ctrl+X followed by N to exit.

Figure 10-3: The temperature shown in the w1_slave file that was created by modprobe.

Now that you’ve completed testing your circuit and you have the sensor working,
you can proceed to the next sections about interfacing with public cloud service
providers.

Storing Data in Google Docs from Your
Raspberry Pi
In this section, we send the temperature readings obtained from the temperature
sensor you build in the last section to a Google Docs spreadsheet that gives you
access to your sensor data from anywhere on the Internet. The main prerequisite for
sending data to Google Docs is having a Gmail address. But we don’t recommend
using your Raspberry Pi’s web browser (Midori) because it’s very slow. Instead,
use a computer or device that you normally use for browsing the web.

Creating a new Google Docs spreadsheet
Using a PC or a device you normally use to browse the web (but not your
Raspberry Pi), go to https://docs.google.com/spreadsheet.

Enter three new column headings — Temperature, Date, and Unit — and give the
spreadsheet a name, as shown in Figure 10-4. Take note of the document key that is
contained in the URL. The URL will look something like this:
https://docs.google.com/spreadsheet/ccc?
key=0Ah0775EeJVAAp0BkTEJha0RyUTBiOU13RS1BVThKcmc#gid=0

Figure 10-4: A new spreadsheet in Google Docs.

The document key is the bold part of the preceding URL, which starts after key=
and ends before cmc#gid=0.

Creating an authentication token
You’re using Google’s OAuth 2.0 for devices to authenticate your Raspberry Pi to
the Google spreadsheet service. For more details on OAuth 2.0 for devices, go to
https://developers.google.com/accounts/docs/OAuth2ForDevices. The
authentication process requires that you authorize your Raspberry Pi to write data
to Google Docs. Authorizing the Raspberry Pi is a one-time three-step process.

Step 1: Creating a client ID
To create a client ID, start by using a web browser to navigate to
https://console.developers.google.com. Then follow these steps:

1. Click Create Project.
The screen shown in Figure 10-5 appears, prompting you to enter a project
name and project ID.
2. Enter the project name (as shown in Figure 10-5), and leave the project ID
whatever Google made up for you.
3. Click Create.
A screen providing the menu options for your new project appears.
4. Click APIs & Auth from the menu bar on the left, and then click
Credentials.
The screen shown in Figure 10-6 appears.
5. Click the Create New Client ID button.
The screen shown in Figure 10-7 appears.
6. Click the Installed Application radio button, and click the Create Client ID
button.
A screen showing your client ID and client secret appears. It looks like Figure
10-8.
You use these two codes later in this section.
7. Click the Consent Screen option in the menu on the left.
A screen showing your email address and a project name appears.
8. Enter your email address in the Email Address field and enter a description
like “Temperature Log” in the Project Name field and click Save.

Figure 10-5: Enter a project name.

Figure 10-6: The Credentials menu option.

Figure 10-6: The Credentials menu option.

Figure 10-7: Create a new client ID.

Figure 10-8: Client ID and Client Secret codes.

Step 2: Initializing the token for your Raspberry Pi
You need to download and run the Python program that will log the temperature
sensor values to the spreadsheet. The first time you run the program, it prompts you
to go to a URL and enter a code (see the next section), which, when entered, gives
the program access to the spreadsheet.
On the Raspberry Pi, log in as the root user and type the following commands:
$
$
$
$
$
$

cd /home
apt-get install python-gdata
git clone git://github.com/gadjetnut/rpipfd.git
cd rpipfd
git clone git://github.com/guyc/py-gaugette.git
ln -s py-gaugette/gaugette gaugette

This process downloads all the software you need. Three Python programs in
particular are important for understanding how the software works:
templogger_gdocs.py: The main program that takes the temperature reading
from the sensor and sends it to the Google Docs spreadsheet.
ds18b20.py: The interface program for the temperature sensor. It contains a
function called GetTemperature that takes two parameters: Fahrenheit and
directory. When Fahrenheit is set to True, this function returns a
temperature reading in Fahrenheit. When Fahrenheit is set to False, it returns
a Celsius reading. The directory parameter is the directory name of your
DS18B20 that you recorded in the “Constructing the temperature sensor” and
“Writing the software” sections, earlier in the chapter.
gdocs.py: Contains the functionality to authenticate with Google Docs. This
was largely adapted from libraries developed by Guy Carpenter
(http://guy.carpenter.id.au/gaugette).
Before you run the temperature logger, you need to do some configuration. At the
command prompt of your Raspberry Pi, perform the following steps:
$ nano templogger_gdocs.py

As shown in Figure 10-9, edit the following configurations:
Enter the unique directory for your DS18B20 sensor that you
took note of in the “Constructing the temperature sensor” section.
ds18b20_dir:
client_id:

client ID.”

Enter the client ID you obtained in the section “Step 1: Creating a

Enter the client secret you obtained in the section “Step 1:
Creating a client ID.”
client_secret:

Enter the spreadsheet key you obtained in the “Creating a
new Google Docs spreadsheet” section.
spreadsheet_key:

fahrenheit: Set this to False if you want a
it set to True for a reading in Fahrenheit.

Celsius reading; otherwise, leave

Figure 10-9: An example of the completed configurations.

Press Ctrl+X, press Y, and then press Enter to save. Now run the database logger
from the command line using the following command:
$ python templogger_gdocs.py

You’re prompted to go to www.google.com/device and enter a code that is
displayed on the screen, as shown in Figure 10-10.

Figure 10-10: An authentication token has to be validated online before the Raspberry Pi is allowed
accessed to Google Docs.

Step 3: Authenticating the token online
Open a web browser, go to www.google.com/device, and enter the code given to
you on your Raspberry Pi, as shown in Figure 10-11. Click the Allow Access
button. You should get the following message:
Success! You've authorized Project Default Service Account.
Please return to your device to continue.

Figure 10-11: Validate your token from the Raspberry Pi online.

Return to your Raspberry Pi, which automatically resumes and starts logging
temperature values to the spreadsheet. You see the temperature reading written to
the screen on the Raspberry Pi as follows:
Temperature of 73.06F logged
Temperature of 73.06F logged
Temperature of 73.06F logged

Finally, open the spreadsheet and check that the temperature values are being
recorded in the spreadsheet, as shown in Figure 10-12.

Figure 10-12: The Google Docs spreadsheet temperature log populated by the Raspberry Pi.

Creating a Dashboard and Temperature
Alerts Using PrivateEyePi
In this section, you create an online temperature dashboard and define rules that
will trigger email alerts to you based on the temperature reading. In this section, the
Raspberry Pi sends temperature readings to PrivateEyePi, where you can view the
temperature and a 24-hour graph on your dashboard. Additionally, each
temperature reading is checked against a set of customizable rules that allow you to
create temperature email alerts.
Follow these steps:
1. Go to www.privateeyepi.com, click the New User link, enter your details,
and click the Update button.
2. Click the GPIO menu option and click Add.
The screen shown in Figure 10-13 appears.

3. Type 7 in the Number field, enter a description in the Description field, and
click Update.
4. Click the Location menu option.
The screen shown in Figure 10-14 appears.
5. In the Description field, enter a description of the location of the
temperature sensor, and click Update.
6. Download the software that will poll the sensor and send the values to the
PrivateEyePi web service.
If you completed the previous section, you can skip this step. Otherwise, type
the following command at the Raspberry Pi command prompt:
cd /home
git clone git://github.com/gadjetnut/rpipfd.git

The preceding commands download the software into the /home/rpipfd
directory.
7. Edit the globals.py file in order to enter your username and password
that you used earlier on the PrivateEyePi website.
At the Raspberry Pi command prompt, type the following:
cd /home/rpipfd
nano globals.py

As shown in Figure 10-15, enter the user and the password in between the
quotes. The user is the email address you used in the signup process from the
PrivateEyePi website.
Page down until you see the DallasSensorNumber settings (see Figure 10-16).
You need to set the GPIO number to 7 in between the brackets (for example,
DallasSensorNumber(7)). Look for DallasSensorDirectory and replace
the numbers you see in the file with your own numbers (refer to the
“Constructing the temperature sensor” section, earlier in this chapter), as
shown in Figure 10-16.

If you want your temperature to be displayed in Fahrenheit instead of
Celsius, find the line that says Fahrenheit=False and change it to
Fahrenheit=True.
8. Press Ctrl+X, press Y, and then press Enter to exit.

Figure 10-13: Configure the GPIO port on the PrivateEyePi website.

Figure 10-14: Configure the location of the sensor.

Figure 10-14: Configure the location of the sensor.

Figure 10-15: User and password for the Private EyePi website.

Figure 10-16: Configure your unique sensor number and sensor directory.

Now you’re ready to run the script and view the temperature on your PrivateEyePi
dashboard display. At the Raspberry Pi command prompt, type the following:
cd /home/rpipfd
python templogger_pep.py

Using a web browser, go to www.privateyepi.com and log in using your email
and password. You’re directed to your dashboard, where you see your temperature
displayed, as shown in Figure 10-17. You can switch on the graph by selecting
Settings from the dashboard and then selecting the Config menu option.

Figure 10-17: The PrivateEyePi temperature dashboard with graph.

You can create rules and actions for each of your sensors. This is useful for
creating a temperature sensor alert if the temperature reaches a certain threshold or
drops below a threshold. Follow these steps:
1. From the dashboard, click Settings and then select the Rules option.
2. Click the Add button and configure a rule and action as shown in Figure 1018 .
In this example, we configured a rule to send an email when the temperature

reading on GPIO 4 is between 0 and –10. (Your email details need to be
configured in the globals.py file.)
Alternatively, you could choose to send an email if the temperature reaches or
exceeds 30°C, for example, which may be an indication of a fire or a problem
with the heating system in your house.
You can define as many rules as you need and you can also combine up to three
rules by clicking the AND drop-down box on the right side of the screen. For
example, you may not want alerts during the day or you may want them only on
specific days of the week.
PrivateEyePi also has alarm system functionality for the Raspberry Pi so you
can configure alerts to be triggered only if the alarm is armed (refer to
www.projects.privateeyepi.com for more details).

Figure 10-18: Define rules in PrivateEyePi.

For more details on how to configure PrivateEyePi rules and actions, visit
www.projects.privateeyepi.com.

Creating a Database Logger
Logging data to the cloud is one way to log data, but you may want to take matters
into your own hands and do it yourself. In the next section, you develop your own
data-logging application and web page to display the data. You install a database
and web server on your Raspberry Pi and write some code to log to the database
and then some HTML and PHP code to view the data. Figure 10-19 shows how all
the components fit together.

Figure 10-19: The interaction of the various components you build in this section.

In the next few sections, we cover topics about which entire books have been
written. Our intent here is to provide you with the tools you need to further your
knowledge in these areas. By following each of the upcoming sections, you end up
with a working database-logging application. You can build on these basics by
modifying the code to add new functionality.

Use the Internet to search for more information. It’s a wonderful resource
for developers seeking knowledge on how to solve problems or in need of
reference material.

Understanding web servers and databases
A web server contains the content (text, pictures, links, tables, and so on) for a
website. It sends the content to a web browser upon request from the web browser.
The content can be static or dynamic. Static content on a web page does not change
(like a book). Dynamic content changes automatically over time, and the content
usually comes from a content management system (CMS) of sorts. An example of a
website with dynamic content is a newspaper website that is continuously updated

with new stories.
In this section, you create a dynamic webpage that displays the temperature and
temperature log, as shown in Figure 10-20.

Figure 10-20: The web page you’ll build.

A database is used to store and query information (data). It’s capable of storing
data and retrieving it at a rapid rate. In this section, we use a database to log the
temperature sensor data and return the data to the web page, which displays the
temperature data to the user (refer to Figure 10-20).

Explaining HTML and server-side scripting
A web page is served from the web server to the browser using Hypertext Markup
Language, more commonly known as HTML. Your web browser interprets the
HTML and displays it. The web browser interprets the HTML and translates it into
graphics, text, links, and tables, but HTML is not a programming language — it’s a
markup language. There are, however, programming languages that can run in the
browser. JavaScript, for example, is a very popular development language that is
inserted into the HTML code and executed in the browser.
Many books have been written on each of these topics, most of which are beyond

the scope of this chapter, but here we share with you the fundamentals of each that
provide you with a platform to further your database knowledge. Try to understand
each line of code and experiment with your own modifications.
For this project, you retrieve data from a database and send it to the web browser
as HTML. Programming languages that perform this function are called server-side
languages because they reside and are executed on the web server (refer to Figure
10-19). There are a number of reasons why you want to perform this action on the
server side and not on the client side (the browser). The most important reason is
security. It’s incredibly risky to expose your data layer to the public Internet.
Another reason to perform it on the server side is that you don’t know what’s
running on the client side, so you can run into incompatibility issues with all the
different operating systems, PCs, tablets, smartphones, and so on that use browsers.
That’s why it’s good practice to keep the client side as simple as possible (using
HTML) and do your database programming on the server side.
There are a number of server-side scripting languages you could use (for example,
PHP, Perl, ASP, or JSP). You use Hypertext Preprocessor (PHP) in this project.
From the browser, you call a PHP file the same way you call an HTML file, except
it has a .php extension (for example, index.php instead of index.html). Figure
10-19 shows interaction between the browser, web and database servers, and PHP
interpreter.
When a PHP file is requested, the web server passes the file to the PHP interpreter,
which executes the PHP code and typically passes back HTML, which the web
server sends back to the browser to display. In Listing 10-1, you can see an
example of a PHP file that resides on the web server that displays either Hello
world or I love Raspberry Pi, depending on the result of a random number.
This demonstrates how PHP can create the dynamic web pages described earlier.
Most of Listing 10-1 is normal HTML except the sections demarcated with  that mark the beginning and end of the PHP code. You don’t need to type
this program in, but we’ve provided it to show you the difference between PHP
and HTML. You code in PHP and HTML later in this chapter.

Listing 10-1: An Example of PHP Code That Resides on
the Web Server



An example PHP application







In Listing 10-2, you can see the HTML that was sent back to the browser. Notice
that the PHP code is not present anymore. Only the result (that is, I love
Raspberry Pi) was sent back to the browser. This is the basic principle of how
server-side scripting works. You build on this principle later in this chapter when
you use PHP to read and write to a database.

Listing 10-2: The HTML That Is Sent to the Web Browser



An example PHP application


I love Raspberry Pi



Delving into database basics
You store the data from the sensor in a database. Think of a database as a
collection of lists of data. Each list is known as a table. Each table has a number of
columns, and each line item in the list is called a row (refer to Figure 10-21).

Figure 10-21: A depiction of a temperature log database table with rows and columns.

A database can store and retrieve large amounts of data very quickly. In this
section, you create a new table called TemperatureLog that contains the
temperature values coming from the temperature sensor. In addition to the
temperature value, you store other information, such as date, time, and unit of
measure (Celsius or Fahrenheit). These data elements will be columns in the table.
The fourth column is a unique identifier for every row called temp_id. It isn’t
strictly required for this project, but it’s good practice to create a unique identifier,
called the primary key, for each row. We configure temp_id to automatically
increment every time a new row is inserted in the database.
The TemperatureLog table will have four columns: temp_id (primary key),
temperature, date/time, and unit_of_measure. Date and time can be stored in
the same column using the DateTime data type. Next, think about how you’ll
manipulate the data. This helps you understand which columns need to be indexed.
An index allows the database to find and sort data very quickly. The ability to sort
the temperature log by date and time is important for reporting, so you’ll create an
index on the date/time column. Lastly, think about how to describe the content of
each of the columns (for example, alphanumeric, numeric, date/time, size, and so
on). These are called data types.

Installing MySQL, PHP, and Apache
After you’ve done some basic database design planning, go ahead and create the

table. You’ll be installing Apache (a very popular web server), MySQL (a
database management system), and PHP (see the “Explaining HTML and serverside scripting” section, earlier in this chapter). All are open-source software and
work very well on a Raspberry Pi.
You’ll be using the root user in this chapter so you don’t run into permission
problems. Start off by logging into your Raspberry Pi as the root user. At the
command prompt, type the following commands:
apt-get
apt-get
apt-get
apt-get
apt-get
apt-get

update
install
install
install
install
install

apache2
php5
php5-mysql
mysql-server mysql-client
python-mysqldb

During the installation, you’ll be prompted to enter a password for the root user in
MySQL.

Creating the data logger
Now you’re ready to create the temperature log table. At the Raspberry Pi
command prompt, type the following:
$ mysql -u root -p

Enter the password you configured earlier during the installation. This will take
you into the command-line interpreter of MySQL. Here you can issue SQL
commands to MySQL. Standard Linux commands will no longer work when you’re
in the MySQL interpreter. Type exit or quit to return to the Linux command prompt.
Next, create a new database by typing the following:
mysql> CREATE database sensor_logs;

Type in the USE command to tell MySQL that all subsequent commands will relate
to the temperature_log table:
mysql> USE sensor_logs;

Next, create a user and password, which you use again later, and assign all
privileges to that user.

We don’t recommend changing the username and password at this point
because we refer to the user “dblogger” with a password of “password” and
it’s also contained in the code. When you have it working, you can come back
and change the password and edit the code with the new password, if you

want.
Create the user and password as follows:
mysql>
mysql>
mysql>
mysql>

CREATE USER 'dblogger'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON sensor_logs.* TO 'dblogger'@'localhost';
FLUSH PRIVILEGES;
quit

Now log back in using the user you just created and create the new table:
mysql -u dblogger -p
mysql> USE sensor_logs;
mysql>CREATE TABLE temperature_log (temp_id INT NOT NULL AUTO_INCREMENT,
temperature DECIMAL(10,2), date DATETIME, unit_of_measure CHAR, PRIMARY
KEY (temp_id));

Check that the table was created successfully by typing the following:
mysql>SHOW TABLES;

As shown in Figure 10-22, you should see the new table listed in the database.

Figure 10-22: Results of a SHOW TABLES command.

Last, create an index on the Date column so that you can search and sort easily by
date:
mysql>CREATE INDEX idx_date ON temperature_log(date);

Now make sure that you’re happy with the new table you’ve created (see Figure

10-23):
mysql>SHOW COLUMNS IN temperature_log;

Figure 10-23: Column view of the temperature_log table.

Log out of MySQL by typing quit.
If you made some mistakes and want to delete the table and start again, use the
DROP statement:
mysql>DROP TABLE temperature_logs;

Be very careful with this command because there is no option to undo it
and you don’t get a warning message that all data in the table will be deleted.

Developing a sensor logger
The next step is to log data into the database from the temperature sensor you built
earlier. You accomplish this by using Structured Query Language (SQL) syntax.
SQL is made up of commands that closely resemble spoken language. Here are
some examples of SQL statements. The following SQL statement will return the
first name, surname (last name), and grade of all students with a surname of Evans:

SELECT firstname, surname, grade FROM student WHERE surname = "Evans"

The following SQL statement creates a new row of data in the student table:
INSERT INTO student (firstname, surname, grade) VALUES ("Jonathan",
"Evans", "A");

The following SQL statement changes the grade of all students that have a surname
of Evans to B:
UPDATE student SET grade = "B" WHERE surname="Evans"

Notice the use of surname in the preceding WHERE clauses. Earlier in the chapter,
we describe how to create an index to sort data and how to make searching data
quicker. Surname would be an ideal candidate for an index. If surname were not
indexed, the database engine would scan through the entire table looking for
students with the surname of Evans. However, by creating an index on the surname
column, the database engine will be able to sort through and pull out the relevant
records much more quickly. However, don’t create an index on many columns
because every index adds overhead to the performance of the table. This is why
planning your database tables, fields, and indexes is important.
Your database logger application will use two SQL statements: an INSERT
statement to log the data and a SELECT statement to retrieve the data that will be
displayed on a web page.
You use a Python program called templogger_db.py to log the temperature
readings to the database. If you didn’t download the chapter software earlier, you
need to download the software using the following commands:
$ git clone git://github.com/gadjetnut/rpipfd.git

Edit the file and observe its contents by typing the following:
$ cd /home/rpipfd
$ nano templogger_db.py

Input the sensor directory name for your DS18B20 sensor (refer to the
“Constructing the temperature sensor” section, earlier in this chapter), as shown in
Figure 10-24.

Figure 10-24: Configure your DS18B20 sensor number.

Page down in the code and observe how the program works. The program starts
execution at def main(): by setting the poll interval to five seconds
(poll_interval = 5). This means you store a temperature reading in the database
every five seconds.
Next, you configure whether you want a Celsius or Fahrenheit temperature to be
stored (fahrenheit=True or False). The program then goes into a loop that logs
the temperature every five seconds. The program uses a function in the
ds18b20.py program called GetTemperature that will run the modprobe
application to obtain a reading from the sensor. If you’re interested in seeing how
the sensor information is retrieved, edit ds18B20.py, which is in the same
directory as templogger_db.py.
Next, the program logs temperature readings to the database using a sequence of
database commands: connect, create cursor, insert, commit, and close. The
MySQLdb.connect statement creates a new database connection, where you pass to
it the IP address of the database server (localhost), the database user name
(dblogger), the password (password), and the name of the database you want to
open (sensor_logs).

Next, prepare a cursor object to execute the SQL statement, followed by execution
of the statement. The commit statement writes the data to the database, and the
close statement closes the database connection.
Exit and save by typing the following:
CTRL-x together, followed by pressing 'Y', then followed by pressing ENTER

Run the program:
$ python templogger_db.py

The program prints temperature readings to the screen and also writes those values
into the database. After the program has logged a few readings, quit by pressing
Ctrl+C. Go back into MySQL and view the data that has been logged by typing the
following commands:
$ mysql -u dblogger -p (then type the password)
$ mysql> USE sensor_logs;
$ mysql> select * from temperature_log;

The rows that were inserted into the database will be listed in a table, as shown in
Figure 10-25.

Figure 10-25: Temperature readings in the database.

Creating a dynamic web page

In this section, you create a web page that displays the temperature log you created
in the previous section on a web page. In the “Installing MySQL, PHP, and
Apache” section of this chapter, you install PHP and Apache. You use both in this
section to create a web page to display your temperature readings. Check that the
Apache installation worked. Open a browser either by typing startx and opening a
browser on your Raspberry Pi, or by using another PC connected to your network,
and type in the IP address of your Raspberry Pi as the URL.
You should see a web page that says It works!, as shown in Figure 10-26.

Figure 10-26: The default page displayed after you’ve installed Apache web server.

You can find the IP address of your Raspberry Pi by typing the following:
/sbin/ifconfig

The output will look something like this:
wlan0 Link encap:Ethernet HWaddr d8:eb:97:18:16:ef
inet addr: 192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0

Your IP address is the number provided after inet addr:, which in this case is
192.168.0.2.

Now that you have your web server up and running, you work with the following
two PHP files to retrieve and display the data on a web page:
Contains two functions: DisplayTemperatureLog displays
the temperature log, and DisplayTheLatestTemperature displays the last
temperature stored in the log.
dbreader.php:

The second PHP file calls both of these functions and displays
the data that the functions return on a web page.
temptest.php:

Later in this section, you create a nicer-looking web page using HTML that reuses
the dbreader.php, but be concerned with the functionality, not the look. PHP files
need to be located in the web server’s directory (/var/www), so you need to copy
both the files into that directory as follows:
$ cd /home/rpipfd
$ cp dbreader.php /var/www
$ cp temptest.php /var/www

Before you run these programs, edit them and observe their contents. At the
command line, type the following:
$ cd /home/rpipfd
$ nano dbreader.php

Read through the PHP code and you see similarities to the Python code you used
earlier to log temperature readings to the database. The syntax is very different, but
the essence of the database commands is the same. A new connection to the
database is made with the following statement:
$mysqli = new mysqli("localhost", "dblogger", "password", "sensor_logs");

Read the database using the following statement:
$res = $mysqli->query("SELECT * FROM temperature_log ORDER BY date
DESC");

The preceding SQL statement returns all the temperature readings and sorts them in
descending order by date. This operation is very fast, even though the table may
contain millions of rows. The reason for the high speed at which SQL can sort
these rows goes back to the index you created on the Date column. The rest of the
function loops through all the records until it reaches the num_rows_to_display
value. The following section loops through the data:
for ($row_no = 0; $row_no < $res->num_rows/
&& $row_no < $num_rows_to_display; $row_no++)
{
echo "";
$res->data_seek($row_no);
$row = $res->fetch_assoc();

}

The echo statements send the HTML back to the web server and then on to the web
browser to get displayed. Press Ctrl+X, press N, and press Enter to exit without
saving.
Next, open the other PHP file that will call each of the two functions and display
the data on the web page:
$ cd /home/rpipfd
$ nano temptest.php

The contents of this program are very simple. All this program does is call the two
functions in dbreader.php and display the contents on the screen. Press Ctrl+X,
press N, and press Enter to exit without saving.
Now return to the browser you used earlier and type the following URL:
http://IPaddress/temptest.php

where IPaddress is the IP address of your Raspberry Pi.
The latest temperature and a table containing the temperatures over the past
calendar day will be displayed on the web page, as shown in Figure 10-27.

Figure 10-27: The raw data from the database log is displayed on a web page.

The data displayed in Figure 10-27 is accurate, but it doesn’t look very nice. Next,
we use more sophisticated HTML in index.php to make look and feel more
professional. index.php is the default file that the web server will look for when
it receives a request from a web browser. For example, you only have to type
http://ipaddress into your browser, and it will display this page.
Edit index.php and observe its contents. Look carefully for , which
demarcate the start end of the PHP code that the PHP interpreter will execute
before sending the HTML back to the browser. At the beginning of the file, you can
see that we’re including dbreader.php, which contains the two functions that are
called later in the file in sections starting with 

Unless you know how to code HTML, the content of the file isn’t easy to
read and won’t make much sense to you. Other than knowing the HTML
basics, you don’t need to know how to code HTML. Few people code HTML
like you would code PHP or Python. This is because there are graphical tools
that are much better suited to creating HTML than coding it in a code editor.
The tool that we used to create index.php is called SiteSpinner Pro, but a
number of other very good tools on the market will do the job.
Exit the file by pressing Ctrl+X, and pressing N to quit without saving. Copy
index.php and the picture file to the web server as follows:
$
$
$
$

cd
rm
cp
cp

/home/rpipfd
/var/www/index.html
index.php /var/www
RPIPFDTLBanner.png /var/www

Now return to your browser and navigate to the IP address of your Raspberry Pi
(http://ipaddress). You should see the final product, as shown in Figure 10-28.

Figure 10-28: The final temperature log web page.

Chapter 11

Webcam and Computer Vision
In This Chapter
Setting up a webcam or Raspberry Pi camera module
Looking at images
Creating image files
Using a webcam to detect motion
Looking at image recognition
Interpreting color
Making a Connect Four game using computer vision
In this chapter, we show you how to give your Raspberry Pi vision using a webcam
or the Pi Camera Module. Using image-processing techniques, you can use the
Raspberry Pi to analyze images to identify things like motion, colors, and shapes.
Here, we show you how computer images are created and how you can look into
the images for information about them.
Note: Throughout this chapter, we provide instructions and code for both a
webcam and the Raspberry Pi Camera module. We use the term camera to refer to
either your webcam or your Raspberry Pi camera. If you’re using Secure Shell
(SSH) and Putty to connect to your Raspberry Pi, you won’t be able to do the
sections of this chapter that require graphical views that aren’t supported in SSH,
but you can view images using FTP. Please ensure that you’re on the latest
Raspbian Wheezy image and have recently performed an update:
$ sudo apt-get update
$ sudo apt-get upgrade

Setting Up the Webcam or Raspberry Pi
Camera Module
Setting up a webcam is as easy as plugging it into the USB port on your Raspberry

Pi or an attached USB hub.

We strongly recommend that you use a powered USB hub for your webcam
because the Raspberry Pi can’t support much more than a keyboard and a
mouse on its own power supply.
You can check the compatibility of your webcam with the Raspberry Pi at
www.elinux.org/RPi_USB_Webcam. When you have your webcam plugged in and
you’ve powered up your Raspberry Pi, type the following commands to see if your
webcam is listed in the listing:
$ lsusb
$ ls /dev

You should see two listings similar to Figure 11-1. We’re using a Creative
Technology, Ltd., webcam (as shown by the first circle in Figure 11-1). In the
second listing, look for video0 (also circled in Figure 11-1). If you see both of
these, you know your webcam is working. If you don’t, try shutting down the
Raspberry Pi, unplugging the webcam, plugging it back in, and starting up again.

Figure 11-1: A listing of USB peripherals, including the USB webcam.

For a list of supported webcams go to
www.elinux.org/RPi_USB_Webcams.
If you have a Raspberry Pi camera module, make sure it’s connected and you’ve
switched on the camera module setting. You should have received setup
instructions with your camera; refer to www.raspberrypi.org/camera for
detailed instructions on installing the camera module.
Test your camera by typing one of the commands in the following sections, position
the camera toward yourself, smile, and press Enter. You should have a wonderful
portrait of yourself saved to a file called test.bmp. You use this technique of
taking pictures throughout this chapter.

Taking a picture with a webcam
To take a picture with a webcam, use the following command:
fswebcam -d /dev/video0 -q -r 1024x768 test.bmp

fswebcam is a utility that’s included in the Raspbian image. Take a close look at
the command to understand what each part does. The -d option is the device name.
(Earlier, we had you look for the video0 file in the /dev directory.) The -q option
is a quiet option that does not display any text to the screen during operation. The r option sets the resolution to 1,024 pixels wide by 768 pixels tall. Finally, you
gave it the filename test.bmp to save the picture to.

For a full list of options, pass the --help option, and all the options will
be written to the screen:
$ fswebcam --help

Taking a picture with the Raspberry Pi camera module
To take a picture with the Raspberry Pi camera module, use the following
command:
raspistill -o test.bmp -t 1 -w 1024 -h 768 -e bmp

raspistill is a utility written specifically for the Raspberry Pi camera. The -o is for
output, followed by the filename where we want the picture to be stored
(test.bmp). The -t is how many seconds it waits before taking a picture (the
default is 5 seconds). As you may have guessed, -w is the width and -h is the height

of the picture.

For a full list of options, pass the --help option, and all the options will
be written to the screen:
$ raspistill --help

Viewing pictures on the Raspberry Pi
Viewing pictures on the Raspberry Pi is best done through X, as follows:
$ startx

Then double-click the lxTerminal icon on the desktop and enter the following
command that will view a picture:
$qinv -f test.bmp

qinv is a utility that displays images. If it isn’t installed, you can type the following
to install it:
$ sudo apt-get install qiv

Understanding Images
A picture may be worth a thousand words, but in this section, we use almost a
thousand words to describe images. Here, we explain, resolution, color spaces,
color models, and file types.

Resolution
Resolution is a term that’s usually associated with the dimensions and pixel count
of an image. Think of an image as a two-dimensional matrix of pixels. In the
previous section, you created a 1,024 x 768 image using your camera. Your picture
contains 1,024 columns and 768 rows, and a total of 786,432 pixels (1,024 × 768 =
786,432).
Resolution is often incorrectly used to determine the clarity of a picture, but the
image size does not determine its clarity. Instead, the number of dots per inch (dpi)
or an image’s spatial resolution is a better determinant of clarity.
For example, compare the 1,024 x 768 pictures created by a webcam to the 1,024 x
768 pictures created by the Raspberry Pi camera module. The Raspberry Pi camera
is a 5-megapixel camera, which means it can produce images with 5 million pixels.

The webcam was designed to produce images that can be sent easily over the
Internet. Even though you may be able to get 1,024 x 768 resolution from the
webcam, the clarity and sharpness of the image doesn’t compare to the camera
picture.

Color spaces
The number of colors, or color space, is measured in bits per pixel (bpp). The
higher the number of bits per pixel, the more colors it represents and the larger the
picture file. A 1-bpp pixel can store 2 (21) colors (if you’re old enough, you may
remember monochrome monitors, which were 2-bit), a 2-bpp pixel can store four
(22) colors, and a 24-bpp pixel can store a staggering 16,777,216 (224) colors. 24
bpp is also known as 24-bit or true color. Deep color (30/36/48-bit) is measured
in the billions of colors per pixel.
If you’re using a Raspberry Pi camera, the picture you took earlier was in 24-bit. If
you’re using a fairly cheap webcam like we are, it’s unlikely that the webcam will
support 24-bit, but some of them can.

Color models
A color model is the mathematical method of representing the color. There are a
whole range of different color models, but a very popular one is the RGB model,
where a color is made up of different intensities of red, blue, and green (known as
channels). Another popular color model is hue, saturation, and value (HSV) or hue,
saturation, and lightness (HSL). You use the RGB and HSV models throughout this
chapter.
For each of these models, a pixel is described using three numbers (one number per
channel). For example the color red in a 24-bit color space would be represented
by the following combination of red, blue, and green: [255,0,0]. There are a total
of 256 different shades of red, blue, and green that, when blended together, produce
a total of 16,777,216 (or 256 × 256 × 256) colors. In Python, we call [255,0,0] a
tuple (a number of values separated by commas). The tuples are stored
sequentially in the image file, one per pixel.

Image file types
Different file types have been created to store the multitude of image types; BMP,
JPG, and GIF are three popular ones. There are so many different file types
because of the massive range of color spaces, color models, and compression

algorithms. Every file type was designed with a particular goal in mind. Some
were created for image clarity, others were created for web pages, and others were
created especially for your webcam to make it easy to share videos and pictures
over the Internet. Our research for this book led us to discover 78 different image
file types, and we’re certain there are more we didn’t find.
In this chapter, you start by using the BMP file format, mainly because its
simplicity makes it a great starting point for understanding how to create and
process image files. Later, you use a Python image library that shields you from the
complexities of each file type and gives you a powerful set of imaging tools.

Check out the image file type comparison chart at
http://en.wikipedia.org/wiki/Comparison_of_graphics_file_formats

Creating an Image File
Enough of the theory — let’s get on with writing some code and working toward
the goal of computer vision! In this section, you write some Python code to create a
BMP image file. You create an image at the lowest possible level without the help
of a camera, scanner, or image programming library. You’re writing the bits and
bytes into a file to create an image.
A BMP file is basically made of up two sections: a header and the image data. The
header describes the file type (24-bit color space, RGB model, and so on). Table
11-1 shows the data that makes up the header.

Table 11.1: BMP File Header Information
Offset

Size
(Bytes)

Description

0

2

The header field used to identify the type of BMP file.

2

4

The size of the BMP file in bytes.

6

2

Not used.

8

2

Not used.

10

4

The offset in bytes where the image data starts.

14

4

The size of the header.

18

4

The bitmap width in pixels.

22

4

The bitmap height in pixels.

26

2

The number of color planes.

28

2

The number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8,
16, 24, and 32.

30

4

The compression method being used.

34

4

The image size.

38

4

The horizontal resolution of the image (pixels per meter).

42

4

The vertical resolution of the image (pixels per meter).

46

4

The number of colors in the color palette.

50

4

The number of important colors used, or 0 when every color is important. Generally ignored.

As you can see from this table, you need to store data in very specific sizes (2 and
4 bytes). This requires you to use data types that match both the size of the data and
the content of the data (character, string, or number). In order to do this, it helps to
understand data types in Python.
Also important is the type of the file. The file you create is known as a binary file.
A binary file is different from a text file that contains characters. The binary file
contains bits and bytes. When you write the Python program, it’s important to write
binary data into the file and not text data. You do this using a byte array and a
function called pack_into().

Refer to the Python reference manual for how to interpret strings as packed
binary data: http://docs.python.org/2.7/library/struct.html?
highlight=pack_into#struct.Struct.pack_into.
Start by opening a new Python program in your home directory. At the Raspberry
Pi command prompt, type the following commands:
$ cd ~
$ nano createbmp.py

Then type the program code in Listing 11-1.

Listing 11-1: Create an Image File
#!/usr/bin/env python
"""
Raspberry Pi Projects For Dummies: create a BMP image

For the Raspberry Pi
"""
import struct
from ctypes import *
def main():
image_size=(1024*768*3)+54
data = create_string_buffer(image_size)
rt=struct.pack_into('=1024:
row_cnt=0
color=color+1
if color>=255: color=0
rt=struct.pack_into(‘threshold:
print "Motion detected:"+str(diff)+"…resetting"
first=True
continue
print "Difference:"+str(diff)
prev_image=current_image
if __name__ == "__main__":
main()

If you’re using a Pi Camera, you need to uncomment the import camera
line near the top of the program by removing the # at the beginning of the line.
The threshold and the pixel sample rate can be fine-tuned with the two variables:
threshold and no_pixels. As we mention earlier, we set them to 100,000 and
3,000, respectively. The first few lines of the main loop (starting with while
True:) are the code that takes a picture either using the webcam or Raspberry Pi
camera. Lines that are commented out start with a #, which tells the Python
interpreter not to execute these lines of code. If you’re using the camera module,
uncomment the four lines that start with camera and comment out the fswebcam
line.
After the picture has been taken, the following line of code loads the picture into an
OpenCV object that you can use to compare the pixels:
current_image = cv2.imread('current.jpg')

When there are two images to compare, the width and height of the image are
determined and the main processing loops start:
for i in range(0, width):
for j in range(0, height):

The next two lines are important because they give you access to the pixel color
tuples (three numbers describing the RGB colors) of every pixel in the sample.
pixel1 = current_image[j][i]
pixel2 = prev_image[j][i]

The j and i variables are the y- and x-axis coordinates of the image, respectively.
The pixel1 and pixel2 variables contain the color tuples of the pixel at the j and
i coordinate as shown here:
pixel1=[245,232,84]
pixel2=[230,220,75]

You can determine the difference between these two pixels by subtracting the
colors from each other and summing the absolute difference. In this example, the
difference would be 15 + 12 + 9 = 36. You do this for every pixel in the sample,
which produces a grand total difference, which is compared to the threshold in the
last if statement of the program. If the threshold is exceeded, the program will
print “Motion detected… .”

Working with Image Recognition
In this section, we create a Python script that can detect circles within an image.
You use this function extensively in the next section where it’s used to detect the
tokens of a Connect Four game. You want to detect not only circles but also the
color. We explain how to detect color in the previous section; here, we build on
that knowledge.

OpenCV has a library of feature detection functions that can be found at
http://docs.opencv.org/modules/imgproc/doc/feature_detection.html

You’re using the Hough Transform Circles technique that was invented in 1959 by
Paul Hough and later patented by the U.S. Atomic Energy Commission. Luckily,
you don’t need to do much programming because the folks at OpenCV have already
done all the hard work. We’ve found that the routine is very good at detecting
circles of common size, but we got less accurate results detecting circles of
different sizes in the same image. In a Connect Four game, we only need to be able
to detect tokens of the same size, so it works very well for that purpose.
Start by finding some round objects of the same size, like Connect Four tokens or
coins, as shown in Figure 11-3. Create an image of the objects called shapes.jpg
using your webcam or Raspberry Pi camera (refer to “Setting Up the Webcam or
Raspberry Pi Camera Module”).

Figure 11-3: Circle detection with OpenCV.

The program in Listing 11-3 processes the image you created and creates a new
image called detectedcircles.jpg. It also automatically displays the new
image, so make sure you’re within X and running an lxTerminal window. To go
into X, type the following command at the command prompt:
$ startx

Then double-click the lxTerminal icon on the desktop and enter the following
command, which will create a new Python script:
$ cd ~
$ nano circles.py

Then type in the code in Listing 11-3.

Listing 11-3: Python Script to Detect Circles with
OpenCV
#!/usr/bin/env python

"""
Raspberry Pi Projects For Dummies: detect circles
For the Raspberry Pi
"""
import cv2.cv
import numpy as np
def main():
img = cv2.imread('shapes.jpg',0)
img = cv2.medianBlur(img,0)
circles = cv2.HoughCircles (img,cv2.cv.CV_HOUGH_GRADIENT, 1,minDist=40,
param1=30, param2=20, minRadius=35, maxRadius=50)
circles = np.uint16(np.around(circles))
img = cv2.imread('shapes.jpg')
for i in circles[0,:]:
# draw the circles
cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
x=i[0]
y=i[1]
Red=img[i[1],i[0],[2]]
Green=img[i[1],i[0],[1]]
Blue=img[i[1],i[0],[0]]
cv2.putText(img,str(int(Red))+","+str(int(Green))+","+/
str(int(Blue)), (x-40,y), cv2.FONT_HERSHEY_SIMPLEX, /
.5, 0)
cv2.putText(img,"Found Circle", (x-50,y+30),/
cv2.FONT_HERSHEY_SIMPLEX, .5, 0)
cv2.imwrite('detectedcircles.jpg', img)
cv2.imshow('detected circles',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()

Run the program from the command line, and a window similar to Figure 11-3
appears. For each circle that it detects, it draws a graphical circle around the
image and writes the text Found Circle and a number that corresponds to the
RGB color of the center pixel of the circle. The program likely won’t work
perfectly the first time you run it because there are a number of parameters that
fine-tune the minimum spacing between circles, and minimum and maximum
diameter.
If you get an AttributeError: rint, this is because it hasn’t detected any
circles. You’ll need to fine-tune it.
The first two lines of the main program open the shapes.jpg image that is located
in the same directory as the program ( ) and convert it to an 8-bit black-and-white

picture that is required by the HoughCircles function. The third line contains the
call to the HoughCircles function. There are three parameters that you need to
fine-tune this function:
minDist

is the minimum distance you want between the center of each of the

circles.
minRadius

is the minimum radius you want for a circle.

maxRadius

is the maximum radius for a circle.

If the function finds circles that do not meet these criteria, it will exclude them from
the list. The next line creates an array (list) of all the circles and stores it in a
variable called circles. The next line opens the image again and discards the
previous black-and-white image. Then there is a for loop that loops through each
of the circles that were found by the HoughCircles function and plots a graphical
circle at the coordinates and with the radius it detected. The program writes the
RGB color code and Found Circle text within each circle (refer to Figure 11-3).
If the program is not detecting the circles correctly, fine-tune it by adjusting the
three parameters accordingly.

Interpreting Color
In the last two sections, we examine the RGB subcomponents of a pixel to
determine the color of a pixel. The RGB color model, however, is not best for
detecting color. A better version of the RGB color model is HSV, sometimes
called HSL. In the “Building a Connect Four Game Using Computer Vision”
section of this chapter, you need to be able to detect the red and yellow colors of
differing brightness. To the human eye, all the pieces in a Connect Four game
appear either red or yellow, but their brightness differs vastly depending on the
lighting conditions, shadows, and angle of the camera. Using the RGB color model,
the number ranges of different shades of the same color differ substantially.
However, using the HSV model, the hue (the main representation of color) remains
constant. The shadows will likely affect the value or maybe the saturation.
We’ve modified Listing 11-3 to perform an HSV conversion and use it to
distinguish between red and yellow circles in Listing 11-4. Instead of printing the
RGB color within the circle, it will now print the HSV values. Instead of printing
Found Circle, it will print the color interpretation of the red or yellow circle. If
you have different color tokens in your image, fine-tune color ranges until you get

accurate interpretations.
The program in Listing 11-4 processes the image you created and creates a new
image called detectedcircles.jpg (see Figure 11-4).

Figure 11-4: Circle and color detection with OpenCV.

The program will also automatically display the new image, so make sure you’re
within X and running an lxTerminal window. To go into X, type the following
command at the command prompt:
$ startx

Then double-click the lxTerminal icon on the desktop and enter the following
command to create a new Python script:
$ cd ~
$ nano circles2.py

Now type the code in Listing 11-4.

Listing 11-4: Python Script to Detect Circles and Red or
Yellow Colors
#!/usr/bin/env python
"""
Raspberry Pi Projects For Dummies: detect circles and color
For the Raspberry Pi
"""
import cv2.cv
import numpy as np
def rgb2hsv(r, g, b):
r, g, b = r/255.0, g/255.0, b/255.0
mx = max(r, g, b)
mn = min(r, g, b)
df = mx-mn
if mx == mn:
h = 0
elif mx == r:
h = (60 * ((g-b)/df) + 360) % 360
elif mx == g:
h = (60 * ((b-r)/df) + 120) % 360
elif mx == b:
h = (60 * ((r-g)/df) + 240) % 360
if mx == 0:
s = 0
else:
s = df/mx*100
v = mx*100
return h, s, v
def main():
img = cv2.imread('shapes.jpg',0)
img = cv2.medianBlur(img,0)
circles = cv2.HoughCircles(img,cv2.cv.CV_HOUGH_GRADIENT,1,minDist=100 /
,param1=30,param2=60,minRadius=45,maxRadius=75)
circles = np.uint16(np.around(circles))
img = cv2.imread('shapes.jpg')
for i in circles[0,:]:
# draw the circles
cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
x=i[0]
y=i[1]
Red=img[i[1],i[0],[2]]
Green=img[i[1],i[0],[1]]
Blue=img[i[1],i[0],[0]]
hsv=rgb2hsv(Red, Green, Blue)
Hue=round(hsv[0])
Sat=round(hsv[1])

Value=round(hsv[2])
if ((Hue>=320) or (Hue>=0 and Hue <=25)) and (Sat>50):
token="Red"
elif (Hue>=30 and Hue<=60) and (Sat>50):
token="Yellow"
else:
token="Blank"
cv2.putText(img,str(int(Hue))+","+str(int(Sat))+","+str(int( /
Value)), (x-40,y), cv2.FONT_HERSHEY_SIMPLEX, .5, 0)
cv2.putText(img,token, (x-30,y+30), cv2.FONT_HERSHEY_SIMPLEX,
.5, 0)
cv2.imwrite('detectedcircles.jpg', img)
cv2.imshow('detected circles',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()

The code explanation is the same as the code explanation in the “Working with
Image Recognition” section, except for the code starting at this line:
hsv=rgb2hsv(Red, Green, Blue)

This line calls the rgb2hsv function within the program with the RGB parameters.
The function performs the mathematical conversion and returns the HSV equivalent
of the color. The next few if statements compare the HSV values to the number
ranges for red and yellow. If your tokens are a different color, adjust these values
until you get the correct readings for your colors.

Many color wheels are available online that will help you determine the
RGB and HSV values for all the colors in the color model. You can use sites
like www.colorizer.org to determine the color numbers for ranges of
colors.

Building a Connect Four Game Using
Computer Vision
In this section, you use a webcam or Raspberry Pi camera to give your Raspberry
Pi a view of a real-life Connect Four game. Using what you learned in the previous
sections of this chapter, you can detect the movement of pieces and the color of
each piece to give the Raspberry Pi enough information to play against a human

opponent. We’ve added speech to the program so the Raspberry Pi can announce
whose turn it is and which moves it wants you to make for it.
This section requires some coding that is more in depth than the rest of the chapter.
The code listing is quite long, but you can download it from
www.dummies.com/go/raspberrypiprojects. Let’s get started!
Start off by calibrating your webcam and the Connect Four grid. Fill most of the
positions on the grid with tokens and try to evenly space out the red and yellow
pieces (or whichever color tokens you have); leave some blank. Position your
webcam evenly in front of the grid and take some 640 x 480 pictures (refer to
“Setting Up the Webcam or Raspberry Pi Camera Module,” earlier in this chapter),
until you’re satisfied that the grid occupies most of the picture. Try to use a white
or neutral background, and don’t use any patterns that contain circles other than the
grid within the picture. Run your sample images through the program in Listing 114 until you have every circle correctly identified (see Figure 11-5).

Figure 11-5: A correctly calibrated Connect Four grid with all pieces identified correctly.

You need to fine-tune these values in the HoughCircles function call:
minDist

is the minimum distance you want between the center of each of the

circles.
minRadius

is the minimum radius you want for a circle.

maxRadius

is the maximum radius for a circle.

After it’s calibrated, you’re ready to move on to the actual game itself. You need to
install OpenCV (if you haven’t done that already in the previous sections):
$ sudo apt-get install libopencv-dev python-opencv

The program makes use of a program called mpg321 to play the MP3 files that the
computer uses to communicate with the player:
$ sudo apt-get install mpg321

Now code the program in Listing 11-5 by typing the following:
$ cd ~
$ nano c4.py

Listing 11-5: Connect Four Game Using Computer Vision
#!/usr/bin/env python
"""
Raspberry Pi Projects For Dummies: Connect Four Game Using Computer Vision
For the Raspberry Pi
"""
import cv2
import cv2.cv
import numpy as np
import struct
import math
import sys
import os
from operator import itemgetter, attrgetter
#Uncomment this line of you have a Pi Camera
#import picamera
import
import
global
global
global

time
random
circles
human_color
computer_color

def rgb2hsv(r, g, b):
r, g, b = r/255.0, g/255.0, b/255.0
mx = max(r, g, b)
mn = min(r, g, b)
df = mx-mn
if mx == mn:
h = 0
elif mx == r:
h = (60 * ((g-b)/df) + 360) % 360
elif mx == g:

h = (60 * ((b-r)/df) + 120) % 360
elif mx == b:
h = (60 * ((r-g)/df) + 240) % 360
if mx == 0:
s = 0
else:
s = df/mx*100
v = mx*100
return h, s, v
def calculate_a_move(c4grid):
global human_color
global computer_color
max_found=0
best_move=0
#find best move for the computer
#first we determine the max amount in row
rt=check_for_4_in_a_row(c4grid)
if rt[0]!=1:
max_found=rt[2]
for x in range (0,7):
for y in range (0,6):
if (y==5) or (c4grid[x,y]=="B" and/
c4grid[x,y+1]!="B"):
#Reevaluate if a disc in this position
#will yield more in a row
c4grid[x,y]=computer_color
rt=check_for_4_in_a_row(c4grid)
c4grid[x,y]=“B”
if rt[0]==1:
return(x+1)
if rt[2]>max_found:
max_found=rt[2]
best_move=x+1
#check if human needs to be blocked
c4grid[x,y]=human_color
rt=check_for_4_in_a_row(c4grid)
c4grid[x,y]="B"
if rt[0]==1:
return(x+1)
break
if best_move==0:
best_move=random.randint(1,7)
return(best_move)
def check_for_4_in_a_row (c4grid):
max_found=0
max_found2=0
#look for vertical
best_move = [0,0]

for x in range (0,7):
found=1
max_found=1
for y in range (1,6):
if (c4grid[x,y]=="Y" or c4grid[x,y]=="R") and/
c4grid[x,y]==c4grid[x,y-1]:
found=found+1
if c4grid[x,y]=="Y":
max_found=max_found+1
else:
found=1
if found==4:
return([1,1,x,c4grid[x,y]])
if max_found > 1:
max_found2=max_found2+max_found
#look for horizontal
for y in range (0,6):
found=1
max_found=1
for x in range (1,7):
if (c4grid[x,y]=="Y" or c4grid[x,y]=="R") and/
c4grid[x,y]==c4grid[x-1,y]:
found=found+1
if c4grid[x,y]=="Y":
max_found=max_found+1
else:
found=1
if found==4:
return([1,2,y, c4grid[x,y]])
if max_found > 1:
max_found2=max_found2+max_found
#look for diagonal bottom left top right
startx=0-(6-4)
for z in range (0,6):
x=startx
y=5
max_found=1
found=1
while y>=1:
if x>0 and x<=6-1:
if (c4grid[x,y]=="Y" or c4grid[x,y]=="R") and/
c4grid[x+1,y-1]==c4grid[x,y]:
found=found+1
if c4grid[x,y]=="Y":
max_found=max_found+1
else:
found=1
if found==4:
return([1,3,x,c4grid[x,y]])

x=x+1
y=y-1
startx=startx+1
if max_found > 1:
max_found2=max_found2+max_found
#look for diagonal bottom left top right
startx=0-(6-4)
for z in range (0,6):
x=startx
y=5
max_found=1
found=1
while y>=1:
if x>0 and x<=6-1:
if (c4grid[x,y]=="Y" or c4grid[x,y]=="R") and/
c4grid[x+1,y-1]==c4grid[x,y]:
found=found+1
if c4grid[x,y]=="Y":
max_found=max_found+1
else:
found=1
if found==4:
return([1,3,x,c4grid[x,y]])
x=x+1
y=y-1
startx=startx+1
if max_found > 1:
max_found2=max_found2+max_found
#look for diagonal bottom right to top left
startx=6+(6-4)
for z in range (0,6):
x=startx
y=5
max_found=1
found=1
while y>=1:
if x>0 and x<=6-1:
if (c4grid[x,y]=="Y" or c4grid[x,y]=="R") and/
c4grid[x-1,y-1]==c4grid[x,y]:
found=found+1
if c4grid[x,y]=="Y":
max_found=max_found+1
else:
found=1
if found==4:
return([1,4,x,c4grid[x,y]])
x=x-1

y=y-1
startx=startx-1
if max_found > 1:
max_found2=max_found2+max_found
return([0,"",max_found2])
def check_for_new_move(prev_grid, c4grid):
for x in range (0,7):
y=0
while y<=5 and prev_grid[x,y]=="B":
y=y+1
if y>0 and c4grid[x,y-1]<>"B":
new_token=c4grid[x,y-1]
return([x, new_token])
return([0,""])
def process_image(new_game):
global circles
c4grid = np.empty((7, 6), dtype=object)
no_empty_slots=0
#If you are using a Raspberry Pi Camera
camera = picamera.PiCamera()
camera.resolution = (640, 480)
camera.capture('c4grid.bmp')
camera.close()
#If you are using a webcam
#os.system("fswebcam -d /dev/video0 -q -r 640x480 c4grid.bmp")
if new_game:
img = cv2.imread('c4grid.bmp',0)
img = cv2.medianBlur(img,0)
circles = cv2.HoughCircles(img, cv2.cv.CV_HOUGH_GRADIENT,/
1,40,param1=20/ ,param2=30, minRadius=25, maxRadius=50)
circles = np.uint16(np.around(circles))
img = cv2.imread('c4grid.bmp')
grid = []
for i in circles[0,:]:
x=i[0]
y=i[1]
Red=img[i[1],i[0],[2]]
Green=img[i[1],i[0],[1]]
Blue=img[i[1],i[0],[0]]
hsv=rgb2hsv(Red, Green, Blue)
Hue=round(hsv[0])
Sat=round(hsv[1])
Value=round(hsv[2])

if ((Hue>=320) or (Hue>=0 and Hue <=25)) and (Sat>50):
token="R"
elif (Hue>=69 and Hue<=165) and (Sat>50):
token="G"
elif (Hue>=30 and Hue<=60) and (Sat>50):
token="Y"
else:
token="B"
no_empty_slots=no_empty_slots+1
grid.append([0,0,x,y,token, img[i[1],i[0]]])
temp = sorted(grid, key=itemgetter(2))
xcounter=0
prev=(int)(temp[0][2])
for i in temp:
if abs(prev-(int)(i[2]))>20:
xcounter=xcounter+1
i[0]=xcounter
prev=(int)(i[2])
temp = sorted(grid, key=itemgetter(0,3))
ycounter=-1
prev=(int)(temp[0][0])
for i in temp:
if prev<>(int)(i[0]):
ycounter=0
else:
ycounter=ycounter+1
i[1]=ycounter
prev=(int)(i[0])
for i in temp:
x=i[0]
y=i[1]
if x>=0 and x <=6 and y>=0 and y<=5:
c4grid[x, y]=i[4]
return(c4grid, no_empty_slots)
def wait_for_play(c4grid):
prev_grid = c4grid
no=0
new_move_detected=False
while not new_move_detected:
rt=process_image(0)
c4grid=rt[0]
print "C4 Grid:"
for y in range (0,6):

print c4grid[0,y] , ",", c4grid[1,y],", /
" , c4grid[2,y],",",c4grid[3,y], ",",c4grid[4,y],",",c4grid[5,y],",",c4grid[6,y]
rt=check_for_new_move(prev_grid, c4grid)
if rt[1]!="":
print "New move detected in column "+str(rt[0]+1)/
+ " color "+rt[1]
prev_grid=np.copy(c4grid)
new_move_detected=True
return(c4grid)
def play_mp3(mp3_no):
if (mp3_no>=1 and mp3_no<=7):
mp3_file="slot"+str(mp3_no)+".mp3"
elif mp3_no==8:
mp3_file="mymove.mp3"
elif mp3_no==9:
mp3_file="yourmove.mp3"
elif mp3_no==10:
mp3_file="letsplay.mp3"
elif mp3_no==11:
mp3_file="youwin.mp3"
elif mp3_no==12:
mp3_file="letsplayagain.mp3"
elif mp3_no==13:
mp3_file="badluck.mp3"
os.system('mpg321 -q '+mp3_file)
return
def main():
global human_color
global computer_color
humans_turn = True
human_color="R"
computer_color="Y"
new_game=True
winner=False
play_grid = np.empty((7, 6), dtype=object)
while True:
while new_game==True:
rt = process_image(1)
if rt[1]==7*6:
new_game=False
winner=False
play_grid=rt[0]
time.sleep(2)

print "Empty grid detected, let's play!"
play_mp3(10)
play_mp3(9)
while True:
play_grid = wait_for_play(play_grid)
rt = check_for_4_in_a_row(play_grid)
if rt[0]==1:
print "four in a row"
if rt[3]==human_color:
play_mp3(11)
play_mp3(12)
else:
play_mp3(13)
play_mp3(12)
new_game=True
humans_turn = True
break;
if not humans_turn:
play_mp3(9)
humans_turn=True
else:
play_mp3(8) # my move
rt = calculate_a_move(play_grid)
play_mp3(rt)
humans_turn=False
if __name__ == "__main__":
main()

Starting at the main() section, there are a few variables you can change in order to
configure the color for the human and the color for the computer. If you use colors
other than red or yellow, do a search for R and Y and replace with your colors. The
game is programmed for the standard grid of seven across by six down. The
program then enters the main loop, which has two sub loops: one for determining
the start of a new game (that is, an empty grid), and one for game play. Notice a
number of play_mp3 function calls throughout the program. These play the sounds
for the Raspberry Pi to communicate with the human. You can download these files
from www.dummies.com/go/raspberrypiprojects. The computer moves are
communicated to the human who must perform the moves on the computer’s behalf.
The computer’s intelligence is limited to the following:
Detecting a change in game state when a piece is dropped into the grid
Determining whether the computer needs to block the human from getting four

in a row
Determining the computer’s best move by calculating which move will produce
the most in a row for the computer.
The computer does not
Detect whether an incorrect move has occurred. (You can cheat!)
Think ahead more than one move (either for blocking or for its own game
strategy).
When an empty grid has occurred, the computer announces “Let’s play!” and the
main game play loop starts. The game play loop consists of the following steps:
1. Wait for a move to occur.
2. Once a move has occurred, check for four in a row.
3. Either tell the human to move or calculate a computer move.
Starting at the top of the program, here’s is an explanation of each function:
converts the RGB color model to HSV (see the “Interpreting Color”
section, earlier in this chapter).
rgb2hsv

determines the best move for the computer, which includes
either blocking the human or calculating a move that yields the most tokens in a
row for the computer.
calculate_a_move

scans the grid to determine whether there are four
tokens in a row vertically, horizontally, or diagonally. This function also serves
the calculate_a_move function by returning the maximum number of tokens in
a row for the computer for each possible move.
check_for_4_in_a_row

check_for_new_move

scans through the grid in memory to determine if it has

changed.
is very similar to the calibration program you wrote earlier.
It’s responsible for taking a picture of the grid, finding the circles, determining
the color and position of each piece, and storing the grid in memory. This
function contains the HoughCircles function that you need to change to match
the values you calibrated earlier. The HoughCircles function returns a long
list of all circles, so this function also sorts each circle by x- and y-coordinate
process_image

to determine its position in the grid.
loops and continuously checks for new moves. It also prints
the grid that the computer has in memory to the screen so you can verify that the
computer is “seeing” each piece correctly.
wait_for_play

plays each MP3 file using the mpg321 external program call. If you’d
prefer to see the move written to the screen and not spoken, this would be a
good place to replace the os.system call with a print command. You can
download these files from www.dummies.com/go/raspberrypiprojects.
play_mp3

Chapter 12

The Raspberry Jazz Glitter Trio
In This Chapter
Hacking a glitter lamp
Attaching a webcam
Reading an image
Assigning sound
Extracting pixel data
Creating the band
This is a fun project that creates a free jazz trio inside your Raspberry Pi. (Some
people joke that free jazz got its name because no one would ever pay for it. True,
jazz is an acquired taste and a little goes a long way, but this is a fascinating little
project nevertheless.) The project points a webcam at a glitter lamp, the kind that
features glitter floating in a liquid. The camera acts as a high-resolution multicolor
sensor. It uses the data gathered from the glitter lamp to trigger the sounds for the
project, thus creating free jazz.

Meeting the Gang
The photograph in Figure 12-1 shows our version of the Raspberry Pi jazz glitter
trio. Yours may be a bit different because of the exact materials you’re able to
gather, but it shows you what you’re aiming for.

Figure 12-1: The finished Raspberry Jazz Glitter Trio.

It consists of two main components — a cheap webcam and a glitter lamp —which
we picked up from a home bargain/thrift store for less than $10 for the pair. These
are cheap, generic devices and are widely available online, including on eBay.

The lamp
The glitter lamp we chose was the smallest we could find. It’s about 5 inches tall
and contains silver glitter suspended in a liquid. When the lamp is still, the glitter
slowly floats up. When the lamp is turned upside down, a tilt switch in the base
triggers a circuit to start one minute of random pulsing of three different colored
light-emitting diodes (LEDs), illuminating the glitter from the lamp’s base. As the
glitter drifts and tumbles, some pieces catch the light from the LEDs and sparkle.
Because the LEDs are in different positions, different bits of glitter get illuminated
with different colors.
In this project, you use this effect to trigger jazz sounds. Both the lamp and the
webcam are mounted in a box. The box includes a back shield so that only the
glitter is picked up and stray light is reduced. (Construction plans of the box are
included as part of the project.)

The webcam
Webcams come in all sorts of shapes, sizes, and resolutions. For this project, get
the cheapest one you can find. The resolution doesn’t matter much for this project,
so a low-resolution webcam will do the trick. Here’s what to look for in a webcam
for this project:
Compatibility: The most important thing is that the camera be supported by the
Raspberry Pi’s Python-based software, which usually seems to support lowcost generic cameras.
Access to the interior of the webcam: You need to be able to physically get
into the camera so you can mount it. Look for a webcam with small screws on
the outside of the case rather than an all-in-one molded type of case. You’re
going to be hacking into the USB power lead to power the glitter lamp’s LEDs.
Manual focus: Make sure that the webcam has a manual-focus lens. The fixedfocus types are hard to adjust for very small distances, which is what you need
for this project.

You can buy the webcam we used at
http://uk.farnell.com/trust/17003/webcam-exis-trustuk/dp/1860369. For a complete list of Raspberry Pi USB webcams,
out www.elinux.org/RPi_USB_Webcams.

check

Testing the Webcam
The first step is to test whether your webcam works and is supported by the
software. Create a directory for the project called glitter, either from the
desktop or by typing the following from your home directory (or wherever you
want to work):
mkdir glitter
cd glitter

Next, download the support files you need by typing the following:
sudo wget http://www.cl.cam.ac.uk/downloads/freshers/image_processing.tar.gz

To extract the files, you just type the following:
sudo tar -xf image_processing.tar.gz

This gives you the support software and some basic tutorial files on how to use the
software, but for the time being, ignore these and install the Python libraries. First,
navigate to the libraries directory. Then install the libraries by typing the
following two lines:
sudo cd library
sudo make install

This executes a script that moves all the files and the library code into the
necessary places in Python’s file system.
Now you’re ready to try out the camera. Create a file, using the code shown in
Listing 12-1, and store it in your glitter directory. Give it the title of
camTest.py, plug in your webcam, change the directory of the prompt to the
glitter directory, and run the file by typing the following:
python camTest.py

Listing 12-1: Camera Test
from imgproc import *
import time
my_camera = Camera(320, 240)
my_image = my_camera.grabImage()
my_view = Viewer(my_image.width, my_image.height, "WebCam")
while True:
my_view.displayImage(my_image)
time.sleep(0.1)
my_image = my_camera.grabImage()

Reading step-by-step through this listing gives you an idea of what’s going on.
First, you have to import the module that supports the webcam, as well as the time
module. Then you define an instance of the Camera class and say what size you
want it to be. Here, it’s only 320 x 240 pixels, so it’s not very high resolution.
(Later, you make this even smaller.) Next, the listing grabs an image from what the
camera is currently seeing and defines a view window for later displaying this
image on the screen. Last, the program goes into an endless loop of displaying the
image, sleeping (or delaying) for 0.1 second, and then getting a new image.
The result of this listing is that you see the image from your webcam in the top-left
corner of the screen. If this fails, your webcam is probably not supported by
Raspberry Pi and you’ll have to get another one to do this project.
If your webcam works, check that you can focus to half an inch or so. If you can’t,
you may be able to adjust the lens when you take the camera apart.

Hacking the Glitter Lamp

Hacking the Glitter Lamp
You can set up your camera pointing to the glitter lamp and turn it on manually —
this will give you some idea of what the finished project will sound like. However,
by hacking the glitter lamp and the camera, you get a neat compact unit all powered
off the USB connection, and you can easily invert the lamp to get the glitter all
mixed up again.

You may have to modify these instructions depending on how your lamp
and camera are constructed.
Note: At this point, you may want to skip to the software section, and get the
system going without doing any hardware hacking. Feel free to skip ahead and
come back to this section later.

Assembling the necessary parts
Besides a glitter lamp and a suitable webcam (covered earlier in this chapter),
here’s a list of the parts we used:
¼-inch plywood or medium-density fiberboard (MDF) to make the box — two
pieces measuring 3 x 5 inches and one piece measuring 3 x 2 inches
¾-x-16-inch strip of pine for the box sides
A tack switch with ¼-inch plunger
A 3-inch length of ⅜-inch angle aluminum
Matte black paint
Four 18mm M3 tapped hexagonal pillars
Ten 10mm pan-head M3 screws
Two M3 nuts
Wood glue, hot glue, and connecting wire
The glitter lamp we bought is shown in Figure 12-2. It was powered by three selfcontained coin cell batteries.

Figure 12-2: Our original glitter lamp.

Except for the battery compartment, we could see no way into the lamp, so
eventually we resorted to drastic measures and cut all around the base with a saw,
leaving it looking a bit truncated, as shown in Figure 12-3.

Figure 12-3: The glitter portion of the lamp.

This left the electronics in the other half of the lamp. In Figure 12-4, the photograph
on the left shows the circuit board in the plastic assembly, and the photograph on
the right shows the removed printed circuit board (PCB). That long component on
the top is the tilt switch; it consists of a small metal ball inside a tube that makes a
circuit between the two wire ends when the lamp is tilted past a certain angle.

Figure 12-4: The electronics of the lamp.

In this project, you need to remove the tilt switch and solder a normal push button
in its place. Extend the power wires by soldering two new wires to the PCB, and

then solder two other wires about 6 inches long to the connections where you
removed the tilt switch. Bend the LEDs so that they point up. You’re going to mount
this under the lamp’s glitter section, as shown in Figure 12-5.

Figure 12-5: The LEDs mounted on the base.

Making the box
Figure 12-6 shows the schematic of the box into which you’ll place the lamp and
webcam.

Figure 12-6: The box schematic.

If your camera or glitter lamp are materially different from the ones we
used, you may have to modify these instructions to suit what you have.
To make the box, follow these steps:
1. Cut two pieces of 5-x-3-inch MDF or plywood.
2. In the top piece, cut a 1½-inch hole at one end to take the diameter of the
clear base of the glitter lamp, and then cut a tapered hole to which the
camera can be attached.
We did this by first drilling a 10mm hole and then enlarging it to 12mm by
drilling only partially through the wood. This allowed us to use the thickdomed plastic plug (which normally attaches the camera to its stand) to attach
the camera to the board.
3. Drill a ⅛-inch hole for the tack switch to poke out of and four ⅛-inch holes
in each corner for the supporting pillar.
When we did this, we also clamped the base and top together so the holes lined
up.
4. Cut a 2¾-inch piece of ¼-inch angled aluminum for the back screen
support, and drill two ⅛-inch holes ½-inch from each side on both faces of
the aluminum.
Mark the holes on the top through the holes in the aluminum, so they line up
correctly.
5. Cut part of a semicircle in the aluminum so you can get the back screen
close to the glitter lamp.
We used a round back file for this.
6. Use ¾-inch strip pine to make the sides, and glue them to the top.
7. Use 18mm tapped pillars between the top and the base to hold it all
together.
8. Cut a 3-x-2-inch back screen from the wood and mount it on the aluminum
angle with two screws and nuts. Then paint the whole thing matte black.
You can use another color if you want, but black cuts down the stray reflected
light, especially from the back shield.

The idea is that the LEDs are placed under the large hole and the glitter lamp is
glued in the lid of the box. We used a small ring from the lower part of the lamp
that we cut off previously.
9. Cut a chamfer (beveled edge) on the inside of the lamp’s ring with a
scalpel or sharp hobby knife so that it fits snugly over the ring surrounding
the LEDs. Push this ring onto the base of the lamp and screw the box
together.
10. Using hot glue or silicon sealant, glue the lamp to the top of the box.
11. When the glue or sealant has set, unfasten the box and apply another fillet
of glue to the underside.
12. Put some glue on the base of the ring and again assemble the box so the
ring is secured in the right place, as shown in Figure 12-7.

Figure 12-7: The lamp/electronics assembly.

Adding the camera
To take the camera apart, first we unscrewed the plastic plug that holds the camera
to its clip or stand. Then we unfastened the screws in the body. (In the case of our
camera, there were four small star-head screws.)
You want to tap off the 5V and ground coming from the USB lead that powers it
with a pair of wires. You need to take this power to the LEDs in the box. With the
camera enclosure removed, you can see the red and black wires carrying the USB

power. Solder two new wires onto this and drill two 1mm holes in the plastic case
so these wires can pass out of the camera body.
You also have to drill two matching holes in the top of the box for them to pass
through. Reassemble the camera and, with the round plastic plug, attach the camera
to the top of the box and pass the wires through the lid.
Connect the two wires from the LED board to a tack switch with a ¼-inch-long top
and glue that in place in the center hole in the top. From the underside, the wiring
should look something like that shown in Figure 12-8.

Figure 12-8: The wiring of the project.

Testing
After you have the hardware built, it doesn’t do any harm to give it a quick test.
You can plug it into your Raspberry Pi and run the program in Listing 12-1 just to
make sure that the camera still works. Then push the tack switch that replaced the

tilt switch and make sure that the LEDs pulse for about a minute.

Letting the Band Play
There are two more things you need before you can get a performance out of this
band: sound samples and software. The way these are brought together determines
how the project works. You need to define an array of pixels to sample from the
glitter image. When these points reach a certain brightness and color, the sounds
are triggered.

Gathering the sounds
First, you have to gather the sounds for the trio. We did a web search for individual
sounds for each instrument: sax, bass, and drums. There are many free sound
sample sites, but the one we found most useful was www.freesound.org because
you can search for specific sounds and listen to them before downloading. We
looked for short samples, mainly single notes, from each of the three instruments.
We got 16 samples for bass and drums and 22 samples of the sax. (You can use
more, but you’ll have to make minor changes to the software if you do.)
We used Audacity (a free downloadable audio editor and recorder, available at
http://audacity.sourceforge.net) to top and tail each sample (that is, to cut
out any long silence at the beginning and end of the sample). Also, while chopping
the samples up, we converted them into a mono sample in order to save memory
space. This is a bit of an iterative process: After you hear the results, you may want
to go back and get different types of sounds.
Finally, after a bit of trial and error, we placed the samples in directories at the
same level as the code called sax, drums, and bass. Each sample is called sound
X.wav, where the X is replaced by a number, starting at 0 and incrementing up to
the biggest sample number.

Writing the software
The idea behind the code is that, from the image, 16 pixels in a 4 x 4 grid will be
monitored for color. When a bright red, green, or blue color is detected, a sound is
triggered. In the case of drums or bass each pixel monitored triggers a fixed
sample, but the sax triggering is slightly more complex. The sax sound triggered
depends on both the number of the pixel triggering it and an offset. The offset is
incremented on each sax trigger, and when it reaches a limit, it resets back to 0. We
found this approach necessary to introduce a bit of variety into the music produced.

(Although a repetitive drum and bass note sounds fine, the sax, being a solo
instrument, needs a bit of variety to keep it interesting.)
Because you’re using only 16 pixels out of the whole image, you don’t need a very
big image. We used a 160-x-120-pixel image. This still results in an image of
19,200 pixels, which is quite a lot of memory for a small embedded processor,
especially considering that you’re only interested in 16 of the pixels. Each pixel
has 3 bytes of memory associated with it — one each for the red, green, and blue
signals. To add a bit of interest, after a pixel triggers a sound, the program draws
an outline around that pixel so you can see what’s happening. All this is done in the
code shown in Listing 12-2.

Listing 12-2: The Glitter Band
from imgproc import *
import time
import os, pygame, sys
pygame.init()
pygame.mixer.quit()
#pygame.mixer.init(frequency= 44100, size=8, channels = 8, buffer= 2048 )
pygame.mixer.init()
print"loading Sound files"
samplesSax = [pygame.mixer.Sound("sax/sound"+str(i)+".wav") for i in range
(0, 22)]
samplesBass = [pygame.mixer.Sound("bass/sound"+str(i)+".wav") for i in range
(0, 16)]
samplesDrum = [pygame.mixer.Sound("drums/sound"+str(i)+".wav") for i in range
(0, 16)]
print"finished"
my_camera = Camera(160, 120)
my_image = my_camera.grabImage()
my_view = Viewer(my_image.width, my_image.height, "WebCam")
monX = [ int(p * 32) for p in range(1,5)]
monY = [ int(p * 24) for p in range(1,5)]
saxOffset = 0
def main():
global my_image
while True:
my_image = my_camera.grabImage()
for x in monX:
for y in monY:
surround(x,y,(0,0,0))
#my_view.displayImage(my_image)
#time.sleep(0.1)
#print" "
for x in monX :
for y in monY :
red, green, blue = my_image[x, y]
if green > 248 :
#print green," green at ", x, y
sampleSax(x,y)
if red > 225 :
sampleDrum(x,y)
#print red," red at ", x, y
if blue > 240 :

sampleBass(x,y)
#print blue," blue at ", x, y
my_view.displayImage(my_image)
def sampleSax(x,y) :
global saxOffset
number = saxOffset + ((x /
samplesSax[number].play()
surround( x,y-3, (0,255,0)
saxOffset += 1
if saxOffset >5 :
saxOffset = 0
def sampleBass(x,y) :
number = ((x / 32)-1) + (4
samplesBass[number].play()
surround( x+3,y, (0,0,255)
def sampleDrum(x,y) :
number = ((x / 32)-1) + (4
samplesDrum[number].play()
surround(x-3, y, (255,0,0)

32)-1) + (4 *((y /24)-1))
)

*((y /24)-1))
)
*((y /24)-1))
)

def surround(x, y, col):
global my_image
my_image[x-1,y] = col
my_image[x-1,y+1] = col
my_image[x-1,y-1] = col
my_image[x,y+1] = col
my_image[x,y-1] = col
my_image[x+1,y] = col
my_image[x+1,y+1] = col
my_image[x+1,y-1] = col
if __name__ == '__main__':
main()

The program uses the pygame module to handle the sound samples and starts off by
loading them in. This could take a few seconds, so a print statement is used just to
give the user the confidence that the program hasn’t crashed. Each instrument is
loaded into its own array. Then the camera is initialized, as are the arrays
containing the x- and y-coordinates of the pixels to monitor.
The main function consists of an infinite loop that grabs an image, examines the
target pixels, and calls the functions to trigger the sounds. Note that in this function,
there are a number of print statements commented out with a hash symbol (#).
These will be skipped, but if you want to see the progress of the program, simply
remove the # from one or more of these lines.
Reading through the main function, you see that first an image is grabbed, and then
each target pixel is surrounded with a black outline. Then each of the target pixels
is examined in turn. The pixel values from the image are extracted into the
variables red, green, and blue. These variables are then tested to see if they
exceed a threshold value. If they do, the appropriate call is made to a function that
actually does the triggering. These thresholds were derived from experimentation

and have a bearing on the note density of the music. Feel free to play around with
these values.
The sample functions take the x- and y-coordinates of the triggering pixel and turn
them into a number from 0 to 15. Then the appropriate sample number is triggered.
Also, the triggered pixel is surrounded by the trigger color. If one pixel triggers
more than one sound, it will be left surrounded with the last color detected.
The result is that when you run the program, the image returned is such that none of
the pixels can trigger the notes. Then when the button is pressed, the LEDs start
pulsing and the sounds start being triggered. The degree of change depends on how
long it was since you last inverted the lamp. The glitter moves fast at first, but
quickly settles down into a slow, steady wandering. If you leave it too long, all the
glitter will float to the top and nothing will be triggered. If you have trouble with
sound being triggered with no LED illumination, try moving the project out of
direct light or arrange some sort of top shade for it.

Playing variations on a theme
Now comes the interesting part: You can make variations on this code that can
change the whole project, hopefully for the better. Simply renaming the sound
samples, so they’re in a different order, can have an effect on the music produced.
Try adjusting the threshold values that cause the triggering as well. Then you could
define three different arrays of pixels to sample for each instrument, or increase the
number of samples for each instrument.
How about triggering a solo mode where the sax plays much longer phrases?
Another set of samples could be switched in order to do this. Better yet, why stick
with the traditional trio lineup? You can use any sounds you like, from instruments
to sound effects to longer phrase loops. Free jazz was never quite so free!

Part IV

Making the Raspberry Pi Your
LEGO’s Magic Brick

Find out about the ev3dev language in a free article at
www.dummies.com/extras/raspberrypiprojects.

In this part …
Connect the Raspberry Pi to LEGO MINDSTORMS.
Build an infrared handset simulator.
Build your own LEGO sensors.
Use LEGO sensors and motors directly from the Raspberry Pi.
Build an interactive luck-free dice game.

Chapter 13

The Pi Meets LEGO
In This Chapter
Meeting the LEGO MINDSTORMS EV3 Intelligent Brick
Sending messages to the brick using Bluetooth
Having the brick send messages back to the Raspberry Pi
Finding out about infrared remote-control codes
Making a Raspberry Pi–powered infrared transmitter
Using the infrared transmitter to make a Tug-of-War LEGO Robot
LEGO has been a popular toy since its invention in 1949, but it has never been
more popular than it is today. This is due, in part, to the LEGO company’s
continual development and ability to reinvent itself, just like the toys it makes.
LEGO Technic has always been a great way to learn the basics of mechanical
engineering, and lately, the MINDSTORMS series of robotic construction has
propelled it successfully into the new century. In this part, we look at some of the
ways you can enhance the latest MINDSTORMS set, the EV3, by using the
Raspberry Pi. In this chapter specifically, we explore how the Raspberry Pi can
communicate with the EV3 control brick.

Exploring the MINDSTORMS Range
The LEGO MINDSTORMS EV3 Intelligent Brick is the fourth incarnation of the
robot-building concept, and, in keeping with the improvements in technology, it’s
the most sophisticated yet. Although the mechanical (plastic) parts are compatible
with earlier versions, the electronic control brick and the sensors and motors it
uses have limited compatibility.
The first system, called LEGO MINDSTORMS Robotics Invention System, was
launched in 1999. It was followed by the NXT in 2006 and the NXT 2.0 in 2009.
Those two systems differ only in the parts supplied with the sets and the software
used on the control bricks. The control bricks themselves are identical. Finally, the

EV3 launched in 2013 using a much more powerful processor with more memory
and limited compatibility with previous systems. The EV3 can be used with all the
sensors of the NXT system, but nothing of the original Robotics Invention System.
These three controllers are shown in Figure 13-1. For the purposes of this book,
the original MINDSTORMS brick is obsolete, so we concentrate on the EV3
system.

Figure 13-1: The three generations of LEGO control bricks.

Programming the control brick has always involved using some sort of graphicsbased language, with increasing sophistication through the LEGO generations. The
languages are based on the LabView graphical programming language used widely
in industry for software-based instrumentation. If you are new to the EV3 system,
we suggest that you take time to get familiar with the basic operation of it using the
supplied software before exploring the extensions that the Raspberry Pi makes
possible.
Hackers have also developed several alternative text-based programming
languages for the bricks. However, the EV3 system offers, for the first time, the
ability for third-party systems to interact with the control brick instead of
overriding or replacing the native brick software. In this chapter, we explore some
of the ways you can use your Raspberry Pi with an unmodified EV3 system.

There are four basic ways to access the LEGO MINDSTORMS EV3
Intelligent Brick:

Wi-Fi
USB
Bluetooth
Infrared (IR)
Wi-Fi and USB are interchangeable and are used for downloading programs to the
control brick and uploading data from it. Wi-Fi requires the separate purchase of a
specific Wi-Fi dongle.
When it comes to interacting with the Raspberry Pi, Bluetooth and IR are the best
ways to control or interact with a robot remotely. They allow much more
sophisticated programs to be written than would otherwise be possible simply by
using the brick’s graphical language alone. They also open up the possibility of
using hardware attached to the Pi to control the LEGO system.
Up to eight EV3 control bricks can communicate with each other by exchanging
messages over Bluetooth. However, this mechanism can also be used to allow the
Raspberry Pi to send and receive messages from the EV3 brick. These messages
can be programmed to trigger actions or to get data back from the robot’s sensors.
These messages can be controlled by a program running on the Raspberry Pi; in
this chapter, we show you how to use Python to do this.
The EV3 set comes with a small handheld IR remote control that is capable of
sending some commands to the IR sensor. The remote control can transmit on four
different “channels” and can be picked up by the IR sensor. This is a dual-purpose
sensor — it’s also capable of detecting the distance to an object by detecting IR
reflection off the object. The Raspberry Pi can be made to generate IR messages
and send them to the control brick from its own programs.
In the following sections, we cover Bluetooth and IR messages in greater detail.

Bluetooth messages
The EV3’s language has a messaging block to send and receive messages. Most of
the flow control blocks in the LEGO language can use the reception of a message to
trigger the execution of a section of a program. So, it would be very useful if you
could send and receive these messages with the Raspberry Pi. You need two things
to do this:
A Bluetooth interface on your Raspberry Pi

Some knowledge of the message structure in order to make sense of the
messages
We cover these requirements in the following sections.

Bluetooth Pi
The simplest way to give your Raspberry Pi Bluetooth capability is to fit it with a
Bluetooth USB dongle. It should be fitted directly to one of the Pi’s USB sockets
and not to a USB hub.

You can get a variety of different types of USB dongles, but the vast
majority use really only two chipsets. Unfortunately, only one of these
chipsets will work with the Raspberry Pi and, surprisingly, it’s the cheaper
one! To find a list of the increasingly large range of recommended devices,
check out www.elinux.org/RPi_USB_Bluetooth_adapters.
To see what type of dongle you have, plug in the dongle, boot up the Raspberry Pi,
and log in. From the command line, type the following:
lsusb

You see a list of devices attached to the USB ports. One of them should read
something like this:
Cambridge Silicon Radio, Ltd Bluetooth Dongle

If yours is a Broadcom or any other manufacturer, try to get a Cambridge
one because, as of this writing, the others may not work properly. That said,
the Linux software in the Raspberry Pi is constantly evolving, so try what you
have first, and if you have trouble, then get a Cambridge chip set.
To get started using your Bluetooth dongle, follow these steps:
1. Install the necessary software by typing the following from a command
line:
sudo
sudo
sudo
sudo

apt-get
apt-get
apt-get
apt-get

update
upgrade
install bluetooth bluez-utils blueman
install python-serial

The first line gets a list of the latest packages, the second line installs them, and

the third line installs the Bluetooth-specific applications.
2. Reboot the system and type lsusb again, just to make sure things are
working.
Occasionally, a dongle won’t power up, so check to make sure it’s working
before you proceed.
3. Type startx to get into the desktop.
You should see a Bluetooth icon in the bar at the bottom-right of the screen. If
you don’t, look for it under the Preferences menu.
4. Click the Bluetooth icon.
The Bluetooth Devices dialog box appears (see Figure 13-2). You may see
several unknown devices listed in the dialog box. Don’t worry about them —
they aren’t real, but we haven’t found a way of getting rid of them permanently.
5. Turn on your EV3 brick and make sure the Bluetooth is enabled and
visible.
Don’t select the iPhone option. See the instructions that came with the EV3
brick if you don’t know how to change the Bluetooth settings.
6. In the Bluetooth Devices dialog box, click Search in the toolbar at the top.
After a short time, the EV3 brick appears.
7. Click the brick to highlight it and then click Setup in the toolbar.
8. Choose the pairing option with a custom pass key, type 1234, and click
Continue or Forward.
The LEGO brick makes a sound and asks you to confirm the keys.
9. Select the check box and press the middle button.
The brick and the Raspberry Pi should now be paired. You won’t have to do
this again.
10. While you’re at it, pair up your computer or laptop and Raspberry Pi as
well.
It’s a very convenient way of swapping files between the two systems.
11. Right-click the EV3 entry in the Bluetooth Devices dialog box and select
Connect to Serial Port.

You should get the following message:
Serial port connected to /dev/rfcomm0

This last step has to be done each time you boot up your Pi or when you leave
the desktop and return to it.

Figure 13-2: The Bluetooth Devices dialog box.

Now you can treat the Bluetooth dongle just like any other serial port in any
programs you write.

The anatomy of a message
Before you can send and receive messages, you have to know the format they use.
At the time of this writing, LEGO hasn’t published the message specification, so
we did a little snooping to see what it was. By looking at the messaging blocks in
the EV3 language, you can see that each message box has a name and contents. The
contents can be Boolean, text, or a number, so the message must contain both the
contents or payload and the message box name. The results of the investigation are
shown in Figure 13-3.

Figure 13-3: The anatomy of a message.

The message starts with two bytes that give the number of bytes in the rest of the
message. This, like all other two-byte numbers in this system, are in the little
endian format, which means that the least significant byte of the two-byte number is
first and the most significant byte is second.

If the numbers are arranged the other way round, that’s called big endian.
Much metaphorical blood has been spilled by proponents of the two systems
as to which is fundamentally better. We’re in the big endian camp ourselves,
but there you go.
The next two bytes are a message counter. When the bricks are talking amongst
themselves, the message counter doesn’t appear to change. The same goes for the
next two bytes, the message ID. Then there is a single byte that gives the number of
bytes in the mailbox name. The name then follows as a null terminated string. Note
that the number of bytes includes the null. Finally, the next two bytes give the
number of bytes in the payload, followed by the payload or message itself.

Sending a message
In principle, it’s very easy to send a message to the EV3 brick. Just put together a
character list that matches the format we just described and then send it character
by character to the serial port. Take a look at that in practice with Listing 13-1,
which sends four text messages to a mailbox called “Brick.”

Listing 13-1: Composing and Sending a Text Message
#!/usr/bin/env python
# Compose a message for Lego Bluetooth
# and send it - Mike Cook
import serial
import time
EV3 = serial.Serial('/dev/rfcomm0')
print "sending EV3 a Bluetooth message"
def main():
for t in range(0,4) :
m = messageG("Brick","See Me "+str(t))
print "sending :- ", "See Me "+str(t)
messageSend(m)
time.sleep(2.0)
EV3.close()

# end of main
# Function definitions
def messageSend(message):
if EV3.isOpen() == True :
for n in range(0, 2 + ord(message[0]) + (ord(message[1]) * 256 )):
EV3.write(message[n])
def messageG(boxName,message): # generate a text message
length = len(boxName) + len(message) + 10
btMessage = [ chr(0) for temp in range (0,length)] # initial blank
btMessage[2] = chr(1)
# message ID
btMessage[4] = chr(0x81)
btMessage[5] = chr(0x9E)
btMessage[6] = chr(len(boxName) + 1)
btMessage[7:7+len(boxName)] = boxName
payloadPointer = 8 + len(boxName)
btMessage[payloadPointer] = chr((len(message) + 1) & 0xff)
btMessage[payloadPointer + 1] = chr((len(message) + 1) >> 8)
btMessage[payloadPointer + 2:len(message)] = message
endPoint = payloadPointer + len(message) + 1
btMessage[0] = chr((endPoint & 0xff))
btMessage[1] = chr(endPoint >> 8)
return btMessage
if __name__ == '__main__':
main()

The first thing this code does is open the Bluetooth serial port to the LEGO brick.
Then the main function composes four messages reading “See Me” with a number
appended. It generates a text message using the messageG function, which first
calculates the length of the message and initializes a blank message containing all
null characters. Then the message counter is set to 1 and the message ID numbers
are set. Then the sixth element in the list is set to the length of the box name plus
one (to accommodate the null at the end) and the box name is inserted in the list
from the seventh position.
Next, a variable called payloadPointer is calculated to give the position of the
last part of the message. This is an intermediate value and makes the calculations
that follow a little easer to write down. Then the length of the message string is
placed in the two bytes, giving the number of bytes in the payload, and the text is
inserted in the message just like the box name was.
Finally, the endpoint of the message is calculated and the first two bytes of the
message, giving the overall message length, are set. The complete message is then
returned from this function. All that remains to be done is to send the message with
the messageSend function, which writes the bytes one by one to the serial port.

Note that this function used the first two bytes of the message to see how many
bytes to send.
In order to test this, you need to put a simple program on the LEGO brick. This
program is shown in Figure 13-4.

Figure 13-4: LEGO code for receiving messages.

This program first turns on the Bluetooth system. Then, when a message is updated,
it makes a brief sound and displays the message. Run the code on the LEGO brick
first, followed by the Raspberry Pi python program, and you’ll see the message
displayed on the LEGO brick.
The payloads for the two types of message are very similar. A logical message has
a simple one-byte payload of a zero for False or a one for True. A numeric
message is just four bytes that make up a floating point number. Even if the number
is an integer, it’s always encoded as a floating point number. In order to send these
other types of messages, we’ve written a function to generate them, shown in
Listing 13-2. (You won’t need these two other types of messages in the project
later in this chapter, but if you ever need them, this is how it’s done.) This code is
very similar to the generate message function messageG in the previous program,
but it takes in a text string that determines what sort of message is generated.

Listing 13-2: Function for Generating All Three Message
Types
import struct
def messageGuin(boxName,message, messageType): # generate any message
mType = False
if messageType == "text" :
length = len(boxName) + len(message) + 10
mType = True
if messageType == "logic" :
length = len(boxName) + 12
mType = True

if messageType == "number" :
length = len(boxName) + 16
mType = True
if mType : # only go on if message type is valid
btMessage = [ chr(0) for temp in range (0,length)] # initial blank
btMessage[2] = chr(1)
# message ID
btMessage[4] = chr(0x81)
btMessage[5] = chr(0x9E)
btMessage[6] = chr(len(boxName) + 1)
btMessage[7:7+len(boxName)] = boxName
payloadPointer = 8 + len(boxName)
if messageType == "text" :
btMessage[payloadPointer] = chr((len(message) + 1) & 0xff)
btMessage[payloadPointer + 1] = chr((len(message) + 1) >> 8)
btMessage[payloadPointer + 2:len(message)] = message
endPoint = payloadPointer + len(message) + 1
if messageType == "logic" :
btMessage[payloadPointer] = chr(2)
btMessage[payloadPointer + 1] = chr(0)
if message == True :
btMessage[payloadPointer + 2] = chr(1)
endPoint = payloadPointer + 2
if messageType == "number" :
btMessage[payloadPointer] = chr(4)
btMessage[payloadPointer + 1] = chr(0)
btMessage[payloadPointer + 2:] = struct.pack('f',message)
endPoint = payloadPointer + 4
btMessage[0] = chr((endPoint & 0xff))
btMessage[1] = chr(endPoint >> 8)
return btMessage
else :
print "Message type is not one of text, logic or number"
return "error"

First, the message type is checked and the appropriate length of blank message is
generated. Then the function proceeds as before until it comes to generating the
payload, where again different payloads are generated depending on the message
type. (We go into more detail about these other message types in the next section.)

Receiving a message
Receiving a message is quite simple: You have to read the bytes in from the serial
port. The number of bytes you have to read is given in the first two bytes you get.
You have to wait until the serial port has at least two bytes in the buffer, read them,
and then you know how many more you have to read.
The more complex part is in decoding what you read, which involves splitting up

the message into the two pieces of information it contains (known as parsing):
mailbox name and payload.

One important thing to realize is that you can’t tell from looking at the
payload what sort of message it is. That means you have to know in advance
what sort of message you’re expecting. One way to get around this problem is
to arrange things so that certain mailbox names always send the same sort of
data payload. Assigning mailbox names that match the data names makes this
more clear, although it isn’t required.
In the next example, we use the mailbox names Text, Logic, and Number to deliver
data of the same type as the name. If you look at Figure 13-5, you see the LEGO
EV3 code to send three types of messages, one after the other, each having a
different data type. You need to run this on your LEGO brick.

Figure 13-5: LEGO code for sending messages.

Note that you need the computer connected to the brick in order to get the dropdown menu to show the message sender’s name. You can’t see all of this name on
the screen when you make the brick’s program.
The messages are continuously sent and the data is the same each time it’s sent. In
order to receive this on your Raspberry Pi, you need to run the code in Listing 133.

Listing 13-3: Simple Message Receive
#!/usr/bin/env python
# Simple receive of message by Mike Cook
import serial
import time

import struct
EV3 = serial.Serial('/dev/rfcomm0')
EV3.flushInput()
print "Receiving EV3 Bluetooth messages"
box = "Mail Box"
def main():
while 1:
rx = readMessage()
decodeMessage(rx)
EV3.close()
# Function definitions
def readMessage():
global box
while EV3.inWaiting() <2 :# hold until message starts to arrive
continue
inMessage = EV3.read(2)
messageBytes = ord(inMessage[0]) + ( ord(inMessage[1]) *256 )
while EV3.inWaiting() < (messageBytes ):
continue
inMessage = inMessage + EV3.read(messageBytes )
box = inMessage[7 : 7 + ord(inMessage[6])-1]
payloadPointer = 9 + ord(inMessage[6])
message = inMessage[payloadPointer:]
return message
def decodeMessage(payload) :
print "Message from box",box,"is a",
if box == "Text" :
print "text message saying",
print payload
if box == "Logic" :
print "logic message of",
logic = False
if ord(payload[0]) == 1 :
logic = True
print logic
if box ==
print
val =
value
print
print

"Number" :
"number with a value of",
struct.unpack('f',payload)
= val[0] # to convert from a tuple
value

if __name__ == '__main__':
main()

The main function repeatedly reads messages and decodes them. The readMessage
function reads in the bytes from the serial port and extracts the mailbox name,
which is used to set a global variable called box. It also extracts the payload and
returns it to the calling program. Then the decodeMessage function uses the global
variable box to decide how to decode the payload. It also prints out the mailbox
name and value of the payload it received.
The readMessage function works just like the reverse of the generate message
function we saw in Listing 13-1. Bytes from the message are read into a string
called inMessage, and then the mailbox’s name string and payload string are
extracted from that. The decodeMessage function then handles the payload string
according to its type. A text message is simply printed out, whereas a logic
message sets a Boolean variable called logic, initially to False. If it finds a one
in the payload string, it changes the variable to True.
The numeric message is a little more complex to cope with. As we mention before,
it’s in a floating point format. In order to convert it into a number, you have to use
the struct functions. The struct.unpack function converts the string given in the
second parameter to a number type given in the first parameter. Just to throw a
curveball into the mix, this function returns a tuple, even if the string contains only
one value. Therefore, the next line extracts a single floating point variable called
value from the tuple.
If you run this code, you should see the messages being sent back from the LEGO
brick. Here’s an interesting experiment to do: Change the LEGO code to send not
the number 42 but the number 42.1. You may be surprised to see that the number
being read back on the Raspberry Pi is not 42.1, but 42.0999984741. This is to be
expected. Many beginners are shocked to discover that floating point numbers are
only an approximation. This can sometimes be masked by rounding when you print
out the number, but it’s worth remembering that if you want anything to be
absolutely accurate, stick to integer-type variables.
Armed with this information, you can now pass information between the brick and
the Raspberry Pi. You can use this to gather data or control what your LEGO
creation does. In the next chapter, you see a full-blown application of control using
message passing.

Infrared messages
The other way of getting information to the LEGO brick is by using infrared. Unlike
the Bluetooth system, however, IR is one-way. That is, you can send messages into

the brick, but the brick can’t send information out.
The IR sensor can receive key presses generated from the handheld remote that
comes as part of the EV3 set. There are five push buttons and one four-position
slider. The slider sets the channel it transmits on and has four positions. At the time
of this writing, LEGO had not published the protocol for this remote controller, so
we had to do a bit of playing around with sensors and an oscilloscope to reveal
how it works.
The IR beam is modulated (turned on and off rapidly) at a rate of 38 KHz. This is a
common frequency for many TV remote control systems, although other frequencies
from 32 KHz to 42 KHz are used as well. This modulation allows the amplifier at
the receiving end to reject signals that are not modulated and, therefore, not get
swamped by interfering IR light from daylight or artificial light. This technique of
modulation gives the remote control a good range.
The LEGO system works entirely on bursts of six IR pulses, and the data is
encoded by the length of the gap after each burst. For example, all messages begin
with a start bit that consists of a burst of six pulses of IR followed by a gap
equivalent to 39 pulses. Similarly, a logic one is six pulses followed by a 21-pulse
gap, and a logic zero is six pulses followed by a 10-pulse gap. At the end is a stop
bit, which is the same as the start bit. If a button is held down, the codes repeat
every 80 milliseconds (mS). This is summed up in Figure 13-6.

Figure 13-6: Infrared code format.

By using a good oscilloscope, we were able to map what was being produced by
each push button. We discovered that changing the channel slider switch changes
only a few of the bits in the code being sent. The horizontal bar button on the EV3

remote produced a continuous stream of codes until it was pressed again, whereas
each of the other buttons produced one repeating code value when it was pressed
and another when it was released. All the release codes were the same for all the
buttons in that channel.
Armed with this information, we can duplicate what the remote controller produces
directly from the Raspberry Pi, thus allowing programmatic control of the
production of the codes. To do this, you need to build a small IR transmitter board
and install and customize a software package.

The Raspberry Pi infrared transmitter
Peering into the smoked plastic cover of the EV3 remote controller shows two
infrared LEDs offset by about 45 degrees, as well as a small green LED that comes
on when it’s sending. Infrared LEDs take more current than visible ones, and the
forward voltage drop is so low that you can happily power two LEDs in series
from 5V.
We designed a simple circuit using one of the general-purpose input/output (GPIO)
pins to switch a transistor to allow the LEDs to turn on and off. The schematic is
shown in Figure 13-7. When the GPIO pin is low, the transistor is off and no
current flows through the LEDs. When the GPIO pin is high, current flows into the
base of the transistor, turning it on. This means that current can flow from the
collector to the emitter of the transistor, allowing the three LEDs all to turn on.

Figure 13-7: A schematic of the IR sender board.

The resistor in series with each LED is important. It limits the current flowing to a
safe level. Note that R3, the resistor controlling the IR LEDs, is much smaller than
you normally see. This is because IR LEDs can take much more current than visible
ones. We made the R2 resistor quite high so the LED is not very bright. Feel free to
drop this to 220R if you want the visible LED brighter.
Here are the parts you need for this circuit (the component’s reference number
shown on the diagrams is in parentheses):
Two 1K resistors (R1–R2)
One 27R resistor (R3)
One 2N2222 transistor or similar NPN transistor (T1)
Two 5mm IR LEDs (L1–L2)
One 2mm red LED (L3)
One 11-x-5-hole stripboard with strips running horizontally
We built this on a small piece of stripboard. The physical construction is shown in
Figure 13-8. There are four breaks in the copper strips on the reverse side. Three
you can break at a hole, but the fourth should be a break between the holes. You
can do this with a scalpel or sharp hobby knife. Make two cuts as close as possible
together and then peel the copper away between the cuts.

Figure 13-8: The physical layout of the IR sender.

The three wires — 5V, Gnd, and GPIO 22 — were connected to the Raspberry
Pi’s GPIO plug through individual flying leads with pin header sockets on both
ends, although you can use any form of breakout board or connector to make this
connection. A photograph of the final board is shown in Figure 13-9.

Figure 13-9: The final IR sender board.

Installing the Linux infrared remote control
Next, you have to install the Linux infrared remote control (LIRC) package that will
generate IR codes according to a configuration file. The LIRC has been developed
for people who want to control electronic consumer products, but the vast
collection of ready-defined protocols didn’t include the EV3 brick, so we had to
design a custom file. The LIRC package has been designed to both transmit and
receive IR communications, but here you’re concerned only with sending, so you
don’t have to bother with the receiving side.
First, you have to get the package onto your machine. This is easily done by typing
the following:
sudo apt-get install lirc

Then when this is installed, you have to add the following two lines to the
/etc/modules file:
lirc_dev
lirc_rpi gpio_in_pin=23 gpio_out_pin=22

Note that you can do this from the desktop if you navigate to the etc directory and
choose the Open Window as Root option. Then modify the
/etc/lirc/hardware.conf file to read like Listing 13-4.

Listing 13-4: The Contents of /etc/lirc/hardware.conf
# /etc/lirc/hardware.conf
#

# Arguments which will be used when launching lircd
LIRCD_ARGS="--uinput"
#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD=false
#Don't start irexec, even if a good config file seems to exist.
#START_IREXEC=false
#Try to load appropriate kernel modules
LOAD_MODULES=true
# Run "lircd --driver=help" for a list of supported drivers.
DRIVER="default"
# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
# Default configuration files for your hardware if any
LIRCD_CONF=""
LIRCMD_CONF=""

Finally, you have to change the /etc/lirc/lircd.conf to be like Listing 13-5.

Listing 13-5: The Contents of /etc/lirc/lircd.conf
begin remote
name Lego_EV3
bits
16
flags SPACE_ENC
eps
30
aeps
100
# see text for note on frequency
frequency 38000
header
one
zero
ptrail
gap

158
158
158
158
1206

begin codes
# EV3 remote codes
beacon1
beacon2
beacon3
beacon4
release1
key1c1
key2c1

1026
552
263

0x4006
0x5004
0x6002
0x7000
0x010E
0x8117
0x8124

key3c1
key4c1
release2
key1c2
key2c2
key3c2
key4c2
release3
key1c3
key2c3
key3c3
key4c3
release4
key1c4
key2c4
key3c4
key4c4
end codes

0x8142
0x818E
0x110F
0x9116
0x9125
0x9143
0x918F
0x210C
0xA115
0xA126
0xA140
0xA18C
0x310D
0xB114
0xB127
0xB141
0xB18D

end remote

This last file controls the code and the format of the IR being sent. There are lots of
other ways of using IR to send messages, and LIRC can cope with most of them.
The first part defines the sort of code to produce with a flag saying that it’s space
encoded (that is, the space after the burst of pulses defines what the data will be).
The header, one, and zero are the format of the data, with the time being defined in
terms of microseconds. So, a one is a 158 uS burst of IR followed by 552uS of gap,
or nothing. This relates to the number of pulses in the data format.
To get LIRC to accept the new control codes in this file, type the following in at the
command line:
sudo /etc/init.d/lirc stop
sudo /etc/init.d/lirc start

The frequency of the modulation is defined in the file, but when we tried it, we got
a frequency of 45.2 KHz despite setting it to 38 KHz. We had to put in a frequency
of 32,000 in order to get the 38 KHz out. It turns out that there was an issue in the
kernel on the Raspberry Pi, and it caused the timing to be wrong. However, it was
corrected at about the same time we found the trouble. To check what version of
kernel you have, type the following at the command line:
uname -rv

If the answer is any earlier than
3.12.18+ #677 PREEMPT Mon Apr 28 22:45:00 BST 2014

you should update your kernel by typing the following and checking again:

sudo apt-get update
sudo rpi-update

The error in the kernel affects not only the frequency but also the accuracy of the
gaps. However, the transmitter still seemed to work with the uncorrected gaps.
The names we gave to each key are based on the number that is detected by the
EV3 brick. So, key1c3 is short for key 1 on channel 3. The code for a key release is
the word release followed by the channel number, and the four beacon modes are
defined by the word beacon followed by the channel number. Feel free to change
these names if something else makes more sense to you. For example, the release
key is detected as zero in the LEGO brick, so you might want to label those keys
K0c. Similarly, the beacon message is seen as the key 9 by the brick. However, you
might want to label the keys after the keys on the remote like redTop, blueBottom,
and so on.

Driving the infrared codes
IR codes are produced from the command line, so if you want to use these codes
from some language, you should do it by calling the operating system. A simple
example of this is shown in Listing 13-6. This simply sends out a beacon signal on
channel 4.

Listing 13-6: Infrared Beacon
#!/usr/bin/env python
'''
Sending IR Beacon message - by Mike Cook
'''
import time
import os
print "Sending Beacon message"
while 1 :
os.system("irsend SEND_ONCE Lego_EV3 beacon4")
time.sleep(0.08) # time between repeats

You see that the os.system call takes a string with the irsend parameters
in it. Don’t be tempted to use the send continuous commands — they don’t
work by simply repeating the command as you may expect. Instead, substitute
other repeat codes in place of the commands.
In order to test this, you need a very simple LEGO model, as shown in Figure 1310. This is basically just the IR sensor mounted on a motor. If you put into the brick

the program shown in Figure 13-11, the sensor turns to face the emitter board. It’s
quite an eerie sensation — it feels like the robot is alive. Test out this model using
the supplied IR remote if you have any trouble.

Figure 13-10: The LEGO model for the tracker.

Figure 13-11: The LEGO program for the tracker.

If that goes well, you can test out the other keys with the code in Listing 13-7,
which simply cycles through the key presses. Note that it shows how you can

change what the program sends by building up a command string.
The key names are held in a list called button, and the channel to use is held in a
variable called ch. These two strings are concatenated to a fixed string to make up
the command. To see this on the brick, put the program in Figure 13-12 into the
LEGO controller.

Figure 13-12: A LEGO program for testing the key codes.

Now it’s time to do something fun with this setup.

Listing 13-7: Key Test Program
#!/usr/bin/env python
'''
IR test IR2
testing config file at
/etc/lirc/lircd.conf
Tests buttons
'''
import time
import os
os.system("sudo /etc/init.d/lirc stop")
os.system("sudo /etc/init.d/lirc start")
ch = "c3" # channel
button = [ "key1", "key2", "key3", "key4"]
while 1 :
for b in range(0,4) :
os.system("irsend SEND_ONCE Lego_EV3 " +button[b]+ch)
print"sent ",button[b]+ch
time.sleep(0.8)
os.system("irsend SEND_ONCE Lego_EV3 release"+ch)
time.sleep(1.5)

Creating a Tug-of-War LEGO Robot

The Tug-of-War LEGO Robot is a fun way to incorporate a program on the
Raspberry Pi with action on a LEGO system. Basically, it’s a two-player reaction
game, with the score being kept by a LEGO robot.
Here’s how it works: The robot is placed on top of a long thin box on a line drawn
halfway across. The Raspberry Pi puts up the word Ready on the screen. After a
random interval, this changes to Go and a noise is generated. The first player to
react by pressing a keyboard key wins, and the LEGO robot moves a small distance
in the losing player’s direction. If a player presses a key before the sound, he has
jumped the gun and the other player gets the robot to move for her. Eventually, the
robot falls off the box and indicates the winner. (The box should be only a few
inches high to prevent any damage to the robot. If you aren’t willing to risk any sort
of a fall for your robot, you can just tape a winning line on a table and place the
robot on that instead.)
We leave it up to you which robot to use. There are plenty of simple two-motor
robots you can build. If you’re stuck for a design, use the TRACK3R robot from
your computer’s LEGO software. The box to click is called EV3 Getting Started,
and it’s located at the bottom right of the main page. There is no need to add all the
tools — you just want the basic movement.
All that is required of the robot is that it be able to move in a straight line
backward and forward in response to the IR remote key press. Then program it
with the very simple program shown in Figure 13-13.

Figure 13-13: The LEGO program for the Tug-of-War Robot.

You can change how far the robot moves in response to each key press
very easily by changing the number of degrees of movement. This affects the
length of time a game runs and depends on the physical size of the space you
have to run it in. You can also build in a handicap system by making the robot
move more in one direction than the other. This is useful in a kids-versusadults situation.
We put an extra condition to stop the motors when the release key was detected.
This shouldn’t have been necessary, but we found that, without it, the motors
sometimes hunted a little (made continuous small movements left and right) when
they were supposed to have stopped. Test it out with the handheld remote before
going on to controlling it with the Raspberry Pi.
Next, you have to program the Raspberry Pi to play the game and control the robot.
Before you start, you have to make sure you have a directory called sounds in the
same directory as this code, and that it contains an .ogg sound file called gun.

Despite the name, the file can be any short, sharp sound. The code to play the game
is shown in Listing 13-8 and is written in Python with Pygame.

Listing 13-8: The Tug-of-War Raspberry Pi Code
#!/usr/bin/env python
'''
Lego-powered Tug-of-War
Reaction Time Game By Mike Cook
'''
import time
import random
import os, pygame, sys
pygame.init()
# initialize graphics interface
pygame.mixer.quit()
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=512)
goSound = pygame.mixer.Sound("sounds/gun.ogg")
os.environ['SDL_VIDEO_WINDOW_POS'] = 'center'
pygame.display.set_caption("Lego Tug of War Reaction Game")
pygame.event.set_allowed(None)
pygame.event.set_allowed([pygame.KEYDOWN,pygame.QUIT])
cBackground =(0,255,255)
cText = (255,0,0)
textHeight = 38
font = pygame.font.Font(None, textHeight)
screenWidth = 350
screenHeight = 160
screen = pygame.display.set_mode([screenWidth,screenHeight],0)
random.seed()
player1 = False # keyboard inputs
player2 = False
space = False
def main():
global player1, player2, screen
print "Tug of War"
draw_screen()
while True : # play the game
updateWords(" ")
while space == False :
checkForEvent()
updateWords("Ready")
player1 = False
player2 = False
go = time.time() + 1.5 + ( random.random() * 5 )
while go > time.time() :
checkForEvent()

# check for jump the gun
if player1 == True or player2 == True :
player1 = not(player1)
player2 = not(player2)
updateWords("Jumped the gun")
time.sleep(2)
else :
updateWords("Go")
goSound.play()
while player1 == False and player2 == False and space == True:
checkForEvent()
if space == True :
if player1 == True :
updateWords("Player 1 wins")
winner = "key1c1"
else :
updateWords("Player 2 wins")
winner = "key2c1"
os.system("irsend SEND_ONCE Lego_EV3 "+winner)
time.sleep(0.08)
os.system("irsend SEND_ONCE Lego_EV3 release1")
time.sleep(2.0)
checkForEvent() # remove losing player's key
else :
updateWords("Game ends")
time.sleep(2)
def draw_screen():
screen.fill(cBackground) # blank screen
drawWords("Q - Player 1",10,2)
drawWords("P - Player 2",10,30)
drawWords("Space - New Game",10,60)
updateWords("Ready")
def updateWords(words) :
pygame.draw.rect(screen,cBackground, (0,100,screenWidth,textHeight), 0)
drawWords(words,120,100)
pygame.display.update()
def drawWords(words,x,y) :
textSurface = pygame.Surface((len(words) * (textHeight / 2),textHeight))
textRect = textSurface.get_rect()
textRect.left = x
textRect.top = y
pygame.draw.rect(screen,cBackground, (x,y,len(words) * (textHeight
/2),textHeight), 0)
textSurface = font.render(words, True, cText, cBackground )
screen.blit(textSurface, textRect)
#pygame house keeping
def terminate(): # close down the program

print "Closing down please wait"
pygame.quit() # close pygame
sys.exit()
def checkForEvent(): # see if we need to quit
global player1, player2, space
event = pygame.event.poll()
if event.type == pygame.KEYDOWN :
if event.key == pygame.K_q :
player1 = True
if event.key == pygame.K_p :
player2 = True
if event.key == pygame.K_SPACE :
space = not(space)
if event.type == pygame.QUIT :
terminate()
if __name__ == '__main__':
main()

The main function is where all the action is, with the other functions supplying
support. Keyboard presses generate Pygame events, and there are three you’re
looking for here. The two players’ reaction keys — P and Q — are placed at
opposite ends of the keyboard for maximum separation, and the spacebar is for
stopping and starting the game. Before looking at the main function, take a quick
look around at the others.
The draw_screen, drawWords, and updateWords functions are all concerned with
writing text into the Pygame window. The checkForEvent function sets logic
variables whenever one of the target keys is pressed and monitors for a click in the
close box of the window. If one is detected, the terminate function is called and
the program ends.
The main function is basically one big loop that starts by blanking out any message
from any previous game and then pauses until the spacebar is pressed. This
controls whether a round of the game will be played. If it is, the window displays
the word Ready and the players ready themselves to be the first to react. The heart
of the game is the following line:
go = time.time() + 1.5 + ( random.random() * 5 )

This sets up a random delay for a minimum of 1.5 seconds and a maximum of 6.5
seconds into the future. The random.random function returns a floating point value
so the time isn’t restricted to whole numbers of seconds. If you want to change the
range of the delays, change the number 5 to something bigger or smaller.
A while loop holds until this time has expired, checking all the time that no player

has pressed early. If a player has pressed early, the other player is declared the
winner. Otherwise, the word Go appears on the screen and the sound is generated.
When the first player to react is detected, a message saying who has won is placed
in the window and the IR signal is sent to move the LEGO robot. The losing player
probably also reacted, so another call to checkForEvent is made to remove that
key from the events buffer. If it isn’t removed, the losing player will be accused of
jumping the gun in the next round.

Going on from Here
You can do plenty more with this game if you want! For a start, there is a small bug
that shows itself if both players jump the gun: The first to do so is declared the
winner. You could conclude that the second player deserves to lose, or you could
change that situation to one you prefer.
Another change you may like to make is to add more sounds to the game, like
cheers and applause to mark one player winning. Or you may want to keep track of
how many rounds one player has won over the other and declare a winner in the
program’s window instead of having the robot fall off a box. You could even make
the robot do something when one player has won, like perform a victory dance or
fire off a red or blue ball, depending on who has won.
You can do many other things with the IR message capability. When the Raspberry
Pi can command the IR control, you have many exciting possibilities. For example,
how about making a joystick input on the GPIO pins of the Pi and having that
control the IR keys? Or why not make a graphics console where you have access to
all the keys on all the channels on one screen? You can even write a sequencer so
you can send the IR commands in a long but repeating sequence.
In the next chapter, we look at incorporating what we know about Bluetooth
messages to create a unique project.

Chapter 14

The LEGO Dice Game
In This Chapter
Learning about a dice game that involves skill, not luck
Discovering how to use the color sensor to read a dice
Constructing a LEGO robot to play a game
Commanding the robot from your Raspberry Pi
Integrating LEGO and Raspberry Pi using Python
This project plays a rather unusual dice game — unusual because it involves skill,
not luck. Players take turns trying to reduce a heap to exactly nothing. The number
removed from the heap each turn is indicated by turning a dice with the required
number on the top face. Now, here’s the rub: You can’t use the same number as the
previous player, nor can you use the number that the previous player had on the
bottom face. The game as described here pits you against the computer, and by the
power of LEGO, the computer can actually place the dice with its turn number
uppermost. Confused? Don’t worry — we explain the game to you in detail in this
chapter.

Introducing the Dice Game
We first saw the dice game described in Ian Stewart’s book The Cow Maze. It’s
one of the few games that involve dice but no element of luck. In this game, the top
number on the dice is used to indicate by how much a target number (or heap as we
call it) should be reduced. The winner is the first to reduce the heap to exactly zero
or get the opponent to overshoot zero. What makes this a game of skill is that, on
any turn, the only numbers you can’t use are the number already shown on the top
of the dice and the number on the bottom side of the dice. This restriction is what
makes the game interesting.
The game is a two-player game and can be played quite simply by two players, but
in order to computerize the game, there are two major problems to overcome:

We need to get the computer to be able to sense which way up the dice is
placed.
More difficult, we need to get the computer to place the dice in the right
position to indicate its own move.
This project has a rather novel way of solving both problems.
A dice has some interesting properties, and one of the more useful of these is that
opposite sides of a dice always add up to a total of 7. That’s the vital piece of
information you need to know in order to write a program for the computer to be
able to identify the complete orientation of the dice. In the LEGO EV3, there is a
color sensor that is capable of identifying seven different colors, as well as no
color at all. This is one more color than we actually need.
The playing mechanism is a bit more problematic. It needs to be able to turn a dice
through 90 degrees. Most robot arms don’t have the degrees of freedom to do this,
so we had to come up with another solution. Instead of lifting up the device, rotate
it and then place it down. This solution throws the dice but in such a way that we
can control exactly what the top face will be. The whole machine is shown in
Figure 14-1.

Figure 14-1: The dice game machine.

By working through the elements one at a time, you can make your own dice game
and even be able to beat it, while the game seems to be unbeatable to all other
players.

Understanding the Game Theory
This sort of game is known as a solved game. Given any starting position and
perfect play, a winner can be determined without actually playing the game. In the
case of the dice game, for any given size of heap, with any dice facing uppermost,
the current player is guaranteed to win or lose if he plays the game correctly. Of
course, it’s easy to lose and a bit harder to win, but the point is that the outcome of
the game is fixed given this information.
The combination of heap size and top dice number determines if the next player can
win. If he can, this is known as a winning position, and as long as he makes the
right moves, there is nothing an opponent can do to stop him from winning. If the
current heap size and top dice number indicate a losing position, there is nothing a
player can do to convert this into a winning position, except by his opponent
making a mistake and deviating from perfect play.
Many games fall in this class. Examples include tic-tac-toe (called noughts and
crosses in the UK), checkers (called draughts in the UK), four in a row, and nim, to
name but a few.
The winning strategy for the dice game is formed by a complete analysis of the
game from every starting position and heap number. This may sound like a daunting
task, but it’s easy to build a table showing these results. For example, if the heap is
1 and the current top dice number is 1 or 6, then this is a losing position and any
valid move must overshoot zero. However, if the heap is 1 and the top dice is any
other number but 1 and 6, the next player can choose a value of 1 and win. This is a
winning position. If, on the other hand, the dice has 1 or 6 uppermost, the only
move left to the next player will force an overshoot of zero and, therefore, he has
lost. This is a losing position.
You can apply the same analysis for a heap of 2. For any combination of dice
positions, you find that all positions are winning by playing either a 2 to win
directly or, if a 2 is not available, playing a 1 will force the next player into
overshooting and thus losing. When you extend this to 7, you get a table of moves
shown in Table 14-1, which shows the size of the heap in each column against the

current dice top number in each row. The body of the table shows the move. An L
indicates that you’re in a losing position and it doesn’t matter what you play;
otherwise, it shows the number to play (that is, the dice number to turn to the top) in
order to win or maintain a winning position. In some places, more than one number
is shown; this means you can play any of these numbers and still be in a winning
position. Notice that it doesn’t matter which way the dice is up because each line
indicates two opposite sides of the dice.

Table 14-1: Analysis of the Moves for a Heap of 1 to 7
Heap Size Dice Up 1 2

3 4 5 6

7

1 or 6

L 2

3 4 5 3

2, 3, 4

2 or 5

1 1

3 4 L 3, 6 3, 4, 6

3 or 4

1 1, 2 L L 5 6

2, 6

All well and good, but the heap can be any number you like so this playing matrix
must be extended. The next stage is to extend the table to heap sizes up to 16, as
shown in Table 14-2.

Table 14-2: Analysis of the Moves for a Heap of 8 to 16
Heap Size Dice Up 8 9 10

11

12

13 14 15

1 or 6

4 L 5

2, 3 3, 4 4

5

3

2 or 5

4 L 1

3

3, 4 4

L

3, 6 3, 4

3 or 4

L L 1, 5 2

L

5

6

L

16
2, 3, 4

2

Table 14-2, along with Table 14-1, shows what to play for any position of the dice
for a heap from 1 to 16. Note how a heap size of 9 is a losing position no matter
what the state of the dice is. Now something very interesting happens if we extend
this analysis for the next nine heap sizes, shown in Table 14-3.

Table 14-3: Analysis of the Moves for a Heap of 17 to 25
Heap Size Dice Up 17 18 19

20

21

22 23 24

1 or 6

4

L

5

2, 3 3, 4 4

5

3

2 or 5

4

L

1

3

3, 4 4

L

3, 6 3, 4

3 or 4

L

L

1, 5 2

L

5

6

L

25
2, 3, 4

2

You see that this playing matrix is exactly the same as Table 14-2. When you get a
repeat pattern like this, you know it has to keep on repeating forever, for every
successive 9 increases in the heap size.
Why is this important? Well, given any heap size and current dice position, you can
repeatedly subtract 9 from the heap until you get into the range of 16 or less and
then, if you can memorize the matrix, you know what to play. It gives a surprisingly
small number of moves to memorize given the apparent complexity of the game,
and you can cut this down even further by memorizing only one number when you
have the choice of two or three numbers. This repeat also makes it much easer to
implement the playing matrix for programming into the computer.
So, analysis of this game reveals a playing strategy that is not obvious or
simplistic, but also is not very complex either.

Detecting Dice
In this section, we look at the detection of the dice state. There are a few ways to
do this, but the way we chose to do it is to use the EV3’s color detector. Each color
returns a number. To make things simple, we used the color numbers 1 to 6 to
represent the dice numbers 1 to 6. The sensor also returns a zero if nothing is in
front of the sensor. Figure 14-2 shows how the dice numbers relate to the colors, as
well as the LEGO part numbers for the tiles and dice body.

Figure 14-2: Dice numbers and colors.

The color sensor is positioned so that it can detect one of the dice sides. If we
know one side of the dice, we can calculate the other side because opposite sides
add up to 7. The dice is positioned on a rotating table. If it’s rotated by 90 degrees
clockwise, we can find two more dice sides. This is all the information we need in
order to calculate the numbers on the top and bottom of the dice. Figure 14-3 shows
a table of the clockwise sequence of the side dice numbers for each top number.

Figure 14-3: Dice side number sequence for each top number.

Note that complementary numbers — that is, dice numbers that add up to 7 — or, in
other words, opposite sides of the dice, are simply the reverse sequence. So, given
two side numbers, we can use this information in a lookup table to find the top
number. This is illustrated in the simple Python program shown in Listing 14-1.

Listing 14-1: Finding a Top Dice Number
#!/usr/bin/env python
# Look up dice orientation - By Mike Cook
# side sequence

diceLookup = [ [
[
[
[
[
[

3,
6,
2,
1,
4,
2,

5,
3,
6,
5,
1,
4,

4,
1,
5,
6,
3,
5,

2,
4,
1,
2,
6,
3,

3], #
6], #
2], #
1], #
4], #
2] ]#

for
for
for
for
for
for

1
2
3
4
5
6

on
on
on
on
on
on

top
top
top
top
top
top

print "Find top number by two side values"
while True :
first = input('first number ')
second = input('second number ')
top = -1
topTry = 0
while top == -1 and topTry < 6:
for n in range(0, 4):
if diceLookup[topTry][n] == first and diceLookup[topTry][n+1]
== second :
top = topTry + 1
topTry += 1
if top == -1 :
print "numbers are not in clockwise sequence"
else :
print 'top of dice is ',top

This code uses a list of lists, or two-dimensional array, to hold the sequence, but
notice how the last number in the list is the same as the first. This makes the code
easy by taking care of any wraparound when searching the list. Given two numbers
entered from the keyboard, the list is searched until the two numbers are found next
to each other in the list. When these two numbers are found, the row they’re found
on gives you the top number of the dice. The rows are numbered for 0 to 5 and the
dice is numbered 1 to 6 so, in fact, the real top number is the row number plus one.

Looking at the Playing Mechanism
In this section, we take a look at the dice-playing mechanism. The aim is to place
the dice with a new number on the top, a number that is the “right” one according to
the playing matrix. Now, the rules of the game preclude the use of the current top or
bottom number, so the mechanism only has to flip the dice over on its side. The
dice is on a rotating platform anyway, so that can be used to move the dice into the
throwing position and a motor can then flick it off onto a static platform. If you get
this landing platform right, the dice will move only 90 degrees and not roll over
any more.

The dice

The dice is the key to making the game. LEGO used to produce a whole series of
games that involved a dice. This series was discontinued in 2013 but is still
available from many outlets, as well as on popular auction sites. One of the
cheaper games, Magikus, provides an ideal dice along with the colored tiles for the
sides. You can also get the dice and colored tiles from online auction sites, but we
found a discount game that was cheaper than buying the separate parts. The only
snag is that the colored tiles don’t have the dot markings found on dice.
To rectify this, we used a 3mm drill to mark the sides with dots by just drilling the
point of the bit in about 1mm. Then we used black paint to fill the holes — all
except the black tile, where we used white paint. This made it easy for a human to
see the dice number but didn’t interfere with the color sensor’s output. Rather than
use a fine brush, we used a solid wire from a resistor to transfer a drop of paint
into the recess left by the drill.
We found it convenient to clamp two blocks to the drill press so that the drill was
just 3mm in from the corner. Then each tile that needed a dot in the corner was
placed between the blocks, drilled, rotated, and drilled again. In that way, all the
corner dots could be drilled consistently. Then the blocks were adjusted so that the
“center side” dots could be drilled; finally, the center dots were drilled. This
arrangement, along with the dice side measurements, is shown in Figure 14-4; a
photograph of the finished dice is shown in Figure 14-5.

Figure 14-4: The dice drilling measurements.

Figure 14-5: The finished dice.

The mechanism
All the parts for the rest of the mechanism can be found in the LEGO
MINDSTORMS EV3 set. The best way of documenting a LEGO model is with
step-by-step build instructions, but there are two problems with this:
It will take up many more pages than this chapter has room for.
Creating these instructions isn’t easy.
There is a free, official LEGO application called LEGO Digital Designer (LDD)
that allows you to make 3D interactive LEGO models. Once complete, LDD can
produce a construction sequence. The big snag with this approach is that, although
it works for a lot of models, technic beams, especially when tilted, can be almost

impossible to construct. The tolerances in the software are much tighter than the
hardware, so some models are impossible to construct virtually. Also, sometimes
the rotation tools simply don’t work or rotate around a wholly unexpected axis.
The construction of the dice-playing mechanism is shown in the digital designer
model as three separate parts, but they all fit together like the photograph in Figure
14-1. Go to www.dummies.com/go/raspberrypiprojects to download the
digital model and generate your own step-by-step instructions. Note that there is the
odd connecting peg that doesn’t fit in the model, but these pegs are in the file and
it’s quite obvious where they should go.
One important aspect of the design is the dice landing platform. We tried many
designs of this until we got it right. We found that the platform couldn’t be
horizontal because it gave too much roll to the dice and the dice ended up being
flipped more than 90 degrees. By angling the platform, it reduced the tendency of
the dice to roll, and the retaining bar at the top of the platform stops the dice from
rolling any more than is required. This produces an almost perfect throw, but very,
very occasionally the dice ends up in the wrong orientation or bouncing off the
platform altogether. Fortunately, for the purposes of the game, there is a graphical
representation of the dice on the screen, which is always the last word in what the
computer’s move should be.
One problem with the cables that connect the EV3 devices to the control block is
that they’re pretty stiff. This could be an issue with the medium motor that has to be
moved by the large motor to flick the dice. We replaced this with a flexible ribbon
cable connector, as described in Chapter 13. Alternatively, we found that by lifting
the robot and platform off the table a bit higher, the throwing arm cable didn’t snag.
We tried putting some alignment strips on the rotating table to get the dice into
exactly the right position, but in the end it only interfered with the angle at which
the dice slipped off the table and changed the flipping characteristics. So, your best
bet is to place the dice as square on as you can to the sensor. We’ve found this isn’t
too critical in practice.

Writing the Code
The code for this project is in two parts: One part runs on the LEGO brick, and its
job is to report back the sensor readings and control the motors according to
messages sent to it by the Raspberry Pi. It’s the code on the Raspberry Pi that
controls the playing of the game and responds to the moves a player makes and

decides what move the computer should make. It also keeps track of the score so it
knows when a game is over. Finally, this code generates a graphic representation
of both the current state of the dice and the heap.

The EV3 code
The code that goes into the EV3 brick can be downloaded from
www.dummies.com/go/raspberrypiprojects, but it’s also shown in Figure 146. Basically, it’s a large loop that receives a message from the Raspberry Pi via
Bluetooth and displays that message on the screen. Then a switch block is used to
perform the appropriate actions and a message is sent back to the Raspberry Pi
with either some data or text saying the action has been performed.

Figure 14-6: The EV3 code for the dice game.

The commands are relatively simple but still a bit more complex than they could be
in order to minimize the communications between the Raspberry Pi and the control
brick. Instead of continually asking the control brick to report what the color the
sensor sees, and the Raspberry Pi making the decision of whether the dice has been
replaced or removed, the brick waits and only sends a message back when the dice
is in place or has been removed.

We found that the command names shouldn’t have spaces in them in order
to operate the switch block correctly. This technique proved to be very
successful.
Following are descriptions of all the commands. Note that these are all
implemented as text messages for simplicity:
Simply reports the color seen by the color sensor and returns it
immediately.
See:

Rotates the dice platform clockwise by 90 degrees, so that another side
of the dice faces the color sensor. Sends back a message indicating the color of
that new side.
Twist:

Waits until the dice is placed on the platform and then returns a
message showing the color reported by the color sensor.
Place_Dice:

Waits until the dice has been removed (as determined by the
color sensor reading 0) and then sends a fixed text message saying “Gone.”
Remove_Dice:

Triggers the throwing of the dice onto the landing platform. This
command is the only one that does not return a message.
My_Move:

The Raspberry Pi code
The job of the code in the Raspberry Pi is to actually play the game and give
commands to the LEGO in order for it to read a player’s move and make the
computer’s move. It draws a graphical representation of the dice reconstructed
from the information given by the color sensor. It also displays the heap number
and graphically depicts it by drawing stacks of coins, with the same number of
coins as the heap size. This software keeps track of the player’s move and works
out the computer’s response. Finally, it adds some sound effects to the game.
At the start of the game, you’re asked to remove the dice from the sensor if it’s
already on and replace it at the starting position. The computer then generates a
heap number based on this starting position. It generates a heap with a value that is
a winning position for you. This means if you play the perfect game, you’ll win;
otherwise, the first deviation from this perfect game that you make will mean the
computer will win.

Resources

Before you begin, you need some sound and graphics resources. These are stored
in directories called sounds and images at the same directory level as the game
code. For the sounds, you need the following files:
laugh.ogg:

Sound effect when the computer wins

applause.ogg:
ching.ogg:

Sound effect when you win

Sound effect when the heap is drawn

The graphics files are a bit more complex. First, you need the image of a coin taken
at an oblique angle. We photographed a euro 20-cent piece and used a graphics
package to make the surroundings transparent. Then you need the component parts
to make up the image of the dice. We made an isometric drawing of the top of the
dice and its right-hand side, for each number; we also gave these sides the actual
color of the LEGO dice tiles, so the drawn representation matches closely the real
dice. There is no need to have files for the left-hand side of the dice because you
can reuse the right-hand side drawing simply by flipping the image horizontally
when it’s drawn by the software.
The best way to create these dice components is to use a vector drawing package,
like Inkscape, and first draw a cube. Then draw grid lines on it and make a copy of
the top and side. Populate all nine locations of the dice dots and remove the grid
lines. Then copy these two elements six times each, and delete the dots on each
piece until you have the appropriate number pattern showing. Then apply a flood
fill of the matching color. Note that you also need a dice graphic where the faces
are unknown, for the start of the game; we used texture patterns for this, but you
could draw one with question marks on each side. You need to use a PNG file
format for these dice elements because you need to make the background
transparent. This can be done with an online image editor such as www.onlineimage-editor.com or any other graphics editor with these capabilities.
These parts are shown in Figure 14-7. Then we saved them individually from the
drawing package as PNG files and used an image editor to make the backgrounds
transparent. The images for the top of the dice should be called t0.png to t6.png
with the zero being the unknown top. Likewise the side images should be called
s0.png to s6.png. We made the dice tops 148 x 148 pixels and the disc sides 100
x 162 pixels, but the size isn’t critical. Also, the coins were 90 x 44 pixels in size.
If you don’t want to do this, all the graphics and sound files are available for
download from www.dummies.com/go/raspberrypiprojects.

Figure 14-7: The elements of the dice graphics.

The code is written in Python and uses the Pygame extension library. Instead of
presenting it as one big lump of code, we’ll present it as a series of functions. You
should type these into the same file using your favorite Python editor (we used
IDLE). The listings should be assembled into the final file by typing each listing in
front of the previous listing, so we’re starting with the bottom of the file and
working up.
The purpose of this code is to produce a graphics-based interface to the game, as
shown in Figure 14-8. The program draws the representation of the current size of
the heap and draws the current state of the dice as understood by the program. In
the very odd occasion when the computer’s turn is not executed correctly, the
graphics of the intended move should always be taken as the correct move.

Figure 14-8: The graphics window of a game in progress.

So, let’s start writing the code by looking at some basic housekeeping functions
required by Pygame, shown in Listing 14-2.

Listing 14-2: Dice Game: Housekeeping Functions
#pygame housekeeping
def terminate(): # close down the program
print "Closing down please wait"
EV3.close() # close the port
pygame.quit() # close pygame
sys.exit()
def checkForEvent(): # see if we need to quit
event = pygame.event.poll()
if event.type == pygame.QUIT :
terminate()
if __name__ == '__main__':
main()

These are almost standard and appear in a lot of our code — just two functions.
The first function is called when the program quits, closes open files, and exits.
The second function monitors for any events in the Pygame system and acts on
them. In this program, the only events we’re bothered about are the shutdown or
quit events, like the Escape key or a click in the close box of the window.

Next comes the code for talking to the bricks. Listing 14-3 is for sending and
receiving messages, as well as generating message blocks.

Listing 14-3: Dice Game: Talking to the LEGO Brick
# Talking to the brick
def init(): #set up messages to the brick
global see, twist, play, place, remove
see = messageG("Brick","See")
twist = messageG("Brick","Twist")
play = messageG("Brick","My_Move")
place = messageG("Brick","Place_Dice")
remove = messageG("Brick", "Remove_Dice")
def readMessage() :
n = 0
while n < 2 :# hold until message starts to arrive
n = EV3.inWaiting()
checkForEvent()
inMessage = EV3.read(2)
messageBytes = ord(inMessage[0]) + ( ord(inMessage[1] .
) *256 )
while EV3.inWaiting() < (messageBytes ):
checkForEvent()
inMessage = inMessage + EV3.read(messageBytes )
payloadPointer = 9 + ord(inMessage[6])
message = inMessage[payloadPointer:]
return message
def messageSend(message):
if EV3.isOpen() == True :
for n in range(0, 2 + ord(message[0]) +
(ord(message[1]) * 256 )):
EV3.write(message[n])
else :
print"Serial port not open"
def messageG(boxName,message): # generate a message
length = len(boxName) + len(message) + 8
btMessage = [ chr(0) for temp in range (0,length)]
# initial blank
btMessage[2] = chr(1)
# message ID
btMessage[4] = chr(0x81)
btMessage[5] = chr(0x9E)
btMessage[6] = chr(len(boxName) + 1)
btMessage[7:7+len(boxName)] = boxName
payloadPointer = 8 + len(boxName)
btMessage[payloadPointer] = chr((len(message) + 1) & 0xff)
btMessage[payloadPointer + 1] = chr((len(message)+ 1)
>> 8)

btMessage[payloadPointer + 2:len(message)] = message
endPoint = payloadPointer + len(message) + 1
btMessage[0] = chr((endPoint & 0xff))
btMessage[1] = chr(endPoint >> 8)
return btMessage

Each of the commands that is going to be sent to the LEGO brick are defined in the
init function. This is done by calling the messageG function, which generates the
message block of data. Note that this takes in both the message text and the name of
the message box that it’s delivered to. For a full explanation of the structure of a
message, see the previous chapter. The readMessage function is simplified in that
here there is no interest in retrieving the mailbox name; it just returns the payload in
the form of a list of characters.
The next block of code concerns the Pygame drawing functions and is shown in
Listing 14-4.

Listing 14-4: Dice Game: Screen-Drawing Functions
# Pygame graphic functions
def drawDice(top) :
pygame.draw.rect(screen,cBackground, (0, 0, 150, 200), 0)
screen.blit(diceTop[top],[0,0]) # draw dice
screen.blit(diceSide[currentDice[0]],[48,48])
screen.blit(pygame.transform.flip(diceSide
[currentDice[3]] ,False,True),[0,48])
pygame.display.update()
def drawHeap(size):
chingSound.play()
pygame.draw.rect(screen,cBackground, (194,50,400,215), 0)
drawWords("HEAP " + str(size), 262, 10)
x = [ 212, 334, 465 ]
y = 220
h = 0
w = 0
if size < 1 :
return
while size != 0 :
screen.blit(coin,[x[h] + heapWobble[w],y])
size -= 1
w += 1
h += 1
if h > 2 :
h = 0
y -= 10
pygame.display.update()
def blank_screen():

screen.fill(cBackground) # blank screen
pygame.display.update()
def drawFeedback(feedback) :
pygame.draw.rect(screen,cBackground, (30,300,570,textHeight), 0)
drawWords(feedback,30,300)
pygame.display.update()
def drawWords(words,x,y) :
textSurface = pygame.Surface((len(words) *
(textHeight / 2),textHeight))
textRect = textSurface.get_rect()
textRect.left = x
textRect.top = y
pygame.draw.rect(screen,cBackground, (x,y,len(words)
* (textHeight /2),textHeight), 0)
textSurface = font.render(words, True, cText, cBackground)
screen.blit(textSurface, textRect)

The drawDice function takes in the number on the top of the dice and draws an
isometric view of the dice. It uses the global list currentDice to see what
numbers to draw for the sides. This list is updated whenever a new dice position
occurs. The drawHeap function takes in the heap size and draws the word Heap
along with its size in the playing window. It then goes on to draw the heap as a
stack of coins in three piles.
There is nothing significant about the three piles — it just makes them fit in the
window better. However, the stacks of coins are staggered for a bit of visual
interest. The same staggering is kept throughout a game so that when a smaller
number of coins are drawn, they appear to have been removed from the top of each
heap. The amount of displacement for each coin is held in a list called
heapWobble, and a new list is generated whenever a new heap is generated.
The drawFeedback function is used to give the human player feedback on the
game’s progress. This is one line on the screen, and the function blanks out any
previous messages before writing the new one. This function calls the drawWords
function that handles the nitty-gritty of rendering text onto the bitmapped area of the
window.
Next, we have the functions that handle the interaction between the game and the
LEGO control brick and act as an interface for hardware. These functions deal with
finding the current dice orientation and positioning the dice for the computer’s
move, as shown in Listing 14-5.

Listing 14-5: Dice Game: Interacting with the Hardware

# Interacting with hardware definitions
def getStartDice() : # read the sensor
messageSend(see)
face = readNumber()
if face != 0 :
drawFeedback("Please remove the dice")
messageSend(remove)
getAck()
time.sleep(0.8)
drawFeedback("Now replace it with start number")
time.sleep(0.5)
messageSend(place)
return getTop(readNumber()) # get the top positions
def getTop(face) : # identifies the dice top number
global currentDice
currentDice[0] = face
currentDice[2] = 7 - currentDice[0]
time.sleep(1.0) # time for hand to clear
messageSend(twist)
face = readNumber()
currentDice[1] = face
currentDice[3] = 7 - currentDice[1]
top = findTopFromSides(currentDice[0],currentDice[1])
return top
def readNumber() :
number = readMessage()
dice = ord(number[0]) - 0x30
return dice
def getAck():
if(readMessage() == "Gone") :
return True
else :
return False
def computerPlay(move) : # move dice into correct place
twists = -1
for t in range(0, 4) :
if currentDice[t] == move :
twists = t
while twists != 0 :
messageSend(twist)
getAck() # not interested in the sensor
adjustCurrentDice()
time.sleep(0.25)
twists -= 1
messageSend(play) # throw the dice
time.sleep(1) # wait until it is done

def adjustCurrentDice() :
global currentDice
tempDice = copy.deepcopy(currentDice)
currentDice[0] = tempDice[1]
currentDice[1] = tempDice[2]
currentDice[2] = tempDice[3]
currentDice[3] = tempDice[0]
def findTopFromSides(first, second):
top = -1
topTry = 0
while top == -1 and topTry < 6:
for n in range(0, 4):
if diceLookup[topTry][n] == first and
diceLookup[topTry][n+1] == second :
top = topTry + 1
topTry += 1
return top

The getStartDice function is the procedure used at the start of the game. If the
dice is in front of the sensor, the game says it should be removed. Then the dice
needs to be placed in front of the sensor. This then becomes the starting position.
When the dice is in place, it returns the value acquired from the next function,
getTop, which passes the number of the face in front of the sensor and updates the
currentDice list. Then the dice platform is rotated by 90 degrees, and the next
face of the dice is read. Having acquired the value of all four sides of the dice, the
findTopFromSides function finds the top number of the dice in the same way as
we’ve already seen in Listing 14-1. The readNumber function extracts a singledigit number from the text message, whereas the getAck function simply reads a
message returning true or false if it’s the string Gone. In this code, no use is
made of this returned value.
The last two functions to consider in this block are concerned with the computer
playing a move. The computerPlay function takes in a move number to make. This
number must then be maneuvered into the throwing position, and the throwing
command must be given. The function uses the currentDice list to find out how
many 90-degree twists to give the dice platform to bring it into the right place.
After each twist, the currentDice list is updated by the adjustCurrentDice
function so that the correct dice sides can be drawn after the throw. This is done
simply by shifting the entries in the list by one place to the left. Note the need to use
the copy.deepcopy function to get a temporary duplicate of the list.
The next block of code consists of the functions that play the game. These functions,
shown in Listing 14-6, set up the heap and make the computer’s move.

Listing 14-6: Dice Game: Setup and Play
# Game playing definitions
def generateHeap(start) :
global heapWobble
total = 9 # impossible win start
line = index[start] # the opening position line in the move table
# now choose another total heap that is not a
losing position
while(moveMatrix[line][total] == 128) :
total= random.randint(8, 16)
# generate a winnable position
total = total + ( random.randint(1, 4) * 9 )
# pick a multiple of 9 of this
for n in range(0,54):
heapWobble[n] = random.randint(0,20) - 10
return total
def computerMove(target, top):
modTarget = target
while modTarget > 16 : # reduce target to final table
modTarget -= 9
potMove = moveMatrix[index[top]][modTarget]
moveToMake = potMove # gets overridden if
not a dice number
if potMove > 6 : # a potential move has a choice
if potMove == 7 : #move is 2 or 3 or 4
moveToMake = random.randint(2, 4)
if potMove == 8 : # move is 2 or 3
moveToMake = random.randint(2, 3)
if potMove == 9 : # move is 3 or 4
moveToMake = random.randint(3, 4)
if potMove == 10 : # move is 3 or 6
moveToMake = random.randint(3, 4)
if moveToMake == 4 :
moveToMake = 6
if potMove == 11: # move is 3 or 4 or 6
moveToMake = random.randint(3, 5)
if moveToMake == 5:
moveToMake = 6
if potMove == 12 : # move is 1 or 2
moveToMake = random.randint(1, 2)
if potMove == 13 : # move is 2 or 6
moveToMake = random.randint(1, 2)
if moveToMake == 1 :
moveToMake = 6
if potMove == 14 : # move 1 or 5
moveToMake = random.randint(1, 2)
if moveToMake == 2 :
moveToMake = 5
if potMove == 128 : # losing move so select
a random move

moveToMake = random.randint(1, 6)
#print "losing position for me" # uncomment to
see if you are winning
while moveToMake == top or moveToMake == 7-top :
moveToMake = random.randint(1, 6)
return moveToMake

Both these functions make use of the move matrix (refer to Tables 14-1 through 143). However, the computer version of this table has numbers in it representing
various things. A number between 1 and 6 indicates the move to make; a number
between 7 and 14 indicates there is a choice of moves, and the specific number
defines what those choices are; finally, a value of 128 shows that this is a losing
position.
The generateHeap function starts off assuming a heap of 9, which is a totally
unwinnable position no matter what number is currently on the top. The code then
generates a random number between 8 and 16 until it finds one where the heap size
and the current top number of the dice produces a winnable position. Then this is
multiplied by a random multiple of 9 to make the heap bigger and add a bit of
variety to the game. Finally, the function generates the heapWobble list for the
staggering of the coin pile graphics.
The last function, computerMove, is where the computer’s move is worked out. It
takes in the current size of the heap and the current top number on the dice. It then
repeatedly subtracts 9 from the heap until it is 16 or less. Then it looks up the
potential move by extracting it from the two-dimensional list of the playing matrix.
The first index decides what line on the table to use; this depends on the top
number. The second index is the reduced heap value.
Now that number is interpreted by a pile of if statements. For example, if the
number 10 is drawn from the moveMatrix table, that means the playing number
should be either 3 or 6. A random number between 3 and 4 is generated; if it turns
out to be 4, the code sets the move to 6. If the number is 128, that’s a losing
position, so a random move is generated. This must still be a legal move so while
the moveToMake variable is an illegal move, random numbers are repeatedly
generated until a legal move is found.
The last function to consider is the main function. This is the loop that defines the
whole game. It’s implemented as a state machine — in other words, there are a
number of phases in play, setup, player move, computer move, player win,
computer win, and end of game, and each one of these phases has a number in the
variable gameState. This function is shown in Listing 14-7.

Listing 14-7: Dice Game: The Main Loop
def main():
init() # Initialize variables
blank_screen()
drawDice(0)
gameState = 0
while True : # play the game
checkForEvent()
if gameState == 0 : # new game send out introduction
drawWords("Take the last coin to win", 30,350)
drawFeedback("Welcome to the dice game")
time.sleep(1)
drawFeedback("Put the dice on the sensor")
move = 0
move = getStartDice()
lastMove = move
drawDice(move)
random.seed() # seed random number generator
heap = generateHeap(move);
drawHeap(heap)
drawFeedback("Now make your first move")
messageSend(remove)
getAck()
time.sleep(0.8)
gameState = 1 # introduction over
if gameState == 1 : # players move
move= 0
while move == 0 or move == lastMove or
move == 7-lastMove :
while move < 1 or move > 6 :
messageSend(place)
move = getTop(readNumber())
if move == lastMove or move == 7-lastMove :
print"can't play this number"
move = 0
drawFeedback("You cannot use "+
str(lastMove)+" or "+ str(7 - lastMove)+ " . Try again")
messageSend(remove)
getAck()
heap -= move
drawDice(move)
drawFeedback("Your move was "+ str(move))
drawHeap(heap)
time.sleep(1.5)
if heap == 0 :
gameState = 4 # player wins
if heap < 0 :
gameState = 5 # computer wins
lastMove = move;

if gameState == 1 : # if we are still playing
gameState = 2 # computer's move next
if gameState == 2 : # Computer's move
move = computerMove(heap,lastMove)
drawFeedback("My move of " + str(move))
computerPlay(move) # play the move
currentDice[0] = 7 - lastMove # bottom number is
now in position 0
drawDice(move)
lastMove = move;
heap -= move
drawHeap(heap)
time.sleep(2)
if heap == 0 :
gameState = 5
if heap < 0 :
gameState = 4
if heap > 0 :
drawFeedback("Your move ")
gameState = 1
if gameState == 4 : # Player wins
applauseSound.play()
drawFeedback( "WOW you won - well done")
gameState = 6
if gameState == 5 : #Computer wins
laughSound.play()
drawFeedback("I win again …")
gameState = 6
if gameState == 6 : # end of game
time.sleep(3)
drawFeedback('Have another go')
time.sleep(2)
gameState = 0

This is the longest function in the program, but it breaks up into a number of small
state sections, or game phases, so it’s best to consider them one at a time.
For most of the game, the gameState variable will alternate from 1 to 2,
representing the player’s move or the computer’s move. Higher values represent
the end of the game and the outcome, and they draw the appropriate feedback and
trigger the appropriate sound effects. A gameState variable value of 0 represents
the setup phase.
To kick things off, there are a few lines that do one-off initialization. The init
function is called to set up the lists used as messages to the LEGO brick, the

window is cleared, and a blank dice is drawn. Then the while True loop is an
infinite loop that will repeatedly play all the moves of a game and play multiple
games.
If the gameState variable is a 0, then this is the setup phase of the game. It makes
sure that there is no dice in front of the sensor and then asks the player to put the
dice down in the starting position. It then reads the dice and draws a picture of it.
This starting dice state is used to generate a heap size that is winnable by the
player. The code then asks the player to make the first move, and the gameState
variable is set to 1.
The main purpose of the if gameState == 1 section is to get the player’s move,
but it must be a legal move (one that is not the same as the previous move or a use
of the number the dice is sitting on). This is achieved by putting the code into a
while loop that keeps repeating until a legal move has been made. When a move is
made, that number is subtracted from the heap and a check is made to see if the
game is over. This is determined by looking at the heap size. A heap size of 0
indicates the player has won; a negative heap size indicates the computer has won.
If neither of those two things has happened, then the gameState variable is
advanced to 2, the computer’s move.
The computer works out its move by giving the current heap size and last move to
the computerMove function. The side dice face corresponding to the computer’s
move is then rotated into the correct place for throwing. Then it’s thrown and the
dice graphic is updated. Then the move is evaluated by subtracting it from the heap
to see if anyone has won. If not, the gameState variable is set back to the player’s
move value of 1.
The end of game values of the gameState variable print messages to the screen
and play sound effects depending on whether the player has won or lost. A value of
4 indicates that the player has won, and a value of 5 shows that the computer has
won. These both change the state to the final value of 6, which invites the player to
play again and then sets the gameState variable back to 0.
All that remains is the initialization of the variables, lookup tables, and loading in
of sound and graphics. This is shown in Listing 14-8.

Listing 14-8: The Dice Game: Initialization
#!/usr/bin/env python
'''
Lego powered Dice Game
By Mike Cook

'''
import
import
import
import
import

serial
time
random, copy
os, pygame, sys
struct

EV3 = serial.Serial('/dev/rfcomm0', timeout=1)
EV3.flushInput()
pygame.init() # initialise graphics interface
pygame.mixer.quit()
pygame.mixer.init(frequency=22050, size=-16,
channels=2, buffer=512)
chingSound = pygame.mixer.Sound("sounds/ching.ogg")
applauseSound = pygame.mixer.Sound("sounds/applause.ogg")
laughSound = pygame.mixer.Sound("sounds/laugh.ogg")
os.environ['SDL_VIDEO_WINDOW_POS'] = 'center'
pygame.display.set_caption("Lego Powered Dice Game")
pygame.event.set_allowed(None)
pygame.event.set_allowed([pygame.KEYDOWN,pygame.QUIT])
cBackground =(255,255,255)
cText = (255,0,0)
textHeight = 48
font = pygame.font.Font(None, textHeight)
screenWidth = 600
screenHeight = 400
screen = pygame.display.set_mode([screenWidth,screenHeight],0)
diceTop = [ pygame.image.load("images/t"+str(num)+".png"
).convert_alpha() for num in range(0,7)]
diceSide = [ pygame.image.load("images/s"+str(num)+".png"
).convert_alpha() for num in range(0,7)]
coin = pygame.image.load("images/coin.png").convert_alpha()
print "Lego Dice"
currentDice = [0 , 0, 0, 0]
heapWobble = [ random.randint(0,20) - 10 for n in range(0,54)]
moveMatrix = [
[0, 128, 2, 3, 4, 5, 3, 7, 4, 128, 5, 8, 9, 4, 5, 3, 7],
[0, 1, 1, 3, 4, 128, 10, 11, 4, 128, 1, 3, 9, 4, 128, 10, 9],
[0, 1, 12, 128, 128, 5, 6, 13, 128, 128, 14, 2, 128, 128, 5, 6,2]
]
index = [ 0, 0, 1, 2, 2, 1, 0] # input the current state
of the
dice to read what line on the move matrix to use
diceLookup = [ [ 3, 5, 4, 2, 3], # side sequence for 1 on top

[
[
[
[
[

6,
2,
1,
4,
2,

3,
6,
5,
1,
4,

1,
5,
6,
3,
5,

4,
1,
2,
6,
3,

6], # for 2 on top
2], # for 3 on top
1], # for 4 on top
4], # for 5 on top
2] ] # for 6 on top

see = "see"
twist = "twist"
play = "play"
place = "place"
remove = "remove"

First, the Python modules needed are imported. Then the Bluetooth connection to
the LEGO brick is established and the buffers are cleared out. Next comes the
Pygame initialization for the sound, window, text, and graphics. Note that the
graphics for the dice side and top are loaded into a list from files in the images
directory, whereas the coin is a single file.
Next come the definitions of the global variables that allow the playing of the
game. The moveMatrix list consists of three lists, each for use with a different top
face number. The values in the list of moves is coded as the move to make if it’s
between 1 and 6 or a number representing a choice of moves, or the value 128
representing the state when there is no winning move to make from this position.
The zero at the start of the list is just a dummy value so that the list index number
and the current heap size match up.
The index list informs the code doing the move lookup which list of the three to
use given the current top state of the dice. The diceLookup list contains the
sequence of numbers on the side of the dice when rotated clockwise for every top
dice number. Note that the first and last numbers are the same so that the code can
be made simpler by not having to cope with wraparound.
Finally, the five strings that define the messages sent to the LEGO brick are defined
as global variables with dummy data. The init function will assign the real data to
it later. It can’t be done at this stage because it involves other functions that can’t
be called yet.

Play
All that remains is to play the game. It works even better if you can memorize the
playing matrix so that you can win every time and astound your friends.

Customizing the Code

Like all projects, you can customize this game to your heart’s content. Here are
some ideas you may want to implement.
The simplest modification is to change the sound effects. You could even add some
extra ones. For example, the computer can speak instructions for your move and tell
you when you’ve made an illegal move. You can record all the numbers and get the
move spoken. If you’re feeling adventurous, you can write a function that takes
several samples of numbers being spoken and speaks the heap size. You’ll just
have to record extra number parts like “teen,” “twenty,” and so on.
Another idea is to remove the coins one at a time from the heap to make the
animation a bit more interesting. You may even want to write a small sequence
where the top coin off each heap rises up and disappears off the top of the screen.
In fact, you don’t have to stick to coins — the heap could be anything drawn in any
arrangement you like. Remember, though, that if you want to use random positions,
you should use a heapWobble-like list of positions so that the heap doesn’t keep
rearranging itself whenever anything is removed from it.
If you really want to take it to another level, how about a LEGO robot that scurries
around the room to find the dice, picks it up, detects what it is, and makes its own
move? That would be a challenge, indeed, but we’re sure it can be done somehow.
If you manage to do that, email us the results!

Chapter 15

LEGO Direct
In This Chapter
Adding a reset button to your Raspberry Pi
Saving on batteries for your EV3 brick
Controlling the LEGO motor directly from your Raspberry Pi
Reading the motor’s rotary sensors
Revealing the secrets of the EV3’s sensors
Accessing the LEGO peripherals without building anything
In the previous two chapters, we show you ways to communicate with the LEGO
MINDSTORMS EV3 Intelligent Brick. In this chapter, we get a lot more hacky and
look at controlling motors and reading sensors directly from the Raspberry Pi.
You can make your own cables that are much more flexible than the official cables,
and we show you how in this chapter. Finally, when using the Raspberry Pi with a
LEGO system, you can save on battery power and customize your project to your
liking, and we cover all that in the pages that follow.

Creating a Reset Button for the
Raspberry Pi
A reset button on the Raspberry Pi may not seem obvious, and we never needed
one until we started playing around with Bluetooth, but it’s a great idea for when
everything is stuck. (Sure, you can just yank out the power lead, but that isn’t really
recommended because it could cause trouble with your SD card.) Even though
there is no reset button on the Raspberry Pi, provision has been made for fitting one
from revision 2 of the board. You can see it in the form of two holes to the left of
the HDMI socket — it’s very easy to solder a two-pin header there. The idea is
that when these two lines are shorted together, the Raspberry Pi’s processor is
reset.

You can use a jumper link to temporarily connect these two lines together when
needed, keeping the jumper on one pin for normal operation. However, you can go
for the deluxe method and wrap a tact push button’s wires around a two-pin header
to produce an actual button. As an alternative, you can solder a button directly into
the two holes. Make sure you have a two-wire push button because there are many
four-wire ones out there. Figure 15-1 shows some photographs of this. On the right
is a tact push button wired to a two-pin socket; on the left, it’s mounted on a twopin header soldered into the Raspberry Pi’s board.

Figure 15-1: Raspberry Pi reset buttons.

Making Batteries Last Longer
Having done a few projects using the LEGO EV3 system, we noticed that the
batteries didn’t last very long. In fact, during development, the brick would often
sit there doing nothing for long periods while we concentrated on the Raspberry Pi
aspect of the software. Turning the brick on and off takes some time — about 30
seconds to power up and 45 seconds to power down — so you tend not to do it too
often. Although there are rechargeable batteries for mobile use, static LEGO
machines like the dice game in Chapter 14 can get away with a tethered power
supply.
The LEGO system runs off 6 AA batteries; at 1.5V each, that adds up to 9V. All the
solutions we found to this problem online involved some very ugly soldering of
wires directly onto the battery springs. We thought that this was a bit too intrusive.
Plus, it was difficult to swap between a power supply and batteries. So, we wanted
something that would look like a AA battery and allow us to connect wires to it.
While thinking, “What is about the size of a AA battery?,” we came up with the
answer: “A AA battery!”
The battery cover at the bottom of the EV3 brick has a small flange that covers a U-

shaped hole in the body of the brick. This hole is just about long enough to put a
long-reach 2.1mm power jack through, so all we had to do was to attach a matching
socket into something that was the same length as a AA battery. However, it isn’t
quite as easy as that because the spring that holds the battery in place tends to apply
a snapping force to the center of any tube. After a few false starts, we hit upon the
solution, shown in Figure 15-2.

Figure 15-2: The LEGO brick battery eliminator.

All this system has to do is to connect the positive end of your external power
supply to the top-right spring in the battery compartment and the negative end to the
top-left spring. The basic idea is that a surface-mount power-jack socket lines up
with the center notch in the battery compartment and attaches to the negative
connector of the brick. It’s held in place by a styrene tube, which fits around the
narrow pip on the battery holder’s spring positive connector. This pip is what
causes trouble — it’s too narrow to allow a stable fitting. The tube and the lefthand side of the PCB fit around the pip, preventing it from producing any sideways
movement and holding the assembly stable. The positive connection from the jack
socket is wired to the full battery’s body with a wire soldered to the body. Note the
positive connection is the main body of the battery with the negative connection just
the end.
To make this project, you need the following parts:
Two old dead AA batteries (the plastic-covered type, not the painted type)
A surface-mount 2.1mm power-jack socket

A 7mm x 30mm piece of single-sided PCB material
A styrene tube with an outside diameter of 20mm x 11mm
70mm of 24-gauge (or thicker) insulated wire
A long-reach 2.1mm power-jack plug
A small amount of epoxy resin
A 9V regulated mains power supply (an SPS-8041 or similar)
To build the battery eliminator, follow these steps:
1. Take the two batteries and strip off all the plastic covers, leaving just the
bare metal.
2. Using a small hacksaw, gently saw off the last 16mm of the negative end of
one of the batteries.
Make sure you catch the black stuff that comes out in a paper towel. You’ll find
that you’ve also sawed through a rod that runs down the center of the battery.

The black stuff is a compressed paste of manganese dioxide with
carbon powder added for increased conductivity. The sticky stuff surrounding
the center negative electrode is composed of zinc powder in a gel containing
the potassium hydroxide electrolyte wrapped up in a layer of cellulose or a
synthetic polymer.
3. Remove all the black stuff, leaving just the center electrode.
We did this by putting a small screwdriver in and scratching the black stuff out.
It comes out very easily.

Make sure you catch all the black stuff and don’t get it in your mouth.
Don’t dispose of this in the normal household garbage; instead, place it in a
resealable plastic bag and put it with your other dead batteries for proper
disposal.
4. Bend down the central electrode rod until it nearly touches the case.
5. Slip the piece of PCB material into the tube and push it as far in as it will
go.

6. Solder the electrode rod to the PCB material.
7. Take a small amount of epoxy resin and fix the PCB into the battery case.
Let it set for 24 hours.
8. Make sure the surface mount socket lines up with the center of the hole in
the LEGO brick when the battery retaining spring is compressed about
halfway. Then solder the surface mount socket in place on both sides.
9. Solder an insulated wire from the center pin of this socket to the body of
the other whole battery.

Clean up the area first with glass paper and make the joint quickly with
a soldering iron. Don’t allow the battery to heat up too much, and allow it much
longer than usual to cool down. The bulk of the battery means it will absorb
more heat before you can solder it.
10. Cut 20mm of styrene tube and fit it over the PCB material. Then place it in
the battery holder.
The construction is shown in Figure 15-3. A photograph is shown in Figure 154.
11. Wire up a long 2.1mm power jack with the center pin as the positive and
attach it to your 9V power supply.
We used an SPS-8041 selectable switch mode supply set to 9V for this. You
may want to cut off the small flange in the battery cover that covers up the hole
for the power jack, or you may want to leave your LEGO unmodified and just
operate the brick with no back cover. The choice is yours.

Figure 15-3: The construction of the battery clip.

Figure 15-4: The battery clip.

Now you can happily power your EV3 brick during development and quickly
change to batteries when needed.

Using Connectors and Cables to Control
the LEGO Motors and Sensors
If you want to have direct control of the LEGO motors and sensors, you have to get
electrical access to them. All the electronic components in the EV3 and NXT
systems are connected to the control brick using a six-way connector called an
RJ12. The RJ12 is very similar to the RJ11 connector — the only difference is that
the RJ11 uses only four of the six wiring positions of an RJ12. Sometimes an RJ12
connector is called a 6P6C RJ11; this stands for six positions and six connectors
(whereas the normal RJ11 is a 6P4C connection).
Although these are both standard connectors in the electronics industry, the LEGO
designers added a small tweak to make things a bit difficult (or as LEGO would
probable say, to ensure the MINDSTORMS system was not connected to things it

should not be connected to). The RJ11 and RJ12 connectors have a latch on the top
to allow for the cable to be locked into the socket. Normal connectors have this
connector in the center, but the LEGO system has it offset on the right side. There
was an old RJ11 telephone connector with an offset latch, but that was offset on the
other side, so making extra cables isn’t straightforward.
RJ12 cables are normally crimped onto the connectors. You get a special size-6
core flat cable and strip off the outer insulation. Then you put the insulated wire
ends into a plug and crimp it with a special tool. This does two things:
It distorts a plastic bar to push against the wires and acts as a mechanical
clamp.
It pushes the blades on the back of the plug’s contacts through the plastic of the
wire’s insulation to make a contact.
Done properly, this produces a good durable connection. The only snag is that the
double insulation tends to make the resulting cables a bit stiff, which can
sometimes cause problems when connecting parts that move.
There are several things you can do with the leads to improve them or allow
electrical access to the signals, some of them more straightforward than others:
Hack an existing lead. This approach is perhaps the simplest one to take. You
have a lead with two ends, so you can simply cut it in half, and you have two
ends to solder your extension wires onto. If you want to extend the cable to use
more flexible wires, you can cut the cable close to the connector and insert a
length of stranded wires with thinner insulation. Make sure you cover any
exposed joints with insulating tape or, better yet, a dab of liquid insulation
tape.
Use a normal RJ12 and crimp tool, but move the latch over to the right
side. We’ve seen this method advocated on some websites, but we haven’t had
much success with this technique ourselves. The idea is that, after you’ve fitted
the cable, you slice off the tab with a sharp knife and glue it on the side using
polystyrene model airplane glue, using an existing socket as a guide so you get
it in the right place. You have to be very careful not to permanently glue the
cable into the socket; plus, the springiness of the latch is in question after the
gluing.
Get some real connectors. In our opinion, the best approach is to get some
real connectors, ones designed for the job. Unfortunately, there isn’t a great

deal of choice with suppliers — we could only find one source, but they’re
available on both sides of the Atlantic. In the United States, go to
www.mindsensors.com ; in Europe, go to www.active-robots.com. Here,
you can buy sockets and readymade leads, as well as the plug connectors.
However, if you’re going to make your own lead, you need a crimping tool, and
the only way we know of accommodating the offset latch is to modify an
existing crimping tool. Crimping tools can be quite expensive, but if you choose
the right one, it’s not only cheap but also easy to modify.
The LogiLink crimp tool is inexpensive and made from bright orange plastic, so
it’s simple to modify. It crimps four-position, six-position, and eight-position
connectors. The two halves unscrew, and it’s comparatively easy to file a
larger slot in the six-position hole to accommodate the offset latch. We used a
small square needle file to do this. Figure 15-5 shows the slot filed away on the
front piece. Note that you also need to file the back piece. You have a
connector of the right size in the LEGO set, so it’s easy to file the crimper so
that the plug fits in snugly.
We found that the best wire to use was ribbon cable. The vast majority of
ribbon cable is 0.1-inch pitch, but it’s too big for these connectors so what you
want is 1mm pitch cable. All you need to do is cut the cable off square, insert it
into the socket, insert the socket in the crimper, and squeeze. For a bit of added
resilience, we added a small spot of Gorilla Glue to the cable underneath the
clamping bar. We left this a few hours to set before flexing the cable.
Using this method, you can make flexible two-ended cables of exactly the right
length for your model. Or you can make single-ended cables for attaching your
LEGO parts to other electronics or your Raspberry Pi.

Figure 15-5: Crimp tool modification.

Reading and Commanding
There are basically two different sets of signals you can get on the LEGO control
brick:
Sensors: You read information from these. They’re labeled A through D.
Actuators or motors: You command these to move. They’re labeled 1 through
4.
Each has a different set of electrical connections. Figure 15-6 shows the signals on
the two types of LEGO peripherals. Note that this is oriented with the latch on the
underside. The colors used on a standard LEGO cable for each wire are also
shown in Figure 15-6.

Figure 15-6: LEGO cable signals.

The motor lead
The LEGO motor basically consists of two components:
A geared motor capable of clockwise or counterclockwise rotation
A rotary sensor giving pulses in response to the motor movement
The motor is geared, through a multigear train, so it turns many times before the
movement is transmitted to the outside world.
To get a motor to move, you apply a voltage across the Motor Power 1 and 2 lines.
This should be 9V, but the voltage isn’t too critical. To make it reverse direction,
you need to swap the polarity of these two lines. To stop the motor, you can do one
of two things:
Remove the power by removing the voltage from these lines. When you do
this, the motor will coast to a stop.
Make the two power lines be the same voltage — either both 0V or both
9V. This is not the same as disconnecting the voltage. Instead, it’s like
connecting the two motor wires together. This results in the motor stopping
very quickly by means of what is known as regenerative breaking or flywheel
breaking.
Flywheel breaking works because an electric motor that is turning is actually
acting like a generator and is producing a voltage that is in the opposite

direction of the voltage required to make the motor turn in that direction. So, by
connecting the two wires of the motor, you’re using the voltage generated by the
movement of the motor to try to drive the motor backward. This is like a power
shutdown and stops the motor much faster than just letting it coast to a stop.
You may have noticed the two stop modes in the LEGO language — the break at
end can be true or false. This is a simple way of saying “stop by coasting” or
“stop by flywheel breaking.”
The other control the motor has in the LEGO language is the power. (This used to
be called speed, but power is a more accurate description.) You can reduce the
power sent to a motor and, thus, see a speed drop by very rapidly turning the motor
on and off. This happens hundreds of times a second. By changing the relative time
the motor is on and off (known as the duty cycle), you can reduce the power fed
into the motor.
For example, at 500 times a second, the motor is turned on and off every 0.002
second or 2 milliseconds (mS). If the motor is on for 1 mS and off for 1 mS, the
power will only be 50 percent of full power. This rapid switching of the motor and
changing the duty cycle is known as pulse width modulation (PWM) and is a
common way of backing off the power on motors. Depending on the mechanical
load the motor is under, the speed will also drop. The off part of the cycle is
normally a flywheel breaking type rather than coasting type.
The last part of the motor is the rotary sensors, which give feedback on the actual
movement of the motor. Applying power to the motor is great, but it may be
jammed up or one motor may actually spin faster than another even if they’re given
the same voltage. Each motor is fitted with a rotational sensor. The sensor works
similarly to a mouse with a ball: Any movement rotates a disc with holes that block
and unblock one of two infrared beams. These beams produce pulses that can be
related to the motor’s actual movement.
The beams are quite accurate — you get one pulse for every degree of rotation. In
fact, there are two pulse outputs that are 90 degrees out of phase with each other
(known as a quadrature arrangement). By looking at which pulse line changes
first, you can also determine the direction of rotation. These pulses on their own
can be used to find how much a motor has moved, even if it isn’t powered and is
moved only by hand. However, the pulses can’t be used to find the absolute
position of the motor — only the relative motion or how much it has moved.

The sensor lead

The sensor leads, connecting to the sensor ports A through D, carry a very different
sort of signal. Pin 3 is ground and pin 4 is positive, and they carry the power
supply for the sensor. The new EV3 sensors communicate using the serial RS485
protocol at normal TTL logic levels. Communication between brick and sensor can
be complex, as you see later in this chapter.

Rolling Your Own Motor Control
In order to control LEGO motors directly from the Raspberry Pi, you have to
convert the signals available on the Pi’s general-purpose input/output (GPIO) pins
into signals suitable for driving the motor. The GPIO pins, when used as outputs,
can provide only a very small current (16 mA at 3.3V). The LEGO motor needs a
voltage of 9V at a current of 60 mA when under no load, and up to 2,000 mA when
it’s stalled. In order to make the motor turn in either direction, any driving circuit
needs to be able to swap the polarity of the voltage on the motor’s wires. In order
to get regenerative breaking, a circuit needs to be able to connect the two wires
from the motor together. A circuit that can do this is called an H-bridge circuit;
it’s composed of two half H-bridges.
A half H-bridge is simply what you get with a changeover switch (a switch that
can be connected to either one of two poles or positions). With each pole
connected to the two polarities of the motor’s power supply, you can make an Hbridge (as shown in Figure 15-7) using only switches.

Figure 15-7: An H-bridge made from switches.

The common connector of each switch is connection to one wire of the motor, as
you can see in Figure 15-7a — one switch is up and the other is down, so the
current flows through the motor and causes the motor to turn in a clockwise
direction. If the two switches are reversed, so switch 1 is down and switch 2 is up,
the current flows through the motor in the opposite direction and the motor rotates
in the opposite direction, as shown in Figure 15-7b. Finally, in Figure 15-7c, both
switches are down and the two motor wires are connected together allowing
regenerative breaking to occur. Note that this would also happen if both switches

were up; if they’re both connected to the same voltage level, they’re in effect
connected together.

Making it move
The only problem with an H-bridge made from switches is that you would have to
physically switch them. You could use relays to make the contacts, but there is a
pure electronic method that does not involve any moving parts. Fortunately, this is
such a common circuit that many integrated circuits are available with this
configuration, so you don’t need to make one from individual parts.
If you just want to control the direction of the motor, all you need is an H-bridge
circuit. But if you want to control the power/speed of the motor, you need to apply
some PWM to the voltage. Unfortunately, the Raspberry Pi is not very well
endowed with PWM signals — there are just two on the processor, and you can
only get to both of them on the plus model’s GPIO pins; the earlier models could
access only one. These pins are also used for generating sound so if you’re
controlling a motor, the Raspberry Pi can’t make any sound. Although each motor
can have its own PWM control, with a Raspberry Pi 2, there is a sneaky trick that
will work with all models to control two motors with one PWM pin. The way this
works is to use logic gates to pass or block signals to the H-bridge switches. The
gates we’ve chosen to use are called NAND gates (which stands for Not AND),
and they’re among the most common gates.
Logic gates have rules for what their output will be when presented with all the
possible different combinations of inputs. In words, an AND gate will have a true
output when input A and input B are true. A NOT gate has an output that is not the
input, so if the input is true, the output is false, and if the input is false, the output is
true. A NAND gate is an AND gate followed by a NOT gate.
All this gets very wordy, and you can quickly become muddled, so it’s normal to
have a table that shows every possible combination of inputs and the output results.
This is known as a truth table; three such tables are shown in Figure 15-8.

Figure 15-8: Logic truth tables.

The AND gate has two inputs — A and B — so there are four different possible
combinations, each with its own row in the table. The symbol for an AND gate is
shown below the table. Similarly, because the NOT function has only one input,
there are only two lines. Sometimes this function is called a logic inverter or just
an inverter for short. Finally, a NAND gate simply has the output of the AND gate
inverted. Notice how the symbol for the NAND gate takes the filled circle from the
output of the inverter and combines it with the body of the AND gate symbol.
Perhaps one of the more mind-boggling aspects of digital logic is that, when you
have a NAND gate, everything else can be made up from this one function. That
means that circuits that add up numbers, circuits that count, circuits that remember
… all the circuitry of your microprocessor or any computer can be made up of
NAND gates. No other functions are necessary. However, showing you how this
can happen would take up a whole other book.
So, why do you need to know about NAND gates here? Well, we use them to send
PWM signals or not send them into the H-bridge inputs to control the motor. Figure
15-9 shows the motor-activating part of an interface circuit for the Raspberry Pi to
control a LEGO motor. With this circuit, you can control two motors. This circuit
can also be used to control any sort of low-power DC motor.

Figure 15-9: A motor-activating interface.

The circuit consists of two interface circuits: the H-bridge and the NAND gate. In
fact, the 74HC00 contains four NAND gates, and the SN754410 contains two Hbridge circuits (or, to be more accurate, it contains four [or quad] half H-bridge
circuits). There are two supply voltages for this chip: One is for controlling the
logic signals, and the other is for driving the motor. The motor supply can be
anything up to 36V, but for a LEGO motor you should stick to between 9V and 12V.
The negative of the motor’s supply must be connected to the ground connection of
this circuit.
The enable lines of the two H-bridges are connected to the logic supply so that
they’re always on. You can apply the PWM to these lines, but then power control is
less effective because the motor will coast through the off parts of the cycle. If you
want, you can connect these enable lines to another Raspberry Pi pin to shut down
the motors altogether, but there isn’t much reason for this because the other pins
will allow you full control of the motor.
Each of the two control lines for the motor passes through an NAND gate, which
has the effect of “gating” the PWM signal. When the PWM signal is low, both
control lines to the H-bridge are high, so the motor is in the breaking mode
irrespective of what state either of the control lines is in. However, when one
control line is high, and the other is low, the rapid PWM signal is applied to the Hbridge control input corresponding to the high motor control, with the other Hbridge input being permanently high. This is exactly what you need for power

control, as well as directional control.
This circuit can drive the LEGO motors in the LEGO Technics and the LEGO
Power series, as well as the original MINDSTORMS motors. However, the NXT
and EV3 motors have another trick up their sleeves: built-in rotational feedback.
Note how the motor’s voltage is shown as 9V to 12V. The LEGO motor is capable
of being run at 12V. But even so, the H-bridge circuit can cut the applied voltage
down by as much as 3V, so even supplying the bridge with 12V, the motor gets only
a touch over 9V anyway. So, if you supply the drive circuit with 12V, it will act
like a very fresh battery; if you supply it with 9V, it will act like a partly
discharged battery.

Knowing where it is: Motor feedback
The built-in sensor is known as an quadrature incremental rotary encoder, and
produces pulses, as shown in Figure 15-10. These signals are 90 degrees out of
phase from each other. By looking at the relative positions of the edges, you can
determine the direction of rotation.

Figure 15-10: Rotary encoder outputs.

The sequence of levels you get from the sensor as it’s rotated is also shown in
Figure 15-10. Notice how, as the rotation proceeds, only one bit will change at a
time. This property in a code makes the code what is known as a Gray code, named
after its inventor, Frank Gray. To a certain extent, it’s self-correcting against
contact bounce by having some forbidden transitions. If you see one of these
transitions, you know it’s an error and it’s a simple matter to ignore in software.
To condition these signals into a form suitable for input to the Raspberry Pi’s GPIO

pins, a comparator or Schmitt trigger circuit is normally used. The LM339 has four
comparators in one package and also has an open collector output, which means it
can be simply pulled up to the 3V3 logic supply of the Raspberry Pi with a resistor.
The schematic of this buffer circuit is shown in Figure 15-11.

Figure 15-11: The motor sensor interface.

This circuit can handle the rotation outputs for two motors. Each output is

connected through a 10K resistor to the positive comparator input to provide some
protection against interference pickup. All the comparator’s negative inputs are
connected together and set to a voltage that is halfway between the two extremes of
the signal. The sensor circuit in the motor is powered by not 5V but 4.3V. We’re
sure it would work fine with 5V, but it’s easy enough to provide the correct voltage
by simply passing it through a diode. Any rectifying diode will do fine.

Constructing the motor control system
Building both aspects of the motor control system on one circuit board is best, so
we’ve have combined the two schematics (Figures 15-9 and 15-11). Here are the
parts you need:
Four 10K resistors (R1–R4)
Five 3K3 resistors (R5–R9)
One 4K7 resistor (R10)
Four 0.1uF ceramic capacitors (C1–C4)
A 1N4001 or similar rectifying diode (D1)
A 74HC00 quad two-input NAND gate (IC1)
An SN754410 quad half H-bridge (IC2)
An LM399 quad comparator (IC3)
Two RJ12 six-way sockets with offset latches (S1–S2)
Stripboard
Connecting wire
Two 14-pin DIL IC sockets (optional)
A 16-pin DIL IC socket (optional)
A 12-way screw terminal strip, 0.2-inch pitch
A 4-way screw terminal strip, 0.1-inch pitch
The last two items can be combined as a 16-way 0.2-inch screw terminal strip at
the expense of having a larger stripboard.
The only component you may have trouble getting ahold of is the RJ12 socket; you
can get them from the same supplier you get the RJ12 plugs from. You can dispense
with them altogether if you cut a cable in half and solder the wires directly onto the

stripboard. If you do get a socket, you have the problem of mounting it on the
stripboard. The trouble is that the socket is not on a 0.1-inch grid, so there is a bit
of work to mount it. Just follow these steps:
1. Drill two 2.5mm mounting holes for the fixing lugs four and a half holes
apart.
Drilling the half-space hole can be tricky.
2. Run two rows of three holes together by putting a small router bit in your
drill.
3. Remove the copper between the two slots with a scalpel.
4. Before you push the socket into the board, smear a small spot of Gorilla
Glue to the base of each socket in order to provide a good mechanical
joint.
5. Wrap thin wire around the protruding socket connectors.
The pin out of this socket as viewed from the underside is shown in Figure 159. A photograph of the slots we cut in the stripboard are shown in Figure 1512.

Figure 15-12: Stripboard preparation for mounting the RJ12 socket.

The wires connecting this board to the Raspberry Pi’s GPIO pins are connected on
our board through screw connectors. In order to fit them onto the board size we
chose, we used two sizes of screw connectors, but for economy you can eliminate

these altogether and solder wires directly to the stripboard.
A photograph of our board is shown in Figure 15-13. There is little point showing
the wiring because the stripboard isn’t used to make any connections — it’s all
wired up on the underside of the board.

Figure 15-13: The motor interface board.

Writing the software
Having built the interface board, you need some software to run it. This software
needs to have access to the GPIO pins. There are a few libraries to choose from,
but we chose WiringPi2 for Python. This is a port of Gordon Henderson’s C
library. It uses a syntax that will be familiar to any Arduino user. If you aren’t an
Arduino user, it takes just as much learning as any other library syntax.
So, the first thing to do is install it. From a command line, type the following:
sudo apt-get update
sudo apt-get install python-dev python-pip

When that has finished, type the following:
sudo pip install wiringpi2

That’s it. However, Linux now throws you a curveball in that you have to run as
root before it will allow you access to the GPIO pins. If you use IDLE to do your
Python development, you can run this as root. From the desktop, open a command
window and type the following:
gksudo idle

The IDLE package opens and you can use it as normal.
The non-real-time aspects of Linux makes controlling a motor not as precise as you
may like, but you can still do a lot. You can apply the same PWM signal to both
motors, which comes out on GPIO 18. The other signals can be connected to any
GPIO pin, but keep the serial port pins (GPIO 14 and 15) free for communicating
with the sensors. We connected the board as shown in Figure 15-14. The motors
can be driven by the Python software shown in Listing 15-1.

Figure 15-14: Connecting the motor drive to the Raspberry Pi.

Listing 15-1: Driving LEGO Motors
#!/usr/bin/env python
"""
Lego Motor Driver test 1 by Mike Cook June 2014
power (PWM) on GPIO 18 (12)
"""
import wiringpi2 as io
import time
mp = 18 # motor power pin (12)
a1 = 4 # motor A control 1 (7)
a2 = 17 # motor A control 2 (11)
b1 = 24 # motor B control 1 (18)
b2 = 22 # motor B control 2 (15)
ar1 = 7 # motor A rotational sensor 1 (26)
ar2 = 8 # motor A rotational sensor 2 (24)
br1 = 11 # motor B rotational sensor 1 (23)
br2 = 9 # motor B rotational sensor 2 (21)
motorControl = [(a1, a2), (b1,b2)]
print "Board Revision",io.piBoardRev()
print "If the program quits here start IDLE with 'gksudo idle' from the command line"
def main() :
pinInit() # define inputs and outputs
print "Python motor control test"

print "Ctrl C to quit"
while True:
allOff()
motor ="q"
motorToMove = 0
while not(motor == "A" or motor == "B") :
motor = raw_input("Motor to move A or B ")
motor = motor.upper()
if motor == "B" :
motorToMove = 1
turn = "s"
directionToMove = 0
while not(turn == "C" or turn == "A") :
turn = raw_input("Clock wise (c) or anti clock wise (a) ")
turn = turn.upper()
if turn == "A" :
directionToMove = 1
power = -1
while power < 0 or power > 100 :
power = input("Power 0 to 100 ")
pwm = 1024* (power / 100.0)
io.pwmWrite(18,int(pwm))
duration = -1
while duration < 0 :
duration = input("Time in seconds for motor to move ")
print "Turning on motor", motor, "for",duration,"seconds"
io.digitalWrite(motorControl[motorToMove][directionToMove],1)
time.sleep(duration)
io.digitalWrite(motorControl[motorToMove][directionToMove],0)
print "Turning off motor", motor
print
def allOff():
io.digitalWrite(a1,0)
io.digitalWrite(a2,0)
io.digitalWrite(b1,0)
io.digitalWrite(b2,0)
io.pwmWrite(mp,0) # motor off
def pinInit():
io.wiringPiSetupGpio()
io.pinMode(ar1,0) # input
io.pinMode(ar2,0) # input
io.pinMode(br1,0) # input
io.pinMode(br2,0) # input
io.pinMode(a1,1) # output
io.pinMode(a2,1) # output
io.pinMode(b1,1) # output
io.pinMode(b2,1) # output
io.pinMode(mp,2) # PWM mode
io.pwmWrite(mp,0) # off to begin with
if __name__ == '__main__':
main()

The code is reasonably straightforward. It starts by giving variable names to pin
numbers, which means you can change things around by simply changing one line
per pin. We’ve also defined the input pins here although they aren’t used in this
program. We do this so the pins are set in a known state for the hardware in case
they have been set to something else.

The pinInit function sets the library to use the GPIO numbering system to address
the pins and sets them up as inputs, outputs, and a PWM output. Next, the code
follows a series of user inputs to get the motor’s direction, the power, and the
length of time it should be on. Each one of these is in a while loop that won’t exit
until the user has made a valid choice. With the power input, a percentage value (0
to 100) is converted into the 0 to 1,024 value needed by the PWM signal. Note that
unlike some other systems, full PWM is achieved at a value of 1,024 and not 1,023.
What pins to write to for the motor control are defined in a tuple list called
motorControl. This is the clever part of the code. The motorToMove variable
picks the first or second tuple in the list, and the directionToMove variable picks
the first or second number in the tuple. So, the pin to set to high to get the correct
motor turning in the correct direction is returned by the following:
motorControl[motorToMove][directionToMove]

This makes the actual setting of the correct pin much simpler than any long-winded
collection of if statements.
We tested this with both our EV3 motors and NXT motors. Both would move at 13
percent power but no lower, which is to be expected. We noticed that, for a given
power, the EV3 motor moved faster and made more noise than the NXT motor.
The motor’s sensors can be read as well. We used a simple sketch to try this out, as
shown in Listing 15-2.

Listing 15-2: Reading the Motor’s Position Sensors
#!/usr/bin/env python
#!/usr/bin/env python
"""
Lego Motor Encoder input test
encoder 1 wired to GPIO 7 (pin 26) & 8 (pin 25)
encoder 2 wired to GPIO 11 (pin 23) & 9 (pin 21)
"""
import wiringpi2 as io
import time
motorId = ["A", "B"]
ar1 = 7 # motor A rotational sensor 1 (26)
ar2 = 8 # motor A rotational sensor 2 (24)
br1 = 11 # motor B rotational sensor 1 (23)
br2 = 9 # motor B rotational sensor 2 (21)
print "Board Revision",io.piBoardRev()
print "if the program quits here start IDLE with 'gksudo idle' from the command line"
io.wiringPiSetupGpio()
io.pinMode(ar1,0) # input
io.pinMode(ar2,0) # input
io.pinMode(br1,0) # input
io.pinMode(br2,0) # input
print "Hi from Python"

lastEncoder = [-1,-1]
count = [0,0]
upCode = 2
downCode = 1
while True:
port = [io.digitalRead(ar1)<<1 | io.digitalRead(ar2), @@ta io.digitalRead(br1)<<1 |
io.digitalRead(br2)]
for e in range (0,2) :
encoder = port[e]
if lastEncoder[e] != encoder and lastEncoder[e] == 0:
if encoder == upCode:
count[e] +=1
elif encoder == downCode :
count[e] -=1
print "Motor",motorId[e]," moved ",count[0], count[1]
lastEncoder[e] = encoder

This follows the same convention as before in defining the input pins. You can
move the motors by hand to make the encoders respond.
The endless loop combines the two sensors from each motor into a number that
ranges from 0 to 3, by using the shift operator (<<) and logical ORing it with the
other sensor using the bitwise OR operator (|) to get a two-bit number. This is put
into a list called port. Then the current value of the sensor number is compared to
the last one, and if the last one was 0, a count is incremented or decremented
depending on whether the current sensor number is 2 or 1. If the current sensor
number is 3, this indicates that a transition has been missed and you can’t be sure
what direction it has moved in, so you do nothing with the count. This is part of the
self-correcting nature of the Gray code. If the count has changed, then the new value
of both counts is printed out.
In Python, printing takes a comparatively long time, so if you can avoid printing,
you can cope with faster movement of the sensors.

Listening to Sensors
Communicating directly with LEGO sensors is not quite as easy as you may hope.
The EV3 sensors use two methods: one for the simple touch sensor and the other
for color, ultrasonic, Gyro, and IR sensors.

Touch sensors
The simplest sensor is the touch sensor. These are annoyingly different for the NXT
and EV3 kits. Basically, they both consist of a switch and 2K2 series resistor. In
the NXT version, the resistor is connected between pins 1 and 2 — sensor to
ground. In the EV3, the resistor is connected between pins 6 and 4 — sensor and
positive power rail. What’s annoying is that early NXT touch sensors didn’t have

pins 2 and 3 connected together, so they won’t work with the EV3 brick unless you
modify either the sensor or the cable to short these two wires. Figure 15-15 shows
how to wire up a LEGO touch sensor to the Raspberry Pi for both types of sensors.

Figure 15-15: Wiring up a touch sensor.

All you need to do to read the touch sensor is to set a GPIO pin as an input and
enable its pull-down resistor for an EV3 touch sensor, or enable the pull-up
resistor for an NXT touch sensor. Note that the I2C lines have strong external pullup resistors on the Raspberry Pi board, which will override any settings of the
internal resistors. These are pins GPIO 0 and 1 on issue 1 boards and GPIO 2 and
3 on issue 2 boards. The code needed for reading this sensor is shown in Listing
15-3, which is essentially a simple switch input.

Listing 15-3: Reading a Touch Sensor
#!/usr/bin/env python
"""
Lego touch sensor test
"""
import wiringpi2 as io
import time
EV3touch = 10
NXTtouch = 25
print "if the program quits here start IDLE with 'gksudo idle' from the command line"
io.wiringPiSetupGpio()
io.pinMode(EV3touch,0) # input
io.pinMode(NXTtouch,0) # input
io.pullUpDnControl(EV3touch,1) # pull down activated
io.pullUpDnControl(NXTtouch,2) # pull up activated
lastEV3state = -1
lastNXTstate = -1
print"Lego touch sensor reading"
while 1 :
EV3state = io.digitalRead(EV3touch)

NXTstate = io.digitalRead(NXTtouch)
if EV3state != lastEV3state :
print "EV3 sensor now at",EV3state
if NXTstate != lastNXTstate :
print "NXT sensor now at",NXTstate
lastEV3state = EV3state
lastNXTstate = NXTstate
time.sleep(0.4)

The code will only print out the state of a sensor when it changes, which prevents
lots of the same numbers from scrolling up the screen.

Advanced sensors
The advanced sensors that come with the EV3 kit are the color sensor, the IR
sensor, the EV3 Ultrasonic sensor, and the Gyro sensor. The last two are supplied
only in the Education Edition of the MINDSTORMS EV3 and not in the Home
Edition. Fortunately, you can buy the sensors separately and download the “blocks”
to use them with the Home EV3 software.

There is an NXT Ultrasonic sensor that will also work with the EV3
software, but they’re very different inside and what we’re about to show you
won’t work with the NXT sensors.
The four advanced EV3 sensors communicate with the EV3 brick by serial
communications using standard 5V logic levels. This is slightly odd because the
EV3 brick is a 3V3 device, so there are buffers in the brick to cut down the 5V
signal to a suitable level. However, there are no buffers that boost the 3V3 serial
signal from the brick to the sensor. That means the sensors can cope with this
voltage, so that simplifies things somewhat. The reason it works is because the
Raspberry Pi is also a 3V3 system, so following LEGO’s example, there is no need
to boost the transmit signal — you just have to cut down the 5V incoming signal.
There is quite a lot of complication involved in the protocol of the brick talking to
a sensor, but a lot of this is taken up by the LEGO brick auto-identifying a sensor
when it’s plugged in. This has to also accommodate the older NXT sensors, as
well as third-party sensors and sensors that haven’t even been thought of yet. If you
know what sensor you’re using, you can greatly simplify the software needed to
talk to the sensor.
The sensor sends out a list of information about itself, which identifies its type, the
modes it can operate in, the range of readings for each mode, and even the baud
rate it wants to communicate in. All this happens at the slow rate of 2,400 bauds.

When the brick has this information, it sends an acknowledgement and the sensor
then switches to its preferred baud rate. Then the sensor sends data back
continuously, with the brick sending an acknowledgement byte at least every 300
mS. If the brick fails to do this, the sensor reverts to the slow speed and starts
sending its identification data again. This little dance is summed up in Figure 1516.

Figure 15-16: The sensor initialization.

The sensor starts working in its default mode, which is Mode 0, the last one to have
its information sent to the brick. Any time the sensor is sending information, the
brick can command it to use another mode by sending it a command write message.
The sensor continues in this mode until commanded into another mode, or it resets
due to a power down or not receiving a NACK byte for 300 mS.
There is a further complication: The brick can tweak its own baud rate to match the
sensor’s, which can be required because the sensor has no accurate crystal clock.
Unfortunately, there is no way to do this on the Raspberry Pi because the baud rate
is governed by dividing the fundamental clock frequency of the processor, so there
is little point in describing that process, because there is nothing that can be done.

We found that the sensors we have work correctly with the Pi without any
adjustment, despite their baud rates being slightly off.
This information is sent back and forth in one of two ways: as a single byte or as a
data packet. When the information is a single byte, this byte has its top two bits as
zero, so they’re easily identifiable, whereas the start of packages have one or both
of these bits set.
A package consists of three parts: a message type, a payload, and a single-byte
check sum (see Figure 15-17).
Message type: The message type byte is complex and is split up into a number
of fields, as shown in Figure 15-18. The top two bits define the message type,
the next three define the payload length, and the last three define the action.
Note how the meaning of these last three bits changes depending on what sort of
message is being sent. When this is an info or data message, these bits are
simply the sensor’s current mode.
Payload: The payload length indicates how long the body of the message is
going to be. This is not a simple number like the mode number; instead, it’s an
encoded value with the values shown in the diagram. The other twist to this is
that an info message byte will be followed immediately by a command byte,
making these sorts of messages a byte longer than any other message.
Check sum: The check sum is calculated by performing an exclusive OR
operation with all the previous bytes and with the number 0xFF (or 255 in
decimal). When the data arrives, you can calculate the value of the check sum
and see if it matches the value that is sent. If it doesn’t match, you know there is
an error; if it does match, there is much less chance of there being an error. A
simple check sum like this is not foolproof; you can get two or more errors that
cancel out and give a false good. Other more complex check sum algorithms do
exist, but something simple like this is good enough most of the time.

Figure 15-17: The format of a message package.

Figure 15-18: The first byte in a message.

To talk to the sensor with a Raspberry Pi instead of the EV3 brick, you need to
understand this message structure and be able to replicate it. But first you have to
connect the sensor and Pi together. The circuit to do this is shown in Figure 15-19,
and it’s pretty straightforward. The GPIO pins brought out to the Raspberry Pi’s
connector include two whose alternative functions include a serial port; these two
pins are GPIO 14 and 15. The transmit pin (TX) can be connected directly to the
sensor’s receive pin, but the 5V output from the sensor needs to be cut down with a
potential divider to bring it into the 3V3 range.

Figure 15-19: The Raspberry Pi–LEGO sensor interface.

The parts list for this circuit follows:
One 300R resistor (R1)
One 1K resistor (R2)
One 0.5mH inductor (optional)
Two 0.1uF ceramic capacitors (C1, C2)
Stripboard, 1 x 2 inches
LEGO connector socket
Four-way 0.2-inch pitch screw connector

If you’re eagle-eyed, you may say, “That 300R resistor is too low. It
should be 510R to get 5V down to 3V3.” And you would be right, if not for
one hidden fact: The sensor itself includes a 220R resistor in series with this
line already, so you only need to add another 300R to give, in effect, a 520R
resistor for the top of the potential divider. So, this circuit is suitable only for
LEGO sensors, not general-purpose 5V serial inputs.
The only other thing that may surprise you about this circuit is the inductor in the
power line. In fact, you can do without it, but the Raspberry Pi will reset every
time you plug a sensor in. This is because the sudden inrush of current to the sensor

causes the 5V line on the Raspberry Pi to dip to a point where the reset is
triggered. What the inductor does is limit the sudden inrush and prevent a reset. The
actual value isn’t critical, and it can be absolutely any value above that shown in
the diagram. A series diode also does the trick of preventing reset, but it reduces
the voltage going to the sensor and messes up the readings from the color sensor.
Replace the inductor with a piece of wire if you don’t mind the reset. We built this
up on a small piece of stripboard, as shown in Figure 15-20.

Figure 15-20: The built Raspberry Pi–LEGO sensor interface.

If you’re wondering where capacitors C1 and C2 are, they’re surface mount
capacitors mounted on the underside, but you can use a leaded capacitor if you
prefer.

The Raspberry Pi software
In order to successfully use a sensor directly with the Raspberry Pi, you have to
write a program to handle the initialization protocol. This mainly involves writing
a function that will read the serial port and split up what comes out into individual
messages. To start off, let’s look at how to read and display the identification

information coming from the sensor and display it.
The Raspberry Pi’s serial port is used during the boot-up process. So, to prevent
the sensor from interfering with the boot up, you must disable getty. Here’s how:
1. Use the File Manager to navigate to the directory /etc/.
2. Choose Tools⇒Open Current Folder as Root.
A new window appears.
3. Right-click the file inittab and choose Open with Leafpad.
4. Now find the line that says the following, and comment it out by putting a #
in front of it:
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

5. Save the file.
6. To stop the Raspberry Pi from sending out data to the port, with the root
view in the File Manager go to the /boot/ directory and open the
cmdline.txt file.
7. Find the line that says the following and delete it:
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

8. Save the file and reboot the Pi.
9. If you don’t have the Python serial module, install it from a command-line
window by typing the following:
sudo apt-get install python-serial

Now you’re all set to go. You can type in the code shown in Listing 15-4, which
will basically monitor the serial port until the sensor has finished sending all its
data and then send a byte command to trigger the sensor into its high-speed mode.
Then it will write to the sensor the required operating mode and milk the data by
sending a NACK command every 230 mS and display the data package sent after
that.

Listing 15-4: Reading a Serial EV3 Sensor
#!/usr/bin/env python
# Serial sensor by Mike Cook June 2014
# Raspberry Pi serial sensor tested with the EV3 color sensor and IR sensor
# It should also work with the EV Ultrasonic sensor (not the NXT one) and the EV3 Gyro
import time
import serial

SYNC = 0x00 # Synchronization byte
ACK = 0x04 # Acknowledge byte
NACK = 0x02 # Not acknowledge byte
payloadLookup = [1, 2, 4, 8, 16, 32, 0, 0]
messageLength = 0
# to fit max message plus command and checksum
message = [ n for n in range(0,34) ]
refreshTime = 0.230 # Rate to read data must be less than 300 mS
checkSumError = False
ser = serial.Serial('/dev/ttyAMA0', 2400, timeout =2 )
def main() :
print "Sensor read"
setup()
mode = 0 # sensor mode to use
changeMode(mode)
print "running in sensor mode",mode
lastRefresh = time.time()
while True :
if time.time() - lastRefresh > refreshTime : # send NACK and look at data
ser.write(chr(NACK))
lastRefresh = time.time()
ser.flushInput() # remove old data
getMessage() # get the data
if not checkSumError :
printMessage() # view data message
def setup():
global ser
print "initializing the sensor"
while not(message[0] == 0x90 and message[1] == 0x80 and @@ta
checkSumError == False) :
getMessage()
if ord(ser.read(1)) != ACK :
print("not got an ACK");
ser.write(chr(ACK)) # tell the sensor to go
time.sleep(0.006) # give it time to finish sending the ACK
ser.close()
ser = serial.Serial('/dev/ttyAMA0', 57600, timeout =2 )
def getMessage() : # parse input stream into message
global checkSumError, messageLength
checkSum = 0xff
command = ord(ser.read(1))
if command == 0x00 or command == 0xff : # color sensor sometimes @@ta
throws these
return
message[0] = command
if (command & 0xC0) == 0 : # single byte
pass
else : # multibyte message
checkSum ^= command;
payloadLength = payloadLookup[(command >> 3) & 7] # number bytes @@ta
in message
if(command & 0xC0) == 0x80 :
payloadLength += 1 # info message has command byte following
for n in range(1, payloadLength + 1) : # read in the message up to the check sum
message[n] = ord(ser.read(1))
checkSum ^= message[n]
# get check sum
message[payloadLength + 1] = ord(ser.read(1))

messageLength = payloadLength + 1
if message[payloadLength + 1] != checkSum :
checkSumError = True # check sum error
else :
checkSumError = False # check sum fine
def printMessage() : # not the check sum
for n in range(0,messageLength) :
print hex(message[n]),
print
def changeMode(newMode):
if newMode <= 5 and newMode >= 0 :
sendMessage(0x44, 0x11) # command write
for n in range(0,3) :
sendMessage(0x43, newMode & 0x7) # command mode
ser.write(chr(NACK));
def sendMessage(cmd, data):
cSum = 0xff ^ cmd ^ data;
ser.write(chr(cmd))
ser.write(chr(data))
ser.write(chr(cSum))
if __name__ == '__main__':
main()

The main function starts off by calling the setup function, which reads what the
sensor is sending until the final message in the sequence. This is always the data
format of the sensor’s mode zero. Then the sensor should send an ACK byte to say
it’s ready to switch into sending the data. At this point, you have 80 mS to reply
with an ACK byte or the sensor will start sending its data again. The setup
function sends this and then sleeps for a short time to allow the byte to be sent.
Then the serial port is closed and opened again using the faster speed before
returning. Then the main function writes to the sensor the mode you want to operate
it in. By default, this is mode 0, but if you want to change it, the code is provided to
do so. Changing the mode is simply done by sending three bytes — the command,
mode number, and check sum. We noticed that the LEGO brick sometimes sends
this message a few times, so this code sends it three times, followed by a NACK
byte. This is done in the functions changeMode and sendMessage. Notice that this
last function also generates the check sum by using ^ the exclusive OR operator.
The while loop runs forever. Here, the system timer is used so that once every 230
mS (to give Linux a bit of slack when it steals time from you) the Raspberry Pi
keeps the sensor alive by giving a NACK byte, flushing the serial buffer, and
reading and printing out the next data message sent. This is done because the sensor
sends data continuously and not every NACK, so the buffer will have old data in it.
If you want to do something with data coming faster, you can simply read the
message as often as you need to.
The heart of the program is the getMessage function. This reads data a byte at a

time from the serial port and analyzes it to see how many bytes are in the message.
Then it goes on to read those bytes and calculate and verify the check sum. This
keeps the input data stream in sync. The result is a sequence of data messages like
this:
0xc0 0x48
0xc0 0x4a
0xc0 0x4c

This is for an IR sensor running in mode 0 proximity and represents the distance to
an object in front of it. Most of the time, the data is in the second byte, but in the
case of reading the numbers from the IR remote, there are four bytes; the one
populated with the key number depends on the channel the remote is set to. We
didn’t get much joy from the angle measurement seek mode, however, because the
data returned seemed inconsistent.
It isn’t possible to print out the information messages as you go because printing in
Python takes a long time and you lose the synchronization between the data coming
in and the need to respond to it. We wrote a much longer program that will print out
and decode all the messages the sensor sends and then, in effect, does what this
program does. You can find that program along with a text file of its output from the
IR sensor on www.dummies.com/go/raspberrypiprojects.

A commercial alternative
The best way to control the LEGO components is not with a Raspberry Pi but with some other realtime microcontroller like the Arduino. The people at Dexter Industries have taken what’s, in effect, two
Arduino processors on one board and produced a controller specifically designed to run with the
Raspberry Pi. It’s called BrickPi.
The BrickPi fits completely over the top of the Raspberry Pi board and even includes a top and
bottom plate with holes so that it can be fitted into a LEGO model. As of this writing, it can only talk to
NXT sensors, but beta software containing EV3 capability has been released. It has example code for
Java, Ruby, C, Python, Scratch, and BlockyTalky along with a support forum.
We had some slight difficulty installing the system on our Pi, but we were given prompt and helpful
support from the administrators. If you’re shy about using the soldering iron, we highly recommend
the BrickPi as an alternative to the normal brick programming environment. Sadly the motor
movement is not very accurate with the current software. Check the forum pages for the latest
updates: www.dexterindustries.com/forum/?forum=brickpi.

Part V

Exploring RISC OS

Find out about the Lorenz attractor in RISC OS in an article at
www.dummies.com/extras/raspberypiprojects.

In this part …
Discover a great alternative to Linux.
Write programs in the structured BBC BASIC.
Make your own desktop applications with ease.
Access the general-purpose input/output (GPIO) from within RISC OS.
Build a transistor tester.
Build your own accurate digital voltmeter (DVM).

Chapter 16

Introducing RISC OS
In This Chapter
Getting RISC OS up and running on your Raspberry Pi
Finding your way around the desktop
Getting RISC OS online
Discovering the amazing preloaded applications that come with RISC OS
One of the great things about the Raspberry Pi is that it’s so easy to change the
operating system: Just change the SD card! Several different operating systems are
available, but most of them are just another flavor of Linux. However, RISC OS is
unique, forged in the depths of time from almost the start of personal computing in
the 1980s and developed into the most advanced operating system of the 1990s.
Many of the things you take for granted on a Linux, Windows, or Macintosh desktop
first appeared in RISC OS and inspired the two personal computing giants. So, take
a step back into the past and the future and explore the operating system made by
the inventors of the ARM chip. And be prepared for a blisteringly fast Raspberry
Pi!

Toto, we’re not in Kansas anymore
Once upon a time, Mary Goldring, a British journalist, asked the head of Acorn Computers, "So, do
you make the chips in the computer?"
"No", came the reply, "we only put them together."
That was one of those unsung moments when the world shifted on its axis without anybody noticing.
It very possibly sparked the invention of the ARM chip, the most widely used processor on the planet.
A very small group of people got the go-ahead to design an experimental microprocessor, one that
ran using much simpler but smarter instruction. The machine code instructions used in hundreds of
programs were analyzed to find out what programmers actually needed as opposed to what the chip
designers gave them. Then a simpler and faster processor architecture was designed. It was sent off
to the fabrication plant and almost forgotten as a financial crisis overwhelmed Acorn and threatened
its existence.
When the chip arrived back, it sat unopened in its packaging for a few days while the demoralized
engineers wondered if they would even get paid at the end of the week. Eventually, the chip was
opened and tested and, miraculously, found to work, with only one minor change. This was totally
unheard of! The first iteration of a new processor working? This chip was the first ARM chip, which
initially stood for “Acorn RISC Machine” (where RISC stood for “Reduced Instruction Set Computer”).

Although the hardware engineers made a few refinements to the chip, the software people looked at
licensing a graphics-based operating system. The cheapest came with a fee larger than their
telephone number, so someone said, "We could write one in a week," and a week later the first
version was running. It was called Arthur.
Eventually, this grew into RISC OS. The latest version is available for download for free onto an SD
card to run on the Raspberry Pi.
The RISC OS desktop, shown here, uses the now familiar desktop or wimp system (short for
windows, icons, menus, and pointers) along with the Acorn innervations of an icon bar showing
running programs and context-sensitive drop-down menus.

Knowing What Makes RISC OS Unique
The biggest difference between Linux and RISC OS is under the hood. Linux is a
preemptive multitasking system, whereas RISC OS is a cooperative multitasking
system.
When the Linux operating system decides what bit of code, or thread, is going to
run, it also determines how long that code will run for. It doesn’t matter if that code
isn’t quite in a state to pause. The rug is pulled out from underneath it, and control
is passed back to Linux. The code has no control over this, nor does the
programmer. There are things you can do about allocating thread priorities, but at
the end of the day, the rug will be pulled.
RISC OS, on the other hand, has a cooperative approach. Control is passed over to
the next thread, or program, in the list of tasks, and this thread continues to run until
the code tells the operating system it’s ready to be swapped out and the next task

can be run. From our perspective, this is a much more civilized way of going about
things and gives the programmer the choice over how much time to use before
letting other tasks have a turn. So, if you want or need all the processing power,
you can have it, which makes the operating system much more responsive.
Although the preemptive nature of Linux is fine in a multiuser system, in a singleuser system like so many Raspberry Pis run in, it’s just a bit too “Big Brother” for
our liking. Debates run very passionately about this point, and a lot depends on
whether you like the protection given by preemptive multitasking or you think it’s
treating you like a child who needs supervision.

Preparing for Action: Getting RISC OS
The simplest way of getting RISC OS is to buy it on an SD card. You can get it
from www.riscosopen.org/content/sales along with some other RISC OS
goodies.
However, if you have a spare SD card, making your own is simple: First,
download the latest RISC OS image at www.raspberrypi.org/downloads.
Unlike the gigantic Linux distributions, RISC OS weighs in at a very trim 113MB
(zipped). Unzipped, it inflates to 2GB. Next, you have to get it onto an SD card.
You can use any size SD card you like as long as it’s at least 2GB. Note however,
that anything over 2GB is no advantage because this is the maximum you can use.
This might sound like a restriction, but 2GB is almost infinite in the world of RISC
OS.
Installing RISC OS is the same as installing any other operating system on the
Raspberry Pi. There are lots of methods — the one that’s best for you depends on
the computer you have available. Your best bet is to go to
www.elinux.org/RPi_Easy_SD_Card_Setup and choose the option that suits you.
Alternatively, www.pilearn.com/Pages/Page1001.html gives you a step-bystep guide for using the Mac to set up an SD card, with links to information for a
PC. (A word of warning: On that page, you find instructions for using a Raspberry
Pi for making a card, but we haven’t been able to get those instructions to work.)
If you need to set the over scan parameters in the config.txt file to make the
desktop fit your TV, use the same number for the left over scan as you do for the
right over scan. Similarly use the same number for the top over scan as you do for
the bottom over scan. Version 12a (the latest one as of this writing) has a small bug
that gives you an offset mouse pointer if you use asymmetric stretches side to side

or up and down.

The mouse
The mouse is somewhat unusual. It has three buttons:
Left (select) button: The select button is used for the normal operation of
dragging and double-clicking to run or open a file like all the other operating
systems.
Right (adjust) button: The adjust button normally performs some sort of
variation on the select button operations. For example, dragging a window with
the adjust button doesn’t bring it to the front; you can drag a window behind
another one with the adjust button. With the adjust button, you can select
several files at once. Clicking the adjust button adds an icon to the group
selected. It also deselects selected files without deselecting all of them.
Middle (menu) button: The menu button brings up a drop-down menu. The
menu that’s brought up is dependent on where the pointer is when the middle
button is clicked; it’s known as context sensitive. The middle button is the
biggest hurdle for a newcomer to get over; other operating systems don’t
reinforce the menu button mindset so beginners can trip up over this. When in
doubt, try the menu button.

RISC OS is best used with a mouse equipped with a center scroll knob that
doubles as a button. If you don’t have this kind of mouse, there is a program
you can install that simulates the middle mouse button when you press the
Windows key on the keyboard. It’s in the Utilities folder and is called
!WinMenu.

The keyboard
A wide variety of keyboards can be used with the Raspberry Pi, and not all of them
are the standard PC type. When you first power up RISC OS, the system is set for
the default British keyboard, which isn’t too dissimilar from the U.S. keyboard —
the only real difference is that Shift+3 gives you £ instead of #. (You can change
this later if you want.)
It’s best if your keyboard has a row of function keys from F1 to F12. These are
used a lot more on RISC OS than on other systems. Many keyboards don’t have that

many function keys, but the keys F12 and F10 are important in RISC OS. F10 is the
break key. F12 is involved in a lot of tasks: By itself, pressing F12 takes you into
the command-line mode; Pressing Ctrl+F12 brings up a task window; and pressing
Ctrl+Shift+F12 shuts down the system (although you can do this from the desktop if
you prefer).

The network
The network connection used to be disabled by default, but on the latest release
(which as of this writing was version 12a), the network connection is enabled. It
requires a network to be connected into the Ethernet socket; unfortunately, there is
no support for a wireless interface (as of this writing).
The network connection is described as “Ethernet over USB,” but it’s actually the
Ethernet socket. In our setup, we connected the Ethernet port to a Mac laptop. Then
we opened System Preferences, clicked Sharing, and enabled Internet Sharing to
share our Wi-Fi connection with our Thunderbolt Ethernet. This will also work on
non-Thunderbolt-enabled systems. You can do the same sort of thing with a PC or
have a direct cable connection to your router if you prefer.

All Systems Go: Starting Up RISC OS
Insert the RISC OS SD card into your Raspberry Pi and power up the Pi. Unlike
with Linux, you’ll be at the desktop in about 15 seconds — be prepared for that
kind of speed up! The first time only, you get a progress bar as the fonts are
scanned, and then a web browser window from NetSurf pops up with a “Welcome
to RISC OS” page held in an internal file.
Now just look at the window. Along the bottom runs what is called the icon bar, a
familiar thing on desktops (but remember that RISC OS had them first!). On the left
are icons concerned with storage; on the right are icons indicating which programs
are running. At startup, there are just two icons, and those are always there: One is
an icon of a monitor and is used to set the monitor resolution; the other is a
raspberry (in the old days, it was an acorn), which is used to control the system. A
left click brings up a task window showing how much memory is allocated to each
task. You can drag the red bars and change the allocated memory.
Scroll to the bottom of the window. The sixth line from the bottom says “RAM
disc.” Click and drag out a red bar to something like 400K. As you release the
mouse button, a new icon appears on the left side saying “RAM.” This is a

temporary fast storage area that uses some of the system’s memory to look like a
mass storage device. Anything put in it will disappear when the Pi is switched off,
but it saves wear and tear on the SD memory (and in the old days was much faster
than a floppy disk).
If you click the raspberry with the center button, a menu appears. One of the
choices is to shut down. This is what you do before turning off the power. In sharp
contrast to Linux, it’s almost instantaneous. You see a window inviting you to
restart, but you can just turn off the power knowing that all the files have been
closed correctly.

Taking a look around
Click the Apps icon on the left of the icon bar. A window with some very basic
applications in it appears. Double-click !SciCalc, and the icon of a calculator
appear on the right side of the icon bar. Left-click that icon to see the calculator.
On the top right of the calculator frame, you see a square. Click that square to see
the calculator’s other functions.
The anatomy of a window is shown in Figure 16-1. It has the close icon as a cross,
as you may expect. However, there are some other things that you may not expect.
For example, there is an Iconise button, which will turn the whole window into a
small icon you can drag around the desktop, useful for quickly clearing some space
on the desktop. You also have a Back button. Unlike most other operating systems
(in which anywhere you click a window, it comes bounding up to the front like an
overeager puppy), a RISC OS window only comes to the front when you click its
title bar. The Back button puts it firmly in its place.

Figure 16-1: The Calculator window and its parts.

Try clicking the Back button and then drag the window by its title bar but hold
down the right mouse button. The window gets dragged as you would expect, but
when you encounter another window, it’s dragged behind that. It looks odd if you
aren’t used to it.
Now move your mouse over the calculator window and press the middle mouse
button. You see a drop-down menu. Move to the bottom entry, Help, and left-click.
A document window appears, telling you all about the workings of the calculator.
You can explore other options in this menu as well. For example, the View option
allows you to toggle between the compact and expanded view of the calculator; the
Edit option allows you to copy the calculator’s results to the clipboard.
Point at the calculator icon on the bottom icon bar and click the middle mouse
button again. This time a menu pops up, and the top entry is Info. This is consistent
in all applications; Info tells you a bit about the program. (You can also access the
Help here exactly as you could with the application window menu.)
The Choices entry brings up another window (shown in Figure 16-2). The choices
are self-explanatory, but look at the icon to the right of where it says Base Decimal.
This is a drop-down list icon. Click it for a list of available number bases. Note
that there are radio buttons for choosing from a number of options and check boxes
for selecting many options.

Figure 16-2: Calculator options.

Double-click the !Help icon in the Apps window. Now every time you hover your
pointer over some aspect of the window, a pop-up contextual help message
appears. This is very useful when you’re first learning RISC OS. You’ll know
when you’ve learned the basics because this pop-up help message becomes really
annoying.
This is the basic way of interacting with a RISC OS application. You may get a bit
muddled at first because you’re used to another OS, but it quickly becomes second
nature.

Making your own space
In this section, you create some folders of your own. This will illustrate the unique
way RISC OS has of handling saving.
At the bottom left of the icon bar, you see the icon of an SD card. This is the SD
card from which you’re running RISC OS. Left-click the icon and you see the basic
root window of the filing system. Its path name is displayed as the window’s title:
SDFS::RISCOSpi.$. SDFS stands for “SD card filing system”; RISCOSpi is the
name of the SD card; $ is the top level. Note the double colons (::) separate the
filing system type from the name of the volume it’s currently using. The dot (.) is
used to separate folders.

Unlike in Linux, there is no root user, super user, or any other form of user — there
is just you. If you double-click the Apps folder, you open the same window you did
when you clicked Apps in the icon bar. In fact, they’re one and the same thing,
except the one from the icon bar is protected (you can’t add or delete anything from
it). The Apps folder you opened from the root window has the path name in the
window’s title.
It’s time to make some space for your own work. Middle-click the root window
and scroll down to New Directory. Move to the right and in the text box, type the
name of your new directory folder. We used the name Mike, but you probably want
to pick something a bit more personal. When you’ve finished, press Return or click
OK, and that directory will appear in the root window. Double-click it to open
your blank window and keep it open while you work through the next section.

Saving and loading by dragging and dropping
Saving and loading files are the operations that may be most different from all the
other computer desktops that came after RISC OS. Most computers use a mini filing
system list to identify files. Some systems allow you to load a file by dragging its
icon onto the application icon, but RISC OS takes this a whole step further.
Follow these steps for saving a file:
1. In the Apps window, double-click !Edit.
The !Edit icon appears on the icon bar.
2. Left-click the !Edit icon.
A blank text window pops up.
3. Click inside the window.
You see the red “focus” cursor.
4. Type a few words.
The title bar will say  *. The asterisk informs you that the file’s
contents have not been saved. You’re now going to save the file in your own
folder that you created in the preceding section.
5. Click the menu button and choose Save or press F3.
A window appears like the one you saw when you created your folder, except
this window has a default name already in it.

6. Press the backspace key until you clear the default name and type
Text_test but do not press the Return key.
7. Drag the text file icon above the name Text_test and drop the icon into
your folder.
A text icon appears and your text window has the file’s path name in it.
8. Type a few more characters.
You see the asterisk (*) in the title bar again, indicating you have unsaved data.
Updating your file now is very easy.
9. Click the menu button, choose Save, and click OK.
The filename has the full path name of the file in it, without an asterisk.

If you want to create a new file with the updates you’ve made, just add
characters to the filename. If you want to save the file somewhere else, simply
drag and drop the icon in the save box into the folder you want to keep it in.
These actions are summarized in Figure 16-3.

Figure 16-3: Saving a file.

Here’s a unique trick: Type in and save another text file. Then drag that
file’s icon into the text window of the first file. Bingo! The contents of the
new file are added to the old file! You can imagine how easy this makes
adding standard paragraphs to things you type. Many applications work like
this — merging data directly into a file you’re working on by drag and drop.

Some applications do this with images or other types of data. Of course, the
addition has to make sense — for example, dragging a JPG image into a text
file won’t work (well, other than dumping the bytes of that file and looking at
it as a text file, which you might want to do).

Focusing on file types
Most operating systems identify the type of file by an explicit extension to the
filename. Typically, a text file would have the extension .txt. In RISC OS, things
are slightly different. Here’s how:
Each file has a type, but the file type is hidden inside the file.
The file type determines what sort of icon is shown for the file.
The file type is a three-digit hexadecimal number, but many file types are
enumerated — that is, they have an associated word with the file type.

What the !
In RISC OS, you see many icons whose names begin with an exclamation point (pronounced pling).
These are applications or programs you can run with a simple double-click. However, like most
superheroes, they have a secret identity: They’re just folders. In your folder, click the menu button and
create a folder called noApp. It appears with the normal folder icon. Now menu-click the folder and
choose Dir. “noApp”⇒Rename and press the backspace key to put an exclamation point (!) at the
start of the name. The icon changes to the default application icon. If you double-click it, you get —
not surprisingly — an error box saying it has failed to find a file called !Run.
So, how do you reveal an application’s secret identity as a folder? Simply hold down the Shift key
while you double-click the icon, and it opens like a folder. You can do this to see inside !Edit or
!SciCalc. This tip makes it easy to build your own desktop clickable applications by gathering together
all the files you need under one folder.
Hold down the Shift key and double-click your noApp icon, and the empty folder opens. Now use the
text editor to type This file is no help and save the file in the open folder under the name !Help. Now
close the folder and close the folder containing the noApp application. Open the folder containing the
noApp application again, menu-click it, go to the second item (App “!noApp”) and then choose Help.
Your unhelpful Help file will be shown.
Simple, understandable structures like this make RISC OS refreshing. Other operating systems
require you to have access to special tools to do things like this. But not RISC OS!

If you menu-click the Text_test file you created in the preceding section, and
move your pointer onto File “Text_test” and then move it down to Set Type and
then move it along to the text box, you see the file type shown as “Text.” Press the
backspace key here and type the word BASIC and press Return. Immediately, you
see the icon change. It’s the same file, but now the computer treats it differently if

you click it. Don’t click it now; instead, go back and set the file type to FFF, and
it’s a text icon again. The file type Text is represented by FFF; you can type either
to set the file type.
You can reload the file into an edit window by dragging it onto the !Edit icon or by
double-clicking it.

Handling Graphics with !Paint and
!Draw
Two of the staples of any computer system, !Paint and !Draw have been in the
RISC OS since the beginning. !Paint handles bitmap graphics; !Draw handles
vector graphics. Although they may seem a bit clunky by today’s standards, they
have the great advantage of being understood formats by most RISC OS
applications. In fact, !Paint plays a vital part in the whole construction of the
desktop world.

!Paint
A !Paint file is called a sprite file, and it can hold one or several images or sprites.
The most common use for sprites is making desktop icons. There are a number of
different types of sprites, mainly differentiated by the number of colors they
contain. The majority of desktop icons have only 16 colors, reflecting their early
origins, but you can have sprites with 2, 4, 16, 256, 32,000, and 16 million colors.
The color selection window changes to reflect the color choice. The higher color
depths are suitable for photographs, although a passable photograph can be
rendered in 256 colors.
The drawing tools are as you would expect: single pixels (pencil), spray can,
brushstrokes, camera (copy block), scissors (move block), hand (shift whole
sprite), as well as a selection of solid and line shapes. One thing you may not find
in other packages is the way the colors are applied — they can be simply set, or
they can be the result of a logic operation between the working color and the color
already in the background.
As a quick example, follow these steps:
1. Double-click the !Paint icon in the Resources apps window.
The !Paint icon appears on the icon bar.

2. Open the Diversions folder.
3. Hold down the Shift key and double-click the !Patience icon.
4. Drag the !Sprites22 file onto the !Paint icon in the icon bar.
You see a window with two sprites: a large sprite and a small sprite. The
larger one is only 34 pixels square, and the smaller one is 18 pixels square.
5. Double-click the larger sprite.
You see a colors palette and the sprite along with the paint tools.
6. Menu-click this sprite and select the zoom option. Repeatedly click the up
arrow next to the first box to get an enlarged view.
These windows are shown in Figure 16-4.

Figure 16-4: The !Patience sprite icon.

Create your own sprite by left-clicking the !Paint icon on the icon bar. The
Create New Sprite window appears with an invitation to set the parameters,
including the size. The window defaults to a sprite the size of the whole
screen, but you can use the arrows or type directly in the boxes to get any size
you want. The sprite shown in Figure 16-5 is a high-resolution sprite we made
to show the effects of various logic operations on filled circles. Notice how
the color selection is controlled by three sliders. It has the option of control
by RGB (that is additive color — red, green, and blue). It can also use the
subtractive color model of CMYK (cyan, magenta, yellow, and black) or the
HSV (hue, saturation, and value) color space.

Figure 16-5: A high color resolution sprite.

!Draw
Whereas !Paint uses individual pixels, !Draw is a vector drawing tool. Here a
drawing is made up of lines, and all that’s stored are the parameters of those lines.
This makes !Draw files very small compared with the larger bitmaps. !Draw files
are very good with splines (curves), allowing you to enter a spline by clicking and

dragging. Then you can edit the control points of the curve by first selecting the
curve with a right-click to show all the control points. Then you can drag the
control points around again with the right (adjust) mouse button.
Producing a good vector drawing takes some skill, but one of !Draw’s major uses
is collating sprite, text, and line drawings. To add a text file or sprite image,
simply drag the icon into the drawing or save the object by dragging the save box
into the !Draw window. They can then be manipulated and composed.

There are some comprehensive online tutorials on these packages. For how
to use the basic tools in !Draw, check out
www.riscos.com/support/users/userguide6/draw/chap02.htm. For
some interesting ways to design patterns, look at
http://homepages.nildram.co.uk/~riscos/tutorial/pattern_tut.
And for a rundown of the tools you get in !Paint, check out
www.riscos.com/support/users/userguide6/paint/chap02.htm.

Connecting to the Outside World
If your network is not configured, double-click the !Configure icon on the desktop.
A folder with lots of applications in it opens. You should notice something strange:
These applications don’t start with an exclamation point — they’re presented
differently.
To configure your network connection, follow these steps:
1. Single-click the Network icon.
The Network Configuration window appears.
2. Click the Internet icon.
The Internet Configuration window appears.
3. Click the Enable TCP box and then click the Interfaces icon.
The Interfaces window appears.
4. Click the Ethernet over USB check box and then click the Configure
button next to it.
The USB 0:Ethernet over USB window appears.

5. Click the Via DHCP radio button and click Set.
6. Click Save in the Network Configuration window and agree to the restart
request.
If you couldn’t before, you should now be able to browse the web using
!NetSurf.
When we tested this out, an entire web page loaded in about 5 seconds, whereas
the best that Midori could do under Linux, loading the same page, was 15 seconds.
When you’re online, there are a number of interesting things you can download.
!Store is already installed on the desktop; it takes you to a source of applications,
both paid for and free. There are a number of utilities and games worth looking at.
Open the application details window and click an application for a description of
it. Some names used can be quite cryptic or require a knowledge of RISC OS
history in order for it to make sense. For example, Hatari is an Atari emulator,
whereas Rise of the Triad is a first person shoot-’em-up game, a bit like Doom.
For Rise of the Tria, you need !UnixHome to be run first; you can find it at
www.riscos.info/packages/SupportDetails.html.

When you download something, make sure that you have a window open
where you want to store the application so you can drag it in.
Most online software comes in a compressed format. The format of choice is
called Spark. Double-clicking the file opens the archive just like a normal window.
You can run many applications directly from this compressed archive window.
However, if the application needs to write anything back to the application’s
folder, this will fail, so it’s best to drag the icons you need out of the archive into
your own folder before you run them.

Identifying the Resources That Are
Already Installed
Many resources come already installed on the SD image, many of which would’ve
cost you quite a bit of money when RISC OS was in its heyday. The highlight of
these resources is the Programmers Reference Manual (PRM), in the
Documents.Books folder. This five-volume set cost more than a hundred bucks in

the ’90s, but here you get them as a set of PDFs for free. The books cover all the
operating system calls for all sections of the machine; they aren’t exactly light
reading, but they do contain all sorts of vital information. (Although you can get
PDF readers for the Raspberry Pi, you may want to transfer the PDFs to your
computer because there you’ll be able to search the PDFs much more efficiently.)

Many authors have released their work under Creative Commons licenses.
We recommend you look at PipeDream, a fully integrated office suite of word
processor, database, spreadsheet, and charting package all in the same
window. The application itself is in the Apps folder, and a full set of tutorials
is in the Documents folder.
Check out the high-quality vector graphics examples in the Documents.Images
folder and the games in the Diversions folder. These aren’t the most exciting
things you’ll ever see, but the Tetris clone !Blocks is as addictive as it ever was,
and !Meteors was retro when the OS was new. Perhaps the oddest diversion is
!Madness — it slowly nudges all the open windows around the screen and is meant
as a demonstration of interapplication messaging. (Just make sure you read the
Help file to find out how to stop it before running.) Finally, we have to mention
!SignalBox, a graphically spectacular simulation of the Exeter West train station,
shown in Figure 16-6.

Figure 16-6: !Signal Box, a graphical simulation.

The Utilities folder contains !ChangeFSI, which is a great way to convert

images between JPG and sprite formats. However, it isn’t just limited to JPGs — it
also handles a wide variety of input graphics file formats (see the Formats file,
located inside the application, inside the Documents folder). The application is
also capable of a number of image processing functions like histogram
equalization, gamma correction, and sharpening.

Shift+click to open an application.

The FSI part of the name !ChangeFSI comes from the Floyd-Stenberg
method of dithering, a way of showing high-resolution images on a lowerresolution screen by using an error diffusion technique.
There are many other delights to explore in the RISC OS distribution. You may not
understand them all — we don’t ourselves — but over time you can get to know
them. People who explore all that RISC OS has to offer tend to grow to love this
operating system.

Chapter 17

RISC OS Coding
In This Chapter
Finding out about BBC BASIC
Seeing how to code in a desktop environment
Experiencing the awesome speed of BASIC
Generating 17th-century insults from the desktop
Shattering desktop illusions
Putting images through a kaleidoscopic ringer
A RISC OS system is easy to program. Not only can you run simple programs, but
you can also build complete desktop applications without too much bother. Unlike
Linux, the operating system is almost static — it doesn’t change very often and
code you write tends to have a remarkable shelf life. This is because most of the
changes in the operating system maintain an unprecedented degree of backward
compatibility.
In this chapter, we show you how to go about writing code, starting off with the
simple “Hello world!” program. Then we move on to a desktop insulting machine
and graphics modes, and end up mangling bits of images by symmetric reflections.
Along the way, we point you toward some great simple demos as you see how to
bend this operating system to do what you want to do.

In the Beginning Was BASIC
Once upon a time, all home computers came with a built-in language. In the vast
majority of cases, this language was some version of BASIC. These days, BASIC
has developed a reputation for being unstructured and producing spaghetti code
(code that jumps all over the place using the infamous GOTO instruction, making it
almost impossible to follow).
Acorn BASIC, or BBC BASIC as it’s known, is different. Yes, it still has the GOTO
command (as does the C language), but just like the C language, you never need to

use it. The latest version of BBC BASIC, called BASIC V, is different. It’s
structured. In fact, it contains most of the same sort of control structures as
languages like C and Python. There is error handling, and it even uses pointers and
indirection in a much simpler way than C. Although it has retained the subroutines
of traditional versions of BASIC, those subroutines are rarely used; instead, it has
functions or procedures just like Python and C.
BASIC V also has a few tricks up its sleeve. It has error handling, something that
no other version of BASIC has. Also, you can drop into machine code any time you
want in a program. This means that you can write the majority of your program in a
high-level language and drop into machine code when you need the speed for a
certain section. (However, there is little need for that with the blistering speed you
get from the Raspberry Pi.) You can also fully interact with the machine’s
operating system using a process known as software interrupt (SWI), which allows
you to write any desktop application entirely in BASIC. Code written in BASIC
tends not to become obsolete under new revisions of the operating system or the
hardware. Programs we wrote in 1982 on a BBC Model B work just as well on the
Raspberry Pi — the only difference is that they run at lightning speed now.
The BASIC language was once the first exposure most people got to a computer
language, but you may be arriving here from another route. You could’ve started on
Scratch, learned C or Python, and now find yourself learning BASIC. If so, you’ve
gotten a good start — you already know about programming structures and flow.
Inevitably, there are differences among the languages, but most of them are
cosmetic. In this section, we provide a quick rundown of the major differences you
see.

Uppercase letters
Most modern computer languages are case sensitive and this version of BASIC is
no exception. However, in the early days of computing, everything was done in
uppercase characters mainly because the mechanical teleprinters used for computer
terminals didn’t have lowercase characters. So, BASIC was designed with
uppercase commands. Nowadays, a program written in all uppercase seems like
it’s shouting at you. Variables and function names can still be in lowercase, but it’s
common to see them in uppercase, too.

Variable types
In C, each variable is declared with a type (the sort of data it holds). In Python, this
is still true, but the language does backward somersaults to hide this fact from you,

which is a pity because often you need to know what type you’re dealing with.
With this version of BASIC, the variable type is built into the name. If you just
have a name, you have a floating point variable. If the name ends in a percent
symbol (%), it’s an integer variable. If the name ends in a dollar sign ($), it’s a
string variable.
Incidentally BASIC has some of the simplest-to-use and most-comprehensive string
handling routines of any language we’ve come across.

Line numbers
Line numbers are absent in languages like Python and C, but most BASIC programs
are written with line numbers. Most of the time, you don’t have to use line numbers
if you don’t want to. Not having line numbers prevents you from actually using the
dreaded GOTO command anyway. There are only two occasions when you may want
to legitimately use line numbers: in error handling and when restoring the pointer
for reading DATA statements.

Indentation
In Python, indentation is the hidden builder of structure. (You and your friends can
debate whether this is a good thing or a bad thing.) In C, indentation is mainly
decorative (although there is some debate about its use and the style you write the
language in). C is a lot more relaxed than Python.
With BASIC, indentation is almost unheard of. Most of the code is written from the
first column, which can be a shame because indentation can make things much easer
to follow. You can use indentation just as you do in C, to aid the readability of the
code, although indentation isn’t used nearly as much as it should be.

Only one equal sign
Most languages use a single equal sign for an assignment operator and a double
equal sign for a comparison operator (used in an if statement). This causes all
sorts of problems for beginners and causes if statements to apparently not work.
With BASIC, there is only one equal sign used for both sorts of operations, so it’s
much simpler to learn (although if you’re used to other languages, you may be a
little confused at first).

Scope

In C, variables are valid only when they’re used in the function they’re defined in.
If they’re defined outside of any function, then they’re global and accessible by all
functions. In Python, it’s roughly the same except if you want to alter a global
variable in a function, you have to declare it as global at the start of the function.
In traditional BASIC, there is no scope to variables at all, but in this current
version there is. Variables can be declared as local in a function, but by default
they’re all global. This is the opposite of what other languages do as a default, but
it’s better than nothing.

Indirection
C is strong on pointers, but this version of BASIC has indirection operators, which
essentially are the same thing. Suppose you have a variable called P%. As noted
earlier, the % means it’s an integer. If you just use P% in a statement, you get the
value stored in that variable, as it should be. However, each variable is stored in
the computer’s memory, and you can access the contents of the memory byte-bybyte using the indirection operator question mark (?). This is most useful when
dealing with arrays, which can then be treated as arbitrary memory allocations.
Check out the following operation:
A% = P%?2

This operation will assign to the variable A% the contents of the memory byte two
bytes along from the memory pointed at by P%. The ! operator does the same thing,
but it deals with four-byte chunks of memory.
Note that this works on both sides of an equal sign. So, to clear the byte one
address away from the memory pointed by P%, you would use the following:
P%?1 = 0

This is much easer to use than the pointer system used by C. And it’s a much more
flexible arrangement that the PEEK and POKE instructions used in other
implementations of BASIC.

Operating system calls
There are several ways that a BASIC program can interact with the operating
system, but the main one is the SYS command, which transfers a string to the
operating system interpreter. Many of these commands are in the form of SWI calls,
instructions that cause a subroutine to be executed in exactly the same way as an
interrupt service routine is evoked by a hardware signal. So an SWI call causes the

SWI handler routine to be called, and in RISC OS, it causes specific operating
system functions to be called depending on the word that follows the SWI. So, it
acts as a sort of pseudo machine code instruction.
The upshot of this is that you can easily invoke a myriad of operating system calls.
These are detailed in the Programmers Reference Manual (PRM), along with the
other ways of affecting the system.
Most things to do with the display can be manipulated by visual display unit (VDU)
commands, which send bytes to the display engine to display onscreen as ASCII
characters. However, the nonprinting ASCII characters control various aspects of
the display, like the screen origin or the color. The other two system calls are
OS_Byte and OS_Word; these take in either a single byte or word to perform
operations. There is nearly always an SWI equivalent of these calls.

Hello World
When computers were first appearing in retail outlets, they would sit on display
showing nothing but the BASIC prompt. A popular pastime for kids was to type in
some sort of variation of this and then run away:
10 PRINT "Hello World"
20 GOTO 10

The hapless sales clerk had no clue what to do as the message filled the screen.
(The message often contained some sort of expletive, and the sales clerk hadn’t a
clue how to stop it.)

The past revisited
You can re-create this world very simply on your fancy desktop operating system.
Simply follow these steps:
1. Press F12.
The whole screen scrolls up and an asterisk (*) appears at the bottom of the
screen. This is the command-line prompt.
2. Type BASIC and press Return.
You see the BASIC prompt of >.
3. Type the following two lines.
10 PRINT "Hello World"
20 GOTO 10

4. Type RUN and press Return.
Your message fills the screen so fast that it looks like it has stopped.
5. Press the Escape key to restore the BASIC prompt.
At this point, you can type LIST to see a listing of the program or NEW to
wipe the old code so you can type in another one. If you type SAVE name, that
saves the code (where name is the name you want to call the file containing the
program). Type LOAD name to load code from the current directory. Finally,
type QUIT to leave BASIC and go back to the operating system prompt.

Operating system modes
In RISC OS, there are basically three different modes the computer can operate in:
Command mode: The asterisk (*) prompt; the computer boots up into this
mode.
BASIC mode: The old BASIC mode with a > prompt.
Desktop mode: The familiar desktop.
You can switch between these modes quite simply. Figure 17-1 shows how these
modes operate. Basically, you can swap modes in either a desktop window or the
full screen. The keys needed to enter and exit these modes are shown next to the
connecting lines. The modes are hierarchical in the sense that they “remember” the
mode that called them, so when a mode is exited, the mode before the call is
restored.

Figure 17-1: RISC OS modes.

This quick transfer into and out of the desktop is in stark contrast with Linux, where
when the desktop is exited, the whole thing restarts afresh when you return. With
RISC OS, when you go back to the desktop, everything is where you left it.
When you close a task window, you’re given the opportunity to save it. This allows
you to look again at your session or incorporate things like a list of modules in
other texts.

BASIC mode
This is how the very first Acorn computers booted up. The idea is that there is a
single BASIC program you’re working on and the commands deal with that. Most
of the commands have a shortcut ending in a full stop to save you typing, and
they’re all in uppercase. These commands are the most useful:
RUN:

Runs the current program.

LIST: Prints
LIST.)

the current program. (You can use the shortcut L instead of typing

Prints just line 40. (You can use any other number here or even a
range of numbers separated by a comma.)
LIST 40:

PRINT variableName:

Prints the value of the variable.

RENUMBER:

Renumbers the program in increments of ten.

Takes you to Help documentation on all the commands. Just type HELP
and it tells you about the current program. Type HELP A, and you get a list of
all BASIC commands starting with the letter A. Type HELP ABS and you get a
description of that particular command.
HELP:

QUIT:

Exits BASIC.

Command mode
There are many commands, but the most useful are the following:
*CAT:

Catalogue or list the current directory. In Linux, this is ls.

*DIR:

Change the current directory. In Linux, this is cd.

*DESKTOP:
*QUIT:

Go back to the desktop.

Go back to the calling program.

*BASIC:

Enter BASIC mode.

Get help with commands. Help will give you a hierarchical help.
Typing *help along with one or more keywords will bring different levels of
help. For example, typing *help modules gives you a list of modules, typing
*help FileSwitch gives you a list of file switch commands, and *help any
command will give more information on the command. This is a handy function
when you’re stuck.
*HELP:

Directory path names are similar to those in Linux except directories are separated
by a dot (.) not the slash (/) that Linux uses. Note that when you’re at the
command-line prompt, you don’t have to use the asterisk (*) in front of the
command, but in other environments like BASIC, prefixing a command with an
asterisk marks it out for sending to the operating system command line.

There are many more commands — the PRM tells you what most of them
are. However, this system is extensible, and there are ways to add your own
commands with relocatable modules.

Desktop mode
In desktop mode, you can write code in a desktop editor like !Edit. There are other

editors that you can use, like !StrongED and our favorite, !Zap. These often have
enhancements when writing BASIC, like automatic coloration of keywords and
renumbering facilities.

The modern way of doing things
The command line BASIC is not used very much these days. Life is so much easier
when you use a graphics editor. It has all the functions you may expect and quite a
few more. However, copy and paste don’t work like other functions — they’re
menu options.
The RISC OS distribution comes with two editors, the simple !Edit (covered in
Chapter 16) and the very powerful !StrongED. We’ve never really liked !StrongED
— there was a bit too much to do in order to get it to work the way we wanted. Our
favorite editor is !Zap, and it’s still available through !Store for free. Installation is
slightly more complex than normal. Just follow these steps:
1. With an Internet connection, double-click the !Store application.
2. Click the Catalogue icon.
3. Locate !Zap in the PlingStore applications window.
It’s the last one in the list at the moment. Select it by clicking the name.
4. Click the download icon.
A box appears telling you that you aren’t logged in. You can ignore this. If you
log in, the !Store application records what you’ve downloaded so you don’t
download anything twice.
5. Double-click the !Configure icon on the desktop.
A configuration window appears.
6. Click the Boot icon in the configuration window.
The Boot sequence window appears.
7. Choose the Install option by clicking it and then dragging the !Boot file
from the zap archive window into the BootMerge window.
8. Click Merge to start the process.
It takes a few minutes.
9. Drag the !Zap fie into the Apps folder at the top level.

You’re done.
Now double-click the !Zap icon to run the program and put it on the icon bar.
Menu-click it and choose Create⇒New File⇒&FFB Basic, and a new window
appears. In that window, type the code in Listing 17-1.
Note: There is no need to type the line numbers or the colon — these will appear
as soon as you start typing. If the line number increments are not 10, don’t worry —
after you’ve typed it in, choose Mode⇒BASIC⇒Renumber.

Listing 17-1: Hello Again
10
20
30
40

:
:
:
:

A%=0
PRINT "Hello for the ";A%;" time"
A% += 1
GOTO 20

Now you need to run it. You can do this from !Zap by choosing
Mode⇒BASIC⇒Run Program⇒Run Then Quit. A window opens and the program
is run in it. Press Escape to end, and then press any other key to get back to the
desktop. You see that the program prints about 300 lines a second. (Eat your heart
out, Linux Python!) We did a quick test and timed the number of lines printed out
over 30 seconds. BASIC produced 293.7 lines per second and Python printed 6.2
lines per second.

From !Zap’s Mode menu, you can get all sorts of useful things to happen.
There is a renumber function and numerous run options. One of the most useful
is the simple Drop into BASIC. Here, a window opens and you have the
BASIC prompt (>). If you then type RUN, the program will run as you might
expect. However, any syntax error is accompanied by a line number. Suppose
an error message says there is an unknown variable at line 250 and you type
LIST 250 to see the line. What do you do if that line contains many variables?
How do you know which one is wrong? Just print them out one at a time. Type
P and then use the cursor keys to maneuver up to the line, and use the copy key
(on the keyboard, it says End) to copy the variable name. Then press Return,
and the value of the variable will be printed out. However, if it says “Error
Unknown Variable,” then you know that’s the one that’s wrong.

Use the cursor method of copying to avoid making a mistake in typing what

you think is the name of the variable rather than what really is the name.
You can also use the same technique for editing a line. Move the cursor up to the
line you want to change and use the copy key to copy part of it. Then use the normal
keys to type in the bit you want to change. Finally, press Return to put that line back
into the text. This is often faster than returning to the desktop, although you need to
save the file if you want those changes to be permanent.
Although BASIC and Python are both interpreted languages, BASIC has a few
tricks up its sleeve. A Python program is just a simple text file whereas in BASIC
it’s a tokenized file. This means that all the BASIC instructions, like PRINT and
WHILE, are compressed into a single byte or token, making it much quicker for the
interpreter to know what instruction needs to be performed. Then the BASIC
interpreter itself is so small that it fits inside the high-speed on-chip memory or
cache of the ARM processor, making it much faster to run. The cache is special onchip memory that runs as fast as the processor, something that doesn’t happen with
all kinds of memory.
So when you save a BASIC file, you aren’t saving a text file — you’re saving a file
where all the BASIC instructions are compressed. If you want to see what this
looks like, in !Zap choose the Mode⇒BASTXT. You see the strings you typed in,
and your variable names, as well as some other strange symbols. To convert your
BASIC program into real text, choose File⇒Dump to Text, and a new copy of the
file in text form will be produced.

The Insult Generator
The insult generator is one step up from “Hello World.” It isn’t a difficult concept
to grasp, but it shows you more of the fundamentals involved with writing and
arranging code in a system. The idea is simple: The program generates insults by
simply choosing a random word or phrase from two files. One contains nouns and
the other contains adjectives. It prints out:
You random adjective random noun
And then repeats on any key press. To set this up, create a new directory and call it
Insult. Then menu-click the !Zap icon and choose Create⇒New File⇒&FEB
Obey.
Into that file, type the following:

| Boot file for Insulter
Set Insult1$Dir 
IconSprites .!Sprites

Save the file under the name !Boot in your Insult directory. The first line starts
with a | and is treated as a comment. The second line sets a system variable, with
the path name to where the file currently is when it’s run. The final line tells the
desktop to look at a file called !Sprites to find what icons to use. This file is not
present at the moment, so nothing will happen, but you may get an error message, so
just ignore it for the moment. Now double-click this !Boot file; again, nothing will
appear to happen, but the path name will be set.

Looking at the main program
Now for the meat of the program, this is shown in Listing 17-2 and is the BASIC
program that actually does stuff. When you’ve typed it in, save it in a file called
Insult1.

There is no need to type the line numbers or the colon — the editor will
put those in for you.

Listing 17-2: The Insult Generator
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

REM Insulter plain BASIC version
REM Version 0.5 By Mike Cook
REM Freeware
MxL%=300
MxI%=200
MxN%=100
DIM Ins$(MxI%),Inn$(MxN%)
PRINT"Insult Generator - Escape to quit"
PROCreadInsults
PRINT"Any key for an insult":PRINT
REPEAT
A% = RND(100)
B% = ADVAL(-1)
UNTIL B%<>0
A$=GET$ : REM dummy read
WHILE(TRUE)
PROC_Insult
PRINT:PRINT"More?"
A$=GET$
PRINT
ENDWHILE
END
DEF FNread
LOCAL x$,A%
x$=""
REPEAT
A%=BGET#F%

310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

IF A%>&1F THEN x$=x$+CHR$(A%)
UNTIL A%<&20 OR LEN(x$)>250
=x$
DEF PROCreadInsults
Insults%=0
F%=OPENIN(".adjective")
REPEAT
Ins$(Insults%)=FNread
Insults%+=1
UNTIL Insults%=MxI% OR EOF#F%
Insults%-=1
CLOSE #F%
F%=OPENIN(".nouns")
names%=0
REPEAT
Inn$(names%)=FNread
names%+=1
UNTIL names%=MxN% OR EOF#F%
CLOSE #F%
names%-=1
ENDPROC

DEF PROC_Insult
PRINT "You "+Ins$(RND(Insults%))+", "+Ins$(RND(Insults%))+
", "+Inn$(RND(names%))+"."
570 : ENDPROC

The main program runs until line 240. The rest of the listing consists of function
and procedure definitions. Line 80 has the dimension statement that defines two
string arrays. You’re going to fill them up by reading the words out of a text file.
This is done with the PROCreadInsults procedure.
This is a bit more complex than it could be, but the way we’ve done it here makes
the text files containing the insult words a lot more simple to prepare. In effect, the
insulting words file consists of plain text, with a new, selectable insult on every
line, so it could be one word or a few. This means that the program has to read
individual bytes out of the file and build up the words to put into the insult arrays.
This is done by the function FNread, which returns a string comprising one line of
the text file.

The colon (:) operator is used to mean a new line, despite it not being on a
physical new line. It’s often used to shorten listings or group commands
together.
The files are opened using the path name given by the system variable, which was
set when you double-clicked the !Boot file, plus the actual file name (adjective
or nouns). This then reads in all the word files. The final procedure (PROCinsult)
prints out the random words that make up the insult.

Lines 130 to 160 need a bit of explanation. This is a crafty way of initializing the
random number generator. By constantly generating random numbers in the random
time it takes for the user to hit the first key, you’re assured of a new starting point
every time for the random number generator.
All we need now before we can test this is to generate the two text files of words.
So, on the !Zap icon, choose Menu⇒Create⇒New File⇒&FFF Text and enter
some adjectives shown in Listing 17-3 and save the file as adjective. Then repeat
this using Listing 17-4 and save the file as nouns.

Listing 17-3: Adjective File Contents
artless
bawdy
beslubbering
bootless
brutish
churlish
cockered
clouted
craven
currish
dankish
dissembling
droning
errant
fawning

Listing 17-4: Noun File Contents
baggage
barnacle
bladder
boar pig
bugbear
bum bailey
canker blossom
clack dish
clotpole
coxcomb
codpiece
death token
dewberry
flap dragon
flax wench
flirt gill
foot licker
fustilarian
giglet
gudgeon
haggard
harpy

You need to press Return after the last word in each of these files. There

are much longer versions of the files at
www.dummies.com/go/raspberrypiprojects.

Having everything in place, you can now run the insult generator by doubleclicking the Insult1 BASIC icon. If you get errors, go back into the editor and
correct them. Make sure that it’s running correctly before proceeding to the next
stage.

Smartening it up
You can’t do much about the actual output, but you can present a better view of this
program to the desktop. You had to double-click the !Boot file before you ran the
program. These next steps will give you a program-like icon to double-click.
First, you have to create an icon to represent your program. We made a
representation of a well-known cartoon character who is known for his insults:
1. Load up !Paint and click the icon bar icon of !Paint.
A new window invites you to create a new sprite.
2. Choose the 256 color mode, set the size as 32 x 32 pixels, set the name as
!Insult, and click OK.
3. Menu-click over the now blank icon in the window with the !Insult title,
and select a zoom of 11 to 1 in the magnify window.
4. Again, menu-click and choose Paint⇒Show Tools and Paint⇒Show Colors.
5. Now use the pencil tool to input your artwork.
Figure 17-2 shows you an enlarged view of what we have. We’re sure you can
work out the colors of this yellow-skinned blue-shirt-wearing fellow, from the
grayscale picture.
6. Save this sprite file under the name of !Sprites in the Insult directory.
Now you need a file to direct operations when the folder is double-clicked.
7. Create an Obey file from !Zap (choose Create⇒New File⇒&FEB Obey),
type the following into the file, and save it as !Run:
| Run file for Insult1
WimpSlot -min 32k -max 32k
Set Insult1$Dir 
Run .Insult1 %*0

This is the sequence of commands that are needed for running the program. The

first line is a comment you used in the !Boot file and could be omitted. The
next line allocates some memory for the program to run it — in this case, no
less than 32K and no more than 32K. Next, there is the setting of the path name,
just like the !Boot file. This is done again just in case this system variable has
been overridden by some other program. Finally, the last line runs the basic
program.
8. Rename the Insult directory !Insult.
9. Close the directory that contains it, and open it again.
You should have your new icon ready to double-click. It isn’t a true desktop
application, but it has all the outward appearances of such. You may like to
include a !Help text file in the directory (see Chapter 16).

Figure 17-2: The insult icon.

The insults themselves have a rather 17th-century restoration comedy sound to
them. You may want to have more colloquial words in your lists. The longer the
lists, the more varied the results. Lines 50 to 70 define the maximum number of
each type of word, and those are easily changed.

Understanding Full Desktop
Applications
At www.dummies.com/go/raspberrypiprojects, you can find not only the
finished code for !Insult but also a “real” desktop version called !Insulter.
!Insulter’s icon appears on the icon bar, the output is in a movable window that you
can iconize, and it happily multitasks with the rest of the desktop. It uses exactly the
same function as this example, but there is a lot more “wimp stuff” hung round it.
(Wimp is short for “windows, icons, menus, pointers.” Wimp stuff is the
fundamentals of any desktop-type application, no matter what the operating
system.)
Any desktop application is written in what is known as an event-driven style.
Events are things that happen. For example, a user clicks a box, a window control,
or a scroll bar, or performs a menu click. This event is notified to the program, and
the program deals with it as appropriate to the application. An event could also be
that some other program wants to send your program a message, or you want to
send another program a message.
On the other hand, you could get a null event — nothing has happened. That doesn’t
necessarily mean there is nothing to do. You could advance an animation, do a bit
more of a long calculation, or check input/output ports for any activity.
The act of asking the operating system for an event is the way that the whole
cooperative multitasking thing works. If you ask for an event, the operating system
takes the opportunity to switch to other tasks because, after all, your program has
nothing to do at the moment or it’s your program’s choice, at this point, to
relinquish control for another task. If you never ask for an event, nothing else gets a
look in, just like the way the simple !Insult program ran — while that was running,
nothing else on the desktop would work.
This may look complex, but this “wimp stuff” is virtually the same from program to
program so you can reuse a lot of it, at least the structure. The heart of it is the
wimp poll system, a loop that’s in lines 510 to 610 of !Insulter. The program calls

and, in doing so, informs the operating system of any events it isn’t
interested in. When this call is returned, the program gets back a number that
indicates what, if any, events have occurred. A case statement then decides what
has occurred and responds to those events of interest. Table 17-1 shows all the
results you can get back from Wimp_Poll.
Wimp_Poll

Table 17-1: Wimp Poll Codes
Code Reason
0

Null_Reason_Code

1

Redraw_Window_Request

2

Open_Window_Request

3

Close_Window_Request

4

Pointer_Leaving_Window

5

Pointer_Entering_Window

6

Mouse_Click

7

User_Drag_Box

8

Key_Pressed

9

Menu_Selection

10

Scroll_Request

11

Lose_Caret

12

Gain_Caret

13

Poll word non-zero

14–16 reserved
17

User_Message

18

User_Message_Recorded

19

User_Message_Acknowledge

This whole wimp business is covered in Volume 3 of the PRM.
Other things can help you with window definitions. Instead of specifying every
element of a window, you can read them off a file. The files can be created by a

graphics program so you can build up each window from the desktop by clicking,
dragging, and using tick boxes. The original program that did this was called
!ResEdit, but it won’t work with the new OS, so now there is one called !TemplEd
and another called !WinEdit. These are both found ready to be installed at the path
Programming/DrWimp/Utils of the RISC OS installation.
Many of the windows can even be copied from other applications and then
customized with these programs. In fact, many elements of the wimp system can
originate from other applications, like the sprites.
The other thing that needs to be set up is the memory that defines the menu structure.
This is done in PROCsetupmenu and consists of simply filling memory with
numbers. These numbers are interpreted as menu items. Again, the PRM tells you
which numbers mean what. In this example, there are only two menu items: one that
opens the information window, a standard part of any application, and another to
quit the application.
You can see the process of “wimpifying” an application in Figure 17-3. It shows
you the basic steps and flow of an event-driven desktop application.

Figure 17-3: Wimpification of an application.

You see a lot of use of the word indirection operator (!) in the !Insulter example.
It’s mainly used to fill and read blocks of memory that are used to pass information
back and forth between BASIC and the operating system. So, when Wimp_Poll is
called, a pointer to a memory space is passed to it — in this case, by the variable
q%. Notice how earlier this had been dimensioned as an array, with a DIM

statement. This is filled in by the operating system in a manner that depends on
what event occurred. For more information about wimp programming, see the
Documents/Books directory.

DrWimp is a tool that attempts to automate this process. It’s included in the
distribution and is found in the programming directory. There are blank
applications for you to customize and plenty of examples to look at in the
Examples directory; there are also tutorials online. There are other such tools
online that do this as well.

Working with Graphics in RISC OS
When it comes to graphics, RISC OS has a lot of legacy to cope with. Early
machines had very limited amounts of memory and there were various
compromises that could be made regarding resolution, the number of pixels, and
pixel depth (the number of colors each pixel could be). This was done by defining
graphics modes, a preset set of compromises. Although that memory restriction no
long applies, the use of modes are still around and are often still convenient to use,
in a non–desktop application context.

Modes and resolution
Although different modes had different resolutions, an attempt was made to have
some sort of mode independency in the software. Things were arranged so that the
drawing coordinates were larger than the actual resolution so that drawings look
approximately the same no matter what mode you were in. It was just that some
modes looked much more chunky than others, but the chunky modes had more
colors. Basically, the range of coordinates the software worked on was 0 to 1,279
for the x-axis and 0 to 1,023 for the y-axis. This has been now overtaken by the
new hardware, and you can get real pixel resolution much greater than this.
As more advanced Acorn machines were introduced, the number of modes
multiplied. Eventually, the mode became not a single number but a string of
parameters. These give the x and y resolution, the color mode, the relationship
between pixels and screen coordinates, and the frame rate. If you menu-click the
display icon in the bottom-right corner of the icon bar, you see what mode your
desktop is set to. On the Raspberry Pi, all the named modes default to a 64-color
display of various resolutions.

You can get an idea of this if you type in the program in Listing 17-5. This draws a
fan of lines in each mode up to mode 53.

Listing 17-5: Mode Tester
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

REM Mode tester by Mike Cook
FOR M% = 0 TO 53
MODE M%
PROC_Size
FOR N% = 0 TO 90
GCOL N%
MOVE 0,0
Th = RAD(N%)
X% = Xmax%*COS(Th)
Y% = Ymax%*SIN(Th)
DRAW X%,Y%
NEXT N%
GCOL 255, 255, 255
PRINT TAB(0,20); "Mode ";M%;" Resolution ";XLim%;" by ";YLim%
PRINT "Coordinates ";Xmax%;" by ";Ymax%
A$ = GET$
NEXT M%
END
DEF PROC_Size : REM get the screen size
SYS"OS_ReadModeVariable",-1,4 TO ,,Xfact%
SYS"OS_ReadModeVariable",-1,5 TO ,,Yfact%
SYS"OS_ReadModeVariable",-1,11 TO ,,XLim%
SYS"OS_ReadModeVariable",-1,12 TO ,,YLim%
Xmax%=XLim%<Rope
MODE 0
CLG:CLS
OFF : REM Turn off flashing text cursor
OSCLI "POINTER 1"
N=10: L=700: E=0.7: g=0.2: D=L/N
DIM V(N),W(N),P(N),Q(N)
REPEAT
MOUSE X,Y,B:MOVE X,Y
FOR I=1 TO N
x=P(I)-X+V(I)*E:y=Q(I)-Y+W(I)*E
d=D/SQR(x*x+y*y+.4)
X+=x*d:P(I)=X:Y+=y*d
Q(I)=Y:d=d/2-.5:V(I)+=x*d
W(I)+=y*d-g:V(I-1)-=x*d:W(I-1)-=y*d+g
NEXT
WAIT
CLG
FOR I=1 TO N
DRAW P(I),Q(I)
NEXT
UNTIL 0

Run this program and you see a rope dangling off the end of the mouse pointer.
Move your mouse and see how it dangles and moves. This is an example of Mode
0 graphics. Try also dragging the program file into GraphTask and see how the
movement is not quite so free.
Next remove the MODE command in line 20, either by deleting the line or by putting
a REM at the start of the line. (This is known as commenting out a line.) Now run it
again. Note that the line is finer and the movement is more fluid. This is because
you’re now using the native screen graphics mode. Finally, as a piece of magic,
you’re going to break the illusion of a desktop. Remove or comment out lines 30
and 180. These clear the screen between drawing each iteration of the rope’s
movement. Double-click the program file and twirl the rope around the whole
desktop. Figure 17-4 is what it looked like when we did it.

Figure 17-4: Lashing the desktop.

This sort of thing is not supposed to happen. Other operating systems go to great
lengths to prevent it. RISC OS is much freer, and if you want this to happen you can
do it very easily. You have to go to a bit more trouble to restrain the graphics and
restore the illusion.

Lines and shapes
As you can see in the last couple of listings BASIC has MOVE and DRAW functions to
create a line. You just move to the starting point and draw to the ending point to
produce a line. There is also a single pixel plot instruction called PLOT. With these
fundamental actions, you can draw everything. The MOVE and DRAW functions are
combined in the LINE function, where you specify the start and the end of the line
you want to draw.
Shapes come in two varieties — outlined and filled — and allow you to draw
rectangles, circles, and ellipses.
However, all these drawing commands are just special cases of the generalpurpose PLOT command, confusingly the same name as the single-pixel plot
function. This one takes in three numbers: a plotting mode and x- and ycoordinates. Where the shape being plotted needs more than a single pair of
coordinates, PLOT uses the previous positions of the graphics cursor to fill in the
missing values. The plotting mode number is quite complex — it consists of a
single byte, where the top five bits define the drawing operation and the bottom
three bits define how it will be drawn. Basically, these different ways of drawing

are how the coordinates are interpreted, absolute on the screen or relative to the
last coordinates. Also, it defines if the operation is a draw or a move, and if it uses
the current foreground color, background color, or logical inverse of the color
already on the screen.

For a full list of plot commands see
www.bbcbasic.co.uk/bbcbasic/manual.

This is a good place to see all the
commands BASIC can offer. There are also downloadable documents with
these BASIC commands explained.

Images
BASIC is capable of plotting images. There are two main formats that are handled
directly: sprites and JPGs. The &E8 to &EF PLOT commands handle the drawing
and plotting of sprite formatted images or bitmaps. However, all image handling is
also included in the “Sprite Extended Modules” covered in Section 107 in Volume
5 of the PRM.
At www.dummies.com/go/raspberrypiprojects, you can find an application
we’ve written called !Tiler, which takes an image in the form of a sprite and
reflects it in a number of ways in a kaleidoscope-like manner. The result is an
image that is a 4 x 4 copy of the original image, so four times larger in each
dimension. Each 2 x 2 block is a reflection of the original sprite. However, in a bit
of a mind-boggling stretch, the original image may be reflected along a diagonal in
a number of different ways. Figure 17-5 shows the way that the sprites can be
reflected.

Figure 17-5: Methods of reflection for !Tiler.

Basically, you can split a rectangle along one of two diagonal lines. Reflections
can be made on a diagonal from bottom left to upper right, known as a positive line

(or P for short). The part of the sprite reflected can be above this line (known as U
for upper part or L for lower part).
The reflection could also occur on the opposite diagonal — from the upper right to
lower left of the sprite. This is known as a negative line (or N for short). Again,
the part of the sprite above or below this can be used for the reflection.
Thus, this gives four extra modes, as well as the simple reflection mode:
8 Fold PU: Positive slope, use above the line, or upper, part of the image
8 Fold NU: Negative slope, use above the line, or upper, part of the image
8 Fold NL: Negative slope, use below the line, or lower, part of the image
8 Fold PL: Positive slope, use below the line, or lower, part of the image
4 Fold: Just the original sprite reflected
When you’ve created an image you like, you can save it or try it out as a
background image on your desktop. If you want to make it permanent feature of
your desktop, menu-click anywhere on the desktop and choose Save and click OK.
Figure 17-6 shows an example of what it produces. The original image was a part
of the Midget drawing in the Documents/Images/Artworks directory.

Figure 17-6: !Tiler output.

Chapter 18

Transistor Tester
In This Chapter
Understanding how a transistor works
Finding out about NPN and PNP transistors
Discovering how to control I2C devices from RISC OS
Building a fully functional, small-signal transistor tester
Writing software to control and analyze the measurement made on the
transistor
Getting a desktop application version of the software
This project is perhaps one of the most useful things we’ve ever made (if we do
say so ourselves). Not only does it test to see if a transistor is working, but it tells
you its gain and even what the pin out is. This is great not only for trawling through
transistors recovered from recycled boards, but also for saving you the time of
looking through data sheets and trying to identify the specific packaging version of
any transistor that you have. This is a valuable working tool that we come back to
again and again during the course of constructing electronic equipment. It also
serves as a good example of using the I2C bus to construct a stand-alone piece of
equipment.
The transistor tester project consists of four basic aspects:
You need to understand what you’re going to measure and why.
You need a means of configuring the transistor’s wiring to achieve a test
circuit.
You need a way of taking measurements on the transistor and getting them back
into the computer.
You need software to take the measurements, analyze them, and display the
results.
We cover all these subjects in this chapter.

Getting Acquainted with Transistors
Transistors are the foundation of modern electronics. All devices contain
transistors in one form or another. Although patented as early as 1925, the first
working transistor was not made until 1947. In the 1950s, transistors became
commercially available, and the word transistor was synonymous with the word
radio. In fact, radios were described by the number of transistors they contained. A
five-transistor radio was a common standard. Today, a microprocessor chip like
the one in the Raspberry Pi contains billions of transistors, all fabricated on a
single chip.
But what is a transistor? A better name for it would be a valve (except the
thermionic vacuum valve was in common use almost 50 years before the first
transistor, so that name was already taken) because it does accurately describe
what a transistor does. With a valve of any type, a large flow of something is
controlled by a small amount of something else. So, you can control the water flow
into your house with a few turns of a screw. Similarly, a transistor uses a small
flow of electricity to control a much larger flow of electricity. We call the flow of
electricity current.
In essence, a transistor consists of a three-layer sandwich of two different types of
material — N-type and P-type semiconductors. The semiconductor bit means that
the material is partway between an insulator and a conductor. What makes these
two types of semiconductor different is the way electricity is carried in them. In Ntype material, electrical conduction is mainly by means of negative charge carriers;
in P-type material, it’s mainly by means of positive charge carriers.
At this point, beginners are often confused and ask, “What direction does current
flow?” The answers to that question, while all true, depend on the substance
through which the electricity is flowing, and have different levels of complexity:
It doesn’t matter. This answer is the simplest. It simply doesn’t matter in
which direction the current flows. Often, a question of direction arises because
beginners think that direction matters. “But what if the current flows through
this resistor first?” they say. Flow is taken as a whole, through a whole circuit.
The current flowing into a simple resistor is the same as the current flowing out
of it. A resistor by itself does not “use up” current or reduce voltage.
From positive to negative. Positive-to-negative flow is called conventional
current flow. It helps to think of a flow direction even though the direction

doesn’t matter, so this direction is what we use in this book and what all
electrical and electronics books use.
From negative to positive. Flow from negative to positive is sometimes
wrongly considered to be the correct direction. This is because, in most solid
materials, the majority of charge carriers are negative electrons and they do
flow in that direction. The “conventional” explanation for this is that earlier
experimenters didn’t know which way current flowed, so they guessed (and
guessed wrong). Actually, early experimenters did know which way current
flowed, but they were studying current flow in liquids where most charge is
carried by positive ions. In other words, they were studying a P-type material,
although such a term was not known at the time.
There are two types of transistors, defined by what types of material make up the
“filling” and “bread” of the “sandwich”: NPN transistors and PNP transistors.
NPN transistors: NPN transistors (see Figure 18-1) are the most common type
of transistor today. As the name implies, there are two layers of N-type
material with a “filling” of P-type material. Each layer is brought out to a
separate wire to give the three connections of a transistor — the collector,
emitter, and base. If we make a small current flow through the base/emitter
junction, a larger current will be forced to flow from the collector to the
emitter.
The ratio of the two currents — that is, the collector-to-emitter current, over the
base-to-emitter current — defines the gain of the transistor. This is sometimes
called the amplification factor, but it’s important to understand that the input
current itself does not get amplified. Instead, the input current causes a much
larger current to flow in the output. As the input current increases, the output
current increases by the same factor. It’s a bit like a mechanical pantograph
where one action causes a much larger secondary action. Note that you can only
get an output current up to what your power supply can provide.

The symbol of a transistor is shown in Figure 18-1. An important thing
to note is the arrow on the emitter. Here, it points out of the symbol, which
means it’s an NPN transistor. A diagram with that arrow pointing the other way
means it’s a PNP transistor.
PNP transistors: When transistors first became available, they were nearly all

PNP transistors because they were easier to make using the technology
available at the time. A PNP transistor is sometimes known as an “upsidedown transistor” because it’s used just like an NPN transistor, but the supply
voltages are inverted when compared to an NPN transistor. Figure 18-2 shows
the two types of transistors in action.

Figure 18-1: A basic NPN transistor.

Figure 18-2: Transistors in action.

There are three ways of connecting a transistor. Here we look at just the most
common way of using a transistor, called a common emitter circuit. In a common
emitter circuit, the emitter is connected to the common point between input and
output (that is, both the input and the output have a common point, and that’s the
emitter). The less often used configurations are the common collector circuit
(sometimes called an emitter follower circuit) and the common base circuit.

Note that because the transistor is a symmetrical three-layer sandwich, you

should be able to swap the collector and emitter and have the same sandwich.
A transistor wired up with its emitter and base swapped over will still
function as a transistor.
Resistors are used to limit the current flow over a wide range of voltages. In the
circuit on the left in Figure 18-2, the NPN transistor conducts more collector-toemitter current as the input voltage increases. However, if you look at the voltage
on the collector, the more current that flows, the lower that voltage will be. It has
to be that way because, in order to make more current flow through the resistor, it
has to, in effect, reduce the resistance between the collector and the emitter.
Sometimes we say that this circuit is a signal inverter because a high voltage in at
the base results in a low voltage out at the collector.
On the right side of Figure 18-2 is a PNP transistor. Note that the emitter here is
connected to the positive rail. So, in order to get a current to flow between the
emitter and the base, the base has to be a lower voltage than the emitter. Therefore,
to turn off the transistor, the base needs to be up to the rail; to turn it on, it has to be
a low voltage. There is still the signal inversion — a low voltage on Vin still gives
a high voltage on the collector. The transistor works just the same, only upside
down.
If you think of the transistor as a switch, it’s between the collector and emitter,
controlled by a voltage on the base. Then you can think of the NPN as a bottom
switch — it turns on the load (puts current through the load resistor) by connecting
it to ground. On the other hand, the PNP transistor is a top switch — it turns on the
load by connecting it to the positive supply rail.

Configuring Transistors
In this project, I use a simple but effective means of testing a transistor: First, with
no base current applied, measure the collector current. Then apply a voltage to the
base resistor and measure the collector current again. If the collector current
increases in the second reading, it’s a good transistor and you can calculate the
gain from the ratio of collector current to base current.

Measurement circuit
Measuring current involves measuring the voltage across a known resistor value.
Then, by making a calculation using Ohm’s law, you can work out the current. This
is how most current measurements work. Therefore, you have to wire up the

transistor under test in a way that you can measure the two currents (see Figure 183).

Figure 18-3: The test circuit.

The base resistor and the collector resistor have been split into two resistors in
order to measure the current. This has been done to keep the voltages produced
within the limits of the chip we’re going to use for the measurements. The collector
and base resistors are very different: One is 220R (ohms) and the other is 220K
(thousand ohms). Note that the transistor is tested under very small currents, the
base resistor and a 5V supply means the base current is only 10uA. Small currents
are where transistors are at their best. The gain will tend to drop off as the base
current increases.

Switching configurations
If you just implemented the circuit in Figure 18-3, it would be simple enough to

make the tester, but we wanted to find out not only the gain but also the pin-out of
the transistor. In order to do that, you must measure the gain with every
combination of wiring for the transistor pins. That means each of the inputs
connectors, which hold the transistor under test, must be capable of being switched
to be a collector, an emitter, or a base, in a common emitter mode for both PNP and
NPN transistors.
That’s quite a lot to get your head around in one go, especially if you look ahead at
the schematics for this project shown later in this chapter. So we’ll break it down
into steps.
The 74HC4066 (which you use in the circuit shown in Figure 18-9) is a quad
bilateral switch. The “quad” bit means there are four in one package, and the
“bilateral” bit means current can flow in both directions. So, in effect, this looks
like a simple on/off switch that can be controlled by a logic-level input. This is
exactly what you need to switch the input pins of the transistor under test to the four
basic positions in the circuit — base, collector, 5V, and ground.
Figure 18-4 shows what that switching arrangement should look like. We’ve
labeled each switch with an S prefix number and the transistor’s input connector
with a simple number.

Figure 18-4: Required switching of the three input connectors.

Switches S0 to S2 connect 5V to either of the three input connectors, and S13 to
S15 do the same for the ground. To the left, S7 to S9 connect any of the three
transistor connectors to a resistor; likewise, the switches S10 to S12 do the same,

albeit a different value of resistor. The other end of these resistors must be capable
of being switched to either 5V or ground to cope with the possibility of having an
NPN or a PNP transistor.

This scheme does carry a bit of danger in that, for example, if switches S1
and S14 were to be closed at the same time, there would be a short circuit
across the supply and things might melt. Likewise, S3 and S4 should never be
on at the same time, nor should switches S5 and S6, S0 and S13, or S2 and
S15. You have to make sure that only certain combinations of switches are on
at any one time.
For an NPN transistor with the base on connector 1, the emitter on connector 2, and
the collector on connector 3, in order to have this transistor configured correctly
for a gain measurement, switches S3, S5, S7, S12, and S14 must be turned on while
all the other switches are off. This is shown in Figure 18-5.

Figure 18-5: Switch states for an NPN transistor with “base, emitter, collector” pin out.

If you set the switches like this and measure the currents, and you see a gain, then

you have an idea that you have a working NPN transistor with the “base, emitter,
collector” configuration. What you have to do is go through each valid
configuration and write down the states of the switches. We’ve done this, and the
result is shown in Figure 18-6.

Figure 18-6: Switch states for each transistor configuration.

There are six different combinations of input pins for each of the two types of
transistor, giving 12 combinations in all. Each switch is either a 0 for off or a 1 for
on. Note how switches S3 and S5 are on for every combination of NPN transistor
and off for every combination of PNP transistor. Also, note how S5 is always the
opposite of S6 and likewise for S3 and S4; to do otherwise would cause a short as
we mention earlier. These then are the set of combinations for the switches for each
measurement. The combination whose measurements makes sense tells you the pin
out of the transistor.

Designing the Circuit
When designing a circuit, it’s always best to start with a block diagram, one that
shows the broad functions and how they interrelate. The transistor tester’s block
diagram is shown in Figure 18-7.

Figure 18-7: Transistor tester block diagram.

On the left, there is the I2C connecting both the analog-to-digital (A/D) converter
and the digital outputs to the Raspberry Pi. The A/D converter is then connected to
the resistors in the test circuit, and the test circuit itself is connected to the analog
switches. Because there are only 8 output lines from the I2C digital chip we used,
these lines are expanded up to 16 by means of a multiplexer (an addressable latch,
to be precise).
The I2C bus is a simple system of connecting many devices to the same pins. Each
device has a unique address to use for communication. In theory, up to 128 can be
used on the one bus. In practice, this is normally fewer than ten or so devices.
There has to be a pull-up resistor on each of the two lines of the bus. It’s built into
the hardware design of the Raspberry Pi, so there is no need to add them to
anything you attach to this bus. It also copes with the 3V3-to-5V conversion.
Devices can be powered with 5V, but the data signals themselves can be 3V3,
forming a neat interface.

Raspberry Pi interface circuit
The circuit of the transistor tester is simpler to understand if it’s split into two
parts. The first part is the I2C interface from the Raspberry Pi and is shown in
Figure 18-8.

Figure 18-8: The Raspberry Pi–to–I2C interface circuit

The interface circuit consists of two chips: PCF8591 (the A/D converter) and
PCF8574A (the digital input/output). If you’ve read Raspberry Pi For Dummies,
you know we used the PCF8591 for some projects in that book as well. It’s a
versatile chip offering a four-input A/D converter and a single D/A output.
We won’t be using the D/A output in this project, but we will be using all four
analog inputs. There is a mode that this chip can operate in, in which you can
configure the inputs into two differential pairs of inputs. A differential A/D
converter is one that measures the difference in voltage between two inputs. If input
0 is a higher voltage than input 1, the difference has a positive value; if it’s the
other way around, it has a negative value. The same applies for inputs 2 and 3: If 2
is higher, it’s positive; otherwise, it reads negative. This is exactly what you need
to measure the current in the base and collector circuits because when they’re
configured for a PNP transistor, these currents are negative; they’re positive for an
NPN transistor.

All the external address lines on these two chips are connected to ground, which
makes the actual I2C address of each device their base, or lowest address. Note
that there are two types of the digital input/output chip — the PCF8574 and the
PCF8574A. They’re identical chips, but they have a different base address. If you
use a PCF8574, you have to alter the software; this change is just one line, though.
The capacitors C1 to C3 are decoupling capacitors and should be fitted as close to
the chips as possible. The value of C1 isn’t critical, but C2 and C3 must be of the
ceramic type.

Test circuit
The test circuit part of the project is shown in Figure 18-9; the component
numbering leads on from the previous schematic. There are two 74LS259
addressable latch chips, and four 74HC4066 bilateral switches. Each chip should
have a 0.1uF capacitor soldered across the power and ground as close to the chip
as possible. (These are omitted from the schematic to make the wiring look less
cluttered, which is a standard practice for some schematics.)

Figure 18-9: Test circuit schematic.

Note that output 3 (pin 7 of IC1 in Figure 18-6) is not used and so does not appear
in Figure 18-9.
The other thing to note is that the test connector is shown three times, again to keep
the wiring from being cluttered. There is only one connector, and pin 1 on the real
connector should be connected to the three instances of pin 1 shown in the
schematic. This sort of thing in a schematic is known as intersheet connections,
and it’s often used to make wiring less cluttered, although some people take it too
far and have hardly any connecting wires shown at all.
The idea of the 74LS259 addressable latch is that the number of the output you
want to change is placed on the select lines — pins 1, 2, and 3 — as a binary
number. The logic level you want to set that output to is placed on pin 13, the data
input. Then that value is transferred to the addressed output when pin 14, the enable
line, is taken low and then high again. You see that the input pins to both latches are
wired together apart from the enable, pin 14. This is so we can trigger the two
latches independently.
There could be a problem if the wrong switches are turned on, so we’ve made use
of pin 15, the clear input. This sets all the output latches to 0 and turns all the
switches off. However, on powering up, the outputs of the 74LS259 could be at any
state, so it would be good if you could arrange the clear input to be low on power
up, because it may be some time before the software has a chance to do anything.
Although you don’t know the state of the 74LS259 outputs, you do know the powerup state of the PCF8574A’s outputs — they’re high. There is no magic about this
— it’s just that it says so in the data sheet. Unfortunately, this is opposite of what
you want. Therefore, we’ve put in a transistor, Q1, to invert the power-up state of
the PCF8574A’s, ensuring that all the switches power up in a state of being turned
off.
The 74HC4066 can be replaced with other chips of the same type, like the
CD4066. It’s the 4066 part that defines the function. There are subtle differences
between these different chips, but they mainly concern the on resistance of the
switch. For this application, it’s very small compared to the other resistances in the
circuit. IC5 handles switches S0 to S4, IC6 handles switches S5 to S8, and so on.
Resistors R3 to R6 are the series resistors used to measure the currents in the base
and collector.

Constructing the Circuit

We built the circuit on stripboard in a small plastic box. Before you start you need
to gather the parts. Component reference numbers are shown in parentheses.
One 47uF electrolytic capacitor (C1)
Eight 0.1uF ceramic capacitors (C2–C9)
One 47K resistor, ¼ or ⅛ watt (R1)
One 10K resistor, ¼ or ⅛ watt (R2)
Two 220K resistors, ¼ or ⅛ watt (R3–R4)
Two 220R resistors, ¼ or ⅛ watt (R5–R6)
One PCF8574A–I2C digital I/O (IC1)
One PCF8591–I2C A/D (IC2)
Two 74LS259–octal addressable latches (IC3–IC4)
Four 74HC4066–quad bilateral switches (IC5–IC8)
One BC183 or similar general-purpose NPN transistor (Q1)
Three miniature crocodile/alligator clips (test connector)
One 0.1-inch pitch stripboard, with 4-x-2-inch strips running vertically
Ten M2 10mm screws, washers, and nuts
One plastic box measuring at least 2¼ x 4⅜ inches
One 8-pin two-row 0.1-inch header socket
One 4-pin single-row 0.1-inch header socket
One 4-pin single-row header pins plug
One 6-inch four-core cable
Four 14-pin DIL sockets (optional)
Four 16-pin DIL sockets (optional)
We always use IC sockets in our projects. They’re very handy for fault finding, and
the ICs are reusable on other projects. They also make the testing easy in that you
can plug in the chips one at a time for testing the circuit, as we describe later in this
chapter. However, you can save a bit of money if you solder them directly onto the
stripboard.
We found a 2¼-x-4⅜-inch plastic box and trimmed our stripboard to suit. Then we

drilled four holes in the corners of the stripboard and the box to fasten the two
together. We fitted the sockets and cut the tracks between the pins on each side of
the IC and also on the tracks between ICs. Most of the wiring was done on the
underside of the board. This is just about the minimum space you can use. You may
want to use a bigger box and piece of stripboard to give yourself a bit more room.
The finished project is shown in Figure 18-10.

Figure 18-10: The transistor tester circuit board.

To allow hot plugging, you need to first connect the ground and positive supply and
then finally the signals. If you look at something like an SD card or a USB memory
stick, you’ll see some connections longer than the others. As you plug it in, the
longer connections get made first.
The I2C connector back to the Raspberry Pi is in the center-right of the board. We
cut a small square hole in the top of the lid to get access to the pins.
The test connector is made up of three miniature alligator/crocodile clips. These
are just about an inch long. We drilled two M2 holes in the back end of each one,
and mounted them on the box lid as close together as we could without their
touching. You can see the connections to the back of these screws in Figure 18-10.
In Figure 18-11, you can see them from the top; this shows how you can connect a

transistor to them. The most vital thing is that you label each clip 1 to 3, because
the software is going to tell you what number clip is what connection on the
transistor.

Figure 18-11: The test transistor clips.

We used a polarized pin header for the lead back to the Raspberry Pi. You may
want to solder a lead straight in. At the Pi end, we used a twin row socket just four
connectors long on each side (eight connectors in all) and fitted them over the end
of the Pi’s P1 plug. Because we need only four connections, there isn’t much point
in getting a full-width connector, but you have to be careful to get the pins aligned.

Writing the Software
Having built the hardware, it’s now time to look at the software to drive it and
perform the analysis of the results. Get the interface working one bit at a time. This
is where sockets come in. Just plug in IC1, connect to the Pi, and power up.

Never plug something into the Raspberry Pi when it’s powered up unless
the thing you’re plugging in is designed for hot plugging, like a USB
connector.

Testing the digital interface
Now, if you have a system with just IC1 fitted, type Listing 18-1 to test out the

digital interface.

Listing 18-1: Testing the I2C Interface
10
20
30
40
50
60
70
80
90
100
110
120

:
:
:
:
:
:
:
:
:
:
:
:

REM> I2C Test digital out
PRINT"I2C BUS OUTPUT"
PRINT"Binary count to device at &70"
PRINT"By Mike Cook"
DIM PBK% 3
REPEAT
FOR A%=0 TO 255
?PBK%=A%
SYS "IIC_Control",&70,PBK%,1
TIME = 0: REPEAT : UNTIL TIME > 1
NEXT
UNTIL FALSE

This sends a binary count to the digital output pins of IC1. To test that it’s getting
there, wire up an LED and a 1K resistor, put the positive end to 5V, and touch the
negative end on each of the outputs in turn. At output 0, you should see the LED
blink rapidly. As you touch the higher outputs, the LED will blink increasingly
slowly.
The line that actually outputs data to the I2C lines is line 90 (page 977 in Volume 1
of the PRM tells you all about it). Note that it’s called IIC, which is an alternate
name for the I2C bus that was more popular at the time the operating system was
written.
The first parameter passed to it is the address. This is a full 8-bit address with the
least significant bit determining if it’s a read (=1) or a write (=0) operation. The
next points to a block of memory (4 bytes) that contains the data to transfer. In our
case, we dimensioned the variable PBK% to point to 4 bytes of memory. Line 50
says three, but that’s the highest byte number to use and we start at zero. The final
parameter is the length of the block in bytes. This is one, because we only want to
send the one byte. The block is set up with the loop variable in line 80, using the
indirection operation question mark (?).
Line 100 is a 10mS delay. Try removing this line and you see that most of the
outputs are flashing so fast that they look like they’re on all the time.
Now if you have sockets on your circuit, you can test the analog input, power
down, fit IC2, power back up, and run the program in Listing 18-2.

Listing 18-2: Analog Input Test
10
20
30
40
50

:
:
:
:
:

REM> I2C Test
PRINT"I2C BUS
PRINT"Read an
PRINT"By Mike
DIM PBK% 3

analogue input
Analogue Input"
A/D device at &90"
Cook"

60
70
80
90
100
110
120

:
:
:
:
:
:
:

?PBK% = 0
SYS "IIC_Control",&90,PBK%,1
REPEAT
SYS "IIC_Control",&91,PBK%,1
PRINT "Reading ";?PBK%
TIME = 0:REPEAT : UNTIL TIME >50
UNTIL FALSE

The program sets up the PCF8591 to just read analog input 0, which is done by
writing 0 to the control register (line 70). Then there is an endless loop that reads
the value from the analog results register (line 90), which prints it out and then has
a half-second delay before repeating. In line 90, note that the least significant bit of
the address is set to 1, meaning it is a read operation. The memory block PBK% is
reused so that it receives the data from the I2C bus, with the indirection operator
(?) being used to fetch the actual byte at this address for the print statement.
When you run this, you see numbers being printed out. If you touch a ground wire
onto pin 1 of IC2, you should see this number go to 0. If you touch the pin with your
finger, you should see the numbers change randomly, and if you touch a wire
between pin 1 and the 5V line (pin 16), the number should go to 255, the maximum.

Setting the switches
Having tested the two I2C devices, it’s time to plug in the rest of the ICs and
consider what we need to do to test a transistor. Figure 18-6 showed what states
you need to set each switch to in order to get the correct configurations. This
showed the switches from left to right. But in order to turn those switches into
numbers, we need to reverse that order so that bit 0 of the number controls switch 0
and bit 15 of the number controls switch 15. So we simply reverse the bit pattern
and turn it into a number. Using hex makes things so much simpler, as shown in
Figure 18-12.

Figure 18-12: Switch state to a hex number.

This is for the first line, where the transistor is an NPN with a pin out of emitter,
base, collector, and yields a hexadecimal value of &3124. This process needs to be
repeated for each line in the table and transferred into an array.

Now BBC BASIC has a neat way of handling sets of numbers like this, one that we
think is far better than C or Python: the DATA statement. This is a line that contains a
sequence of numbers or strings. To get that into an array, there is a READ statement
that takes the next value and puts it into the variable that accompanies the READ
statement. This is way more efficient and flexible than assigning each array element
individually, which is what you have to do in other languages if you want to
redefine the contents of an array.
The configuration list along with switch states to test for that configuration are
shown in Listing 18-3.

Listing 18-3: Initializing the Configuration and Switch
Arrays
REM Initialise switch pattern
DEF PROC_SPinit
LOCAL A%
FOR A%=0 TO 11
READ Lead$(A%),Config%(A%)
NEXT
DATA ebc,&3128,cbe,&8528,ecb,&2A28,ceb,&4628,bce,&88A8,bec,&50A8
DATA ebc,&1151,cbe,&0554,ecb,&0A51,ceb,&0652,bce,&08D4,bec,&10D2
ENDPROC

Notice how the READ statement has two array variables: a string for the pin out and
a number for the switching configuration. It’s in a FOR loop, and the loop variable
is used as the array index. When data is exhausted from one DATA statement, the
program automatically looks to the next DATA statement.
Having acquired the number that defines the switch configuration, you have to use it
to set the switches. That means driving the two addressable latches to have the
switch states on their outputs correspond to this number. Figure 18-9 showed you
what the schematic of the latches is, it does not help a programmer very much to
know what to do. So, in Figure 18-13 you can see a programmer’s view of the
addressable latches.

Figure 18-13: A programmer’s view of the addressable latches.

This gives the view of the individual bits of the I2C digital interface and how they
drive the addressable latch. Bit 4 is the clear input. When it’s high, all the bits in
the latch are cleared — that is, set to zero. This is very handy for quickly turning
off all the switches when you’re changing configurations. You need to do this so
that in moving from one configuration to another you don’t accidentally turn on a
forbidden combination of switches that would cause a short circuit.

Analog readings
When it comes to making the voltage measurements that allow you to determine the currents in base
and collector, you need to set the PCF8591’s configuration register to be two differential inputs. This
is done by setting bits 4 and 5 in the control register. The channel number in this mode is set by just
bit 0. So, to read the collector current, first write the hex value &30 into the control register and then
read the value, and for the base current write &31 into the control register and read the results.

So, to set up any one switch, you have to set bits 0 to 2 to the least significant three
bits of the address you want to write to. Put the data you want to write onto bit 7.
Then pulse bit 6 if the most significant bit of the address you want to write to is 1;
otherwise, pulse bit 5 if it is a 0. This involves you in a little piece of numeric

gymnastics using bit shifts.

Transistor testing methodology
As we mention earlier, a transistor will work with its emitter and collector
swapped over — the difference being that when it’s wrong, the gain is smaller.
Therefore, when testing a transistor, you need to make a note of the gain for each
configuration. You must also guard against the case where the transistor has a short
between collector and emitter. That initially may look like it has a high gain, so for
a good transistor, you need to see that you don’t have this high gain when you
remove any base current. If you do this, and you still have a high gain, you know
you have a faulty transistor. Similarly, a current reading of 0 in the collector when
you do have base current also indicates that the transistor is faulty.
As you test each configuration, you need to keep a record of the configuration if the
gain you just measured is greater than any gain you previously measured. So, at the
end of looking at all the combinations, you have the combination that gives the
maximum gain. However, if the maximum gain is less than two or you reached the
end of the combinations with no maximum gain set, then you know it’s a faulty
transistor.

Putting it all together
Let’s see how all this comes together and produce a program to test our transistor.
The listing for this is shown in Listing 18-4. Note that this is just a simple BASIC
program at the moment, not a desktop application.

Listing 18-4: The Transistor Tester Program
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

REM>IICtt
PRINT"IIC Transistor Tester"
PRINT"By Mike Cook"
DIM PBS% 4,PBK% 8,Lead$(12),Config%(12)
AA%=&90 : REM Analogue Chip Address
DA%=&70 : REM Digital Chip Address for 8594A - &40 for 8574
PRINT"8574 chip at ";~DA%;" and 8591 chip at ";~AA%
PROC_SPinit
REPEAT
MGain%=0
LC%=12
PRINT
PRINT SPC(15);"Ic
Ib
Gain"
FOR A%=0 TO 11
IF A%<6 THEN Type$="NPN" ELSE Type$="PNP"
Gain%=0
REM First test with no base current
PROC_Mulout(Config%(A%) EOR &18)
IF DeviceD%=FALSE THEN PRINT"IIC Digital chip not responding":END
PRINT Type$;" ";Lead$(A%);" ";

220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
640
650
660
670
680
690
700
710
720
730
740
750
760
770
780
790
800
810
820
830
840
850
860

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

PROC_AIN
IF DeviceA%=FALSE THEN PRINT"IIC Analogue chip not responding":END
IF ABS(col%)<5 THEN
PROC_Mulout(Config%(A%))
PROC_Analyse
ELSE
PRINT"Not Valid"
ENDIF
IF Gain%>MGain% THEN MGain%=Gain%:LC%=A%:Atype$=Type$
NEXT
REM Disconnect transistor
PROC_Rsm
PRINT
IF LC%=12 OR MGain%<2 THEN
PRINT"Faulty transistor"
ELSE
PRINT"This is a ";Atype$;" transistor, pinout "Lead$(LC%);" Gain ";MGain%
ENDIF
PRINT"Press any key for another test"
A$=GET$
UNTIL FALSE
DEF PROC_Analyse
PROC_AIN
Ic=((5*col%)/256)/220
Ib=((5*bas%)/256)/220000
IF Ib<>0 AND Ic<>0 THEN Gain%=Ic/Ib
PRINT ;Ic;" ";Ib;" ";Gain%
ENDPROC
DEF FNtc(N%)
IF N%>&7F THEN N%=&FFFFFF00 OR N%
=N%
DEF PROC_Rsm
?PBK%=&FF
SYS "XIIC_Control",DA%,PBK%,1 TO ;Fl
ENDPROC
DEF PROC_Mulout(N%)
LOCAL A%,B%,C%,M%
PROC_Rsm
FOR A%=0 TO 15
B%=N% AND 1
N%=N%>>1
M%=B%<<7 OR A% OR &60
?PBK%=M%
SYS "XIIC_Control",DA%,PBK%,1 TO ;Fl
C%=M%
IF A%>7 THEN C%=C% AND &BF ELSE C%=C% AND &DF
?PBK%=C%
SYS "XIIC_Control",DA%,PBK%,1 TO ;Fl
?PBK%=M%
SYS "XIIC_Control",DA%,PBK%,1 TO ;Fl
NEXT
IF (Fl AND 1) =1 THEN DeviceD%=FALSE ELSE DeviceD%=TRUE
ENDPROC
DEF PROC_AIN
LOCAL Fl,B%
?PBS%=&30
REM Set up the control register
SYS "XIIC_Control",AA%,PBS%,1 TO ;Fl
SYS "XIIC_Control",AA% OR 1,PBK%,2 TO ;Fl
bas%=PBK%?1

870
880
890
900
910
920
930
940
950
960
970
980
990
1000
1010
1020
1030
1040

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

?PBS%=&31
SYS "XIIC_Control",AA%,PBS%,1 TO ;Fl
SYS "XIIC_Control",AA% OR 1,PBK%,2 TO ;Fl
IF (Fl AND 1) =1 THEN DeviceA%=FALSE ELSE DeviceA%=TRUE
col%=PBK%?1
col%=FNtc(col%)
bas%=FNtc(bas%)
ENDPROC
REM Initialise switch pattern
DEF PROC_SPinit
LOCAL A%
FOR A%=0 TO 11
READ Lead$(A%),Config%(A%)
NEXT
DATA ebc,&3128,cbe,&8528,ecb,&2A28,ceb,&4628,bce,&88A8,bec,&50A8
DATA ebc,&1151,cbe,&0554,ecb,&0A51,ceb,&0652,bce,&08D4,bec,&10D2
ENDPROC

This will test a transistor attached to the hardware and print out the results in terms
of transistor type, pin out, and gain. Lines 50 and 60 define the addresses of the two
I2C devices. If you set the external address lines or get a PCF8574 instead of a
PCF8574A, then you only have to change the address here.
The infinite loop of the main program goes from line 100 to line 420. It prints out
the result of testing each configuration as it goes and finally comes up with a result.
Because the first six configurations are for NPN transistors, the current transistor
type is easily set; this is done in line 160.
Next, the transistor is tested for the current configuration, but with the base resistor
switched to the common line. This is the test without any base current. This is done
by simply exclusive ORing the configuration number with &18, which controls the
two base switches, S3 and S4. It inverts the state of those bits so that where it
would normally be set for a current source (high for PNP or low for NPN), it’s
switched to the same potential as the emitter. This is done in line 160.
Then, at line 250, the normal configuration is set and the transistor’s readings are
made and analyzed. This is repeated for all 12 configurations, and the transistor is
disconnected. Then the conclusions are printed, and the program waits on a user
pressing a key before doing it all again. To quit this program, press the Escape key.
Let’s look more closely at some of the procedures that do the hard work. Line 560
is the start of the very short procedure Rsm (reset switch matrix). Its job is to write
all 1s to the digital interface, thus triggering the latch’s clear line. Notice that the
SYS call has an X in front of it. This is a trick you can use in programming for the
desktop. It means, “Don’t throw an error if something goes wrong.” This is to
allow the calling program to handle any error, the TO;F1 at the end of the call is
telling the computer to put the error byte into a variable F1. It isn’t used in this

procedure, but it’s in the multiplex output procedure ( Mulout).
This procedure takes in a number and outputs it to the multiplexed addressable
latch. This is the numeric gymnastics we mention earlier. It writes the number
passed to it one bit at a time in a FOR loop starting at line 640. The least significant
bit of the number is put into the variable B%, and then the number is shifted one
place to the right to move the next bit into the least significant bit for next time
around the loop.
The variable M% in line 670 is used to gather the bits you need to write to the digital
output. First, the bit you want to write is shifted up seven places to the left. To put
it into bit 7, this is the logically ORed with the loop counter (which is the latch
address), as well as the number &60, which sets the two data latches high. This is
then written to the digital output. Then the appropriate data latch is set to low and
again this is sent out to the device. Finally, the first number is written to the output
again. This ensures that the data and address is stable on the latch inputs before the
enable line is sent low and then high. The procedure also used the error flag F1 to
set a variable that tells if the analog device is actually present.
The procedure AIN (analog in) sets the channel to read and then reads it. Note that
when reading the data back, the byte we’re interested in is the second byte. Hence,
line 860 uses the ?1 indirection operator (meaning one byte away from that pointed
to by the variable).
The function tc may look odd. It just takes in a number and converts it from the 8bit signed value received from the A/D converter into a 32-bit signed value that
BASIC uses.
When this code is run, it produces an output like the following:
IIC Transistor Tester
By Mike Cook
8574 chip at 70 and 8591 chip at 90
Ic
Ib
Gain
NPN ebc 0 0 0
NPN cbe Not Valid
NPN ecb 0 0 0
NPN ceb Not Valid
NPN bce 0 0 0
NPN bec Not Valid
PNP ebc -2.752130682E-3 -9.232954547E-6 298
PNP cbe -1.775568182E-4 -9.854403409E-6 18
PNP ecb Not Valid
PNP ceb 0 0 0
PNP bce Not Valid
PNP bec 0 0 0
This is a PNP transistor, pinout ebc Gain 298

Note the two lines with a gain are configurations where the collector and emitter

are swapped over. However, you can see the drastic reduction in gain for the
“wrong” pin out.

Out to the desktop
Now that listing is all well and good, but it isn’t a desktop multitasking application.
The code for that is too long to print here, but it’s downloadable at
www.dummies.com/go/raspberrypiprojects. Just like the example in the last
chapter, the listing shown here is the working part of the code. All the rest is wimp
stuff.
Figure 18-14 shows a portion of the screen while it’s running. You just need to
click the Test box to run a new test, and the window displays the gain, transistor
type, and pin out. Happy testing!

Figure 18-14: The desktop transistor application.

Chapter 19

The General-Purpose Input/Output
Port in RISC OS
In This Chapter
Seeing how to access the GPIO pins under RISC OS
Making an LED blink
Mixing BASIC and machine code
In this chapter, we show you how to use the GPIO pins under RISC OS. We present
the obligatory flashing LED, a sort of “Hello world!” for hardware. We also tell
you how to speed up output using machine code embedded into the BASIC
program. Finally, we show you how to read a GPIO input.
When you know the fundamentals of using the GPIO from RISC OS, you can handle
any interfacing project. After reading this chapter, you may want to try to write the
programs for the projects in Chapters 5 and 6 in BBC BASIC instead of the Python
we used. Have fun using this hidden side of the Raspberry Pi!

Using the GPIO Pins in RISC OS
In the last chapter, we look at using the I2C bus, which occupies just two of the
pins of the GPIO connector. Both the Raspberry Pi Model A and the Raspberry Pi
Model B have 17 pins available to control or monitor things, whereas the
Raspberry Pi Model B+ and Raspberry Pi 2 Model B+ have 28 pins. However, in
order to talk to these pins under RISC OS, you have to resort to a little trickery.

The GPIO port is described on page 89 of the Broadcom BCM2835 ARM
Peripherals reference manual (www.raspberrypi.org/wpcontent/uploads/2012/02/BCM2835-ARM-Peripherals.pdf), which may
seem overwhelming at first, but when you break it down isn’t so difficult.
To read or write physical logic levels on those pins you read or write to memory

locations within the chip. These special memory locations are connected to logic
circuits that eventually appear as signals on the GPIO lines. The Raspberry Pi is
made from an advanced chip, so there are many options and modes that the GPIO
pins can operate in, which can be very confusing at first.
Each GPIO pin is capable of being switched between various hardware
peripherals inside the chip. Each pin can be switched to being an input or an
output, but there are six other alternative options for each pin, although not all the
options are actually connected to anything. GPIO pin 18 is one pin with more
alternate functions than most. A diagram of how the GPIO pins are switched, and
GPIO 18 in particular, is shown in Figure 19-1.

Figure 19-1: GPIO pin 18, alternate functions.

This diagram may look complex, but it’s a simplification of how every pin is wired
up. The only difference between this pin and the others is what extra circuitry,
associated with the ALT (alternative) functions, it’s connected to. In a move whose
reason is perhaps known only to the chip designers, the switch positions and the
alternative function numbers do not match up. So, when the switch is in, say,
position 4, as defined by the alternate function register bits for that pin, it is said to
be in the ALT 0 position.
On the end of each pin are two switches allowing the pin to be pulled up, pulled
down, or not connected to either resistor. Pulling a pin gives a default input level,
if needed, for the pin. Note that the resistor values are not very precisely defined,
because it’s difficult to fabricate accurate resistor values in a silicon integrated
circuit (IC). All input pins must be driven to one logic level or the other, and using
an internal pull-up or pull-down resistor is the simplest way to do this.
Most of the time, someone is kind enough to provide a library to sort these registers
and functions into manageable proportions. There are several libraries for GPIO

manipulation under Linux; each language has a choice of more than one. Things are
slightly more complex under RISC OS for two reasons:
The operating system remaps the address of these registers.
The area of memory allocated to these registers is accessible only when the
processor is running in supervisor mode, and you can only enter that from
machine code. Fortunately, using machine code is easy to do from BASIC.

There is a GPIO library, implemented as a relocatable module (RM), from
a user who goes by the name of Tank, at
www.tankstage.co.uk/software.html. RMs are the way RISC OS extends
its operating system. Over the years, the number of modules has grown, and
most of the operating system updates are now performed by adding RMs. This
is the equivalent of libraries or drivers in Linux. You can see what modules
are already loaded by opening a task window (menu-click the raspberry icon)
and type modules. You can save this window or scroll up and down.

Getting an LED to Blink
Time to get practical. Here, we start off by blinking an LED. Every project we’ve
worked on that uses a microcontroller starts off by blinking an LED. At the same
time, you can control the speed of the blinking by a GPIO input. Follow these steps:
1. Attach the cathode (negative end) of an LED to a ground pin, connect the
anode to a 220R resistor, and connect the other end of the resistor to a
GPIO pin.
A photograph and diagram of this are shown in Figure 19-2. Although the pin
out labels in this figure are for a revision 2 or later board, the only pins used
are unchanged on any board revision. We used single-pin header sockets to
connect to the pins, and we soldered the LED and resistor between two of
them. We used GPIO 17 for the LED output and a single wire connected
between GPIO 4 and ground for the speed control input.
2. Download and unpack the GPIO module from
www.tankstage.co.uk/software.html .
3. Double-click the file called GPIO.

This loads in the RM and adds extra software interrupt (SWI) calls to the
operating system. You only need to do this once per boot-up. If you fail to do it,
an error window will appear, telling you that there is an unknown SWI in any
program in which you try to use the GPIO calls. Correctly loading this module
results in no visible feedback.
4. Now create a BASIC file and enter the program shown in Listing 19-1 .
Listing 19-1: LED Blinking
10 :
20 :
30 :
40 :
50 :
60 :
70 :
80 :
control"
90 :
100 :
110 :
120 :
130 :
140 :
150 :
160 :
170 :
180 :
190 :
200 :
210 :
220 :

REM GPIO blink
PRINT"Blink an LED"
PRINT"By Mike Cook"
PinOut%=17
PinIn%=4
SYS "GPIO_WriteMode", PinOut%,1 :REM Make output
SYS "GPIO_WriteMode", PinIn%,&18 :REM Make input with pull up
PRINT "Using GPIO ";PinOut%;" for the LED and ";PinIn%;" for speed
PRINT:PRINT"Escape to end"
REPEAT
SYS "GPIO_WriteData", PinOut%,1
PROC_Delay
SYS "GPIO_WriteData", PinOut%,0
PROC_Delay
UNTIL FALSE
DEF PROC_Delay
T% = TIME + 10
SYS"GPIO_ReadData",PinIn% TO A%
IF A% = 0 THEN T% = T% + 30
REPEAT: UNTIL TIME>T%
ENDPROC

Lines 40 and 50 define what GPIO pins to use for the LED and speed control.
The operating system call in line 60 then sets the output, and line 70 sets the
speed control as an input. Note that the first three bits of the number set the
alternate mode switch, and the next two bits define if there is a pull-up resistor
switched in and if it’s a pull-up or pull-down.

It’s much easier to define bit patterns like this in hexadecimal, because you can see the bit
pattern almost directly. The number we used here is the hexadecimal value 18, which
corresponds to the binary bit pattern 11000.

Finally, an infinite loop is entered that sets the output pin first to a 1 and then to
a 0. This is called toggling. In between each of those operations, a delay
procedure is called. This slows down the program so that you can actually see
the blink. Otherwise, it blinks too fast and you think the LED is on all the time.
The delay procedure sets the variable T% to a time 0.1 second ahead of the
current time (line 180). Then line 190 reads the value on the input pin and puts

it into the variable A%. If this pin is at 0 (that is, it’s grounded), then an extra 0.3
second (or 30 centiseconds) is added to T%. The rest of the procedure then
keeps checking the current time until it exceeds the variable T% when it will
return.
5. Save the file and then double-click it to run.
You should now have a happily blinking LED. Connect a wire between GPIO
pin 4 and ground, and note how the blink rate slows down. Press the Escape
key to stop it and try altering the numbers in the delay function.
6. If you have access to an oscilloscope or a frequency counter, remove lines
120 and 140 and run the code again.
Look at the frequency, and you see that you can change the state of the LED
every 48 microseconds (uS) or so. Although that is by no means the fastest it
can go, this is an interpreted language and there is quite a lot of instruction
needed to change just a single GPIO line.
Note that this pulse train is not totally steady. This is because of interrupts
going off to do things like updating the system TIME variable and looking at the
keyboard input. But it’s much steadier than the equivalent program running
under Linux.

Figure 19-2: Connecting an LED to the GPIO pins.

Mixing Languages
One of the biggest advantages of the RISC OS version of BASIC is that you can

drop into machine code any time you need to make something go faster. Machine
code is the raw language of the processor, so it executes at maximum speed. It isn’t
difficult to learn, but it is different.
The processor has 16 registers — R0 through R15 — or internal memory locations,
to play about with. R15 is used as the program counter, so generally you don’t use
that. Registers R14 and R13 also have special uses with this operating system, as
the return address storage and stack pointer, respectively, so you should avoid
them. All the others are up for general use. You can also load and store registers in
memory, but many of the machine code functions you may be writing don’t involve
that.

A good introduction to machine code programming is given in Appendix A
of Volume 4 of the Programmers Reference Manual (PRM), which is already
in the documentation directory of the RISC OS distribution. Alternatively, an
up-to-date version is online at
www.riscos.com/support/developers/prm/asm.html.
You use machine code from BASIC a bit like an assembler. You program in
mnemonics, and when you run the program, BASIC turns this into machine code
and places it into memory. For forward referencing (referring to memory location
labels the assembler has not seen yet), you need the assembler to make two passes.
This is done with a FOR loop and suppressing the errors during the first pass with
the OPT call. You can save that memory block the machine code has been
assembled into and load it into future programs if you like. But by far the simplest
method is to run it in the same program because assembly is very quick and
happens one time only.
As an example of using machine code, we’ve taken the LED blinking code, with no
delays, and turned it into machine code version shown in Listing 19-2.

Listing 19-2: Simple Machine Code Blink
10
20
30
40
50
60
70
80
90
100
110

:
:
:
:
:
:
:
:
:
:
:

REM GPIO Speed Test
PRINT"GPIO Speed Test"
PRINT"By Mike Cook"
PRINT"How fast can machine code flash an LED:-"
Pin%=17
SYS "GPIO_WriteMode", Pin%,1 :REM Make output
PRINT"Using GPIO ";Pin%
DIM CODE% 255
FOR A%=0 TO 3 STEP 3
P% = CODE%
[

120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

OPT A%
.entry
MOV R8,#&300000 :REM Change for longer time
.loop
MOV R0,#Pin%
MOV R1,#1
SWI "GPIO_WriteData"
MOV R0,#Pin%
MOV R1,#0
SWI "GPIO_WriteData"
SUBS R8,R8,#1
BNE loop
MOVS PC,R14 : REM return to BASIC
]
NEXT
REPEAT
PRINT "This will flash for 5 seconds"
PRINT "Any key to continue - escape to quit now"
A$ = GET$
CALL entry
UNTIL FALSE

This is still using the system calls that the GPIO module gives, but this time they’re
called from machine code. This means that they aren’t interpreted by the BASIC
language. You can’t stop a machine code loop with the Escape key. We’ve written
this program so that it loops for a fixed number of cycles before returning to
BASIC. This takes about five seconds.
When calling an SWI from machine code, the parameters are passed and returned
in the registers, using R0 for the first parameters, R1 for the next, and so on. When
the SWI returns, R0 will contain the first returned value, R1 the second, and so on.
Most calls have only one or two parameters. This explains why R0 needs to be
loaded with the pin number to write to just before every call, because the value in
R0 is overridden by the call itself when it exits.
Note that you can use variables set up in BASIC in your machine code, so the pin
number to output to is what has been set up before. However, once the code is
assembled, any further changes in that variable will not be recognized. Register R8
has a big number in it — it is the number of cycles to flash the LED before ending.
After each flash, line 220 decrements this number and if it hasn’t reached 0, it
jumps back to the “loop” label.
When you run this, you see that the LED looks like it’s permanently on, but a bit
dimmer than before. If you look at this pin with an oscilloscope, you see that it’s
rapidly turning on and off. Figure 19-3 shows a screenshot from our oscilloscope.

Figure 19-3: The GPIO pin running Listing 19-2.

Basically, an oscilloscope gives you a graph of voltage against time. You can see
that the pin is spending 780 nS high and then going low for about the same amount
of time, which gives a frequency of 673kHz. The SWI is still doing a lot of work
behind the scenes, and the absolute maximum speed you could toggle that pin is
about 20MHz with the right software. Of course, at that speed, there is no time to
do anything else.
In Tank’s download, there is an application called !GPIOconfig. If you click that
application, you get a graphic representation of the GPIO connector, which will
change depending on whether you’re using a Model B or a Model B+. Pins are
shown outlined in red for inputs or green for outputs, and, rather cleverly, the
center of the pin is filled in for a logic 1 and gray for a logic 0. The GPIO pins are
already set up after running the last program, so you can see the link being
connected and disconnected on pin 4 and, by clicking pin 17, you can make the
LED turn on and off. A menu-click on any pin will bring up a small menu allowing
you to select the mode of operation for the pin. Figure 19-4 shows this application
for a Model B+.

Figure 19-4: !GPIOconfig graphic GPIO monitoring.

Part VI

The Part of Tens

Find ten great online Raspberry Pi resources in a free article at
www.dummies.com/extras/raspberrypiprojects.

In this part …
Find ten great LEGO Raspberry Pi projects from around the Internet.
Find out about ten reliable suppliers of tools and components and learn about
different classes of suppliers.

Chapter 20

Ten Great LEGO Pi Projects
In This Chapter
Uncovering useful and interesting LEGO contraptions
Using LEGO bricks with commercial software
Bringing your old RXC brick back to life
LEGO bricks are great mechanical prototyping tools. They allow you to explore
mechanical design with the minimum of tooling and construction. Although some
people see them as nothing more than children’s toys, those who know better see
working with LEGO bricks as an exciting and quick way to give a physical side to
your electronic projects.

Panobot
Created by Andrew Mulholland, the Panobot (http://pi.gbaman.info/?p=174)
allows the Raspberry Pi to take a series of pictures using the Raspberry Pi camera.
These pictures can then be stitched together to produce spectacular panoramic
pictures. The Panobot works by moving the camera both up and down and left and
right. It’s run by a Python script, which allows you to set how wide the panorama
should be and how many elevation pictures to take. After the images are taken, you
download them to a laptop and stitch them together into one image using the
application Hugin (http://hugin.sourceforge.net).
Andrew is a teacher in Northern Island who formed a robotics club at his school.
The club won the FLL Northern Ireland Technical Design Award in 2012 and came
in first in the category in the UK-wide PA Consulting Raspberry Pi competition. A
photograph taken with the Panobot won the 2014 Adafruit Raspberry Pi photograph
competition for Andrew as well.

MATLAB and Simulink
Not so much a single project but a whole bunch of projects using the Simulink

package of the MATLAB language, this is a two-wheel balancing, edge-following,
and obstacle-avoiding robot (http://makerzone.mathworks.com/lego). It can
even balance on a ball, all from LEGO. MATLAB isn’t free — a home license
costs $149 as of this writing.

Raspberry Pi LEGO Case
There are lots of takes on producing a case for your Raspberry Pi using LEGO
bricks. This may not be the most high-tech project you’ll come across, but it’s
simple, fun, and practical! You can be creative and make your own unique case, or
you can copy a case someone else has made — just search the web for images
using the keywords “Raspberry Pi case.” We particularly like the one at
www.raspberrypi-spy.co.uk/2012/06/my-raspberry-pi-lego-case.

Book Reader
With a handful of LEGO bricks, a Raspberry Pi, and a Raspberry Pi camera, you
can make a book reader. The camera takes photographs of the pages of the book
and, using optical character recognition software, converts it into a text file. A
LEGO contraption turns the pages of the book, and you can even use some free textto-speech software to read the book out loud. This project requires a BrickPi
(www.dexterindustries.com/BrickPi) for the control. Find out more at
http://makezine.com/projects/lego-bookreader-digitize-books-withmindstorms-and-raspberry-pi.

A Stop-Motion LEGO Movie
Be the next Nick Parker — make your own LEGO movie using the Raspberry Pi!
You can create your own original film, or re-create a popular film or sporting
event. During the FIFA World Cup 2014, England’s goals were successfully
reproduced by stop-motion LEGO (http://gu.com/p/3q643/stw). Matches
involving the United States have also been reproduced in LEGO. You can find the
project code and worksheets at www.raspberrypi.org/learning/pushbutton-stop-motion.

SriShooter
Using your mouse, a BrickPi, and the Raspberry Pi, you can control a ball-shooting
robot to freak out your family. You can find the materials you need at
www.dexterindustries.com/BrickPi/projects/shooter.

browserBot
browserBot is a web-browser-controlled robot using the BrickPi. You can control
it from any computer, phone, or tablet connected to the same network, with only a
few lines of code. This is a great beginner’s project using the dedicated Raspberry
Pi extension controller board. Find out more at
www.dexterindustries.com/BrickPi/projects/browserbot.

BrickPi Remote Sentry Cannon

Using the Raspberry Pi camera with a gun sight overlay, this project employs a
Python program to aim and fire a LEGO cannon via a network connection. Jasper
Hayler-Goodall put this together using a BrickPi interface and the SriShooter to
locate a target and fire. This just uses one axis of rotation to steer the robot and has
a Pygame interface, which introduces a bit of lag into the video feedback. It isn’t a
perfect project, which means that it’s ripe for improvement! Check it out along with
Jasper’s camera-feed remote-control vehicle, at http://topshed.tumblr.com.

LEGO Digital Clock
Hans Anderson designed a digital clock where the numbers are displayed on the
face of Rubik’s Cube–like blocks. Then blogger dwalton76 took it and wrote a
version to use with the Raspberry Pi using Python and the BrickPi. The results are
quite stunning. You can find out more at
http://programmablebrick.blogspot.co.uk/2014/06/lego-digitalclock.html.

The Original LEGO MINDSTORMS
The original LEGO MINDSTORMS RCX kit has not been forgotten! This project
shows you how to program it using your Raspberry Pi and a language called NQC.
NQC stands for Not Quite C. It’s a simple C-like language that you can use to
program the original LEGO control brick using the USB IR tower of the 2.0 version
of the kit or the serial IR interface of the earlier ones. There are still lots of
projects online for the older system. Go to
http://minordiscoveries.wordpress.com/2014/01/20/using-nqc-on-araspberry-pi-to-program-a-lego-mindstorms-rcx-brick to find out how to

recompile the NQC compiler, as well as how to get the base software on the brick.
This project may be a bit involved, but it’s worth it to bring your old controller
back to life with the Raspberry Pi!

Chapter 21

Ten Suppliers of Components and
Tools
In This Chapter
Understanding the difference between a manufacturer, a distributor, and a
supplier
Finding hobbyist-friendly resources
Discovering the big five worldwide distributors
No matter what project you undertake, you need the right components, the right
tools, and the idea. Most of this book is about the idea, but components and tools
are vital for any project’s success, and that’s where this chapter comes in.

Farnell/Newark
Farnell (known as Newark in the United States) is a major distributor and partner
of the Raspberry Pi Foundation. It has a vast range of parts, but it does tend to
charge top price, and some one-off delivery charges on some items are high. You
can start shopping at www.farnell.com or www.newark.com. A subsidiary of
Farnell, called CPC, handles most hobby orders. Next-day delivery ensures
minimum disruption to your projects.
Farnell also runs element14, a forum for developers and hobbyists, with web
events, video tutorials, and webinars. You can find out more at
www.element14.com.

RS Components
RS Components is the other major UK distributor. It used to be known as Radio
Spares (not to be confused with Radio Shack in the United States). RS Components
is hobbyist friendly and carries a great range of stock. Along with Farnell, it
oversees the production and distribution of the Raspberry Pi. Find out more at

www.rs-online.com.

Rapid Electronics
Rapid (www.rapidonline.com) tends to have some parts that are a lot cheaper
than Farnell/Newark and RS Components, and it also has a specialized education
section. Rapid’s website is more hobbyist friendly, and although it doesn’t have as
wide a range as some distributors, it’s worth looking at.

Mouser Electronics
Mouser (www.mouser.com) is another major distributor, bigger in the United States
than in the UK, but still accessible worldwide. It has a wide range of items in stock
and offers free shipping in the UK on orders over £50.

Digi-Key
The last of the big five major distributors, Digi-Key (www.digikey.com) ships
product to more than 170 countries worldwide from a single location in Thief
River Falls, Minnesota. It has a wide range of products and easily accessible data
sheets, along with a good search section.

Proxxon
Proxxon (www.proxxon.com) is a German manufacturer of small, high-precision
tools. Its tools aren’t the cheapest, but they’re the best we’ve come across. Often,
small tools are just cut-down versions of larger ones, but Proxxon understand that,
as you go smaller, you have to push up the precision of the tool. One of this book’s
authors, Mike Cook, couldn’t be without his bench drill press, bench circular saw,
and disc sander. They’re made for light work and are ideal for model making and
prototyping.

Adafruit
Adafruit (www.adafruit.com), founded by the now legendary Limor Fried (one of
the founders of the open-source movement), is a strange hybrid of supplier and
designer of hobbyist-friendly boards and sub systems. It supplies its own designs,

taking advantage of whatever interesting components come on the market. Adafruit
has produced a number of Raspberry Pi expansion boards, which it calls plates. It
also organizes competitions and has regular live podcasts with a strong
learning/teaching bias. Adafruit is based in the United States but has distributors in
many countries.

SparkFun
SparkFun (www.sparkfun.com) is another hybrid supplier/designer like Adafruit,
with its own manufacturing facility. As its name implies, SparkFun is enthusiastic
and puts the fun into the subject. It offers a great many breakout boards, which are
small PCB boards with a surface-mounted IC with easy soldered or breadboard
access to the chips. Mainly a U.S.-based company, SparkFun has some worldwide
distributors.

Electronic Goldmine
Electronic Goldmine (www.goldmine-elec-products.com) specializes in
surplus components and equipment and is a veritable treasure trove of electronic
delights. This is the sort of place you don’t so much go looking for something
specific, but instead look through its catalog and think, “Ooh, I could use that for…
.”

E.M.A. Model Supplies
Electronic components are important, but so is the enclosure you put them in.
Companies like E.M.A. (www.ema-models.co.uk) supply parts for making the
mechanical components of a project, from sheet plastic to plastic beams, screws to
glue, as well as a few tools.

Straight talk about pricing
The main problem with components and tools is that consumer electronics have given people the
wrong idea about cost. In the past, it was always cheaper to make something yourself. Unfortunately,
electronics doesn’t work like that today. The process needed to make integrated circuits is, by and
large, the same no matter how complex the circuit is; but when you go to buy one, you’ll see a vast
range of prices. This range of prices is mainly due to how new a device is, where the manufacturers
are trying to cover their development cost, what the yield is (how many actually work off the end of the
line), and last but no means least, the number you want to buy. When buying parts, quantity is
everything.

Now, we’re not talking about the quantities that the average hobbyist may buy. We’re talking about
industrial quantities that are measured in the millions of parts. Sure, there are small price breaks
(sometimes for 10 or 100 of a single part), but most manufacturers won’t get out of bed for anything
less than half a million. This is where distributors come in. They buy in bulk and sell to smaller
buyers, taking a cut.
The last in the chain are the suppliers, which are different from distributors in that they’re specifically
geared toward hobbyists. By and large, suppliers sell you quality parts. But the new players on the
block are the many suppliers on sites like eBay. They may have prices that look too good to be true
— and in some cases, they are. A lot of these suppliers have limited quantities of end-of-line stock
picked up for next to nothing, or even access to the reject bin of manufacturers, so you don’t always
get what you think, or the supply is limited. You can get some bargains, but you can also end up with
junk. You can even find yourself with some fakes, where the chip actually looks fine but nothing is
inside. Buying from less-than-reputable sites is a gamble, and there is little chance of getting your
money back if anything goes wrong. You can’t go wrong with the suppliers we mention in this chapter,
but when you start shopping elsewhere, do your research and be prepared to get what you paid for it.

About the Authors
Mike Cook: Mike has been making electronic things since he was at school.
Former Lecturer in Physics at Manchester Metropolitan University, he wrote more
than 300 computing and electronics articles in the pages of computer magazines for
20 years starting in the 1980s. Leaving the university after 21 years when the
Physics Department closed down, he got a series of proper jobs where he designed
digital TV set-top boxes and access control systems. Now retired and freelancing,
he spends his days surrounded by wires, exhibiting at maker fairs, and patrolling
the forums as Grumpy Mike.
Jonathan Evans: Jonathan has a lifelong interest in computers and electronics.
Captivated by the microcomputer age in the 1980s, he taught himself how to
program a computer and quickly learned the marriage between computers and
electronics. He has gone on to become a distinguished IT professional with more
than 20 years of experience. His passion for creation and innovation combines
perfectly with the Raspberry Pi phenomenon. In his spare time, he enjoys exploring
projects to make the Raspberry Pi relevant to everyday life. He enjoys sharing his
ideas at http://projects.privateeyepi.com, where he continues to explore
the endless possibilities of this computing platform.
Brock Craft: Brock is a lecturer in creative coding in the Department of
Computing at Goldsmiths, University of London, and a senior tutor at the Royal
College of Art. He is a specialist in physical computing, data visualization, and the
Internet of Things. Brock’s background is in the field of human–computer
interaction; he has more than a decade of experience making interactive things that
people can use, explore, and play with. When he isn’t teaching and learning, Brock
likes to make interactive stuff and digital art.

Dedication
To my sons, Alec and Graham. I am very proud of them both. As different as chalk
and cheese while being the same as peas in a pod.
—Mike Cook
For Joann, Gabriella, and Jemma.
—Jonathan Evans
For Barbara and Eleanor.
—Brock Craft

Authors’ Acknowledgments
I would like to thank Brock Craft and Jonathan Evans for their contributions to this
book. I would also like to thank the staff at John Wiley & Sons for all their help,
encouragement, cajoling, and cooperation, especially Craig Smith, Katie Mohr,
Linda Morris, and Elizabeth Kuball.
—Mike Cook
Thanks to my wonderful family for allowing me the space to dedicate time to this
book. Thanks also to the talented staff at Wiley, in particular Craig Smith, who
spotted me and converted me from blogger to writer. Full credit to my two coauthors, especially Mike, who provided technical assistance with Chapter 9:
Advanced Interfaces and whose idea spawned the Connect Four section in Chapter
11: Webcam and Computer Vision.
—Jonathan Evans
Putting this book together has been a long and rewarding process. It would not have
been possible without the support of my family, colleagues, and friends, to whom I
owe a tremendous debt of gratitude. I also thank my many students, whose
questions have inspired me to come up with all kinds of new projects and ideas.
Finally, I acknowledge the tireless work of my co-authors, with whom I’ve had the
great pleasure to collaborate.
—Brock Craft

Publisher’s Acknowledgments
Senior Acquisitions Editor: Katie Mohr
Project Editor: Elizabeth Kuball
Copy Editor: Elizabeth Kuball
Technical Editor: Daniel Soltis
Production Editor: Vinitha Vikraman
Cover Image: © Mike Cook

To access the cheat sheet specifically for this book, go to
www.dummies.com/cheatsheet/raspberrypiprojects.

Find out "HOW" at Dummies.com

Take Dummies with you everywhere
you go!

Go to our Website

Like us on Facebook

Follow us on Twitter

Watch us on YouTube

Join us on LinkedIn

Pin us on Pinterest

Circle us on google+

Subscribe to our newsletter

Create your own Dummies book cover

Shop Online

WILEY END USER LICENSE
AGREEMENT
Go to www.wiley.com/go/eula to access Wiley’s ebook EULA.



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Author                          : Mike Cook
Create Date                     : 2015:08:06 08:43:17+00:00
Producer                        : calibre 1.31.0 [http://calibre-ebook.com]
Description                     : 
Title                           : Raspberry Pi® Projects For Dummies®
Publisher                       : 
Subject                         : 
Creator                         : Mike Cook
Date                            : 2015:01:29 16:00:00-08:00
Language                        : en
Identifier Scheme               : isbn
Identifier                      : 9781118766712
Metadata Date                   : 2015:08:06 01:43:17.730000-07:00
ISBN                            : 9781118766712
Isbn                            : 9781118766712
Timestamp                       : 2015:08:06 01:42:35.768000-07:00
Page Count                      : 498
EXIF Metadata provided by EXIF.tools

Navigation menu