Sense HAT Introduction

Introduction to Sense HAT projects

Posted by wojtek on June 21, 2022 in Raspi

A couple of months ago I wrote two posts about RaspberryPi and Python (Docker and Oh My ZSH). At the same time I bought Sense HAT to play a little bit with it. The first thing, besides modification to my RasPi case, was coding tutorial which took me trough basic concepts of the hardware while I was creating classic Slug game (probably known under different name).

Once I’ve managed to complete it I decided to write another classic myself. Here you can find my “Sense Racing” tutorial.

This tutorial requires basic Python or generic programming knowledge

Getting started with Sense HAT

In any Sense HAT project (or tutorial) you woul need either:

  • Raspberry Pi
  • Sense HAT
  • Preferably lates version of Raspbian
  • Python3
  • Sense HAT for Python3
    sudo apt-get install sense-hat



Every project needs to be started with either sense_hat or sense_emu library import. In my code I’m doing it like that:

from sense_hat import SenseHat
# from sense_emu import SenseHat

Where one of them needs to be always commented out and by default sense_hat is the active one. It allows an easy switch between the production environment (actual Sense HAT) and the development environment (Sense emulator).

Game Concept

Before we will step into further implementation lets define how the game should look like. So here is our project definition.

  1. We will have a car (single pixel) driving on the stright track whith some obstacles appearing on the road as we move forward.
  2. Car will be able to move left and right in the bottom row, by pressing left and right keys.
  3. Hitting any obstacle will end game.
  4. Points are based on distance we make.
  5. We can accellerate speed for a short time by pressing up key.
  6. Base speed will increase beased on game time.

Game layout

Drawing Track

As everything on Sense HAT 8x8 display our graphic will be simplified to the maximum. Objects will be represented by different colour pixes, lets first define all colours that we need:

  • blank for background
  • border_colour for track borders that will create illusion of movement
  • car_colour so we know where we are
  • obstacle_colour and of course things we don’t want to hit

All colours are defined as (R,G,B) in range 0 - 255 here are mine:

blank = (0, 0, 0)
border_colour = (0, 0, 200)
car_colour = (100, 200, 0)
obstacle_colour = (100, 0, 0)

Race is completely different concept to Slug, our car will be moving by not moving at all. Actualy background has to move downwards. In such case we have to “remember” state of each point on screen and move it one row down and then create new row of track at the top. As shown on the image below, in the next step first row is becoming second, second is becoming third and so one. Only the car stays always at the bottom.

Game layout

In order to achieve that we have to always redraw whole screen (like in classic CRT screen), so we have to create a matrix which will keep value of each pixel and at the beginning we will fill it with our background colour. As well as we have to define distance and startup SenseHat().

track = [[blank for x in range(8)] for y in range(8)]
distance = 0

sense = SenseHat()

Now any movement will be achieved by simple operations on track matrix.

It’s time to create actual drawing function, as an argument we will take our track matrix.

def draw(matrix):
    flat_list = [item for sublist in matrix for item in sublist]

To refresh state of pixels we will use built in sense.set_pixels() which argument is a vector of rows from one the eight put one ofter another. So we have to convert our 8x8 matrix into 64 elements vector:

flat_list = [item for sublist in matrix for item in sublist]

And what is most important here, as we want our car to move forward by actually moving background backwards we have to reverse the matrix.

Generating Track

As we already have a function which will draw a frame based on a given matrix of values. It’s time to generate some track:

def gen_track():
    line = [blank for x in range(8)]

    if distance % 4 > 1:
        line[0] = border_colour
        line[7] = border_colour

    return line

This function is generating single line, which later on will be put ath the end (so after reverse at the beginning) of the matrix. At the moment its just empty line generated in the same way as initial matrix [blank for x in range(8)].

And then it generates track borders in two of four cycles distance % 4 > 1 this can be change later if you desire different pattern of track border.

Filnally we have to use all created functions:

if __name__ == '__main__':
    while True:
        draw(track[distance:distance + 8])

        distance += 1

Game needs to happen in the infinit loop, eveytime frame wi will append track with a new line generated by gen_trac() and we will draw last 8 rows of it. Then we have to increment distance which tells program how far we moved on the track and to slow down cycles a little bit we will use sleep(0.5) the actual value can be adjusted to your needs. Dont forget to add import:

from time import sleep

If you run this and you have everything setup corectly you shoudl see in your emulator track moving forward. Now you can try commenting out matrix.reverse() reverse line and see the effect.

This will be contiuned in the next post.

Everything together: