Skip to content
BetaDE
Lesson 6 of 8Robotics with LEGO SPIKE

Robotics with LEGO SPIKE · Lesson 6 · 25 minutes

Display and sounds

What you'll learn

  • Build your own image as a list of lists
  • Control single pixels and their brightness
  • Calculate a status display from measurements
  • Play sounds and melodies

The code in this lesson comes from the book “Python for Robots”, chapter 2.3, and runs unchanged in the simulator. German edition on Amazon ↗

The display as a list of lists

The hub’s 5×5 display can do more than ready-made icons. Your own image is simply a list of 5 rows, and every row is a list of 5 brightness values from 0 (off) to 100 (fully bright). This example from the book draws an X:

from pybricks.hubs import PrimeHub

hub = PrimeHub()

# Custom pattern: a simple "X" on the matrix
pattern_x = [
    [100, 0, 0, 0, 100],
    [0, 100, 0, 100, 0],
    [0, 0, 100, 0, 0],
    [0, 100, 0, 100, 0],
    [100, 0, 0, 0, 100],
]

hub.display.icon(pattern_x)

Look at the numbers: the 100s form two diagonals – just like the X on the hub.

Single pixels and brightness

With hub.display.pixel(row, column, brightness) you switch a single pixel. Rows and columns are counted from 0. Together with a loop this becomes a small animation:

from pybricks.hubs import PrimeHub
from pybricks.tools import wait

hub = PrimeHub()

for column in range(5):
    hub.display.pixel(2, column, 100)
    wait(200)

for brightness in [80, 60, 40, 20, 0]:
    for column in range(5):
        hub.display.pixel(2, column, brightness)
    wait(150)

Calculate patterns instead of typing them

Instead of writing every image by hand, your program can calculate it. Here a staircase appears:

from pybricks.hubs import PrimeHub

hub = PrimeHub()

stairs = []
for row in range(5):
    line = []
    for column in range(5):
        if column <= row:
            line.append(100)
        else:
            line.append(0)
    stairs.append(line)

print(stairs)
hub.display.icon(stairs)

That’s how you build status displays that follow your measurements – like how close an obstacle is or how full the battery still is. That’s your task.

Sounds and melodies

The hub has a small speaker. hub.speaker.beep(frequency, duration) plays a tone – the frequency in hertz (the higher, the brighter), the duration in milliseconds. With play_notes() you play whole melodies: "C4/4" is a C in the 4th octave as a quarter note, "R/8" an eighth rest.

from pybricks.hubs import PrimeHub
from pybricks.tools import wait

hub = PrimeHub()

# Three beeps, getting higher
for frequency in [440, 660, 880]:
    hub.speaker.beep(frequency, 150)
    wait(100)

# A little fanfare
hub.speaker.play_notes(["C4/8", "E4/8", "G4/8", "C5/4", "R/8", "G4/8", "C5/2"], tempo=120)

In the simulator you hear the tones through your speakers. With the 🔊 Sound on button on the virtual hub you can switch them off. A tone is a great signal: “goal reached”, “obstacle!” or “battery almost empty”.

Tip from the book: Custom patterns are great for small status indicators: a checkmark for success, an exclamation mark for an error, or an arrow for the driving direction.

Your task

Your turn

Build a battery level display. Write a function battery_level(percent) that returns a 5×5 pattern: for every started 20 %, one more row lights up, from the bottom up (brightness 100). At 0 % everything is off, at 1 to 20 % only the bottom row lights up, at 100 % everything. At the end, show battery_level(60) on the hub.

from pybricks.hubs import PrimeHub

hub = PrimeHub()


def battery_level(percent):
    pattern = []
    # build 5 rows with 5 values each
    return pattern


hub.display.icon(battery_level(60))

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

from pybricks.hubs import PrimeHub

hub = PrimeHub()


def battery_level(percent):
    rows_on = (percent + 19) // 20
    pattern = []
    for row in range(5):
        if row >= 5 - rows_on:
            pattern.append([100, 100, 100, 100, 100])
        else:
            pattern.append([0, 0, 0, 0, 0])
    return pattern


hub.display.icon(battery_level(60))