5

Built-in LED Matrix Display and Push Buttons

In the previous chapter, we got acquainted with advanced concepts in Python programming and syntax. We also wrote and executed a Micro:bit-specific MicroPython program. Going forward, we will use those concepts in all of our demonstrations with Micro:bit.

The previous two chapters mostly served as an introduction to the syntax of Python. We did not use any Micro:bit-specific hardware features and libraries. From this chapter onward, all the programs will be specific to the MicroPython flavor for the Micro:bit as all of them will employ and demonstrate the hardware capabilities of MicroPython on Micro:bit. They will not execute on the other implementations of Python such as Python 3 or any MicroPython implementation for other devices such as Raspberry Pi Pico W and ESP8266 or ESP32.

This chapter explores two very important hardware features of the Micro:bit and demonstrates them with MicroPython. The built-in components include a 5x5 LED matrix display and a pair of push buttons. We will explore the following list of topics together:

  • Built-in programmable 5x5 LED matrix
  • Images and animations
  • Working with built-in push buttons

Let’s explore the built-in matrix display and push buttons.

Technical requirements

This chapter does not require any additional hardware. A Micro:bit board, a computer, and a micro USB cable are enough to follow the demonstrations in the chapter.

Built-in programmable 5x5 LED matrix

LED stands for light-emitting diode. Just like a normal diode, an LED allows the current to flow only in one direction. An LED has two pins (or legs): an anode and a cathode. Just as with any other diode, we must connect the anode of an LED to a positive pin and the cathode to the ground or negative pin of the power source. Then, the LED will allow the current to flow through it. However, if we connect the anode pin to the ground/negative pin and the cathode to the positive pin of the source, the LED will not let the current pass through it. When current passes through LEDs, they glow. We will study LEDs and their programming in detail in this and the next chapter. This chapter focuses on the built-in programmable 5x5 LED matrix of the Micro:bit board and the next chapter focuses on external discrete LEDs. Figure 5.1 shows an LED matrix. It has 5 rows and 5 columns, totaling 25 LEDs:

Figure 5.1 – Built-in programmable 5x5 LED matrix (Courtesy: https://commons.wikimedia.org/wiki/File:Micro_bit_position_des_DEL.png)

Figure 5.1 – Built-in programmable 5x5 LED matrix (Courtesy: https://commons.wikimedia.org/wiki/File:Micro_bit_position_des_DEL.png)

Figure 5.1 shows their positional indices, which are used to refer to them in the MicroPython programs we will write and execute. The LEDs glow with in red. Let’s get started with the programming of the LED matrix.

Displaying characters and text

Let’s see how to display characters, numbers, and strings. Here is a sample program:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
a = 'A'
display.show(a)
sleep(1000)
a = 'BBC'
display.show(a)
sleep(1000)
a = 'MicroPython'
display.show(a, delay=750, clear=True)
sleep(1000)
a = 'Micro:bit'
display.show(a, delay=750, loop=True)
sleep(1000)

The library mentioned in the first line of the program, microbit, is a MicroPython library specific to Micro:bit. The next if statement checks if display.is_on() returns True. If not, then it calls display.on() to turn the built-in display on. Then, the display.show() method shows a single character on display. The sleep() method suspends (or waits) the current thread’s execution for a given number of milliseconds. 1 second equals 1,000 milliseconds. The display continues to show the given character while the Micro:bit sleeps. Then, we show a string with the show() method. It shows all the characters in sequence and the final character in the string while the Micro:bit sleeps. Next, we are showing a string with a custom delay between characters defined by the 750 argument to the delay parameter. Because we passed the True argument to the clear parameter, the Micro:bit clears the display after showing the final character in the sequence. As a result, while it sleeps for a second, the display is blank. We are showing the final string in a loop. Once we enable it with the parameter loop, the next statements will not be executed. Run the program and see the code in action.

We can use the exception handling feature in Python programming to interrupt the forever loop by pressing Ctrl + C on the keyboard, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
a = 'A'
display.show(a)
sleep(1000)
a = 'BBC'
display.show(a)
sleep(1000)
a = 'MicroPython'
display.show(a, delay=750, clear=True)
sleep(1000)
try:
    a = 'Micro:bit'
    display.show(a, delay=750, loop=True)
    sleep(1000)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")
print("Program ended..")

Run the program and see the exception handling in action. In the final block of code, we are including the code in the try block where we suspect we would encounter an exception (in this case, the keyboard interrupt). We can then catch the exception in the except block and process it. However, there is one major catch. We can use this for debugging only when Micro:bit is connected to a computer with a keyboard.

We can also display numbers as follows. I have just modified the preceding program:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
a = 1
display.show(a)
sleep(1000)
a = 1234
display.show(a)
sleep(1000)
a = 3.14
display.show(a, delay=750, clear=True)
sleep(1000)
try:
    a = 3.1416
    display.show(a, delay=750, loop=True)
    sleep(1000)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")
print("Program ended..")

This LED display uses the digital GPIO pins of Micro:bit. We can turn off the display with the display.off() statement and use those GPIO pins. We will see this in detail in the next chapter.

Scrolling text on the display

We can also scroll text and numbers on the display as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.scroll(3.14)
display.scroll("Micro:bit", delay=300, monospace=True, loop=True)

Here, we use the method scroll() to scroll the passed argument (a number or a string). We can pass arguments for the parameters delay (decides the speed of scrolling), loop, and monospace (characters and numbers consume all the five columns for their width).

Working with the individual LEDs

We can also write the code that addresses the individual LEDs. We can refer to Figure 5.1 for the indexing scheme of LEDs. The individual LEDs are capable of emitting 10 different intensities of the red light. The intensity values range from 0 (lowest) to 9 (highest). Let’s see a simple demonstration of that:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
k = 0
for i in [0, 1]:
    for j in range(0, 5, 1):
        print (j, i, k)
        display.set_pixel(j, i, k)
        k = k + 1

The method display.clear() clears the display by setting all the LEDs to the intensity of 0 which means off. We are calling it in the beginning as we do not wish the output of the execution of the preceding program to interfere with the output of the execution of the current program. Then, we use a nested for loop and set_pixel() to set the intensities of the pixels in the first two rows from 0 to 9. The method set_pixel() accepts the column number, the row number, and the intensity as arguments. Run the program and see the output.

We can also use the method get_pixel() to fetch the current intensity of a LED. Add the following two lines at the end of the program and re-run it:

print(display.get_pixel(0, 0))
print(display.get_pixel(0, 1))

The output is as follows:

>>> %Run -c $EDITOR_CONTENT
Display is already on...
0
5

We can also create a simple animation as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
values = [0, 1, 2, 3, 4]
print (values)
try:
    while True:
        for i in range(0, 5, 1):
            display.set_pixel(i, 0, values[i])
            values[i] = (values[i] + 1) % 10
            print(values)
        sleep(100)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

The first line of the LED display shows the list of intensity values scrolling in the REPL shell. Similarly, we can create 2D animation utilizing all the LEDs, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
values = [[0, 1, 2, 3, 4],
          [1, 2, 3, 4, 5],
          [2, 3, 4, 5, 6],
          [3, 4, 5, 6, 7],
          [4, 5, 6, 7, 8]]
print (values)
try:
    while True:
        for i in range(0, 5, 1):
            for j in range(0, 5, 1):
                display.set_pixel(i, j, values[i][j])
                values[i][j] = (values[i][j] + 1) % 10
                print(values)
        sleep(100)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

Run the program and see the animation in action. This way, we can create a lot of custom animations. The possibilities are unlimited.

The next section explores displaying simple images and animations.

Images and animations

We can display a custom-made image with the show() method. Let’s see a demonstration:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
pattern0 = Image("00000:"
                 "11111:"
                 "22222:"
                 "33333:"
                 "44444")
display.show(pattern0)

Run the program to see the output. We can also define a pattern or an image in a single line in our program, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
pattern0 = Image("00000:11111:22222:33333:44444")
display.show(pattern0)

We can also create a list of patterns and create a simple animation. We studied Python lists in the previous chapter and will use that concept in this demonstration:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
pattern0 = Image("00000:11111:22222:33333:44444")
pattern1 = Image("11111:22222:33333:44444:55555")
pattern2 = Image("22222:33333:44444:55555:66666")
pattern3 = Image("33333:44444:55555:66666:77777")
pattern4 = Image("44444:55555:66666:77777:88888")
pattern5 = Image("55555:66666:77777:88888:99999")
patterns = [pattern0, pattern1, pattern2,
            pattern3, pattern4, pattern5]
display.show(patterns, delay=100, loop=True)

In this program, we have created a list of patterns to be displayed. Then, we are passing that list to the show() method call to animate with a delay factor of 100 milliseconds between consecutive frames.

We also have plenty of built-in images. Here is a list of all of them:

Image.HEART
Image.HEART_SMALL
Image.HAPPY
Image.SMILE
Image.SAD
Image.CONFUSED
Image.ANGRY
Image.ASLEEP
Image.SURPRISED
Image.SILLY
Image.FABULOUS
Image.MEH
Image.YES
Image.NO
Image.CLOCK12, Image.CLOCK11, Image.CLOCK10, Image.CLOCK9, Image.CLOCK8, Image.CLOCK7, Image.CLOCK6, Image.CLOCK5, Image.CLOCK4, Image.CLOCK3, Image.CLOCK2, Image.CLOCK1
Image.ARROW_N, Image.ARROW_NE, Image.ARROW_E, Image.ARROW_SE, Image.ARROW_S, Image.ARROW_SW, Image.ARROW_W, Image.ARROW_NW
Image.TRIANGLE
Image.TRIANGLE_LEFT
Image.CHESSBOARD
Image.DIAMOND
Image.DIAMOND_SMALL
Image.SQUARE
Image.SQUARE_SMALL
Image.RABBIT
Image.COW
Image.MUSIC_CROTCHET
Image.MUSIC_QUAVER
Image.MUSIC_QUAVERS
Image.PITCHFORK
Image.XMAS
Image.PACMAN
Image.TARGET
Image.TSHIRT
Image.ROLLERSKATE
Image.DUCK
Image.HOUSE
Image.TORTOISE
Image.BUTTERFLY
Image.STICKFIGURE
Image.GHOST
Image.SWORD
Image.GIRAFFE
Image.SKULL
Image.UMBRELLA
Image.SNAKE
Image.SCISSORS

We can use one of these built-in images, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
display.show(Image.HEART)

We can create simple animations by creating a list of built-in images, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
pattern = [Image.HEART, Image.XMAS, Image.PACMAN,
           Image.TARGET, Image.TSHIRT]
display.show(pattern)

The library also has a couple of built-in lists of images for animations. Those are Image.ALL_CLOCKS and Image.ALL_ARROWS. Let’s use them in our programs, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
display.show(Image.ALL_CLOCKS)
display.show(Image.ALL_ARROWS)

This is how we can use the built-in display. In the next section, we will explore the functionality offered by built-in push buttons.

Working with built-in push buttons

Figure 5.1 shows two built-in push buttons in Micro:bit. They are named A and B. They are connected to GPIO pins 5 and 11, respectively. The MicroPython implementation for Micro:bit comes with built-in methods to work with them. Let’s see a simple example, as follows:

from microbit import *
try:
    while True:
        if button_a.is_pressed():
            print("Button A is pressed...")
        elif button_b.is_pressed():
            print("Button B is pressed...")
        else:
            print("No Button is pressed...")
        sleep(100)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

The is_pressed() method checks if an associated button is presently being pressed. It returns True if the button is pressed. We can also use the display to show the status of the button press, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
try:
    while True:
        if button_a.is_pressed():
            display.show(Image.HAPPY)
        elif button_b.is_pressed():
            display.show(Image.SAD)
        else:
            display.show(Image.HEART)
        sleep(100)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

The was_pressed() method returns True at the release of the button, as follows:

from microbit import *
if not display.is_on():
    display.on()
else:
    print("Display is already on...")
display.clear()
try:
    while True:
        if button_a.was_pressed():
            display.show(Image.HAPPY)
        elif button_b.was_pressed():
            display.show(Image.SAD)
        else:
            display.show(Image.HEART)
        sleep(100)
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

We can also see how many times a button is pressed, as follows:

from microbit import *
try:
    while True:
        sleep(5000)
        print("Button A has been pressed " + str(button_a.get_presses()) + " times.")
        print("Button B has been pressed " + str(button_b.get_presses()) + " times.")
except KeyboardInterrupt as e:
    print("Interrupted by the user...")

The Micro:bit sleeps for 5 seconds and counts button presses while it sleeps. We will use both buttons in the demonstrations in the coming chapters throughout the book.

Summary

We have learned how to work with built-in display and push buttons of Micro:bit. We also immersed ourselves in MicroPython programming that is specific to Micro:bit. Now, we have a fair understanding of how MicroPython interacts with the hardware features of Micro:bit. Like this one, the rest of the book’s chapters will be full of hands-on programming with MicroPython using Micro:bit.

The next chapter explores the interfacing and programming of external LEDs and LED-based hardware with digital GPIO pins of Micro:bit and MicroPython.

Further reading

The following pages have more information on the programming of displays and buttons:

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

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