This post will be about the display of the actual alarm clock. It will consist of two components, visualising different information.
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.
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 (188.8.131.52-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:
Let's take a look at how I connected them to the Pi
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:
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
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
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:
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
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.
Navigate to the next or previous post using the arrows.