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.
.. figure:: ../Sphinx/_static/sensehat.jpg
:align: center
:alt: Der Sense-HAT
:scale: 50%
*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)*
.. figure:: ../Sphinx/_static/raspbianOS.png
:align: center
:alt: Respbian Imager
:scale: 70%
*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:
.. code-block:: bash
$ 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
.. code-block:: bash
$ 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:
.. code-block:: python
from sense_hat import SenseHat
zusätzlich interessante Libarys sind:
.. code-block:: python
from time import sleep
from random import randint
Für bessere Lesbarkeit können wir auch noch:
.. code-block:: python
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:
.. code-block:: python
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
.. code-block:: python
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
.. code-block:: python
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.
.. code-block:: python
:linenos:
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
.. code-block:: python
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.
.. raw:: html
*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:
.. code-block:: python
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:
.. code-block:: python
:linenos:
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.
.. code-block:: python
:linenos:
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:
.. code-block:: python
from sense_hat import SenseHat
from time import sleep
Danach folgt eine Setup() funktion welche später das Spielfeld setzt und die Farben Kalibriert
.. code-block:: python
:linenos:
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:
.. code-block:: python
:linenos:
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.
.. code-block:: python
:linenos:
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:
.. code-block:: python
:linenos:
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.
.. raw:: html
*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] 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/