Thursday, January 11, 2018

Raspberry Pi Sparkfun 7 Segment Display Clock


Originally published: September 2, 2013

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.
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:

DNS-323 Toolchain

Originally published: June 22, 2012
I’ve been wanting to be able to compile software for my NAS, the DNS-323 from D-Link, and I found instructions at a couple of different places on the internet.  In order to do this, you’ll need a cross compilation toolchain, which you can either download or build yourself.
I found some good information on the dns 323 wiki, but ultimately those instructions didn’t work for me, on firmware 1.08.  Which incidentally, can be downloaded from D-Link’s website, ftp://gpl.dlink.com/DNS-323/dns323_GPL_v1.08_12182009.tgz.  The pre-built toolchain provided on the wiki, didn’t have libstdc++, and the instructions for building your own failed for me (couldn’t get binutils to build).
I found very good instructions here for how to build the toolchain, complete with modifications to enable dynamic linking of libraries.  Binaries are provided on that site, but they were for x86-64, and I’m on a 32-bit host.
So, I used Ubuntu Hardy Heron running in a VirtualBox VM to build it for myself.  Read on for instructions on how to build it on your machine.

Cross Compile Instructions

First you’ll need to set up some build dependencies.  The toolchain requires an older (3.x) gcc in order to build.  gcc 4.x may work, but most of what I’ve read seems to indicate that it probably does not.  You can set the /usr/bin/gcc symlink back to it’s original when you’re done.
$ sudo apt-get install gcc-3.4 g++-3.4 bison flex gettext make bzip2 libncurses5-dev patch git-core
$ cd /usr/bin
$ sudo mv gcc gcc-orig
$ sudo ln -s gcc-3.4 gcc
$ sudo mv g++ g++-orig
$ sudo ln -s g++-3.4 g++
Next you’ll need to clone the git repository containing the toolchain source.  Note that when you run ‘make’ a number of packages will be downloaded and then built.
$ git clone git://github.com/juergh/toolchain_arm.git 
$ cd toolchain_arm
$ make
The resulting toolchain files are in the toolchain_arm directory.

Using the Toolchain

Test minimum cross compiler functionality, by building a hello world app.  Save the following to hello.cpp
#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "the toolchain worked!" << std::endl;
    return 0;
}
Now compile it with the toolchain
$ source toolchain_arm/build-env
$ ${CXX} hello.cpp -o hello
Verify that the resulting file is an ARM executable
$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), not stripped
Now you can just copy the executable to your device and run it to see if it works.

Building Autotools style projects

You’ll probably have some open source software that you want to compile for your device. Here an example using curl.
$ wget http://curl.haxx.se/download/curl-7.26.0.tar.gz
$ tar -zxvf curl-7.26.0.tar.gz
$ cd curl-7.26.0
$ source ~/toolchain_arm/build-env #or wherever you decided to save your toolchain
$ ./configure --host=arm-linux-uclibc 
$ make