Sense-Hat

Für das Praktikum DV-Anwendungen haben wir uns genauer mit dem Sense-Hat-Aufsatz für den Raspberry Pi auseinandergesetzt.

Einführung

Infolge der [Astro-Pi]-Mission, bei welcher 2 Raspberry Pi - Computer im Jahr 2015 mit einer Crew zur ISS geflogen wurden, wurde der [Sense_Hat] entwickelt, um eine integrierte Erweiterung zum Pi zu liefern, welche zur Durchführung von Messungen für wissenschaftliche Experimente mit mehreren Sensoren ausgestattet wurde.

Der Sense-HAT

Abb.:Nr.1 Der Sense-Hat

Ziel dieses Projekts ist die Auseinandersezung mit dem [Sense_Hat] (siehe Abb.1), seiner Dokumentation und schließlich die Erstellung kleinerer Programme, welche die Sensoren und Aktoren des Sense-HAT interaktiv nutzen.

Aufbau

Folgende Sensoren und Aktoren sind Teil des Sense-HAT:

8 x 8 RGB-LED-Matrix
Das Shift-Register der Matrix ist ein LED2472G, welches mit einem Atmel ATTINY88 verbunden ist und dadurch mit dem Pi kommuniziert. Mit den hierfür bereitgestellten Funktionen lassen sich Schriftzüge erstellen, welche über die Matrix wandern, einzelne Pixel ansprechen und mit gewünschter Farbe beleuchten sowie Informationen über den Zustand des gewünschten Pixels erhalten
Temperatur-Sensor
Sensor (je nach aufgerufener Funktion): HTS221 (Luftfeuchtigkeit/Temperatur), LSM9DS1 (Luftdruck/Temperatur): Im eigentlichen Sinne kein zwar kein eigener Sensor, jedoch kann entweder über den Luftdruck- oder den Luftfeuchtigkeits-Sensor die Umgebungstemperatur beziehen. Liefert die Temperatur in °C
Luftfeuchtigkeits-Sensor
Sensor: HTS221 (Luftfeuchtigkeit/Temperatur) Liefert die relative Luftfeuchtigkeit der Umgebung in %-Angabe
Luftdruck-Sensor
Sensor: LSM9DS1 (Luftdruck/Temperatur) Liefert den Luftdruck in der Umgebung in Millibar
IMU-Sensor (Inertial Measurment Unit)
Sensor: LSM9DS1 Besteht aus 3 Sensoren, welche jeweils über 3 Raumachsen messen können: einem Gyroskop, einem Beschleunigungssensor sowie einem Magnetometer
Joystick
Switch/Joystick: SKRHABE010 Der Joystick kann in vier Richtungen bewegt sowie gedrückt werden. Man kann die mit Aktionen kombinieren, welche bei Betätigung des Joysticks ausgeführt werden

Raspberry-Pi

Die Micro-SD Karte des Raspberry haben wir mit Hilfe des [Rasbian-Imagers] mit dem Raspbian Lite OS aufgesetzt. (siehe Abb.2)

Respbian Imager

Abb.:Nr.2 Respbian mit zugehöriger OS-Lite Version

Das ist ein Betriebsystem mit dem sich ein Raspberry Pi nur von einem Terminal aus steuern lässt. Um nun Zugriff auf dieses Terminal zu erlangen, muss man sich per SSH mit diesem verbinden. Um SSH einfach auf dem Raspberry zu aktivieren, kann man eine leere Datei mit dem Namen ssh in den boot Ordner der SD Karte erstellen. Der zugehörige Befehl um von einem Linux Rechner auf das Terminal der Raspberry-Pi zuzugreifen lautet:

$ ssh pi@"Ip-Adresse des Pi's":

Danach noch das standart Passwort des Pi’s eingeben, welches „raspberry“ lauter und es kann losgehen.

Package installieren

Damit man den Sense-Hat nun mit Python ansteuern kann, muss man ein Software Packet installieren

$ sudo apt-get install Sense-Hat

Python Syntax

Um nun in einem Python Programm den Sense-Hat zu steuern oder auszulesen muss man erstmal die Libary einbinden mit dem Befehl:

from sense_hat import SenseHat

zusätzlich interessante Libarys sind:

from time import sleep

from random import randint

Für bessere Lesbarkeit können wir auch noch:

sense = SenseHat()
sense.low_light = True

Mit diesem Befehl .low_light wird die Helligkeit der LEDs um etwa 50% verringert und der Befehl sense = SenseHat() kürzt zukünftigen Code.

Wichtige Befehle für den Zugriff auf den [Sense_Hat] sind:

sense.set_pixel(x,y,255,0,0)
#Setzt den Pixel an stelle x,y auf den Farbwert (255,0,0) = rgb = rot

sense.get_pixel(x,y)
#Gibt den Farbwert eines Pixels an der Stelle x,y zurück

sense.clear()
#Setzt die LED Matrix zurück

sense.stick.get_events()
#Fängt die Eingabe vom Joystick des Sense-Hats ab

sense.get_pressure()
#Gibt den Luftdruck aus

sense.get_temperature()
#Gibt die Temperatur aus

sense.get_humidity()
#Gibt Luftfeuchtigkeit aus

sense.get_orientation()
#gibt 3 verschiedene Arten von Rotation aus [pitch][roll][yaw]

Klima-Sensoren

In diesem Versuch werden die Daten der Klima-Sensoren ausgelesen und auf der LED-Matrix ausgegeben. Zunächst bekommt man jedoch die Möglichkeit, mittels des Joysticks zu entscheiden, ob die Temperatur, die Luftfeuchte oder der Luftdruck ausgegeben werden soll.

Zuerst werden die benötigten Bibliotheken eingebunden sowie eine Instanz der Klasse SenseHat erzeugt

from sense_hat import SenseHat, ACTION_PRESSED
import time
from signal import pause

sense = SenseHat()

Nun folgt die erste Anzeige auf der Matrix, die beschreibt in welche Richtung der Joystick zu bewegen ist, um die jeweilige Aktion auszuführen

sense.show_message("TEMP: left HUM: up PRESS: right")

Je nach Auswahl wird nun eine Funktion aufgerufen, welche die Messdaten auf der Matrix ausgibt. Als Beispiel folgt die Definition der Temperaturausgabe - Funktion, jene für Luftfeuchte und -druck sind fast identisch definiert.

1
2
3
4
5
6
7
def show_temp(event):
    if event.action == ACTION_PRESSED:
        sense.show_message("Ausgabe Temperatur.")
    while True:
        temperature = sense.get_temperature()
        sense.show_message("%s C" %round(temperature, 2))
        time.sleep(2)

Am Ende des Codes finden sich schließlich die Zuweisungen der Funktionsobjekte zu den Richtungs-Attributen der stick Instanz der sense-Instanz. Dies bewirkt, dass die jeweilige Funktion bei einem Press, Release oder Hold-Event bei der jeweiligen Richtung ausgeführt wird

sense.stick.direction_left = show_temp
sense.stick.direction_up = show_hum
sense.stick.direction_right = show_press
pause()

Beschleunigungs-Sensor

In diesem Versuch wird der Beschleunigungs-Sensor verwendet, um die Orientierung des Buchstaben ‚A‘, welcher auf der LED-Matrix angezeigt wird, nach eventueller Drehung des Pi entsprechend anzupassen.

Video Nr.1 Orientierung Video

Damit der Buchstabe für den Benutzer lesbar bleibt, wird der genannte Sensor verwendet, um herauszufinden, in welche Richtung die Erdbeschleunigung wirkt. Nach dem schon oben beschriebenen Einbinden der sense_hat-Bibliothek und dem Erstellen einer senseHat-Instanz werden am Anfang des Programms die Sensordaten aus dem Beschleunigungs-Sensor ausgelesen und auf eine volle Zahl gerundet. Da die Messdaten in Vielfache der Einheit G angegeben werden, ergibt sich für die Erdbeschleunigung naturgemäß der Wert 1. Die so erhaltenen Messdaten werden von der Auslese-Funktion in einem Dictionary gespeichert, dessen Keys anschließend genutzt werden, um die Daten für die einzelnen Achsen zu extrahieren:

acceleration = sense.get_accelerometer_raw()
x = acceleration['x']
y = acceleration['y']
z = acceleration['z']

x=round(x, 0)
y=round(y, 0)
z=round(z, 0)

Anschließend wird geprüft, für welche jeweilige Achse der Sensor die Gravitation registriert und abhängig davon der angezeigte Buchstabe an die Achse angepasst (wird entweder zu X, Y oder Z) sowie seine Farbe ggf. verändert:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pixel_list = sense.get_pixels()

if y == -1:
    sense.set_rotation(180)
    sense.show_letter("Y")
    pixel_list = sense.get_pixels()
    sense.set_pixels(pixel_list_to_red(pixel_list))
if y == 1:
    sense.set_rotation(0)
    sense.show_letter("Y")
    pixel_list = sense.get_pixels()
    sense.set_pixels(pixel_list_to_green(pixel_list))
if x == 1:
    sense.set_rotation(270)
    sense.show_letter("X")
    pixel_list = sense.get_pixels()
    sense.set_pixels(pixel_list_to_green(pixel_list))
if x == -1:
    sense.set_rotation(90)
    sense.show_letter("X")
    pixel_list = sense.get_pixels()
    sense.set_pixels(pixel_list_to_red(pixel_list))
if x == 0 and y == 0 and z == 1:
    sense.show_letter("Z")
    pixel_list = sense.get_pixels()
    sense.set_pixels(pixel_list_to_green(pixel_list))

Die Funktionen pixel_list_to_green sowie pixel_list_to_red sorgen dafür, dass der Buchstabe entsprechend der Ausrichtung des Pi zu der Achse des Sensors grün dargestellt wird, falls die Gravitation entlang der positiven Richtung der Achse wirkt und rot, falls das Gegenteil der Fall ist.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
green = [34,139,34]
red = [139,0,0]
black = [0,0,0]

def pixel_list_to_green(pixel_list):
    for index in range(len(pixel_list)):
        if pixel_list[index] != black:
            pixel_list[index] = green
    return pixel_list

def pixel_list_to_red(pixel_list):
    for index in range(len(pixel_list)):
        if pixel_list[index] != black:
            pixel_list[index] = red
    return pixel_list

Labyrinth Spiel

In diesem Versuch wurde ein Spiel entwickelt, welches sich an der LED Matrix und dem Joystick bedient. In diesem Spiel muss der Spieler seinen Charakter (eine rote LED) zum Ziel (eine lila LED) bewegen ohne die grünen „Hecken“ zu berühren.

Zu beginn müssen wir zwei Librarys einbinden:

from sense_hat import SenseHat
from time import sleep

Danach folgt eine Setup() funktion welche später das Spielfeld setzt und die Farben Kalibriert

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def setup():
    global setupcheck,lab,r,g,w,f,level, running
    sense.set_pixel(0,0,r)
    r = sense.get_pixel(0,0)
    sense.set_pixel(0,0,g)
    g = sense.get_pixel(0,0)
    sense.set_pixel(0,0,w)
    w = sense.get_pixel(0,0)
    sense.set_pixel(0,0,f)
    f = sense.get_pixel(0,0)
    sense.clear()
    if level == 1:
        sense.set_pixels(lab)
    elif level == 2:
        sense.set_pixels(lab2)
    elif level == 3:
        sense.set_pixels(lab3)
    elif level == 4:
        sense.show_message("Winner!")
        running = False
    setupcheck = False

Dies ist wichtig weil die sense.get_pixel(x,y) Funktion oft Probleme damit hat Farben 100% genau auszulesen. Also hab ich wie in Zeile 3 zu sehen den Pixel an der Stelle 0,0 alle Möglichen Farben meines Spiels annehmen lassen, um diese dann in ihre eigene Variable zu schreiben.

Danach folgt eine Funktion welche die Kollision mit einer Wand erkennt. Diese funktioniert wie folgt:

1
2
3
4
5
def collisioncheck(x,y):
    if sense.get_pixel(x,y) == g:
        collision()
    elif sense.get_pixel(x,y) == f:
        finish()

Es werden hier die Farbwerte der Pixel miteinander verglichen um so eine Kollision zwischen Spieler und Wand festzustellen.

Dazu muss der Spieler sich auch noch Bewegen können. Dies wird mit Abfrage der Joystick Eingabe erzielt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def movePlayer():
    global x,y,w
    for event in sense.stick.get_events():
        if event.action == "pressed":
            if event.direction == "up":
                sense.set_pixel(x,y,w)
                y -= 1
            elif event.direction == "down":
                sense.set_pixel(x,y,w)
                y += 1
            elif event.direction == "left":
                sense.set_pixel(x,y,w)
                x -= 1
            elif event.direction == "right":
                sense.set_pixel(x,y,w)
                x += 1

Hier wird jedes mal wenn der Joystick in eine bestimmte Richtung gedrückt wird die x oder y Koordinate um jeweils 1 erhöht bzw. verringert.

Zum Schluss müssen alle Funktionen zusammengesetzt werden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
while running:
    if setupcheck == True:
        setup()

    drawPlayer(x,y,r)
    movePlayer()
    collisioncheck(x,y)
    sleep(0.05)

sense.clear()

Hier wird alles in einer while Schleife nacheinander immer wieder aufgerufen bis der while running Status auf False gesetzt wird. In Video Nr.2 kann man nun die Anwendung live sehen.

Video Nr.2 Labyrinth Spiel

Den gesamten Quellcode zum nachlesen findet man unter: https://r-n-d.informatik.hs-augsburg.de:8080/dvati/berichte-ws21/2/-/blob/main/Sense-Hat/gyrlab.py

Fazit

Der Sense-Hat ist eigentlich ein All-in-One Auslesegerät für den Raspberry-Pi. Er bietet dem Nutzer, leicht in die Python Programmierung einzusteigen und ein Verständnis für erste Sensoren zu entwickeln.

Literaturangaben

[Astro-Pi]Die Astro Pi Homepage (besucht am 1.11.2021) https://astro-pi.org/de/mission-zero/
[Sense_Hat](1, 2, 3) Eine Website zum nachlesen von Funktionen des Sense-Hats (besucht am 1.11.2021) https://projects.raspberrypi.org/en/projects/getting-started-with-the-sense-hat
[Rasbian-Imagers]Die Website zum download der imaging Software für den Raspberry Pi (besucht am 1.11.2021) https://www.raspberrypi.com/software/