Chapter 14. Displays

14.0 Introduction

Although the Raspberry Pi can use a monitor or TV as a display, it is often nice to use a smaller, more specialized display with it. In this chapter, we explore a range of different displays that can be attached to a Raspberry Pi.

Some of the recipes require the use of a solderless breadboard and male-to-female jumper wires (see Recipe 9.8).

14.1 Using a Four-Digit LED Display

Note

Be sure to check out the accompanying video for this recipe at http://razzpisampler.oreilly.com.

Problem

You want to display a four-digit number in an old-fashioned, seven-segment LED display.

Solution

Attach an Inter-Integrated Circuit (I2C) LED module, such as the model shown in Figure 14-1, to a Raspberry Pi using female-to-female jumper wires.

F1301A
Figure 14-1. Seven-segment LED display with a Raspberry Pi

To make this recipe, you will need the following:

The connections between the Raspberry Pi and the module are as follows:

  • VCC (+) on the display to 5V on the Raspberry Pi general-purpose input/output (GPIO) connector

  • GND (-) on the display to GND on the Raspberry Pi GPIO connector

  • SDA (D) on the display to GPIO 2 (SDA) on the Raspberry Pi GPIO connector

  • SCL (C) on the display to GPIO 3 (SCL) on the Raspberry Pi GPIO connector

Note that Adafruit also supplies a jumbo-sized LED display. You can connect this to the Raspberry Pi using the just-listed connections, but the larger display has two positive power pins: one for the logic (V_IO) and one for the display (5V). This is because, being a large display, it requires more current. Fortunately, the Raspberry Pi can supply enough power for it. You can use an extra female-to-female jumper wire to connect this extra pin to the second 5V pin on the GPIO connector.

For this recipe to work, you will also need to set up your Raspberry Pi for I2C, so follow Recipe 9.3 first.

Enter these commands to install the Adafruit code to support this display:

$ cd /home/pi
$ git clone https://github.com/adafruit/Adafruit_Python_LED_Backpack.git
$ cd Adafruit_Python_LED_Backpack
$ sudo python setup.py install

The Adafruit library includes examples, and it’s one of these that we will use to illustrate the use of the display. Run the program using the command below and the display should show the time. Note that this code is Python 2 only, so use the python (not python3) command:

$ cd examples
$ sudo python ex_7segment_clock.py

Discussion

If you open the example file ex_7segment_clock.py in an editor, you’ll see that the key commands are the following:

from Adafruit_LED_Backpack import SevenSegment

This imports the library code into your program. You then need to create a instance of SevenSegment using the next line of code. The address supplied as an argument is the I2C address (see Recipe 9.4).

Every I2C slave device has an address number. The LED board has three pairs of solder pads on the back that can be bridged with solder if you want to change the address. This is essential if you need to operate more than one I2C device from a single Raspberry Pi. This is why we specify an address of 0x70 in the following line:

segment = SevenSegment.SevenSegment(address=0x70)

To actually set the contents of a particular digit, use a line like this one:

segment.set_digit(0, int(hour / 10))

The first argument (0) is the digit position. Note that these positions are 0, 1, 3, and 4. Position 2 is reserved for the two dots in the center of the display.

The second argument is the number to display.

See Also

Find out more about the Adafruit library.

Recipe 14.2 uses the same Adafruit software for a matrix display.

14.2 Displaying Messages on an I2C LED Matrix

Problem

You want to control the pixels of a multicolor LED matrix display.

Solution

Use an I2C LED module, such as the model shown in Figure 14-2, attached to a Raspberry Pi using female-to-female jumper wires.

F1302A
Figure 14-2. LED matrix display with a Raspberry Pi

To make this recipe, you will need the following:

The connections between the Raspberry Pi and the module are as follows:

  • VCC (+) on the display to 5V on the Raspberry Pi GPIO connector

  • GND (-) on the display to GND on the Raspberry Pi GPIO connector

  • SDA (D) on the display to GPIO 2 (SDA) on the Raspberry Pi GPIO connector

  • SCL (C) on the display to GPIO 3 (SCL) on the Raspberry Pi GPIO connector

For this recipe to work, you will also need to set up your Raspberry Pi for I2C, so follow Recipe 9.3 first.

The display uses the same library as Recipe 14.1. To install it, run the following commands:

$ cd /home/pi
$ git clone https://github.com/adafruit/Adafruit_Python_LED_Backpack.git
$ cd Adafruit_Python_LED_Backpack
$ sudo python setup.py install

Run the example program using:

$ cd examples
$ sudo python bicolor_matrix8x8_test.py

Discussion

The program demonstrates the versatility of the Adafruit library. It starts by iterating through all of the colors for each pixel in turn. The first part of the code is listed here, with some of the comments removed:

import time
from PIL import Image
from PIL import ImageDraw
from Adafruit_LED_Backpack import BicolorMatrix8x8

display = BicolorMatrix8x8.BicolorMatrix8x8()

for c in [BicolorMatrix8x8.RED, BicolorMatrix8x8.GREEN, BicolorMatrix8x8.YELLOW]:
    # Iterate through all positions x and y.
    for x in range(8):
        for y in range(8):
            # Clear the display buffer.
            display.clear()
            # Set pixel at position i, j to appropriate color.
            display.set_pixel(x, y, c)
            # Write the display buffer to the hardware.  This must be called to
            # update the actual display LEDs.
            display.write_display()
            # Delay for a quarter second.
            time.sleep(0.25)

The code is well explained in its accompanying comments.

See Also

You can find out more about this product at http://www.adafruit.com/products/902.

14.3 Using the Sense HAT LED Matrix Display

Problem

You want to display messages and graphics, using the display of a Sense HAT.

Solution

Follow Recipe 9.16 and install the software that the Sense HAT needs and then use the library commands to display text.

The program ch_14_sense_hat_clock.py illustrates this by repeatedly displaying the date and time in a scrolling message:

from sense_hat import SenseHat
from datetime import datetime
import time

hat = SenseHat()
time_color = (0, 255, 0) # green
date_color = (255, 0, 0) # red

while True:
    now = datetime.now()
    date_message = '{:%d %B %Y}'.format(now)
    time_message = '{:%H:%M:%S}'.format(now)
    
    hat.show_message(date_message, text_colour=date_color)
    hat.show_message(time_message, text_colour=time_color)

As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Discussion

Two colors are defined so that the date and time parts of the message can be displayed in different colors. These colors are then used as an optional parameter to show_message.

Other optional parameters to show_message are:

scroll_speed
This is actually the delay between each scrolling step rather than the speed. So a higher value makes the scrolling slower.
back_colour
This sets the background color. Note the British spelling of “colour,” with a “u.”

You can use the display for a lot more than just displaying scrolling text. Starting at its most basic, you can set individual pixels using set_pixel, set the orientation of the display using set_rotation, and display an image (albeit a small one) with load_image. The example that follows, which you can find in ch_13_sense_hat_taster.py, illustrates these function calls. As with all the program examples in this book, you can download them (see Recipe 3.22).

The image must be just 8×8 pixels, but you can use most common graphics formats, such as .jpg and .png, and the bit depth will be handled automatically:

from sense_hat import SenseHat
import time

hat = SenseHat()

red = (255, 0, 0)

hat.load_image('small_image.png')
time.sleep(1)
hat.set_rotation(90)
time.sleep(1)
hat.set_rotation(180)
time.sleep(1)
hat.set_rotation(270)
time.sleep(1)

hat.clear()
hat.set_rotation(0)
for xy in range(0, 8):
    hat.set_pixel(xy, xy, red)
    hat.set_pixel(xy, 7-xy, red)

Figure 14-3 shows the Sense HAT displaying a crude image.

F1351
Figure 14-3. A Sense HAT displaying an “image”

See Also

For full documentation on the Sense HAT, see https://pythonhosted.org/sense-hat/api/.

For information on formatting dates and times, see Recipe 7.2.

Other recipes that use the Sense HAT are Recipes 9.16, 13.11, 13.14, 13.15, and 13.17.

14.4 Displaying Messages on an Alphanumeric LCD HAT

Problem

You have a few lines of text that you want to display neatly on an LCD display.

Solution

Use a Pimoroni Displayotron HAT attached to your Raspberry Pi, as shown in Figure 14-4.

F1350
Figure 14-4. A Displayotron LCD HAT

This HAT requires both I2C and SPI to be enabled, so if you have not already done so, follow Recipe 9.3 and Recipe 9.5.

Then fetch the code for its accompanying library from GitHub and install it by using the following commands:

$ curl -sS get.pimoroni.com/displayotron | bash

This command will ask you if want to install the examples and documentation. Be warned: the whole thing takes quite some time to install.

By way of example, the following program (ch_14_displayotron_ip.py) finds the hostname and IP address of your Raspberry Pi and displays them, along with the time. If all is well, the backlit LED will be green, but if the network connection is down, the backlight will turn red:

import dothat.lcd as lcd
import dothat.backlight as backlight
import time
from datetime import datetime
import subprocess

while True:
    lcd.clear()
    backlight.rgb(0, 255, 0)
    try:
        hostname = subprocess.check_output(['hostname']).split()[0]
        ip = subprocess.check_output(['hostname', '-I']).split()[0]
        t = '{:%H:%M:%S}'.format(datetime.now())
        lcd.write(hostname)
        lcd.set_cursor_position(0, 1)
        lcd.write(ip)
        lcd.set_cursor_position(0, 2)
        lcd.write(t)
    except:
        backlight.rgb(255, 0, 0)
    time.sleep(1)

As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Discussion

The test program imports the necessary libraries, including subprocesses (see Recipe 7.15), which will be used to find the IP address (see Recipe 2.2) of the Raspberry Pi and its hostname.

Here are the main methods in the library:

lcd.clear
Clears the display of any text
lcd.set_cursor_position
Sets the position for new text to be written to the column and row specified as its two parameters
lcd.write
Adds the text supplied as its parameter to the current cursor position
backlight.rgb
Sets the red, green, and blue values of the backlight (0 to 255)

You can find the examples that are supplied by Pimoroni in two subdirectories, basic and advanced, within the directory /home/pi/Pimoroni/displayotron/examples/dothat.

See Also

You can find out more about this HAT on Pimoroni’s product page.

14.5 Using an OLED Graphical Display

Problem

You want to attach a graphical OLED (Organic LED) display to your Raspberry Pi.

Solution

Use an OLED display based on the SSD1306 driver chip, using an I2C interface (Figure 14-5).

F1352
Figure 14-5. An I2C OLED display

To make this recipe, you will need the following:

The connections between the Raspberry Pi and the module are as follows:

  • VCC on the display to 5V on the Raspberry Pi GPIO connector

  • GND on the display to GND on the Raspberry Pi GPIO connector

  • SDA on the display to GPIO 2 (SDA) on the Raspberry Pi GPIO connector

  • SCL on the display to GPIO 3 (SCL) on the Raspberry Pi GPIO connector

For this recipe to work, you will also need to set up your Raspberry Pi for I2C, so follow Recipe 9.3 first.

Adafruit has a library for these displays, which you can install by using these commands:

$ git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
$ cd Adafruit_Python_SSD1306
$ sudo python3 setup.py install

This library uses the Python Image Library (PIL), which you can install by using the following command:

$ sudo pip3 install pillow

The code example ch_14_oled_clock.py displays the time and date on the OLED display:

import Adafruit_SSD1306
from PIL import Image, ImageDraw, ImageFont
import time
from datetime import datetime

# Set up display
disp = Adafruit_SSD1306.SSD1306_128_64(rst=None, i2c_address=0x3C)
small_font = ImageFont.truetype('FreeSans.ttf', 12)
large_font = ImageFont.truetype('FreeSans.ttf', 33)
disp.begin()
disp.clear()
disp.display()
# Make an image to draw on in 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))
draw = ImageDraw.Draw(image)

# Display a message on 3 lines, first line big font        
def display_message(top_line, line_2):
    draw.rectangle((0,0,width,height), outline=0, fill=0)
    draw.text((0, 0),  top_line, font=large_font, fill=255)
    draw.text((0, 50),  line_2, font=small_font, fill=255)
    disp.image(image)
    disp.display()

while True:
    now = datetime.now()
    date_message = '{:%d %B %Y}'.format(now)
    time_message = '{:%H:%M:%S}'.format(now)
    display_message(time_message, date_message)
    time.sleep(0.1)

As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Every I2C slave device has an address, which is set in the line:

disp = Adafruit_SSD1306.SSD1306_128_64(rst=None, i2c_address=0x3C)

This is fixed at 3C (hex) for many of the low-cost I2C modules but may vary, so you should check any documentation that comes with the device or use I2C tools (Recipe 9.4) to list all the I2C devices attached to the bus so that you can see the address of your display.

The preceding code example uses a technique called double buffering. This involves preparing what is to be displayed and then switching it onto the image in one go. This prevents the display from flickering.

You can see the code for this in the display_message function. This first draws onto the image a blank rectangle the entire size of the display. It then draws the text onto the image and then sets the display content to be image using disp.image(image). The display isn’t actually updated until the function disp.display() is called.

To be able to use text of different sizes, a TrueType font is used. This font is already on the Raspberry Pi, but to be able to use it, you need to copy it into the current directory using the following command:

$ cp /usr/share/fonts/truetype/freefont/FreeSansBold.ttf

Discussion

Small OLED displays are cheap, don’t use much current, and have high resolution despite their diminutive size. They are replacing LCD displays in many consumer products.

See Also

The instructions here are for four-pin I2C interfaces. If you really want to use the SPI interface, take a look at Adafruit’s tutorial on this.

14.6 Using Addressable RGB LED Strips

Problem

You want to connect an RGB LED strip (NeoPixels) to your Raspberry Pi.

Solution

Use an LED strip based on the WS2812 RGB LED chips on your Raspberry Pi.

Using these LED strips (Figure 14-6) can be really easy, with a direct connection to the Raspberry Pi and power for the LEDs supplied by the Raspberry Pi’s 5V supply. This is the “Happy Day” scenario that should work just fine, but do see the Discussion for providing external power so that your LED strip use is trouble free.

Don’t Power the LEDS from the Pi’s 3.3V Supply

Although it might be tempting to power the LEDs from the 3.3V supply pin on the GPIO connector, do not do this—it can supply only low currents (see Recipe 9.2). Using this pin could easily damage your Raspberry Pi.

F1353
Figure 14-6. An LED strip of 10 LEDs

The LED strip used in Figure 14-6 is cut from a reel. In this case, there are 10 LEDs. Because each LED can use up to 60mA, 10 is probably a sensible limit for the number of LEDs that can be used without arranging for a separate power supply for the LED strip (see the Discussion section).

To connect the strip to the Raspberry Pi, jumper wires with female connectors on one end were cut and the wire ends soldered to the three connections on the LED strip (see Recipe 9.2): GND, DI (Data In), and 5V. These can then be attached to GPIO pins GND, GPIO 18, and 5V, respectively.

Notice that the LED strip has a right-facing arrow printed on it (Figure 14-7). Make sure that when you solder leads to the LED strip, you start from the cut end to the left of the arrow.

F1354
Figure 14-7. An LED strip close-up

We are going to use the Adafruit software to control our addressable LEDs. To install it, run the following commands:

$ pip3 install adafruit-blinka
$ sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel

The following example program (ch_14_neopixel.py) will set the LED red in successive positions along the strip:

import time
import board
from neopixel import NeoPixel

led_count = 5
red = (100, 0, 0)
no_color = (0, 0, 0)

strip = NeoPixel(board.D18, led_count, auto_write=False)

def clear():
    for i in range(0, led_count):
        strip[i] = no_color
    strip.show()

i = 0
while True:
    clear()
    strip[i] = red
    strip.show()
    time.sleep(1)
    i += 1
    if i >= led_count:
        i = 0
As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Run the program with Python 3 and use the sudo command like this:

$ sudo python3 ch_14_neopixel.py

If you have a different number of LEDs in your strip, modify led_count. The rest of the constants do not need to be changed.

You can use only GPIOs 10, 12, 18, and 21 with NeoPixels. If you want to use a different GPIO pin, change board.D18 to whichever pin you are using.

You can set the color of each of the LEDs independently. The colors are set as a tuple of red, green, and blue intensities. The changes to the LED colors are not actually updated until the method show is called.

Discussion

Each LED in the strip can use a maximum of about 60mA. They will do this only if all three color channels (red, green, and blue) are at maximum brightness (255). If you plan to use a lot of LEDs, you will need to use a separate 5V power supply sufficient to supply all the LEDs in your strip. Figure 14-8 shows how you would wire up a separate power supply. A female direct current (DC) jack-to-screw terminal adapter (see “Prototyping Equipment and Kits”) makes it easy to connect an external power supply to a breadboard.

F1355
Figure 14-8. Powering an LED strip with an external power supply

See Also

NeoPixels are also available in ring format, such as this display: https://www.adafruit.com/product/1586.

You can read more about the Adafruit approach to NeoPixels here.

14.7 Using the Pimoroni Unicorn HAT

Problem

You want an RGB LED matrix display for your Raspberry Pi.

Solution

Use a Pimoroni Unicorn HAT to provide an 8x8 LED matrix (Figure 14-9).

Start by installing the Unicorn HAT software from Pimoroni:

$ curl https://get.pimoroni.com/unicornhat | bash

You will be asked several times to confirm various bits of software to install and finally to reboot your Raspberry Pi.

Figure 14-9. The Pimoroni Unicorn HAT on a Raspberry Pi 3

When you’ve completed the installation, here’s a colorful program (ch_14_unicorn.py) to run on it. It will repeatedly set the color of a random pixel to a random color. Run the program using the sudo command:

import time
import unicornhat as unicorn
from random import randint

unicorn.set_layout(unicorn.AUTO)
unicorn.rotation(0)
unicorn.brightness(1)
width, height = unicorn.get_shape()

while True:
    x = randint(0, width)
    y = randint(0, height)
    r, g, b = (randint(0, 255), randint(0, 255), randint(0, 255))
    unicorn.set_pixel(x, y, r, g, b)
    unicorn.show()
    time.sleep(0.01)

time.sleep(1)

As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Discussion

The Unicorn HAT makes a very convenient way to attach a matrix of addressable LEDs. You will also find other chains of addressable LEDs laid out in various configurations, including matrices with even more LEDs on them. Generally, such matrices of addressable LEDs are actually arranged electrically as a long chain of LEDs.

See Also

For more information on addressable (NeoPixel) LEDs, see Recipe 14.6.

14.8 Using an ePaper Display

Problem

You want to use your Raspberry Pi to control an ePaper display.

Solution

Attach an Inky pHAT or Inky wHAT module to your Raspberry Pi (Figure 14-10). Download the Pimoroni software for this using the command:

$ curl https://get.pimoroni.com/inky | bash

If (when prompted) you accept the option to fetch examples and documentation, this will take quite some time to install.

As an example program (ch_14_phat.py), let’s have the Inky pHAT display the Raspberry Pi’s IP address:

from inky import InkyPHAT
from PIL import Image, ImageFont, ImageDraw
from font_fredoka_one import FredokaOne
import subprocess

inky_display = InkyPHAT("red")
inky_display.set_border(inky_display.WHITE)

img = Image.new("P", (inky_display.WIDTH, inky_display.HEIGHT))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(FredokaOne, 22)

message = str(subprocess.check_output(['hostname', '-I'])).split()[0][2:]
print(message)

w, h = font.getsize(message)
x = (inky_display.WIDTH / 2) - (w / 2)
y = (inky_display.HEIGHT / 2) - (h / 2)

draw.text((x, y), message, inky_display.RED, font)
inky_display.set_image(img)
inky_display.show()

As with all the program examples in this book, you can also download this program (see Recipe 3.22).

Figure 14-10. The Pimoroni Inky pHAT attached to a Raspberry Pi 3

Discussion

You won’t be playing any video games on these displays because they take a few seconds to update, but after they update, the ePaper keeps whatever you have drawn on it even when the power is removed. Pimoroni sells small displays like the Inky pHAT used here, and also a display twice the size that is pretty much as big as the Raspberry Pi (Inky wHAT).

See Also

More information is available in the full documentation of Inky pHAT.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset