Understanding SPI on the Raspberry Pi

I’ve been asked to include SPI (and I2C – more on that soon) support for the Raspberry Pi in my wiringPi… However because it’s hard to anticipate exactly what SPI devices you may connect up, it’s hard to provide something specific, so what I’ve done is provide some “helper” functions in a library and a guide on how to use SPI and what it’s all about…

SPI – Serial Peripheral Interface

SPI is an interface developed (or named?) by Motorola which is a Synchronous serial clocked, full-duplex master/slave bus….

That’s a mouthful. In essence, data is sent out synchronised (or locked) to a clock signal which is also sent out (so 2 wires), there is a separate wire for incoming data (3 wires, so data can be sent and received at the same time, so full-duplex) and a fourth wire to act as a “chip select” signal. Because of this, it’s sometimes called a 4-wire bus. The master/slave part indicates that any device on the bus can start a transmission to any other device on the bus. There can be multiple chip-select wires to talk to multiple devices on the same SPI bus.

The Raspberry Pi only implements master mode at this time and has 2 chip-select pins, so can control 2 SPI devices. (Although some devices have their own sub-addressing scheme so you can put more of them on the same bus)

One thing to remember about SPI is that to receive a byte, you need to send a byte. This may sound a little odd, but consider a device which accepts a command byte, then a data byte, then sends back a result byte… To make this happen, we need to send three bytes to the device, which will send back 2 dummy bytes, followed by the 3rd byte with data in it. For example, a GPIO expander chip (e.g. the MCP23S17 as used in the PiFace) where you send it a command (read register), then the data (the register number), then it sends back a return value (the register contents). So, when you send the command, it will send back a byte which you ignore, you send it the data, it sends back a byte which you also ignore, but to make it send the result, you need to send it a third byte which it will ignore!

Another example is the MCP3002 2-channel, 10-bit analog to digital converter chip as used the the Gertboard – that chip actually uses the SPI clock signal to drive its internal logic. The command sequence you send to it is only 4 bits long, but you get 10 bits of data back from it, starting one bit after the last command-bit… so you need to send it 2 bytes and read 2 bytes back from it, and in the 2 bytes back, the data starts at the 5th bit and extends for 10 bits, so to keep the clock going, you need to send 2 bytes, read 2 bytes then pick the 10 data bits out of the returning 16 bits…

So it’s not always obvious!

Installing the kernel driver

The Linux kernel in recent Raspberry Pi releases supports the SPI as a native device (no more bit-banging!) but it’s disabled by default, so we need to load the module before we can use the SPI device. Additionally we may need to change the permissions and/or ownerships of the files in /dev/ so that we can access them from out programs without needing to be root or run them with sudo.

The easiest way to do this is with the gpio program that’s part of wiringPi:

(Instructions to get and install wiringPi are here)

gpio load spi

That command will load the SPI driver and change ownership to the user running the command. Once we’ve done that, we can then run our SPI programs.

If you want to do it the hard/traditional way, then:

sudo modprobe spi_bcm2708
sudo chown `id -u`.`id -g` /dev/spidev0.*

Use the lsmod command to make sure the modules are loaded.

Using SPI

WiringPi provides a small library to help hide most of the issues dealing with opening and sending bytes to/from SPI devices, however if you need something that’s outside what this library can do, then you’ll need to write your own – however the library code is easy to follow, so you should be able to use that as a basis for your own code.

These are documented elsewhere, but in-essence:

if (wiringPiSPISetup (channel, 1000000) < 0)
  fprintf (stderr, "SPI Setup failed: %s\n", strerror (errno))

will get you going (channel is 0 or 1, the 1000000 is the speed – 1MHz here) and:

wiringPiSPIDataRW (buffer, size) ;

will then perform a concurrent transmit and receive of the contents of the buffer (unsigned chars) of the given size. Note that the buffer will be overwritten.

Do have a look at the gertboard.c library for examples of this code – in particular the analog read function, where it sends a command to the SPI A/D converter and reads back the data in the same transaction – then picks the data out of the return bytes.

Abusing SPI

Abusing is perhaps a harsh word here, but it’s possible to use the SPI bus for things that weren’t designed for SPI – one example is shift registers. Just use the clock and MOSI outputs, and write a byte at a time to the SPI device. Another use is the daisy-chained LED strings that are now available at a reasonable price – you can send up to 4096 bytes at a time which might represent a string of over 1000 LEDs, each accepting a 3-byte value, then pause (typically 500μS) to make the devices display the pattern.

SPI Speed?

An important aspect of SPI is that the clock can (usually) be driven at varying speeds – the dependence is usually on the peripheral device being driven. E.g. the analog to digital converter on the Gertboard must be driven at a speed between 1MHz and 3MHz – however the upper limit is the voltage it’s supplied with (3MHz max. at 5v), so it’s important to know in-advance what limitations of the devices you are talking to.

To experiment with timings, I wrote a little test program to see the effects of the different speeds – starting at 0.5Mb/sec going up to 62Mb/sec. I simply looped the MOSI and MISO pins together and checked that the data received was the same as the data sent.

The first thing I found was that the Pi stops sending at clock speeds over 62Mb/sec., and that in-reality 32Mbs is the upper limit of the SPI clock.

Next, I noticed that for some clock speeds, the data rate doesn’t change – this is due to the rounding issues when calculating the clock divider value. What I have observed is that the speeds available are:

  1. 0.5 MHz
  2. 1 MHz
  3. 2 MHz
  4. 4 MHz
  5. 8 MHz
  6. 16 MHz and
  7. 32 MHz.

You can see the progression, it’s powers of 2, and this reflects the clock divider values too.

The important thing to realise is that if you are clocking a part designed for a SPI clock rate of 25MHz, then setting the clock to 25MHz will really create a clock of 16MHz. There is no way to get an exact 25MHz clock speed. This probably isn’t important, and the reality of trying to send a 25MHz signal down a pair of wires or along a PCB track is that it’s highly likely to not work unless you take good care with the signal routing, shielding and so on.

Another observation was that the overheads in the Linux kernel increase with clock speed and the data throughput doesn’t quite increase linearly with clock speed. So with a clock at 1MHz we get a throughput of 0.108 MB/sec, at 2MHz it’s 0.214 MB/sec and it more or less doubles up to 16MHz (1.55MB/sec) but at 32Mb/sec clock, it’s barely 2.2MB/sec when you might expect it to be closer to 3MB/sec.

Finally, it’s worth while noting that the actual latency of calling the wiringPiSPIDataRW() function is rather high – an example I tested was sending 2 bytes at a time to the Gertboards digital to analog converter and rather than the 50,000 updates/sec I was expecting I was seeing barely half that, and a few experiments shows that it wasn’t that tied to the SPI clock frequency either.

Summary:

SPI is easy to use and can be fast. Be aware that communication is full duplex and data comes back at the same time as you send it, so be prepared to pick bits out of the return data – often at funny bit offsets, rather than byte offsets. The Pi can only directly drive 2 SPI channels, but some devices have their own sub-addressing scheme to allow for more on the same bus.

Software PWM on the Raspberry Pi

Frustrated by the fact there there is only one easily accessible PWM output on your Raspberry Pi? Then this article is for you, because now you can use ANY GPIO pin as a PWM output thanks to the latest addition to wiringPi

The latest addition is a software driven PWM generator that runs as a thread in the background of your program managing the outputs of the pins in a PWM manner. It can be used to control any number of pins on your Pi – from 1 to all 17 if desired.

The down-side? Well, like my 7-Segment LED driver, it’s not perfect. Even though it runs at a high priority using a real-time scheduler inside Linux, it’s still prone to being temporarily descheduled for a fraction of a second, however for  driving LEDs and motors, it should be fine. The other overhead since it’s software driven is CPU cycles – and in the default configuration with a base PWM frequency of 100Hz, then the overhead is about 0.5% per pin. It’s not really practical to increase the base frequency without CPU usage going through the roof, or the resolution (range) going through the floor. The minimum pulse-width is 100μS due to Linux timing issues – combine that with a range of “100” and you get a frequency of 100Hz. (See the code for more details).

Oscilloscope output of 3 PWMs

Oscilloscope output of 3 PWMs

The ‘scope trace above shows… The Purple trace is the one it’s triggering one and that represents an output value of 10 – the vertical markers and the ΔT measurement shows 1mS which is right – 10 x 100μS pulses. If you count the dotted squares, there are 5 between the leading edges of the rising edge in the Purple trace which at 2mS per division is 10mS giving a PWM frequency of 100Hz.

The Yellow trace is an output value of 25 and the Cyan trace has an output value of 50.

Each PWM signal is generated by a separate thread so they all run independantly of each other. The traces are surprisingly steady though.

Finally, one of my infamous videos:

NES Controller on the Raspberry Pi

Part 1: The Hardware & Driver

Some time back, I joked that the Raspberry Pi’s GPIO port really stood for Game Port IO… So to make that joke come true, I present a way of interfacing the NES Joysticks to the Raspberry Pi.

First you need the joystick/controller unit, and a quick trip to the Plymouth Market where I’d had a tip that there was a stall selling retro gaming gear and I returned with a pair of them for under a tenner. Bargain!

NES Joystick

NES Joystick/Game Controller

Note the weird 7-pin connector. You can buy sockets for this off eBay and if you currently own an old console, then you may wish to pursue this approach, but as I don’t own a console (and am unlikely to ever own one!) I decided to chop the connector off…

(Yes, sorry – if you’re a retro gaming enthusiast, I know you can now buy matching sockets for them, but I really didn’t want to go to the added expense, and I did leave a long enough tail on the plug so that I could re-connect it should I ever have the need…)

Inside, I found 5 wires… 5 wires and 8 buttons. Curious, but some googling later and I found this diagram:

NES Controller Schematic

NES Controller Schematic

Many thanks to Seb for letting me post it here.

And if you don’t read German, the colours on the diagram are (from the top down), White, Brown, Yellow, Orange and Red.

So what’s inside is a 4021N CMOS shift register. This has the task of sampling 8 buttons and then makes the data available via a serial interface controlled by 2 pins – a latch and a clock. The way it’s wired up requires one latch pulse and 7 clock pulses to get all 8 data bits out, but this is easily accomplished in software.

Some wire trimming, soldering and heat shrinking later and I end up with a pair of joysticks with pins on the ends:

Two NES Controllers on a Pi

Two NES Controllers on a Pi

I took 5 short male/male breadboard patch leads, chopped them in half and soldered & heat-shrunk them on. I’d no brown patch leads, so I used green here. I’m using an Adafruit Cobler breakout just because it was next to me and already plugged into a Pi, but when I first developed it, I used the cute little Piio protoboard from DTRONIXS:

NES Controller on a Mini Piio Protoboard

NES Controller on a Mini Piio Protoboard

So you have plenty of options for hooking them up…

You could even make some sort of plug & socket arrangement and I may do just that in the near future too… The thing to note is that you have to split power (3.3v) to go to both controllers, then separate the 3 data/clock/latch pins…

In-theory the Pi can drive 5 Joysticks without any issues and I suspect (but haven’t tested it yet) that you can double up on the either the latch or clock pin, so 3 pins for the first controller, then 2 pins for each subsequent one, giving the possibility of connecting up 8 joysticks if you were really inclined to do so!

So I’ve catered for up to 8 joysticks in my driver code and made the code part of the wiringPi library. (It needs wiringPi to drive the GPIO pins anyway) The library is simple enough – firstly initialise wiringPi in either native pins mode, or GPIO mode (You can use Sys mode, but it’s really quite slow!), then call the NES controller setup code to tell it what pins to use, then you can read the controller. So:

#include <wiringPi.h>
#include <piNes.h>
...
 if (wiringPiSetupGpio () < 0)
  {
    fprintf (stderr, "Can't setup GPIO: %s\n", strerror (errno)) ;
    exit (1) ;
  }

// Data on pin 21, Clock on pin 18, Latch on pin 17
//    (BCM_GPIO pin numbers)

  if ((joystick = setupNesJoystick (21, 18, 17)) == -1)
  {
    fprintf (stderr, "Unable to setup joystick\n") ;
    return 1 ;
  }

  buttons = readNesJoystick (joystick) ;
  if ((buttons & NES_UP) != 0)
    // The Up button is being pushed

Do see the nes.c program in the examples directory and refer to the piNes.h file for the defined constants for each button. It is possible to read simultaneous multiple button pushes – the return from readNesJoystick is an 8-bit value with one bit set per button.

Now we have joysticks, we need a game, and to get something going quickly I used my BASIC and wrote a simple game of Pong (aka Tennis) which I’ll describe tomorrow!

Adafruit Protoplate for the Rasbperry Pi

As part of my Big Trak refurbishment (not going as well as I wanted it to), I decided to use the Adafruit Prototyping Pi Plate to mount the additional electronics on. If you’re not familiar with it, then this is it:

Adafruit Prototyping Pi Plate

Adafruit Prototyping Pi Plate

So it’s a double-sided PCB with a GPIO connector tracked to various pads round the outside of the board with space to solder in headers or screw-terminals (or both!), as well as having space in the middle to solder components to, supporting a standard DIL type layout, SOIC chip mounting pads and an open area.

An interesting feature is that it extends the GPIO pins through the board, giving the possibility for stacking – almost like an Arduino shield…

So for the Pi Trak, what I needed to do:

  • Power supply. Powering the Pi off batteries, I needed a regulator to feed a stable 5V supply into the Pi.
  • A motor controller. Essentially a dual H-bridge controller of some sort.
  • Interface from a wheel position sensor of some sort.
  • Interface to the keypad.

As I was running out of time to produce a prototype, I used a handy 7805 type regulator. This is great, but not too efficient – ie. it gets a bit hot when fed from 9v.

The keypad was originally going to be the Big Traks own keypad, but I substituted one I’d made earlier (some 25 years ago!) – it’s a simple 4×4 matrix and you can see 4 resistors on the protoboard. There is a 5th next to them which acts as a limiter for the LED that’s on one of the switches.

Keypad next to the Protoboard

Keypad next to the Protoboard

For the motor controller, I used the Pololu TB6612FNG unit which I bought locally via SKPang. (The Adafruit parts were supplied directly from the US, but note than SKPang now stock Adafruit components on the UK!)

The wheel position sensor was an interesting one – initially I thought I could use a Lego sensor (since the rest of the thing was going to be made out of Lego by that point), however it turns out the Lego rotation sensor is analog – and outputs 4 different voltages depending on the angle… So a Plan B was hatched and I re-cycled the sensor from the original Big Track – seen here under test using the Adafruit Cobler board:

Using the Adafruit Cobler to test the wheel sensor

Using the Adafruit Cobler to test the wheel sensor

The wheel rotation sensor is the board to the left – it’s nothing more than an infra-red LED pointing to an IR photo diode. With a suitable current limiting resistor on the LED, the photo diode can be connected directly to one of the Pi’s GPIO inputs.

I also used to to test the motor driver too. I was a very easy way to do some “rapid prototyping” before committing to solder!

The end results was this:

Raspberry Pi plus "PiTrak" Adafruit Protoboard

Raspberry Pi plus “PiTrak” Adafruit Protoboard

Closer view of the top of the PiTrak Controller

Closer view of the top of the PiTrak Controller

Solder Side of the PiTrak Controller

Solder Side of the PiTrak Controller

This was the first time I’d used a board like this – more often I’d build projects on a re-usable breadboard, or on stripboard, so it did pose a few issues which I’d never encountered – The DIL area where I mounted the voltage regulator and the motor controller seemed fairly straightforwards, but with hindsight, I’d have made some of the links to the +3.3v and 0v supplies under the motor controller! In the open area, I cheated and just bent the wires of the components over to touch the pins of the 8-way socket I’d soldered on. Is that cheating, or is it the way everyone else does it? (Sensible answers please!)

However, overall, the board was very easy to work with – and does look a lot more professional than just hacking together some stripboard, and combine the board with the Adafruit case as I’ve done here, and it does open up many more possibilities for Pi interfacing projects.

Finally:

Lego PiTrak Mk.1

Lego PiTrak Mk.1

This is the Mk1 Lego PiTrak. Much room for improvement and I need to mount the keypad on it – also want to put on an LCD display, so watch this space as they say…

Bristol RaspberryJam

Just a quick post and a few photos from last nights RaspberryJam in Bristol – held in the most excellent Bristol and Bath Science Park.

Alan (@teknoteacher) the driving force behind the RaspberryJams, was on-form as usual, keeping everything flowing nicely with his usual jokes, and while I didn’t count the people, there seemed to be well over 100 attending! There was a nice time to do some networking before the main event (spread the jam as Alan says!), then the talks then a big break-out session afterwards with people showing off what they’re doing with their Pi’s and so on.

I did a one of the talks, and while it wasn’t quite fully what I’d planned, due to some technical hitches before-hand with Keith Dunlops presentation – all about RiscOS on the Pi…

(The Pi is a bit of a fussy little beast which won’t normally output to HDMI when it doesn’t detect a “live” HDMI display connected to it, so when you connect a Pi into a fancy multi-switching input thingy, unless the switch is set to take the HDMI input, then the Pi won’t boot up in HDMI mode!)

However after that delay, as Keith often ends his talk with BBC BASIC running under RiscOS on the Pi, I cut my talk a little short and spoke more about my BASIC than what I’d fully planned to speak about – however the essence of what I was going to saw was that programming (or Software engineering!) isn’t just about glitzy/glamorous web “apps” with shiny graphics and fancy buttons… Programming also encompasses a lot more – which some people think is boring, but others (like me) find much more exciting – and that’s the world of computer control.

I also think of myself as a Programmer or Software Engineer. I’m not a developer – I’ll leave that term for the airy fairy web people 😉

So, someone, somewhere has to write the code that drives the braking system on your car, the engine management and so on. Someone has to write the low-level software for your hand held GPS, your microwave, your washing machine, etc. Someone (or probably some team!) wrote the software for the Mars Curiosity robot – now there’s a project you can’t afford to get wrong!

And if you’re wondering who wrote the software for some of these things, and thinking it’s some underpaid chap in India or China, then think again – Heber who hosted the RaspberryJam last night is based in the UK, manufacture their own control boards (in the UK!) and write software for things as diverse as vending machines to the Dyson Washing machine!

Here’s a few photos from the evening:

 

Links to other peoples photos, etc.:

Learning GIT

I’ve decided to start to use the GIT Source Code Management system… So hoe better to learn about it than to jump in at the deep end and actually use it for a project… So to that end, I’ve moved wiringPi to it and setup some simple hosting for it – mostly for my own convenience, but also to allow others who’re using GIT to quickly obtain updated versions and so on.

I’ll eventually be putting links from the main downloads site I’m using to the GIT repository, but until then, a quick look and it can be found here.

Accurate Delays on the Raspberry Pi

One of the issues on the Raspberry Pi is that I’m now seeing a lot of people coming to it from a traditional microcontroller background and trying to use the same ides on the Pi as they use on the microcontrollers – and promptly falling into a trap, or getting wildly unexpected results.

One of these areas is timed-delays. On a microcontroller, you can often simply loop for a number of times and get the result you desire… On the Pi, your program can be pre-emtively interrupted by Linux doing something else, it can be stalled by the GPU accessing memory and probably several other things. So timing loops in software is generally not that useful (Not to mention the CPU usage they consume – again, not an issue on a microcontroller without an operating system, but under Linux, it’s wasteful if you have something else to do!)

So… Linux provides a standard set of system calls – the issue is that you have the overhead of calling them – and that overhead can be quite variable, it depends on the system call and what it needs to do. The standard delay call, nanosleep(2) will sleep for at least how long you tell it, plus any operating system overhead and that comes to at least 20 to sometimes over 100 microseconds.

So.. when we need accurate short delays in the order of microseconds, it’s not always the best way, so to combat this, after studying the BCM2835 ARM Peripherals manual and chatting to others, I’ve come up with a hybrid solution for wiringPi. What I do now is for delays of under 100μS I use the hardware timer (which appears to be otherwise unused), and poll it in a busy-loop, but for delays of 100μS or more, then I resort to the standard nanosleep(2) call.

A quick look at the wiringPi code to see what I’m doing:

void delayMicrosecondsHard (unsigned int howLong)
{
  *(timer + TIMER_LOAD)    = howLong ;
  *(timer + TIMER_IRQ_CLR) = 0 ;

  while (*timerIrqRaw == 0)
    ;
}   

void delayMicrosecondsWPi (unsigned int howLong)
{
  struct timespec sleeper, dummy ;
  
  /**/ if (howLong ==   0)
    return ;
  else if (howLong  < 100)
    delayMicrosecondsHard (howLong) ;
  else
  {
    sleeper.tv_sec  = 0 ;
    sleeper.tv_nsec = (long)(howLong * 1000) ;
    nanosleep (&sleeper, &dummy) ;
  } 
}

I’m using the count-down timer and polling for the IRQ event (it doesn’t generate an IRQ, we’re just polling for the completion event here) This avoids any issues with having to take into account counters that wrap over.

This isn’t perfect though, and it can still take longer than we want it to, but for small delays it should be a lot closer to what we want than just calling the standard nanosleep(2) routine.

This will be in the next version of wiringPi which I’ll publish in a day or 2.

Pi, Linux and C Training

I recenty ran a 2-day course for someone who was keen to learn more about Linux, C and the Raspberry Pi.

Teaching isn’t new to me, I’ve run courses on my telephone systems, various aspects of Internet operations for people like web design companies and even used to teach something called Engineering Computing during my years at Napier, so to run a 2-day course in my office wasn’t hard and turned out to be a very rewarding experience for both myself and my student!

So what did we do? Started with getting more to grips with the Linux command-line, the use of pipes and redirection. Demonstrating that programmers are lazy (ie. command and filename completion!) We then went on to look at C programming. My student had been doing some C already, but wanted to learn a bit more. Variable scope – the difference between local and global variables. Static variables and so on. We moved on to separate compilation and linking files together – how we can use header (.h) files to give the compiler “hints” about how to call a function in another file.

We also moved on to some of the wiringPi functions too. Talked about concurrent programming and had a brief introduction to threads (with the simplified thread library inside wiringPi).

So a very worthwhile 2 days – it’s always good to share knowledge and meet more like-minded people too, and I’ve just sent my student some homework 😉

DTRONIXS Mini PiIO Protoboard

Hot on the heels of the PiFace, to add to my collection of Raspberry Pi interface boards comes the Mini PiIO Protoboard from DTRONIXS.

Photos

Mini PiIO Protoboard

Mini PiIO Protoboard

Ladder game built on Mini PiIO

Ladder game built on Mini PiIO

Top photo is the base board sitting on a Raspberry Pi, the 2nd one is the board made up with a minature version of my Ladder game.

First impression

It’s tiny!

It sits directly on-top of the Pi on the GPIO connector. The other end is sort of floating in space and like the PiFace, I’d strongly suggest putting some sticky-backed foam or felt pads to stop the board shorting out anything on the Pi (Which it did once when I was building this project on it, fortunately only rebooting the Pi…)

Kit and Assembly

It came as a kit of parts, PCB, GPIO connector, the 2 long edge connectors, a short 5-pin connector and some surface mount components to make up an independent 3.3v regulator fed off the Pi’s 3.3v supply.

Assembly was strightforward, although I did solder on the additional 5-pin connector, then realised nothing actually connects to it, and it stops the little breadboard from fitting, so had to unsolder and remove it.

The long pins down each side carry almost identical signals… Starting at the end furthest away from the GPIO connector, there is 5v, 0v, GPIO pins 17, 18, 21, 22, 23, 24, 25 and 4, then 0v and 3.3v. After that the 2 sides are different – the side nearest the edge (SD card) carrys the serial and I2C port pins and the opposite side carries the 5 SPI interface pins.

One thing I really like about the board is that the GPIO pins are actually labelled 0 through 7 – and they correspond directly with the wiringPi pin numbering scheme!

The 3v connections can be jumpered to come from the on-board regulator or the Pi’s own 3.3v supply.

And a little note about putting the breadboard on – it comes with a sticky-back, but if you are careful, then you can align the holes in the bradboard with the edge connectors, then it’s possible to plug in some DIL chips directly into the GPIO pins which may save a little bit of wiring.

Using it

As a quick experiment, I assembled a miniature version of my ladder gameusing a 10-segment LED bargraph display chip and assembly was quick and straight forward – the original used 12 LEDS but I only had 10 LEDs in a convenient package, so had to modify the program a little.

Conclusion

So if your after something to help you quickly get a few LEDs and switches going, or to experiment with a single DIL chip interface, then this little board is certainly one to look out for! It makes the main 8 GPIO signals easily avalable on both sides of the board with power and ground on both sides too which can make wiring signals to either side relatively easy.

The separate 3.3v regulator can be used to take some of the load off the Pi’s 3.3v supply – probably essential if driving something that’s going to take more than a few 10’s of mA.

Other than putting some sort of isolation between it and the Pi, the only minor issue I have with it is that like the PiFace board, it won’t fit into the SKPang cases I’m using although I’m pretty sure I could modify the pillars on the SKPang cases to take one, other than that it’ll very probably be the first protoboard I’ll reach for when trying out something small.

 

 

PiFace

PiFace is a peripheral IO device for the Raspberry Pi. It was announced at the recent Cambridge Raspberry Jam event so I bought one for the princely sum of £30.

It’s designed to fit on-top of the Pi and has an identical footprint with cut-outs to accommodate the Composite video, Ethernet and USB ports. It takes 3.3v and (optionally) 5v from the Pi itself, although there is provision for a separate supply to power the output relays and buffers. While the driver chips will support up to 20V, the relays are designed to only run at 5V, so the external supply needs to be 5v. My board was not fitted with this socket.

Photos

PiFace

View of the PiFace fitted onto a Raspberry Pi

Top View of the PiFace fitted to a Raspberry Pi

Top View of the PiFace fitted to a Raspberry Pi

These photos show the PiFace fitted to a Raspberry Pi. The 9 screw terminals at the bottom/front of the photos are the output pins (Power is the pin on the left), the 2 sets of 3-way screw terminals are the relay outputs and the set of 9 at the top/back are the inputs with 0v being the one on the left, closest to the composite video output.

The PiFace leaves all ports accessible on the Raspberry Pi itself, with the obvious exception of the GPIO port. It uses power and the SPI bus on the GPIO only. It does not make the other GPIO pins available for use.

2 of the outputs are connected to relays which are capable of switching 10amps and 230volts… That’s a 2Kw load however I would not personally like to try to switch anything close to that with those little screw terminals.

Fitting

The PiFace itself is supported only by the large capacitor on the Raspberry Pi board as well as the GPIO connector. If you were to exert a little too much force on the PiFace, it’s possible you may damage the capacitor and also short circuit some of the PiFace’s pins on the HDMI connector. One of those sticky felt pads on the PiFace at the location of the HDMI connector is helpful.

It’s probably not recommended anyway, but do not try to fit the PiFace to your Raspberry Pi when the Pi is turned on – they do it in one of the videos but it caused my Pi to reboot – presumably due to a power spike going through the board.

What You Get

PiFace gives you 8 buffered input pins (with 4 switches on-board connected to 4 of these pins), and 8 buffered output connections. 2 of the output connections are connected to mechanical relays.

You can use the 2 buffered outputs in parallel with the relays, but they will obviously click on/off when you use them. The relay outputs have an LED wired in parallel with the relays and there are 2 other LEDs on the output pins, so with the 4 buttons and 4 LEDs (with the relays clicking away), it’s possible to do some very simple experiments right away.

GPIO

The GPIO is handled by an MCP23S17 SPI/GPIO interface chip. This provides 16 general purpose IO pins with the PiFace dividing them into 8 inputs and 8 outputs.

The Input pins have a 330Ω series resistor and the MCP23S17 is capable of applying internal pull-up resistors making it easy to detect signals that pull to ground such as simple switches without any additional components.

NOTE: Like the GPIO on the Raspberry Pi, the MCP23S17 is a 3.3v chip. Do not attempt to connect it to systems generating more than 3.3v outputs.

The outputs are driven via a standard ULN2803A darlington driver chip.

There is no support for the interrupt capability of the MCP23S17 although this could be achieved by soldering a wire from its interrupt output pins to 2 of the Raspberry Pi’s GPIO pins.

Software

There isn’t any 🙁

At least none that I could find, other than references to a new SPI driver for the kernel, and as I’m using one of Chris Boot’s kernels with his SPI driver installed, (which I think is now back-ported to the official kernel released by the foundation), so I didn’t think there was much point pursuing that line of attack… So armed with the circuit diagram, the MCP23S17 data sheet and some time, I wrote a version of wiringPi to work with the PiFace board. Details here including a software library and demonstration program.

Conclusion

It’s a nice little board. Relatively easy to use, but with no software supplied, could be quite daunting to use! Hopefully someone will produce and publish a Python, scratch, etc. libraries to enable it to be used easily, but until then, there’s wiringPiFace.

I’m somewhat disappointed that there is no way to disable the 2 on-board relays. I wanted to drive 8 LEDs and detect a switch with it to hopefully use it to drive a copy of Mike Cooks Magic Wand the buzzing from the relays is too much to bear and I really don’t want to un-soldering them, so a couple of jumpers would be handy on the next revision…

I feel that the inputs could have been handled better – especially for something intended for classroom use – with e.g. opto-isolators to allow for a range of input voltages from 3 to 12v for example. That would make it much more robust and versatile in a classroom environment… Probably add to the cost, and possibly board size too though, so I can see where a compromise may have been made, however the MCP23S17 is socketed and replacements cost under £1 in the UK.

Also, the circuit diagram shows 2 jumpers that are not fitted to my board – they are attached to the chips address-select lines. The manual for the MCP23S17 says that these pins must be strapped either way, even if they are not being used, so I soldered on some 0.1″ headers and put on a couple of jumpers. I’m hoping this is just an oversight on my early production board… It’s also hard-wired to the Raspberry Pi’s first SPI chip select output – again, a jumper would have been nice, but given that you can’t connect anything else to the Pi when this is connected it’s probably a moot point.

And the inability to connect anything else to the Raspberry Pi’s GPIO connector is somewhat frustrating. I can’t use the PWM output, can’t use the serial port, can’t use the I2C port, nor can I use any of the other GPIO ports that the Pi provides. Maybe one day we’ll see some sort of stacking “shield” arrangement like Arduinos have, however…

The mounting is a little flimsy, I’d like to see a proper spacer pillar in the underside of the board, just to stop it wobbling, although even a sticky-backed felt pad over the HDMI port would be a good start.

I feel it is much less capable than the Gertboard, but at the same time it’s also much simpler and might just be the thing to enable some easy control applications for demos, and even with the 2 relays the ability to drive some low-voltage motors – that combined with its size might just make it a good little board for a floor-crawler robot of some kind. A control board for my PiTrack project? Now there’s a thought…