This post will be about the display of the actual alarm clock. It will consist of two components, visualising different information.

 

IMG_1899.JPG

 

Enabling I2C

 

Both components, a 4 digit 7-segment display and a 8x8 LED matrix, make use of an I2C backpack to facilitate wiring and control.

 

To enable I2C on the Raspberry Pi, launch the "raspi-config" tool from the command line. Select the advanced options and go to the I2C menu. When asked, enable I2C. Reboot the Pi for changes to take effect.

 

Screen Shot 2016-07-28 at 21.17.27.pngScreen Shot 2016-07-28 at 21.17.30.png

 

Install the "i2c-tools" package if not already done so, as it will help verify all is as expected:

 

pi@piiot1:~ $ sudo apt-get install i2c-tools
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  libi2c-dev python-smbus
The following NEW packages will be installed:
  i2c-tools
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 51.3 kB of archives.
After this operation, 227 kB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian/ jessie/main i2c-tools armhf 3.1.1+svn-2 [51.3 kB]
Fetched 51.3 kB in 0s (65.1 kB/s)
Selecting previously unselected package i2c-tools.
(Reading database ... 123842 files and directories currently installed.)
Preparing to unpack .../i2c-tools_3.1.1+svn-2_armhf.deb ...
Unpacking i2c-tools (3.1.1+svn-2) ...
Processing triggers for man-db (2.7.0.2-5) ...
Setting up i2c-tools (3.1.1+svn-2) ...
/run/udev or .udevdb or .udev presence implies active udev.  Aborting MAKEDEV invocation.

 

You should now be able to detect I2C devices:

 

pi@piiot1:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 71 -- -- -- -- -- --

 

In my case, both displays have been detected. The first one at address 0x70, the second one at 0x71.

Initially, both displays have address 0x70. It is however possible to short some pads at the back using solder, changing the address to a different value:

 

IMG_1908.JPG

 

Let's take a look at how I connected them to the Pi

 

Connecting Hardware

 

3.3V vs 5V ?

 

The safest option is to connect everything using 3.3V, as the Pi's logic level is 3.3V and using 5V may damage the Pi. The connections would then look like this:

Screen Shot 2016-07-28 at 22.35.58.pngIMG_1902.JPG

 

 

Because the displays I used are supposed to be "super bright", powering them using 5V instead of 3.3V would result in the best brightness output. I was however worried as the Pi's I/O uses 3.3V levels. But would powering the displays using 5V damage my Pi's I2C pins?

 

Doing some research, I found an old discussion from Drew Fustini asking the same thing: Is level shifting really needed for I2C?  Ultimately, I verified the voltage on the I2C pins using a scope, and it seems it is safe (in this particular case) to power the displays using 5V instead of 3.3V and not damage my Pi's I2C pins

 

F0001TEK.png

 

 

Python Library

 

Adafruit has published a Python library to control most of their LED I2C "backpacks". Like the rest of their software, it can be found on GitHub: https://github.com/adafruit/Adafruit_Python_LED_Backpack

 

Installing the library is straightforward but requires some dependencies to be installed first:

 

pi@piiot1:~ $ sudo apt-get install build-essential python-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
The following extra packages will be installed:
  libpython-dev libpython2.7-dev python2.7-dev
The following NEW packages will be installed:
  libpython-dev libpython2.7-dev python-dev python2.7-dev
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 18.2 MB of archives.

 

pi@piiot1:~ $ sudo apt-get install python-smbus python-imaging
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  python-imaging python-smbus
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 19.3 kB of archives.

 

Once the dependencies are installed, the actual library can be downloaded using the "git clone" command:

 

pi@piiot1:~ $ git clone https://github.com/adafruit/Adafruit_Python_LED_Backpack
Cloning into 'Adafruit_Python_LED_Backpack'...
remote: Counting objects: 167, done.
remote: Total 167 (delta 0), reused 0 (delta 0), pack-reused 167
Receiving objects: 100% (167/167), 43.64 KiB | 0 bytes/s, done.
Resolving deltas: 100% (110/110), done.
Checking connectivity... done.

 

Finally, after downloading the library, it ca be installed on the Pi:

 

pi@piiot1:~ $ cd Adafruit_Python_LED_Backpack/
pi@piiot1:~/Adafruit_Python_LED_Backpack $ sudo python setup.py install

 

Library installation:

 

7-Segment Display

 

This will be used to display the most basic information an alarm clock should display: the time.

 

I wrote a small Python script taking the time, parsing the hours and minutes and concatenating them in a single value. That value is then sent to the display to be visualised. For the colon, it is simply alternated every 500ms

 

The small script is defined below:

 

#!/usr/bin/env python

import time
from datetime import datetime
from Adafruit_LED_Backpack import SevenSegment

display = SevenSegment.SevenSegment(address=0x70, busnum=1)

colon = False

display.begin()

while True:
  now = datetime.now()

  hours = now.hour
  minutes = now.minute
  seconds = now.second

  string = str(hours) + str(minutes).zfill(2)

  colon = not colon

  display.clear()
  display.print_float(float(string), decimal_digits=0, justify_right=True)
  display.set_colon(colon)
  display.write_display()
  time.sleep(0.5)

 

To verify the placement of the colon and the time, I temporarily set the time to Japan and then back to Belgium.

 

pi@piiot1:~ $ sudo cp /usr/share/zoneinfo/Japan /etc/localtime
pi@piiot1:~ $ sudo cp /usr/share/zoneinfo/Europe/Brussels /etc/localtime

 

This is the result:

IMG_1906.JPGIMG_1907.JPG

 

Looks like the time is taken care of, on to the next display!

 

8x8 LED Matrix

 

The LED matrix will be used to display additional information in the form of icons.

 

It could display whether or not a connection to the internet is available or display the forecasted weather with simple icons. Below is an example demonstrating the connectivity check.

 

The script pings a given host and displays a cross if not reachable or nothing if reachable.

 

#!/usr/bin/env python

import time
import os
from PIL import Image
from PIL import ImageDraw
from Adafruit_LED_Backpack import Matrix8x8

display = Matrix8x8.Matrix8x8(address=0x71, busnum=1)

display.begin()

image = Image.new('1', (8, 8))
draw = ImageDraw.Draw(image)

draw.rectangle((0,0,7,7), outline=255, fill=0)
draw.line((1,1,6,6), fill=255)
draw.line((1,6,6,1), fill=255)

while True:
  host = "192.168.0.228"
  response = os.system("ping -W 1 -c 1 " + host)

  if response == 0:
    display.clear()
  else:
    display.set_image(image)

  display.write_display()
  time.sleep(0.1)

 

Check the video below to see both displays in action

 

Demo

 

Here's a short video clip demonstrating the clock and the connectivity check. It's checking connectivity to the Pi behind it, that is being rebooted.

 

 


arrow_prev.png

 


Navigate to the next or previous post using the arrows.

arrow_next.png