Raspberry Pi Sparkfun 7 Segment Display Clock

raspberrypiclock

I recently purchased a 7 Segment Display from Sparkfun, model COM-11629.  I was interested in using my Raspberry Pi to control some external devices, and this seemed like the perfect fit.  It’s controllable via I2C, SPI, and serial.  So far I’m able to communicate with the device via I2C and SPI.  Sparkfun provides a lot of great information on the display here.  It seems to be well supported on Arduino, but I was interested in a python implementation that could run on my Raspberry Pi. You’ll need to set up a few things before you’re able to interface with the display.  I’ll cover the software first.

Enable I2C and SPI on Raspberry Pi

1. First you’ll need to enable the Kernel modules that provide I2C and SPI functionality.  It’s disabled by default on Rasbian (the distro I’m using). First type:

$ lsmod

If you see i2c_dev and i2c_bcm2708, you’re ready to go, if not, edit /etc/modprobe.d/raspi-blacklist.conf.  Comment out (or delete) the following lines:

 blacklist spi-bcm2708
 blacklist i2c-bcm2708

You should then reboot and run lsmod again to verify that the drivers are loaded on boot:

$ lsmod
 Module Size Used by
 bnep 10582 2
 bluetooth 192486 7 bnep
 rfkill 18210 2 bluetooth
 i2c_dev 5628 2
 snd_bcm2835 16312 1
 snd_pcm 77568 2 snd_bcm2835
 snd_page_alloc 5153 1 snd_pcm
 snd_seq 53337 0
 snd_seq_device 6446 1 snd_seq
 snd_timer 20006 2 snd_pcm,snd_seq
 snd 58455 6 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
 spidev 5232 0
 evdev 9434 2
 8192cu 490361 0
 leds_gpio 2243 0
 led_class 3570 1 leds_gpio
 i2c_bcm2708 3931 0
 spi_bcm2708 4824 0

2. Install Packages

We’ll use the python smbus module to communicate over I2C with the device.

sudo apt-get install python-dev python-smbus

The i2c tools package contains some utilities to scan the I2C bus, and read and write values to it, which can be very useful for debugging

sudo apt-get install i2c-tools

To enable control via SPI, you’ll need the py-spidev package

git clone https://github.com/doceme/py-spidev
cd py-spidev
sudo make install

Not necessary, but you can download and compile the spidev-test program in order to test your SPI connection in a loopback mode.

wget https://www.kernel.org/doc/Documentation/spi/spidev_test.c
gcc spidev_test.c -o spidev_test

To test with the program, you’ll need to connect the Pi’s MOSI to the Pi’s MISO. Run it like this (assuming you’re using SPI bus 0 and chip enable 0).

sudo ./spidev_test -D /dev/spidev0.0

You should see the following output:

spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D

Hardware Setup

Check the GPIO pinout for the PI here, so that you can see which pins on the headers I’m referring to.  You should only connect one of these buses at a time.  This example makes connections to 3.3v.  You can however hook the display up to 5v (which will make it brighter), but you’ll need to use a Logic Level Converter to go from the Pi’s 3.3v to the display’s 5v. You can’t just connect the Pi directly to 5v, or you’ll damaging your Pi.  Note: I did try to use a Logic Level Converter to connect the display at 5v, but I was unable to get it to work properly with I2c (didn’t try SPI).  More investigation required. If using I2C:

Raspberry PiSparkfun 7 Segment Display
SDASDA
SCLSCL
3.3v+
GND-
Make sure that you can see the device on the I2C bus, by default it’s address is 0x71.  I’m using a rev. 1.0 Raspberry Pi Model B (256MB version), which means that the I2C is wired to bus 0.  If you’re using a newer rev. 2.0 Model B (512MB version), you’ll want to use bus 1. For 256MB Pis:

sudo i2cdetect -y 0

For 512MB Pis:

sudo i2cdetect -y 1

You should see something that looks like this:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- 71 -- -- -- -- -- --

If you don’t see a 71, then your connections are not set up properly.

If using SPI:

Raspberry PiSparkfun 7 Segment Display
SCLKSCK
MOSISDI
MISOSDO
3.3vVCC
GNDGND

You can check out the connection with this:

sudo echo -ne "\x00" > /dev/spidev0.0

if successful you should see a ‘0’ illuminate on your display

Running the Clock Example

Now that your connections are checked out you run the clock example software.  It’s implemented in python and uses a library (written by me) that you can use to write additional applications that use this display.  Note, that this software is not a Sparkfun product and I am not responsible if it messes up your display or your Pi.

Download it here: Raspberry Pi Sparkfun 7 Segment Display Python Code

Depending on how you’re connected to the display you can run either:

sudo python clock_i2c.py

or

sudo python clock_spi.py

 Library Examples

The following programs will print ‘1234’ on the 7 segment display

I2C

import seven_segment_display
import seven_segment_i2c
#for rev 2.0 Model B, use:
#bus = seven_segment_i2c.SevenSegmentI2cBus(1)
#for rev 1.0 Model B, use:
bus = seven_segment_i2c.SevenSegmentI2cBus(0)
display = seven_segment_display.SevenSegmentDisplay(bus)
display.clear_display()
display.write_int(1234)

SPI

import seven_segment_display
import seven_segment_spi
# SPI bus 0, Chip Enable 0
bus = seven_segment_spi.SevenSegmentSpi(0, 0)
display = seven_segment_display.SevenSegmentDisplay(bus)
display.clear_display()
display.write_int(1234)

Notes

I2C at the moment seems less reliable than SPI and I occasionally get IOError exceptions when talking to it.  This could be the result of my wiring setup.  It’s enitrely possible I botched things horribly when soldering on the headers that allow me to plug the device into my breadboard.  I’ve added retry mechanism when writing commands via I2C in order to compensate for this, but it’s probably something that I need to look into further.

References: