Conrad 4019631150011 Operation Manual [de]

Page 1
POWERED BY
HANDBUCH
TM
15001-1 HB_U1.qxp_Layout 1 27.04.17 10:02 Seite 1
Page 2
Page 3
Adventskalender 2017 für
MinecraftTM ist eines der beliebtesten Computerspiele weltweit – und das, obwohl es kein wirkliches Spielziel hat. Gerade die offene Spielwelt, in der jeder für sich Landschaften bauen und eigene Träume verwirklichen kann, fasziniert über 100 Millionen Spieler weltweit. Der Spieltitel setzt sich üb­rigens aus den beiden englischen Begriffen Mine (= Bergbau, Rohstoffab­bau) und craft (= verarbeiten) zusammen. Und genau darum geht es auch in MinecraftTM: Es gilt, Rohstoffe aus der Landschaft abzubauen und sie zu neuen Landschaften oder Objekten zu verarbeiten.
Neben den bekannten Versionen für PC und verschiedene Spielkonsolen gibt es Minecraft installiert. Die Raspberry-Pi-Version bietet einen großen Vorteil, sie ist über eine eigens entwickelte Schnittstelle in der Programmiersprache Python programmierbar. Python ist ebenfalls auf dem Raspberry Pi vorinstalliert und ermöglicht unter anderem die Ansteuerung externer Hardware. So ist es auf dem Raspberry Pi möglich, mit MinecraftTM LEDs zum Blinken zu brin­gen oder mit Hardwaretasten und Sensorkontakten die Spielfigur „Steve“ in MinecraftTM zu steuern.
Dieser Adventskalender enthält jeden Tag ein kleines Hardwareexperiment für den Raspberry Pi, dazu das passende Python-Programm und Elemen­te in der Minecraft berry Pi 2 oder 3 und der aktuellen Version des Betriebssystems Raspbian.
Die wichtigsten Bauteile kurz erklärt
Steckbrett
Für den schnellen Aufbau elektronischer Schaltungen, ohne löten zu müs­sen, enthält der Adventskalender ein Steckbrett. Hier können elektronische Bauteile direkt in ein Lochraster gesteckt werden.
Die Verbindungen auf dem Steckbrett.
TM
auch auf dem Raspberry Pi – und sogar kostenlos vor-
TM
-Welt. Alle Experimente funktionieren mit dem Rasp-
Bei diesem Steckbrett sind alle äußeren Längsreihen über Kontakte (X und Y) miteinander verbunden. Diese Kontaktreihen werden oft als Plus- und Minuspol zur Stromversorgung der Schaltungen genutzt. In den anderen Kontaktreihen sind jeweils fünf Kontakte (A bis E und F bis J) quer miteinan­der verbunden, wobei in der Mitte der Platine eine Lücke ist. So können hier größere Bauelemente eingesteckt und nach außen hin verdrahtet werden.
LED
LEDs werden in Schaltungen mit einem pfeilförmigen Dreieckssymbol dar­gestellt, das die Flussrichtung vom Pluspol zum Minuspol oder zur Masselei­tung angibt. Eine LED lässt in der Durchflussrichtung nahezu beliebig viel Strom durch, sie hat nur einen sehr geringen Widerstand. Um den Durch­flussstrom zu begrenzen und damit ein Durchbrennen der LED zu verhin­dern, wird üblicherweise zwischen dem verwendeten GPIO-Pin und der Anode der LED oder zwischen Kathode und Massepin ein 220-Ohm-Vorwi­derstand eingebaut. Dieser Vorwiderstand schützt auch den GPIO-Ausgang des Raspberry Pi vor zu hohen Stromstärken. Die LEDs im Adventskalender haben den Vorwiderstand bereits eingebaut und können daher direkt an die GPIO-Pins angeschlossen werden.
Schaltplan einer LED mit Vorwiderstand.
LED in welcher Richtung anschließen?
Die beiden Anschlussdrähte einer LED sind unterschiedlich lang. Der längere ist der Pluspol, die Anode, der kürzere die Kathode. Einfach zu merken: Das Pluszeichen hat einen Strich mehr als das Minuszeichen und macht damit den Draht optisch etwas länger. Außerdem sind die meisten LEDs auf der Minusseite abgeflacht, vergleichbar mit einem Minuszeichen. Auch leicht zu merken: Kathode = kurz = Kante.
Widerstand
Widerstände werden zur Strombegrenzung an empfindlichen elektroni­schen Bauteilen sowie als Vorwiderstände für LEDs verwendet. Die Maß­einheit für Widerstände ist Ohm. 1.000 Ohm entsprechen einem Kiloohm, abgekürzt kOhm. 1.000 kOhm entsprechen einem Megaohm, abgekürzt MOhm. Oft wird für die Einheit Ohm auch das Omega-Zeichen Ω verwendet.
Die farbigen Ringe auf den Widerständen geben den Widerstandswert an. Mit etwas Übung sind sie deutlich leichter zu erkennen als winzig kleine Zahlen, die man nur noch auf ganz alten Widerständen findet.
Die meisten Widerstände haben vier solcher Farbringe. Die ersten beiden Farbringe stehen für die Ziffern, der dritte bezeichnet einen Multiplikator und der vierte die Toleranz. Dieser Toleranzring ist meistens gold- oder sil­berfarben – Farben, die auf den ersten Ringen nicht vorkommen. Dadurch ist die Leserichtung immer eindeutig. Der Toleranzwert selbst spielt in der Digitalelektronik kaum eine Rolle. Die Tabelle zeigt die Bedeutung der farbi­gen Ringe auf Widerständen.
Farbe Widerstandswert in Ohm
1. Ring (Zehner)
Silber 10
Gold 10 Schwarz 0 10 Braun 1 1 10 Rot 2 2 10 Orange 3 3 10
Gelb 4 4 10 Grün 5 5 10
Blau 6 6 10
Violett 7 7 10
Grau 8 8 10
Weiß 9 9 10
2. Ring (Einer)
3. Ring (Multiplikator)
−2
= 0,01 ±10 %
−1
= 0,1 ±5 %
0
= 1
1
= 10 ±1 %
2
= 100 ±2 %
3
= 1.000
4
= 10.000
5
= 100.000 ±0,5 %
6
= 1.000.000 ±0,25 %
7
= 10.000.000 ±0,1 %
8
= 100.000.000 ±0,05 %
9
= 1.000.000.000
4. Ring (Toleranz)
In welcher Richtung ein Widerstand eingebaut wird, ist egal. Bei LEDs dage­gen spielt die Einbaurichtung eine wichtige Rolle.
GPIO-Verbindungskabel
Alle farbigen Verbindungskabel haben auf der einen Seite einen dünnen Drahtstecker, mit dem sie sich auf die Steckplatine stecken lassen. Auf der anderen Seite befindet sich eine Steckbuchse, die auf einen GPIO-Pin des Raspberry Pi passt.
Pinbelegung der GPIO-Pins.
Sicherheitsmaßnahmen
Auf keinen Fall sollte man irgendwelche GPIO-Pins miteinander verbinden und abwarten, was passiert.
Nicht alle GPIO-Pins lassen sich frei programmieren. Einige sind für die Stromversorgung und andere Zwecke fest eingerichtet.
Einige GPIO-Pins sind direkt mit Anschlüssen des Prozessors verbunden, ein Kurzschluss kann den Raspberry Pi komplett zerstören. Verbindet man über einen Schalter oder eine LED zwei Pins miteinander, muss immer ein Schutz­widerstand dazwischengeschaltet werden. Eine Ausnahme bilden die LEDs mit eingebautem Vorwiderstand.
Für Logiksignale sollte immer Pin 1 verwendet werden, der +3,3 V liefert und bis 50 mA belastet werden kann. Pin 6 ist die Masseleitung für Logiksignale.
Pin 2 und Pin 4 liefern +5 V zur Stromversorgung externer Hardware. Hier kann so viel Strom entnommen werden, wie das USB-Netzteil des Rasp­berry Pi liefert. Diese Pins dürfen aber nicht mit einem GPIO-Eingang ver­bunden werden.
Page 4
Heute im Adventskalender
1 Steckbrett (SYB 46)
1 LED rot mit eingebautem Vorwiderstand
2 GPIO-Verbindungskabel
Raspberry Pi vorbereiten
Um den Raspberry Pi in Betrieb zu nehmen, braucht man:
USB-Tastatur und Maus
HDMI-Kabel für Monitor
Netzwerkkabel
MicroSD-Karte mit Betriebssystem Raspbian Jessie
Micro-USB-Handyladegerät als Netzteil (mindestens 1.000 mA,
besser 2.000 mA)
Das Netzteil wird als Letztes angeschlossen, denn damit schaltet sich der Raspberry Pi automatisch ein. Es gibt keinen eigenen Ein-/Ausschalter.
Betriebssysteminstallation in Kürze
Für alle, die ihren Raspberry Pi noch nicht mit der aktuellen Raspbian-Versi­on betriebsbereit haben, folgt hier die Systeminstallation in zehn Schritten:
1. NOOBS (mindestens Version 2.0.0) von www.raspberrypi.org/downloads auf den PC herunterladen und Zip-Archiv auf die Festplatte entpacken.
2. Wurde die SD-Karte bereits benutzt, mit SD-Formatter im PC neu forma­tieren: www.sdcard.org/downloads/formatter_4. Dabei Format Size Adjust-
ment einschalten (die SD-Karte muss mindestens 4 GByte groß sein).
3. Die Dateien und Unterverzeichnisse von NOOBS auf die SD-Karte ko­pieren.
4. SD-Karte aus dem PC nehmen, in den Raspberry Pi stecken und boo­ten. Ganz unten Deutsch als Installationssprache wählen. Damit wird automatisch auch die deutsche Tastatur ausgewählt. Das Häkchen beim vorausgewählten Raspbian-Betriebssystem setzen und oben links auf Install klicken. Nach Bestätigung der Sicherheitsinformation, dass die Speicherkarte überschrieben wird, startet die Installation, die einige Minuten dauert.
5. Nach abgeschlossener Installation bootet der Raspberry Pi neu.
6. Im Menü unter Einstellungen das Tool Raspberry-Pi Konfiguration starten.
7. Auf der Registerkarte Lokalisierung im Feld Zeitzone festlegen die Op- tionen Europe und Berlin auswählen. Sprachumgebung und Tastatur sollten automatisch auf Deutsch gesetzt sein.
8. Auf der Registerkarte Schnittstellen den Schalter SSH auf Aktiviert set­zen, wenn Sie vom PC über das Netzwerk Daten auf den Raspberry Pi übertragen wollen.
9. Auf OK klicken und den Raspberry Pi über den Menüpunkt Shutdown neu booten. Eine eventuell auftauchende Warnung wegen eines unsi­cheren Passworts kann ignoriert werden.
LED leuchtet
Für das erste Experiment wird kein Programm benötigt. Der Raspberry Pi dient hier nur als Stromversorgung für die LED. Das Experiment zeigt, wie LEDs an­geschlossen werden. Achten Sie darauf, dass die LED richtig herum eingebaut ist. Die Kathode (der kurze Draht) steckt in der Längsschiene des Steckbretts, die in den meisten Schaltungen als Masseleitung verwendet wird (in der Ab­bildung ganz rechts). Die abgebildete Schaltung lässt die LED rot leuchten.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
2 GPIO-Verbindungskabel
Dateien zum Download
Die im Adventskalender verwendeten Programme, die MinecraftTM-Welt sowie die Aufbauzeichnungen der Schaltungen in Farbe gibt es unter www.buch.cd. Tragen Sie für dieses Produkt im Eingabefeld den Code 15001-1 ein.
Öffnen Sie die Webseite direkt mit dem vorinstallierten Brow­ser auf dem Raspberry Pi und laden Sie die Zip-Datei in das Home-Verzeichnis /home/pi herunter.
Starten Sie den Dateimanager auf dem Raspberry Pi. Dieser zeigt beim Start automatisch das Home-Verzeichnis an. Klicken Sie mit der rechten Maustaste auf die heruntergeladene Zip-Datei und wählen Sie im Kontextmenü Hier entpacken.
Kopieren Sie mit dem Dateimanager die Dateien der Minecraft adventskalender in das Verzeichnis /home/pi/.minecraft/
games/com.mojang/minecradftWorlds auf dem Raspberry Pi.
Da sich in den abgedruckten Code-Beispielen Zeilenumbrüche nicht immer vermeiden ließen, haben wir sie mit einem Pfeil ( Diese Pfeile sind nicht Bestandteil des Codes.
) kenntlich gemacht.
TM
-Welt
Page 5
Um das Verzeichnis der MinecraftTM-Welten zu sehen, muss im Dateimana­ger-Menü unter Ansicht die Option Versteckte anzeigen eingeschaltet sein.
Minecraft™
MinecraftTM, das beliebte Weltenbauer-Spiel, ist in der aktuellen Raspbi­an-Version bereits vorinstalliert. In MinecraftTM erkundet man eine schier endlose Welt, die aus einfachen Würfeln erbaut ist. Die Blöcke bestehen aus verschiedenen Materialien und können abgebaut werden, um sie als Roh­stoffe zu verarbeiten und daraus andere Dinge zu bauen. Der Spieler über­nimmt die Rolle der Spielfigur Steve und steuert diese. Dabei kann man die Szene aus Steves Perspektive sehen oder aus Sicht einer Kamera von außen darauf blicken.
2. Mit vier auch aus anderen Spielen bekannten Buchstabentasten be-
wegt man sich: mit [W] nach vorne, mit [S] nach hinten, mit [A] nach links und mit [D] nach rechts. Bei Stufen im Gelände steigt man wäh­rend der Bewegung automatisch nach oben oder unten.
3. Mit der [Leertaste] kann man in die Höhe springen. Drückt man die [Leertaste] zweimal kurz hintereinander, wird auf den Flugmodus umgeschaltet. In diesem Modus schwebt man und ist nicht mehr an den Boden gebunden. Im Flugmodus steigt man durch längeres Drü­cken der [Leertaste] weiter nach oben.
4. Umgekehrt duckt man sich mit der linken [Umschalt]-Taste etwas nach unten. Im Flugmodus verringert man mit dieser Taste die Flug­höhe.
5. Die Taste [E] öffnet das Inventar, in dem jede Menge unterschiedlicher Blöcke zum Bau zur Verfügung stehen. Acht verschiedene Blöcke oder Werkzeuge sind in der Inventarleiste am unteren Bildschirmrand jeder­zeit verfügbar. Hier wählt man mit den Tasten [1] bis [8] oder mit dem Mausrad das gewünschte Objekt aus.
6. Ein Klick mit der linken Maustaste entfernt den angeklickten Block, ein Klick mit der rechten Maustaste platziert einen Block des gewählten Typs an der angeklickten Position.
7. Die [Esc]-Taste blendet ein Menü ein, über das man das Spiel verlas­sen oder über ein Symbol links oben auf die Sicht eines außenstehen­den Betrachters wechseln kann.
8. Die [Tab]-Taste befreit die Maus aus dem Minecraft
TM
-Fenster, wenn
man zwischendurch in ein anderes Programm wechseln möchte.
Die erste LED leuchtet am Raspberry Pi.
Wer MinecraftTM kennt, wird sich auch in der Pi Edition schnell zurechtfin­den. Die Steuerung des Spiels und die Bewegungen in der Spielwelt laufen sehr ähnlich. Wer Minecraft
TM
bis jetzt nicht kennt, braucht sich nur wenige
Tasten zu merken:
1. Mit der Maus dreht man sich, ohne eine Maustaste zu drücken, um die eigene Achse und neigt den Blick nach oben oder unten. Das Spiel reagiert sehr schnell, man muss also aufpassen, dass man sich beim Drehen nicht „überschlägt“.
Ausschnitt aus der MinecraftTM-Welt des Adventskalenders.
Page 6
Heute im Adventskalender
1 LED grün mit eingebautem Vorwiderstand
1 GPIO-Verbindungskabel
LED leuchtet beim Betreten einer bestimmten Fläche
Das Experiment des 2. Tags lässt die grüne LED leuchten, wenn man mit der Figur eine grüne Fläche betritt, die sich in der vorgegebenen Minecraft Welt bei der Nummer 2 befindet. Gesteuert wird das Ganze über ein Pro­gramm in Python.
TM
-
Zwei LEDs am Raspberry Pi.
Die Python 3 Shell IDLE
Das Programm
Das Programm zeigt wichtige Techniken der Python-Programmierung, die Sie für die weiteren Programme brauchen werden. Um ein Python-Pro­gramm mit MinecraftTM nutzen zu können, muss MinecraftTM bereits laufen. Verlassen Sie das MinecraftTM-Fenster mit der Taste [Tab], wechseln Sie dann in die Python-Shell und starten Sie dort das Programm mit der Taste [F5]. Danach können Sie mit einem einfachen Klick in das MinecraftTM-Fens- ter ins Spiel zurückkehren.
#!/usr/bin/python import mcpi.minecraft as minecraft import RPi.GPIO as GPIO
Die grüne Fläche neben der 2 lässt die LED leuchten.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
3 GPIO-Verbindungskabel
Heute verwenden wir, wie bei allen Experimenten in diesem Adventskalen­der, ein Steckbrett zum Aufbau der Schaltung. Die in der Abbildung untere Längsreihe wird als Masseleitung verwendet und ist mit dem GND-Pin des Raspberry Pi verbunden. Die LEDs sind mit der Kathode (dem kurzen Draht) in dieser Kontaktreihe eingesteckt.
Die Programmiersprache Python ist auf dem Raspberry Pi ebenfalls vorin­stalliert, sogar in zwei verschiedenen Versionen. Python 3 ist nicht, wie der Name vermuten lässt, einfach eine neuere Version von Python 2. Die Spra­chen verwenden teilweise eine andere Syntax. Programme sind also nicht eins zu eins kompatibel. Viele externe Bibliotheken sind nur für eine der beiden Versionen erhältlich. Entwickler von Python-Programmen müssen ihren Nutzern also immer mitteilen, mit welcher Version ein Programm funk­tioniert. Wir verwenden in diesem Adventskalender immer das moderne Python 3.
Starten Sie im Menü unter Entwicklung das Programm Python 3. IDLE ist eine komplette Python-Shell und Entwicklungsumgebung. Für den Start in die Programmierung sind keine zusätzlichen Komponenten nötig.
Öffnen Sie über File/Open das Programm 02mc_led01.py aus dem Down­load oder gehen Sie in der Python-Shell über File/New in ein neues Fenster und tippen Sie das Programm ein.
mc = minecraft.Minecraft.create() GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) GPIO.setup(23, GPIO.OUT)
while True: p = mc.player.getTilePos() if (p.x<=1 and p.x>=-1 and p.z<=-2 and p.z >=-4): GPIO.output(23, True) GPIO.output(18, False) else: GPIO.output(18, True) GPIO.output(23, False)
Page 7
So funktioniert das Programm
#!/usr/bin/python
Python-Programme, die über die Kommandozeile gestartet werden, müs­sen am Anfang immer obige Zeile enthalten. Bei Programmen, die nur über die Python-Shell gestartet werden, ist das nicht nötig. Aus Gründen der Kompatibilität sollten Sie sich aber angewöhnen, diese Zeile am Anfang je­des Python-Programms einzutragen.
import mcpi.minecraft as minecraft import RPi.GPIO as GPIO
Ein großer Vorteil von Python ist die einfache Erweiterbarkeit um neue Funk­tionen aus Funktionsbibliotheken. Für nahezu jede Aufgabe gibt es bereits fertige Bibliotheken, sodass Sie viele Standardaufgaben nicht mehr selbst zu lösen brauchen. Die Bibliothek mcpi.minecraft wird für die Verbindung zu Minecraft Bibliothek RPI.GPIO wird für die Unterstützung der GPIO-Pins importiert.
mc = minecraft.Minecraft.create()
Diese Zeile ist in jedem Programm enthalten, das Minecraft generiert ein Python-Objekt für das laufende MinecraftTM-Spiel. Objekte sind weit mehr als nur einfache Variablen. Sie können verschiedene Eigen­schaften haben und über Methoden beeinflusst werden. Methoden werden durch einen Punkt getrennt direkt hinter dem Objektnamen angegeben. Verschiedene Methoden dieses Objekts können dann ins Spiel eingreifen oder Daten aus dem Spiel auslesen.
GPIO.setmode(GPIO.BCM)
Die Bibliothek RPi.GPIO unterstützt zwei Methoden zur Bezeichnung der Pins. Im Modus BCM werden die bekannten GPIO-Portnummern verwendet, die auch in Scratch genutzt werden. Im Modus BOARD entsprechen die Be­zeichnungen den Pinnummern auf der Raspberry-Pi-Platine. Üblicherweise wird BCM verwendet.
GPIO.setup(18, GPIO.OUT) GPIO.setup(23, GPIO.OUT)
Die Funktion GPIO.setup initialisiert einen GPIO-Pin als Ausgang oder als Eingang. Der erste Parameter bezeichnet den Pin je nach vorgegebe­nem Modus BCM oder BOARD mit seiner GPIO-Nummer oder Pinnummer. Der zweite Parameter kann entweder GPIO.OUT für einen Ausgang oder
GPIO.IN für einen Eingang sein.
while True:
Schleifen mit while laufen so lange, wie die danach angegebene Bedin­gung wahr ist. Da die Bedingung hier einfach True lautet, also immer wahr ist, läuft die Schleife endlos.
TM
benötigt. Hier sind alle Steuerungsfunktionen enthalten. Die
TM
nutzt. Sie
Einrückungen sind in Python wichtig
In den meisten Programmiersprachen werden Programmschleifen oder Entscheidungen eingerückt, um den Programmcode übersichtlicher zu ma­chen. In Python dienen diese Einrückungen nicht nur der Übersichtlichkeit, sondern sind für die Programmlogik sogar zwingend nötig. Dafür braucht man in dieser Sprache keine speziellen Satzzeichen, um Schleifen oder Ent­scheidungen zu beenden.
p = mc.player.getTilePos()
Die eingerückten Zeilen werden in jedem Schleifendurchlauf einmal ausge­führt. Diese Zeile liest die Koordinaten des Minecraft
TM
-Klotzes aus, auf dem
die Spielfigur gerade steht, und schreibt diese in die Variable p.
Das MinecraftTM-Koordinatensystem
Koordinaten in MinecraftTM werden in Rastereinheiten in der Größe der Klöt­ze gezählt. Im Gegensatz zu vielen bekannten 3-D-Programmen hat die ho­rizontale Ebene in Minecraft oben in die Luft.
Die Spielfigur soll die kleine grüne Fläche neben der gemauerten 2 betreten. Diese Fläche liegt in der x-Achse zwischen den Koordinaten –1 und 1, in der z-Achse zwischen 2 und 4. Ob die Figur dort steht, wird mit einer if-Abfrage geprüft:
if (p.x<=1 and p.x>=-1 and p.z<=-2 and p.z >=-4):
Innerhalb der if-Abfrage sind vier Bedingungen mit and verknüpft. Sie müssen alle gleichzeitig wahr sein, damit die Abfrage im Ganzen wahr er­gibt. p.x liefert die x-Koordinate des in p gespeicherten Punkts, p.z liefert die z-Koordinate.
GPIO.output(23, True) GPIO.output(18, False)
Die eingerückten Zeilen werden immer dann ausgeführt, wenn die if­Abfrage wahr liefert.
Die Funktion GPIO.output setzt den Status eines GPIO-Pins. Jeder Pin kann auf zwei verschiedene Zustände gesetzt werden. True schaltet den Pin ein, False schaltet ihn wieder aus. Diese Zeilen schalten die LED an GPIO-Pin 23 ein und die LED an GPIO-Pin 18 aus.
Ergibt die if-Abfrage nicht wahr, weil die Spielfigur außerhalb der grünen Fläche steht, wird der zweite Teil der Abfrage hinter else ausgeführt.
else: GPIO.output(18, True) GPIO.output(23, False)
Diese Zeilen schalten, entgegengesetzt zum ersten Teil der Abfrage, die LED an GPIO-Pin 18 ein und die LED an GPIO-Pin 23 aus.
TM
x- und z-Koordinaten. Die y-Achse zeigt nach
Starten Sie das Programm mit der Taste [F5]. Eventuell auftauchende War­nungen wegen verwendeter GPIO-Ports können Sie ignorieren. Die rote LED leuchtet. Bewegen Sie die Spielfigur auf die grüne Fläche neben der 2, leuchtet die grüne LED. Verlässt die Spielfigur diese Fläche wieder, leuchtet erneut die rote LED.
Spielfigur Steve steht auf der grünen Fläche
Spielfigur Steve steht außerhalb der grünen Fläche
Page 8
Heute im Adventskalender
1 LED gelb mit eingebautem Vorwiderstand
1 GPIO-Verbindungskabel
Ampel auf einer Straße
Das Experiment des 3. Tags stellt eine Ampel dar. Stellen Sie sich mit der Spielfigur auf die Haltelinie, und die Ampel schaltet auf Grün.
Die in MinecraftTM aufgebaute Ampel kann nicht wirklich leuchten. Dies überneh­men drei LEDs.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
4 GPIO-Verbindungskabel
Das Programm
Das Programm 03mc_ampel01.py schaltet einen Ampelzyklus auf den drei LEDs, wenn die Spielfigur auf dem Wartebalken auf der Straße steht.
#!/usr/bin/python import mcpi.minecraft as minecraft import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() rot = 0 gelb = 1 gruen = 2 Ampel=[18,23,25]
GPIO.setmode(GPIO.BCM) GPIO.setup(Ampel[rot], GPIO.OUT, initial=True) GPIO.setup(Ampel[gelb], GPIO.OUT, initial=False) GPIO.setup(Ampel[gruen], GPIO.OUT, initial=False)
try: while True: p = mc.player.getTilePos() mat = mc.getBlock(p.x, p.y-1, p.z) if mat==42: GPIO.output(Ampel[gelb],True) time.sleep(0.6) GPIO.output(Ampel[rot],False) GPIO.output(Ampel[gelb],False) GPIO.output(Ampel[gruen],True) time.sleep(2) GPIO.output(Ampel[gruen],False) GPIO.output(Ampel[gelb],True) time.sleep(0.6) GPIO.output(Ampel[gelb],False) GPIO.output(Ampel[rot],True) time.sleep(2)
except KeyboardInterrupt: GPIO.cleanup()
Der Ampelzyklus
Farbe(n) Zeit
Rot/Gelb 0.6 sek Grün 2.0 sek Gelb 0.6 sek Rot 2.0 sek
Drei LEDs simulieren eine Ampel am Raspberry Pi.
So funktioniert das Programm
import time
Zusätzlich zu den bereits bekannten Bibliotheken wird die Bibliothek time importiert, die verschiedene Funktionen zur Berechnung von Zeiten enthält. Damit werden die Wartezeiten zwischen den Ampelphasen erstellt.
rot = 0 gelb = 1 gruen = 2 Ampel=[18,23,25]
Um die GPIO-Pins im Programm besser unterscheiden und das Programm leichter an einen anderen Schaltungsaufbau anpassen zu können, werden die Pinnummern am Anfang in einer Liste Ampel[] gespeichert. Die Num­mern der drei Listenelemente werden in den drei Variablen rot, gelb und
gruen gespeichert und können so sehr einfach zugeordnet werden.
GPIO.setup(Ampel[rot], GPIO.OUT, initial=True)
Page 9
GPIO.setup(Ampel[gelb], GPIO.OUT, initial=False) GPIO.setup(Ampel[gruen], GPIO.OUT, initial=False)
Die drei GPIO-Pins werden über die Liste als Ausgänge eingerichtet. Der zusätzliche Parameter initial schaltet die rote LED ein und die beiden anderen aus.
try: while True:
Um zu vermeiden, dass Python beim Programmstart GPIO-Warnungen aus­gibt, wird die Endlosschleife in eine try:…except:-Konstruktion einge­bettet, die am Ende die GPIO-Ports wieder schließt.
p = mc.player.getTilePos()
Am Anfang speichert die Endlosschleife wieder in jedem Durchlauf die Posi­tion der Spielfigur in der Variablen p.
mat = mc.getBlock(p.x, p.y-1, p.z)
Die Methode mc.getBlock() liest die Material-ID des Blocks unterhalb der Spielfigur aus. Dazu wird von der y-Koordinate 1 subtrahiert.
if mat==42:
Jeder Block hat ein typisches Material. Diese Materialien haben alle einzelne Nummern. Die Material-ID der für den Wartebalken auf der Straße verwen­deten Blöcke ist 42.
== ist nicht gleich =
Das doppelte Gleichheitszeichen == steht für eine Gleichheitsabfrage, das einfache Gleichheitszeichen = wird dagegen für Variablenzuweisungen ver­wendet.
GPIO.output(Ampel[gelb],True) time.sleep(0.6)
Steht die Spielfigur auf einem Block mit dieser Material-ID, beginnt der Am­pelzyklus, indem die gelbe LED zusätzlich zu der bereits leuchtenden roten eingeschaltet wird. Danach wartet das Programm 0,6 Sekunden.
GPIO.output(Ampel[rot],False) GPIO.output(Ampel[gelb],False) GPIO.output(Ampel[gruen],True) time.sleep(2)
Anschließend werden die rote und die gelbe LED aus- und die grüne LED eingeschaltet. In diesem Zustand wartet die Ampel 2 Sekunden. Auch bei realen Verkehrsampeln dauert die Grünphase deutlich länger als die Zwi­schenphasen Rot/Gelb und Gelb.
GPIO.output(Ampel[gruen],False) GPIO.output(Ampel[gelb],True) time.sleep(0.6) GPIO.output(Ampel[gelb],False) GPIO.output(Ampel[rot],True) time.sleep(2)
Anschließend schaltet die Ampel über Gelb auf Rot und wartet wieder 2 Se­kunden, bevor die Endlosschleife einen weiteren Durchlauf startet.
except KeyboardInterrupt: GPIO.cleanup()
Die letzten beiden Zeilen sind nicht mehr eingerückt, sie werden erst dann ausgeführt, wenn der Benutzer die Endlosschleife mit der Tastenkombina­tion [Strg]+[C] abbricht.
Am Ende eines Programms sollten alle verwendeten GPIO-Pins wieder zu­rückgesetzt werden, um Warnungen beim nächsten Programmstart zu vermeiden. Die letzte Zeile dieses Programms erledigt das für alle vom Pro­gramm initialisierten GPIO-Pins auf einmal. Pins, die von anderen Program­men initialisiert wurden, bleiben davon unberührt. So wird der Ablauf dieser anderen möglicherweise parallel laufenden Programme nicht gestört.
Spielfigur Steve steht auf dem Wartebalken vor der Ampel
Tag 3 in der MinecraftTM-Welt
Schon gewusst...?
Der Begriff ‚Ampel‘ kommt von dem mittelhochdeutschen Wort
‚ampulla‘ und bezeichnet ein kleines Gefäß für Öl oder andere Flüssigkeiten. Im Mittelalter wurde damit das Ewige Licht in katho­lischen Kirchen bezeichnet. Die ersten Verkehrsampeln hingen an Drahtseilen über Kreuzungen und sahen daher ähnlich aus.
Die offizielle Bezeichnung von Verkehrsampeln ist nach § 43 der
deutschen Straßenverkehrsordnung (StVO) ‚Lichtzeichenanlage‘, abgekürzt: LZA. In der österreichischen Straßenverkehrsordnung und in der Signalisationsverordnung (SSV) zum Schweizer Straßen­verkehrsgesetz werden Verkehrsampeln als ‚Lichtsignalanlage‘, ab­gekürzt: LSA, bezeichnet. Eine ‚Lichtzeichenanlage‘ ist in Österreich dagegen eine Anlage an Bahnübergängen.
In Deutschland dürfen Radfahrer bei roter Ampel rechts von einem
Radweg auf einen anderen abbiegen, wenn dabei keine Fahrbahn überquert wird. In den Niederlanden ist das nur erlaubt, wenn ein entsprechendes Zusatzschild an der Ampel angebracht ist.
Ampeln in der DDR hatten teilweise eine Grün/Gelb-Phase zwi-
schen den Phasen Grün und Gelb. Dieses Signal wurde mit der Wie­dervereinigung abgeschafft, da es nicht den Richtlinien für Lichtsi­gnalanlagen (RiLSA) entspricht.
Das ostdeutsche Ampelmännchen entsprach ebenfalls nicht den
RiLSA und wurde an vielen Stellen umgebaut. Nach Protesten aus der Bevölkerung wurden die Richtlinien angepasst und das Ost-Ampelmännchen nachträglich wieder für zulässig erklärt.
Die Dauer der roten und grünen Ampelphasen wird je nach Situ-
ation unterschiedlich eingestellt. Die Rot/Gelb-Phase dauert eine Sekunde. Für Gelb gibt es Vorgaben in den RiLSA, die von der zuläs­sigen Geschwindigkeit auf der Straße abhängen:
Geschwindigkeit Gelbphase
50 km/h 3 sek. 60 km/h 4 sek. 70 km/h 5 sek.
In Düsseldorf gibt es Fußgängerampeln mit Gelbsignal.
Alle Ampeln weltweit haben die gleiche Anordnung der Lichter:
Rot oben, Grün unten - mit einer Ausnahme: Das rote Licht der Tipperary-Hill-Ampel in Syracuse, USA ist unten, das grüne oben. Anhänger der irischstämmigen Bevölkerung empfanden es als Dis­kriminierung, dass das grüne Licht unter dem roten Licht hängt und haben die Ampel mehrfach beschädigt. Die Zerstörungswut ende­te erst, nachdem die Anordnung der Lichter umgedreht wurde.
Page 10
Heute im Adventskalender
1 LED blau mit eingebautem Vorwiderstand
Steve lässt es schneien
Das Experiment des 4. Tags lässt es auf jedem Feld schneien, das die Spielfi­gur Steve betritt. In der MinecraftTM-Welt gibt es für diesen Tag keine Num­mer. Bewegen Sie die Spielfigur auf eine möglichst freie Fläche, bevor Sie das Programm starten.
Auf allen Feldern, die die Spielfigur betreten hat, liegt Schnee.
Bauteile
1 Steckbrett
1 LED blau mit eingebautem Vorwiderstand
2 GPIO-Verbindungskabel
Das Programm
Das Programm 04mc_schnee01.py legt Schnee auf jedes Feld, das die Spielfigur Steve betritt.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() LED = 18
GPIO.setmode(GPIO.BCM) GPIO.setup(LED, GPIO.OUT, initial=False)
try: while True: p = mc.player.getTilePos() mat = mc.getBlock(p.x, p.y, p.z) if mat!=block.SNOW.id: GPIO.output(LED, True) time.sleep(0.1) GPIO.output(LED, False) mc.setBlock(p.x, p.y, p.z, block.SNOW)
except KeyboardInterrupt: GPIO.cleanup()
Die blaue LED zeigt an, dass die Spielfigur ein Schneefeld angelegt hat.
So funktioniert das Programm
import mcpi.block as block
Zusätzlich zu den bereits bekannten Bibliotheken wird die Bibliothek mcpi.
block importiert, die die Materialien für Minecraft
hält, sodass man sich keine Nummern zu merken braucht.
LED = 18
Der GPIO-Pin für die LED wird wieder in einer Variablen gespeichert, um die Schaltung leichter umbauen zu können.
GPIO.setup(LED, GPIO.OUT, initial=False)
Dieser Pin wird als Ausgang definiert und die LED am Anfang ausgeschaltet.
try: while True: p = mc.player.getTilePos() mat = mc.getBlock(p.x, p.y, p.z)
Auch dieses Programm besteht aus einer Endlosschleife, die in jedem Durch­lauf die Position der Spielfigur in der Variablen p und das Material des Blocks in der Variablen mat speichert. Schnee ist kein vollständiger Block, sondern nur eine dünne Schicht, die auf einem anderen Block liegt. Um zu prüfen, ob die Spielfigur im Schnee steht, wird deshalb das Material des Blocks aus­gelesen, der die Koordinaten der Spielfigur hat, und nicht das Material des Blocks darunter.
Immer wenn die Spielfigur nicht im Schnee steht, soll die LED kurz aufblin­ken, und dann soll das Feld mit Schnee bedeckt werden. Man könnte auch einfach das Feld, auf dem die Spielfigur steht, immer mit Schnee bedecken, unabhängig davon, ob vorher Schnee darauf lag. Die LED würde dann aber auch immer leuchten.
if mat!=block.SNOW.id:
Diese if-Abfrage prüft, ob das gespeicherte Material ungleich dem Materi­al block.SNOW.id aus der Bibliothek mcpi.block ist. Die Zeichenfolge
!= steht in Python für ungleich.
GPIO.output(LED, True) time.sleep(0.1) GPIO.output(LED, False)
Ist das der Fall, wird die LED für 0,1 Sekunden eingeschaltet und danach wie­der aus.
mc.setBlock(p.x, p.y, p.z, block.SNOW)
Jetzt wird ein Block an den aktuellen Koordinaten gesetzt. Das verwende­te Material block.SNOW entspricht der Material-ID 78. Danach startet die Endlosschleife den nächsten Durchlauf und überprüft erneut, ob Steve auf Schnee steht. Das Programm läuft, bis der Benutzer in der Python-Shell die Tastenkombination [Strg]+[C] drückt. Zum Schluss werden die GPIO-Pins zurückgesetzt.
Laufen Sie, nachdem Sie das Programm ausprobiert haben, über das Feld und schlagen Sie die Schneeblöcke mit dem Schwert wieder weg, um eine freie Spielfläche zu bekommen.
TM
-Blöcke im Klartext ent-
Page 11
Heute im Adventskalender
1 GPIO-Verbindungskabel
Lauicht beim Schlag auf einen
Minecraft™-Klotz
Das Programm des 5. Tags schaltet eine kurze Lauflichtsequenz ein, wenn die Spielfigur auf einen bestimmten Klotz schlägt, der neben der Nummer 5 in der MinecraftTM-Welt steht. Hat die Spielfigur das Schwert in der Hand, kann sie mit einem Klick der linken Maustaste Blöcke zerschlagen. Ein Klick mit der rechten Maustaste löst in Python ein Event aus, worauf das Pro­gramm beliebig reagieren kann.
Das Programm
Das Programm 05mc_led02.py liest die MinecraftTM-Ereignisse, die durch Schläge auf Blöcke ausgelöst werden. Schlägt die Spielfigur auf einen Block aus dem Material GOLD_ORE, wird eine Lauflichtsequenz ausgelöst.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() LED = [18,23,25,7]
GPIO.setmode(GPIO.BCM) for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.GOLD_ORE.id: for i in LED: GPIO.output(i,True) time.sleep(0.05) GPIO.output(i,False)
except KeyboardInterrupt: GPIO.cleanup()
Diese Zeile speichert den an einer bestimmten Position getroffenen Block in die Variable bl.
if bl.id == block.GOLD_ORE.id:
Wenn das Material dieses Blocks GOLD_ORE ist, wird der Lichteffekt ausge­löst. In diesem Programm funktioniert das auch, wenn Sie einen anderen Block aus dem gleichen Material mit dem Schwert anschlagen. Die Koordi­naten des Blocks werden nicht geprüft.
for i in LED: GPIO.output(i,True) time.sleep(0.05) GPIO.output(i,False)
Eine Schleife lässt die vier LEDs kurz hintereinander für jeweils 0,05 Sekun­den aufblinken. Diese Schleife läuft genau einmal, danach wartet die Haupt­schleife wieder, dass ein Block angeschlagen wird.
Das Programm läuft, bis der Benutzer in der Python-Shell die Tastenkom­bination [Strg]+[C] drückt. Zum Schluss werden die GPIO-Pins zurückge­setzt.
Beim Schlag auf diesen Klotz blinken die LEDs.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
5 GPIO-Verbindungskabel
So funktioniert das Programm
LED = [18,23,25,7]
Sobald die bereits bekannten Bibliotheken importiert sind und die Verbin­dung zu Minecraft verwendeten GPIO-Pins angelegt.
for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
Diese GPIO-Pins werden als Ausgänge initialisiert und ausgeschaltet.
try: while True: for hit in mc.events.pollBlockHits():
Die Hauptschleife des Programms liest jetzt in jedem Schleifendurchlauf die Liste der Events, die durch Schwertschläge auf Blöcke ausgelöst werden. Die Variable hit erhält unter anderem die Koordinaten des getroffenen Blocks.
bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
TM
hergestellt ist, wird eine Liste mit den vier für die LEDs
Vier LEDs als Lauflicht auf dem Steckbrett.
Page 12
Heute im Adventskalender
1 Taster
Minecraft™-Blöcke mit einer Taste bauen
Das Programm des 6. Tags baut MinecraftTM-Blöcke, wenn man auf einen Taster drückt. Bei jedem Druck auf den Taster werden neun Blöcke in einer quadratischen Anordnung (3 × 3) gebaut, und die Spielfigur wird anschlie­ßend mittig darauf gestellt. Durch mehrfaches Drücken der Taste lassen sich so Türme bauen.
Das Programm verwendet das Material Sand, das eine besondere Eigen­schaft hat. Die meisten Minecraft beliebigen y-Koordinate bauen, wohingegen Sandblöcke immer bis auf den Boden herunterfallen. Dadurch kann man mit dem Programm und kleinen Bewegungen Hügellandschaften erzeugen.
Eine einfache Hügellandschaft, die das Programm erstellt hat.
Bauteile
1 Steckbrett
1 Taster
2 GPIO-Verbindungskabel
GPIO-Ports können nicht nur Daten ausgeben, zum Beispiel über LEDs, sondern auch zur Dateneingabe verwendet werden. Dazu müssen sie im Programm als Eingang definiert werden. Zur Eingabe verwenden wir im fol­genden Projekt einen Taster, der direkt auf die Steckplatine gesteckt wird. Der Taster hat vier Anschlusspins, wobei je zwei gegenüberliegende (großer
TM
-Blöcke lassen sich frei in der Luft an jeder
Abstand) miteinander verbunden sind. Solange die Taste gedrückt ist, sind alle vier Anschlüsse miteinander verbunden. Im Gegensatz zu einem Schal­ter rastet ein Taster nicht ein. Die Verbindung wird beim Loslassen sofort wieder getrennt.
Liegt auf einem als Eingang definierten GPIO-Port ein +3,3-V-Signal an, wird es als logisches True bzw. 1 ausgewertet.
Ein Druck auf den Taster verbindet in unserer Schaltung den GPIO-Pin 8 mit +3,3 V. Lässt man den Taster wieder los, bekommt der Eingang einen undefi­nierten Zustand, was in der Digitalelektronik nicht passieren darf. Für solche Fälle verfügen alle GPIO-Pins über sogenannte Pull-down-Widerstände, die einen Eingang, an dem kein Signal anliegt, automatisch auf False herun­terziehen.
Ein Taster auf dem Steckbrett.
Das Programm
Neben der Zahl 6 in der MinecraftTM-Welt befindet sich eine große graue Flä­che, auf der man die aus Sand aufgebauten Klötze besser erkennen kann als auf der Sandfläche. Das Programm 06mc_taster01.py baut bei jedem Druck auf den Taster neun Blöcke in einer quadratischen Anordnung (3 × 3) rund um die aktuelle Position der Spielfigur und stellt die Spielfigur anschlie­ßend mittig darauf.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() t1 = 8
GPIO.setmode(GPIO.BCM) GPIO.setup(t1, GPIO.IN, GPIO.PUD_DOWN)
try: while True: if GPIO.input(t1)==True: p = mc.player.getTilePos() mc.setBlocks(p.x-1, p.y, p.z-1, p.x+1, p.y, p.z+1, block.SAND) mc.player.setPos(p.x, p.y+1, p.z) time.sleep(0.2)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
t1 = 8
Sobald die bereits bekannten Bibliotheken importiert sind und die Ver­bindung zu Minecraft GPIO-Pin in der Variablen t1 gespeichert.
GPIO.setup(t1, GPIO.IN, GPIO.PUD_DOWN)
Dieser GPIO-Pin wird als Eingang initialisiert, und der auf dem Raspberry Pi eingebaute Pull-down-Widerstand wird eingeschaltet.
try: while True: if GPIO.input(t1)==True:
Die Endlosschleife wartet darauf, dass der Taster gedrückt wird. Dabei be­kommt der GPIO-Pin den Wert True, da er über den Taster mit +3,3 V ver­bunden wird.
p = mc.player.getTilePos()
Jetzt wird die Position der Spielfigur in der Variablen p gespeichert.
mc.setBlocks(p.x-1, p.y, p.z-1, p.x+1, p.y, p.z+1, block.SAND)
Die Funktion setBlocks() setzt in Form eines Kubus mehrere Blöcke auf einmal. Dazu brauchen nur zwei gegenüberliegende Ecken dieses Kubus angegeben zu werden. Der Kubus ist hier 3 × 3 Einheiten in der Fläche groß und eine Einheit dick.
mc.player.setPos(p.x, p.y+1, p.z)
Jetzt wird die Spielfigur eine Einheit nach oben versetzt, sie befindet sich dann in der Mitte auf den neu angelegten Blöcken.
time.sleep(0.2)
Das Programm wartet 0,2 Sekunden, um Tastenprellen zu vermeiden. So wird sichergestellt, dass ein etwas längeres Drücken des Tasters gleich meh­rere Schichten von Blöcken anlegt. Danach startet die Endlosschleife neu.
Das Programm läuft, bis der Benutzer in der Python-Shell die Tastenkombina­tion [Strg]+[C] drückt. Zum Schluss werden die GPIO-Pins zurückgesetzt.
TM
hergestellt ist, wird der für den Taster verwendete
Page 13
Achtung
Verwenden Sie nie die +5-V-Pins des Raspberry Pi für Logiksignale in Schal­tungen. 5 V würden die GPIO-Eingänge überlasten und den Raspberry Pi beschädigen.
Heute im Adventskalender
1 Schaltdraht
Der Schaltdraht wird für verschiedene Experimente benötigt, um Brücken zwischen verschiedenen Kontaktreihen auf dem Steckbrett herzustellen. Schneiden Sie den Draht mit einem kleinen Seitenschneider je nach Experi­ment auf die passenden Längen ab. Um die Drähte besser in die Steckplatine stecken zu können, empfiehlt es sich, sie leicht schräg abzuschneiden, sodass eine Art Keil entsteht. Entfernen Sie an beiden Enden auf einer Länge von etwa einem halben Zentimeter die Isolierung.
LEDs dimmen
LEDs können zwei verschiedene Zustände annehmen, ein und aus. Das Glei­che gilt für die als digitale Ausgänge definierten GPIO-Ports. Demnach wäre es theoretisch nicht möglich, eine LED zu dimmen.
Mit einem Trick erreicht man es dennoch, die Helligkeit einer LED an einem digitalen GPIO-Port zu regeln. Lässt man eine LED schnell genug blinken, nimmt das menschliche Auge dies nicht mehr als Blinken wahr. Die als Puls­weitenmodulation (PWM) bezeichnete Technik erzeugt ein pulsierendes Si­gnal, das sich in sehr kurzen Abständen ein- und ausschaltet. Die Spannung des Signals bleibt immer gleich, nur das Verhältnis zwischen Level False (0 V) und Level True (+3,3 V) wird verändert. Das Tastverhältnis gibt das Verhältnis der Länge des eingeschalteten Zustands zur Gesamtdauer eines Schaltzyklus an. Je kleiner das Tastverhältnis, desto kürzer ist die Leuchtzeit der LED innerhalb eines Schaltzyklus. Dadurch wirkt die LED dunkler als eine permanent eingeschaltete LED.
Links: Tastverhältnis 50 % – rechts: Tastverhältnis 20 %.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 Drahtbrücke
2 GPIO-Verbindungskabel
Zwei LEDs, an einem GPIO-Pin angeschlossen.
Die Drahtbrücke wird dazu verwendet, zwei Kontaktreihen des Steckbretts zu verbinden, um so zwei LEDs an einem GPIO-Pin des Raspberry Pi anzu­schließen. Das ist möglich, um beide LEDs genau gleich zu schalten. Schlie­ßen Sie nicht zu viele LEDs auf diese Weise an einem GPIO-Pin an, dieser kann überlastet werden. Zwei oder drei LEDs funktionieren aber problemlos.
Das Programm
Das Programm 07mc_pwm01.py zeigt, wie PWM-Signale mit Python ausgegeben werden. Neben der Zahl 7 in der MinecraftTM-Welt sind zwei stilisierte Pfeile in den Boden eingelassen. Der Pfeil nach oben lässt beim Daraufschlagen mit dem Schwert die LED schrittweise heller leuchten, der andere lässt sie jedes Mal einen Schritt dunkler leuchten.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() LED = 23
GPIO.setmode(GPIO.BCM) GPIO.setup(LED, GPIO.OUT, initial=False)
pwm = 0 l = GPIO.PWM(LED, 50) l.start(pwm)
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.GOLD_ORE.id and pwm<100: pwm += 10 if bl.id == block.IRON_ORE.id and pwm>0: pwm -= 10 l.ChangeDutyCycle(pwm) time.sleep(0.1)
except KeyboardInterrupt: l.stop() GPIO.cleanup()
So funktioniert das Programm
LED = 23
Sobald die bereits bekannten Bibliotheken importiert sind und die Verbin­dung zu Minecraft Pin in der Variablen LED gespeichert.
GPIO.setup(LED, GPIO.OUT, initial=False)
TM
hergestellt ist, wird der für die LED verwendete GPIO-
Page 14
Dieser GPIO-Pin wird als Ausgang initialisiert und ausgeschaltet.
pwm = 0
Das Tastverhältnis des PWM-Signals wird in der Variablen pwm gespeichert und am Anfang auf 0 gesetzt.
l = GPIO.PWM(LED, 50)
Die Funktion GPIO.PWM() aus der GPIO-Bibliothek ist entscheidend für die Ausgabe von PWM-Signalen. Diese Funktion benötigt zwei Parameter, den GPIO-Pin und die Frequenz des PWM-Signals. In unserem Fall wird der GPIO­Pin über die Variable LED festgelegt, die Frequenz ist 50 Hertz (Schwingun­gen pro Sekunde).
Warum 50 Hertz die ideale Frequenz für PWM sind
Das menschliche Auge nimmt Lichtwechsel schneller als 20 Hertz nicht mehr wahr. Da das Wechselstromnetz in Europa eine Frequenz von 50 Hertz nutzt, blinken viele Beleuchtungskörper mit dieser Frequenz, die vom Auge nicht wahrgenommen wird. Würde eine LED mit mehr als 20 Hertz, aber weniger als 50 Hertz blinken, käme es zu Interferen­zen mit anderen Lichtquellen, wodurch der Dimmeffekt nicht mehr gleichmäßig erschiene.
GPIO.PWM() erzeugt ein Objekt, das in der Variablen l gespeichert wird.
l.start(pwm)
Die Methode start() startet die Generierung des PWM-Signals. Dazu muss noch ein Tastverhältnis angegeben werden. In unserem Fall ist das Tast­verhältnis 0, was vorher in der Variablen pwm gespeichert wurde. Die LED ist also immer ausgeschaltet. Python verwendet für PWM Werte zwischen 0 und 100, die direkt dem Prozentsatz der eingeschalteten Zeit des Pins innerhalb eines Frequenzzyklus entsprechen. Ein PWM-Wert von 25 schaltet die LED also ein Viertel der Zeit ein, die übrigen drei Viertel des Zyklus aus.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Die Hauptschleife des Programms wartet wieder darauf, dass der Spieler mit dem Schwert auf einen Block schlägt, und speichert diesen Block dann als Objekt bl.
if bl.id == block.GOLD_ORE.id and pwm<100: pwm += 10
Besteht der getroffene Block aus dem Material GOLD_ORE, ist es also der Pfeil nach oben, wird der PWM-Wert bei jedem Schlag um 10 erhöht. Dies soll aber nur passieren, solange der PWM-Wert noch kleiner als 100 ist, da höhere Werte nicht verarbeitet werden können. Ein PWM-Signal von 100 entspricht einer voll eingeschalteten LED.
if bl.id == block.IRON_ORE.id and pwm>0: pwm -= 10
Schlägt der Spieler auf einen Block aus dem Material IRON_ORE, also den Pfeil nach unten, wird der PWM-Wert bei jedem Schlag um 10 verringern, solange er noch größer als 0 ist.
l.ChangeDutyCycle(pwm) time.sleep(0.1)
Unabhängig davon, was diese Abfragen ergeben haben, wird das PWM-Si­gnal auf den neuen Wert gesetzt und danach eine Zehntelsekunde gewartet. Solche Wartezeiten werden in Schleifen eingefügt, damit der Raspberry Pi nicht vollständig damit beschäftigt ist, das Python-Programm auszuführen. In diesem Fall würde sich Minecraft
TM
deutlich träger verhalten.
except KeyboardInterrupt: l.stop() GPIO.cleanup()
Beim Drücken der Tastenkombination [Strg]+[C] auf der Tastatur wird vor dem Zurücksetzen der GPIO-Pins noch das PWM-Signal beendet.
Spielfigur Steve schlägt auf die Pfeilsymbole
Der Tag 7 in der MinecraftTM-Welt
Die Minecraft™-Blocktypen
Material ID Material ID
AIR 0 STONE_SLAB 44 STONE 1 BRICK_BLOCK 45 GRASS 2 TNT 46 DIRT 3 BOOKSHELF 47 COBBLESTONE 4 MOSS_STONE 48 WOOD_PLANKS 5 OBSIDIAN 49 SAPLING 6 TORCH 50 BEDROCK 7 FIRE 51 WATER_FLOWING 8 STAIRS_WOOD 53 WATER 8 CHEST 54 WATER_STATIONARY 9 DIAMOND_ORE 56 LAVA_FLOWING 10 DIAMOND_BLOCK 57 LAVA 10 CRAFTING_TABLE 58 LAVA_STATIONARY 11 FARMLAND 60 SAND 12 FURNACE_INACTIVE 61 GRAVEL 13 FURNACE_ACTIVE 62 GOLD_ORE 14 DOOR_WOOD 64 IRON_ORE 15 LADDER 65 COAL_ORE 16 STAIRS_COBBLESTONE 67 WOOD 17 DOOR_IRON 71 LEAVES 18 REDSTONE_ORE 73 GLASS 20 SNOW 78 LAPIS_LAZULI_ORE 21 ICE 79 LAPIS_LAZULI_BLOCK 22 SNOW_BLOCK 80 SANDSTONE 24 CACTUS 81 BED 26 CLAY 82 COBWEB 30 SUGAR_CANE 83 GRASS_TALL 31 FENCE 85 WOOL 35 GLOWSTONE_BLOCK 89 FLOWER_YELLOW 37 BEDROCK_INVISIBLE 95 FLOWER_CYAN 38 STONE_BRICK 98 MUSHROOM_BROWN 39 GLASS_PANE 102 MUSHROOM_RED 40 MELON 103 GOLD_BLOCK 41 FENCE_GATE 107 IRON_BLOCK 42 GLOWING_OBSIDIAN 246 STONE_SLAB_DOUBLE 43 NETHER_REACTOR_
CORE247
Page 15
Heute im Adventskalender
1 GPIO-Verbindungskabel
LEDs zeigen an, wie hoch Steve im Gelände steht
Das Programm des 8. Tags zeigt auf vier LEDs an, wie weit oben die Spielfigur im Gelände steht. Für dieses Programm gibt es keine Zahl in der Minecraft Welt. Bewegen Sie die Figur nach hinten in die grüne Hügellandschaft.
Die Spielfigur Steve läuft durch das Gelände.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
5 GPIO-Verbindungskabel
TM
Das Programm
Das Programm 08mc_led04.py liest fortlaufend die Position der Spielfi­gur aus. Abhängig von deren y-Koordinate leuchtet eine der vier LEDs.
#!/usr/bin/python import mcpi.minecraft as minecraft import RPi.GPIO as GPIO
mc = minecraft.Minecraft.create() LED = [18,23,25,7]
GPIO.setmode(GPIO.BCM) for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
try: while True: p = mc.player.getTilePos() for i in LED: GPIO.output(i,False) if p.y <= 4: GPIO.output(LED[3],True) elif p.y <= 6: GPIO.output(LED[2],True)
-
elif p.y <= 8: GPIO.output(LED[1],True) else: GPIO.output(LED[0],True)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
LED = [18,23,25,7]
Auch diesmal wird eine Liste mit den vier GPIO-Pins der LEDs angelegt, die dann als Ausgänge initialisiert und ausgeschaltet werden.
try: while True: p = mc.player.getTilePos()
Die Endlosschleife schreibt in jedem Durchlauf die aktuelle Position der Spielfigur in das Objekt p.
for i in LED: GPIO.output(i,False)
Als Erstes werden alle vier LEDs ausgeschaltet, damit danach immer nur eine leuchtet.
if p.y <= 4: GPIO.output(LED[3],True)
Ist die y-Koordinate der Spielfigur kleiner als 4, steht die Figur auf der Sand­fläche oder nur eine Stufe höher. In diesem Fall leuchtet die blaue LED mit der Nummer LED[3]. Wie auf einer Landkarte werden niedrig gelegene Regionen in Grün- und Blautönen dargestellt, höher gelegene Regionen in Gelb- und Rottönen.
elif p.y <= 6: GPIO.output(LED[2],True)
Liefert die erste if-Abfrage das Ergebnis False, werden nacheinander die folgenden elif-Abfragen ausgeführt. Ist die y-Koordinate der Spielfigur kleiner als 6, leuchtet die grüne LED mit der Nummer LED[2].
elif p.y <= 8: GPIO.output(LED[1],True)
Liefert auch diese Abfrage das Ergebnis False, wird eine weitere elif-Ab­frage durchgeführt. Ist die y-Koordinate der Spielfigur kleiner als 8, leuchtet die gelbe LED mit der Nummer LED[1].
else: GPIO.output(LED[0],True)
In allen anderen Fällen, wenn die Spielfigur also auf der y-Koordinate 8 oder höher steht, leuchtet die rote LED mit der Nummer LED[0].
Vier LEDs zeigen, wie weit oben in der Landschaft die Spielfigur steht.
Page 16
Heute im Adventskalender
1 x Knete
1 20-MOhm-Widerstand (rot-schwarz-blau)
Sensorkontakt aus Knete
Ampeln, Türöffner, Lichtschalter und Automaten werden heute oft mit Sen­sorkontakten gesteuert, die man nur zu berühren braucht. Taster, die wirk­lich gedrückt werden müssen, werden immer seltener. Das Experiment des
9. Tags lässt einen Steinblock über einen einfachen Sensorkontakt leuchten.
Bauteile
1 Steckbrett
1 LED blau mit eingebautem Vorwiderstand
1 20-MOhm-Widerstand (rot-schwarz-blau)
4 GPIO-Verbindungskabel
1 Knetekontakt
So funktionieren Sensorkontakte
Der als Eingang geschaltete GPIO-Pin ist über einen extrem hochohmigen Widerstand (20 MOhm) mit +3,3 V verbunden, sodass ein schwaches, aber eindeutig als High definiertes Signal anliegt. Ein Mensch, der nicht gerade frei in der Luft schwebt, ist immer geerdet und liefert über die elektrisch leit­fähige Haut einen Low-Pegel. Berührt dieser Mensch einen Sensorkontakt, wird das schwache High-Signal von dem deutlich stärkeren Low-Pegel der Hand überlagert und zieht den GPIO-Pin auf Low-Pegel.
Das Programm
Das Programm 09mc_knete01.py prüft in einer Endlosschleife, ob der Knetekontakt berührt wird. Ist das der Fall, wird neben der Zahl 9 in der MinecraftTM-Welt ein 2 × 2 Einheiten großer Quader aus dem Material DIAMOND_ORE erstellt. Wird der Knetekontakt nicht berührt, erscheint an der gleichen Stelle ein Quader aus dem Material STONE. Beide Materialien
ähneln sich stark, sodass die Veränderung wie ein Aufleuchten des Blocks aussieht. Zusätzlich leuchtet die blaue LED immer dann, wenn der Knete­kontakt berührt wird.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() LED = 18 k1 = 20
GPIO.setmode(GPIO.BCM) GPIO.setup(LED, GPIO.OUT, initial=False) GPIO.setup(k1, GPIO.IN)
try: while True: if GPIO.input(k1) == False: GPIO.output(LED, True) mc.setBlocks(-8, 4, 5, -7, 4, 4, block. DIAMOND_ORE) else: GPIO.output(LED, False) mc.setBlocks(-8, 4, 5, -7, 4, 4, block.STONE) time.sleep(0.05)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
LED = 18 k1 = 20
Die Nummern der GPIO-Pins der LED und des Knetekontakts werden in Va­riablen gespeichert.
GPIO.setup(k1, GPIO.IN)
Damit die Sensorkontakte funktionieren, muss zuerst der interne Pull-down-Widerstand an GPIO-Pin 20 ausgeschaltet werden. Deshalb fehlt in der Zeile GPIO.setup() der dritte Parameter.
try: while True: if GPIO.input(k1) == False:
Die Endlosschleife überprüft, ob der Knetekontakt berührt wurde. Da der GPIO-Pin bei Berührung mit Masse verbunden wird, ohne Berührung dage­gen ein High-Signal erhält, fragt die if-Abfrage, ob der Pin auf False steht.
GPIO.output(LED, True)
Ist das der Fall, wird die LED eingeschaltet.
mc.setBlocks(-8, 4, 5, -7, 4, 4, block. DIAMOND_ORE)
Die Methode .setBlocks() baut einen 2 × 1 × 2 Blöcke großen Quader aus dem leuchtenden Material DIAMOND_ORE.
else: GPIO.output(LED, False) mc.setBlocks(-8, 4, 5, -7, 4, 4, block.STONE)
Wird der Knetekontakt dagegen nicht berührt, wird die LED ausgeschaltet, und ein Quader aus dem grauen Material STONE wird gebaut.
time.sleep(0.05)
Eine kurze Wartezeit soll das Flackern zwischen beiden Zuständen des Blocks verhindern. Je nachdem, wie gut die Masseverbindung über den Knetekontakt ist, müssen Sie diese Zeit eventuell etwas verlängern.
Sensorkontakt und Kontroll-LED.
Page 17
Heute im Adventskalender
1 RGB-LED mit eingebautem Vorwiderstand
RGB-LEDs
Eine normale LED leuchtet immer nur in einer Farbe. Die im Adventskalen­der verwendeten RGB-LEDs können wahlweise in mehreren Farben leuch­ten. Hier sind im Prinzip drei LEDs in verschiedenen Farben in einem trans­parenten Gehäuse eingebaut. Jede dieser drei LEDs hat eine eigene Anode, über die sie mit einem GPIO-Pin verbunden wird. Die Kathode, die mit der Masseleitung verbunden wird, ist nur einmal vorhanden. Deshalb hat eine RGB-LED vier Anschlussdrähte.
Anschlusspins einer RGB-LED.
Die Anschlussdrähte der RGB-LEDs sind unterschiedlich lang, um sie eindeu­tig kenntlich zu machen. Im Gegensatz zu normalen LEDs ist die Kathode bei ihnen der längste Draht.
RGB-LEDs funktionieren wie drei einzelne LEDs und brauchen deshalb auch drei Vorwiderstände. In den RGB-LEDs in diesem Adventskalender sind sie ebenfalls bereits eingebaut.
Additive Farbmischung
RGB-LEDs nutzen die sogenannte additive Farbmischung. Dabei werden die drei Licht­farben Rot, Grün und Blau addiert und er­geben am Ende reines Weiß. Im Gegensatz dazu verwendet ein Farbdrucker die sub­traktive Farbmischung. Jede Farbe wirkt auf einem weißen Blatt wie ein Filter, der einen Teil des weiß reflektierten Lichts wegnimmt (also subtrahiert). Druckt man alle drei Dru­ckerfarben übereinander, ergibt es Schwarz, das gar kein Licht mehr reflektiert.
RGB-LEDs steuern
Neben der Zahl 10 in der MinecraftTM-Welt finden Sie drei farbige Blöcke, die die drei Farben der RGB-LED darstellen. Schlägt die Spielfigur mit dem Schwert auf eine Farbe, leuchtet diese in der Minecraft die entsprechende Farbkomponente der RGB-LED wird eingeschaltet. Ein weiterer Schlag schaltet die Farbe wieder aus. Durch Einschalten zweier Farbkomponenten lassen sich Farben mischen.
Die drei farbigen Blöcke für die RGB-LED.
Bauteile
1 Steckbrett
1 RGB-LED mit eingebauten Vorwiderständen
4 GPIO-Verbindungskabel
TM
-Welt auf, und auch
RGB-LED auf dem Steckbrett.
Das Programm
Das Programm 10mc_rgb01.py schaltet beim Schlag auf einen Block aus einem bestimmten Material Farben der RGB-LED ein oder aus.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO
mc = minecraft.Minecraft.create() r = 25 g = 24 b = 23 r0 = 14 g0 = 13 b0 = 11 r1 = 1 g1 = 5 b1 = 3
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False)
Schaltplan für eine RGB-LED mit drei Vorwiderständen.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Page 18
if bl.id == block.WOOL.id and bl.data == r0: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, r1) GPIO.output(r, True) if bl.id == block.WOOL.id and bl.data == r1: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, r0) GPIO.output(r, False) if bl.id == block.WOOL.id and bl.data == g0: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, g1) GPIO.output(g, True) if bl.id == block.WOOL.id and bl.data == g1: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, g0) GPIO.output(g, False) if bl.id == block.WOOL.id and bl.data == b0: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, b1) GPIO.output(b, True) if bl.id == block.WOOL.id and bl.data == b1: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, b0) GPIO.output(b, False)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
r = 25 g = 24 b = 23
Nach dem Laden der Bibliotheken werden diverse Variablen angelegt. r, g und b bezeichnen die GPIO-Pins der drei Farben der RGB-LED.
r0 = 14 g0 = 13 b0 = 11
Die Blöcke, die die RGB-LED steuern, verwenden alle das Material WOOL. Dieses kann über einen zusätzlichen Parameter unterschiedliche Farben an­nehmen. Die drei Variablen r0, b0 und g0 bezeichnen die Farben im ausge- schalteten Zustand der RGB-LED.
r1 = 1 g1 = 5 b1 = 3
Die drei Variablen r1, b1 und g1 bezeichnen die Farben der RGB-LED im eingeschalteten Zustand.
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False)
Die drei GPIO-Pins werden als Ausgänge initialisiert und ausgeschaltet.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Die Hauptschleife des Programms wartet wieder darauf, dass die Spielfigur mit dem Schwert auf einen Block schlägt, und speichert diesen Block im Ob­jekt bl.
if bl.id == block.WOOL.id and bl.data == r0: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, r1) GPIO.output(r, True)
Besteht der Block aus dem Material WOOL und hat die in r0 gespeicherte Farbe (Rot ausgeschaltet), wird an der gleichen Position ein hellroter Block gleichen Materials mit der Farbe r1 (Rot eingeschaltet) angelegt. An jeder Position kann immer nur ein Block existieren, neue ersetzen ältere automa­tisch. Anschließend wird die rote Farbe der RGB-LED eingeschaltet.
if bl.id == block.WOOL.id and bl.data == r1: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.WOOL.id, r0) GPIO.output(r, False)
Schlägt die Spielfigur aber umgekehrt auf einen Block aus dem Material
WOOL und der in r1 gespeicherten Farbe (Rot eingeschaltet), wird an der
gleichen Position ein dunkelroter Block gleichen Materials mit der Farbe r0 (Rot ausgeschaltet) angelegt, und die rote Farbe der RGB-LED wird ausge­schaltet.
Auf die gleiche Weise werden auch Schläge auf den grünen und den blauen Block ausgewertet, und die entsprechenden Farben der RGB-LED werden geschaltet.
Sensorkontakte
Wie hoch der Widerstand zwischen Hand und Masse wirklich ist, hängt von vielen Dingen ab, unter anderem von Schuhen und Fußböden. Barfuß im nassen Gras ist die Verbindung zur Masse der Erde am bes­ten, aber auch auf Steinfußboden funktioniert es meistens gut. Holz­fußböden isolieren stärker, Kunststoffbodenbeläge sind oft sogar posi­tiv aufgeladen. Sollte der Sensorkontakt nicht funktionieren, berühren Sie die Pinleiste auf der Masseschiene des Steckbretts und den eigent­lichen Sensor gleichzeitig. Dann ist die Masseverbindung auf jeden Fall hergestellt.
Knete leitet den Strom etwa so gut wie menschliche Haut. Sie lässt sich leicht in jede beliebige Form bringen, und ein Knetekontakt fasst sich viel besser an als ein einfaches Stück Draht. Die Fläche, mit der die Hand den Kontakt berührt, ist deutlich größer. So kommt es nicht so leicht zu einem „Wackelkontakt“. Stecken Sie ein etwa 20 Zentimeter langes Stück Schaltdraht, von dem Sie an beiden Enden die Isolierung etwa einen Zentimeter weit entfernt haben, in ein Stück Knete und sein anderes Ende in das Steckbrett. Sollten Sie den Massekontakt benö­tigen, können Sie, um einen besseren Kontakt zur Hand herzustellen, einen zweiten Knetekontakt an der Masseschiene anschließen.
Der Tag 10 in der MinecraftTM-Welt
Alle drei Farben leuchten, nachdem sie mit dem Schwert angeschaltet wurden.
Page 19
Heute im Adventskalender
1 GPIO-Verbindungskabel
RGB-LED mit PWM steuern
Das Experiment des 11. Tags zeigt, wie man mit einer RGB-LED mehr als die sechs Farben und Weiß darstellen kann. Mischfarben entstehen, indem man die einzelnen Farben einer RGB-LED über PWM-Signale unterschiedlich hell einstellt. Der Schaltungsaufbau entspricht dem von Tag 10. Bei der Zahl 11 in der Minecraft rechts die Spielfigur auf diese Blockreihe schlägt, desto heller leuchtet die jeweilige Farbe.
Farbige Blockleisten steuern die PWM-Signale für die RGB-LEDs.
TM
-Welt sind drei farbige Blockreihen aufgebaut. Je weiter
Bauteile
1 Steckbrett
1 RGB-LED mit eingebauten Vorwiderständen
4 GPIO-Verbindungskabel
Das Programm
Das Programm 11mc_rgb02.py steuert die drei PWM-Signale der RGB­LED über Reihen aus farbigen Blöcken, die nach dem Prinzip des Programms von gestern funktionieren.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO
mc = minecraft.Minecraft.create() r = 25 g = 24 b = 23 r0 = 14 g0 = 13 b0 = 11 r1 = 1 g1 = 5 b1 = 3 rx = -8 gx = -9 bx = -10 y = 3 z = 21
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False)
rp = GPIO.PWM(r, 50) gp = GPIO.PWM(g, 50) bp = GPIO.PWM(b, 50) rp.start(0) gp.start(0) bp.start(0)
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.WOOL.id and hit.pos.x == rx: for i in range(hit.pos.z-z): mc.setBlock(rx, y, z+i, block.WOOL. id, r1) for i in range(10-hit.pos.z+z): mc.setBlock(rx, y, hit.pos.z+i, block. WOOL.id, r0) rp.ChangeDutyCycle(hit.pos.z-z) if bl.id == block.WOOL.id and hit.pos.x == gx: for i in range(hit.pos.z-z): mc.setBlock(gx, y, z+i, block.WOOL. id, g1) for i in range(10-hit.pos.z+z): mc.setBlock(gx, y, hit.pos.z+i, block. WOOL.id, g0) gp.ChangeDutyCycle(hit.pos.z-z) if bl.id == block.WOOL.id and hit.pos.x == bx:
RGB-LED auf dem Steckbrett.
for i in range(hit.pos.z-z): mc.setBlock(bx, y, z+i, block.WOOL. id, b1) for i in range(10-hit.pos.z+z): mc.setBlock(bx, y, hit.pos.z+i, block. WOOL.id, b0) bp.ChangeDutyCycle(hit.pos.z-z)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
Auch hier werden am Anfang Bibliotheken importiert und Variablen ange­legt. r, g und b enthalten die Nummern der verwendeten GPIO-Pins der RGB-LED, r0, g0 und b0 die Farben der ausgeschalteten Blöcke und r1, g1 und b1 die der eingeschalteten.
rx = -8 gx = -9 bx = -10 y = 3 z = 21
Die Lage der Blöcke wird anders als im gestrigen Programm ebenfalls in Va­riablen gespeichert. Jede Farbe hat ihre eigene x-Koordinate, die Variable z bezeichnet den Anfang der Reihen links und y die Höhe im Raum.
Page 20
Anschließend setzt eine weitere Schleife die Blöcke rechts von der getroffe­nen Stelle auf Dunkelrot r0. Bei diesem Algorithmus kann die Spielfigur auf jeden beliebigen Block der Reihe schlagen und muss sie nicht nacheinander umschalten. Es wird immer der richtige Wert eingestellt.
rp.ChangeDutyCycle(hit.pos.z-z)
Als Letztes wird der PWM-Wert der roten Farbe der RGB-LED auf den neuen Wert eingestellt. Auf die gleiche Weise werden auch Schläge auf die grünen und blauen Blöcke ausgewertet, und damit werden der grüne und der blaue PWM-Wert der RGB-LED geschaltet.
Farbnummern für Blöcke vom Typ WOOL
Die Abbildung zeigt die Koordinaten der Eckpunkte der Blockreihen.
rp = GPIO.PWM(r, 50) gp = GPIO.PWM(g, 50) bp = GPIO.PWM(b, 50)
Nachdem die GPIO-Pins initialisiert wurden, werden drei PWM-Objekte mit jeweils 50 Hertz für die drei Farben angelegt.
rp.start(0) gp.start(0) bp.start(0)
Alle drei PWM-Signale starten bei 0. Die RGB-LED ist komplett ausgeschaltet.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Die Hauptschleife des Programms wartet wieder darauf, dass die Spielfigur mit dem Schwert auf einen Block schlägt, und speichert diesen Block im Ob­jekt bl.
if bl.id == block.WOOL.id and hit.pos.x == rx: for i in range(hit.pos.z-z): mc.setBlock(rx, y, z+i, block.WOOL. id, r1)
Wenn die Spielfigur auf einen Block in der Reihe rx schlägt, der aus dem Material WOOL besteht, beeinflusst das die rote Farbe. Eine Schleife läuft bis zum angeschlagenen Block und setzt alle links davon auf Hellrot r1.
for i in range(10-hit.pos.z+z): mc.setBlock(rx, y, hit.pos.z+i, block. WOOL.id, r0)
Nummer Farbe
0 Weiß 1 Orange 2 Magenta 3 Hellblau 4 Gelb 5 Lime 6 Pink 7 Grau 8 Hellgrau
9 Cyan 10 Lila 11 Blau 12 Braun 13 Grün 14 Rot 15 Schwarz
Die Spielfigur Steve regelt die Farben der RGB-LED
Schon gewusst...?
Es gibt zwei Arten von RGB-LEDs: Gemeinsame Kathode (CC = Com­mon Cathode) und gemeinsame Anode (CA = Common Anode). Im Adventskalender werden RGB-LEDs mit gemeinsamer Kathode ver­wendet. Bei diesen leuchten die einzelnen Farben, wenn am entspre­chenden Pin ein High-Signal anliegt.
RGB-LEDs mit gemeinsamer Anode brauchen eine umgekehrte Pro­grammierlogik. Die Anode wird an ein +5V-Signal angeschlossen. Da­mit eine Farbe leuchtet, muss der entsprechende Pin (R, G oder B) mit Masse verbunden sein, also auf Low gesetzt werden. Pins, an denen ein High-Signal liegt, bewirken, dass die entsprechende Farbe nicht leuchtet.
Tag 11 in der MinecraftTM-Welt
Page 21
Heute im Adventskalender
1 20-MOhm-Widerstand (rot-schwarz-blau)
Knetekontakte und Steve steuern RGB-LED
Im Experiment des 12. Tags steuern die Spielfigur Steve und zwei Knete­kontakte die RGB-LED. Neben der Zahl 12 in der MinecraftTM-Welt befindet sich eine Treppe, die zum Teil in den Boden eingegraben ist. Je weiter die Spielfigur in der blauen Richtung nach oben geht, desto heller leuchtet die blaue Farbe der RGB-LED. Je weiter die Spielfigur in der grünen Richtung nach oben geht, desto heller leuchtet die grüne Farbe der RGB-LED. Die rote Farbe lässt sich schrittweise über zwei Knetekontakte nach oben oder unten regeln.
Diese Treppe steuert zwei Farben der RGB-LED.
Bauteile
1 Steckbrett
1 RGB-LED mit eingebauten Vorwiderständen
2 20-MOhm-Widerstände (rot-schwarz-blau)
7 GPIO-Verbindungskabel
2 Knetekontakte
Das Programm
Das Programm 12mc_rgb04.py fragt die Position der Spielfigur sowie die beiden Knetekontakte ab und stellt danach die Farben der RGB-LED ein.
#!/usr/bin/python import mcpi.minecraft as minecraft import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() r = 25 g = 24 b = 23 k1 = 12 k2 = 21 x = -17 z = -4
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False) GPIO.setup(k1, GPIO.IN) GPIO.setup(k2, GPIO.IN)
rp = GPIO.PWM(r, 50) gp = GPIO.PWM(g, 50) bp = GPIO.PWM(b, 50) rp.start(0) gp.start(0) bp.start(0) pwm = 0
try: while True: p = mc.player.getTilePos()
Zwei Sensorkontakte und RGB-LED.
if p.x >= x and p.x <= x+5 and p.z >= z and p.z <= z+5: gp.ChangeDutyCycle((p.x-x)*20) bp.ChangeDutyCycle((p.z-z)*20) if GPIO.input(k1) == False and pwm<100: pwm += 10 rp.ChangeDutyCycle(pwm) time.sleep(0.1) if GPIO.input(k2) == False and pwm>0: pwm -= 10 rp.ChangeDutyCycle(pwm) time.sleep(0.1)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
r = 25 g = 24 b = 23
Auch hier werden am Anfang Bibliotheken importiert und Variablen ange­legt. r, g und b enthalten die Nummern der verwendeten GPIO-Pins der RGB-LED.
k1 und k2 enthalten die Nummern der verwendeten GPIO-Pins für die Kne-
tekontakte.
x und z sind die Koordinaten der untersten Treppenstufe. Das Programm
fragt nur die x- und z-Koordinaten ab. Die Höhe, auf der die Spielfigur steht, spielt keine Rolle.
Nachdem die GPIO-Pins initialisiert wurden, werden drei PWM-Objekte für die drei Farben angelegt und mit 0 gestartet. Die LED ist ausgeschaltet.
Die Endlosschleife fragt ständig die Position der Spielfigur ab und prüft, ob sich diese im Bereich der x-/z-Koordinaten der Treppe befindet.
Ist das der Fall, werden die PWM-Werte für Grün und Blau entsprechend den Koordinaten eingestellt. Die Treppe hat fünf Stufen, und eine Stufe ent­spricht 20 Einheiten, da der Maximalwert für PWM-Werte 100 beträgt.
if GPIO.input(k1) == False and pwm<100: pwm += 10 rp.ChangeDutyCycle(pwm) time.sleep(0.1)
Wenn der Knetekontakt an GPIO-Pin k1 berührt wird und der in der Variablen pwm gespeicherte PWM-Wert für Rot den Wert 100 noch nicht erreicht hat, wird er um 10 Einhei­ten erhöht, das PWM-Objekt rp entsprechend geändert und 0,1 Sekunden gewartet, um versehentlich zu langes Drücken abzufangen.
Nach dem gleichen Schema wird beim Berühren des ande­ren Knetekontakts der PWM-Wert schrittweise gesenkt.
Page 22
Heute im Adventskalender
1 RGB-LED mit eingebauten Vorwiderständen
Das Programm
Das Programm 13mc_ampel02.py steuert die Fußgängerampel, wenn die Spielfigur auf den metallischen Block am Straßenübergang schlägt.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
Ampel mit Fußgängerampel
Neben der Zahl 13 in der MinecraftTM-Welt liegt eine Straße. Zwei schwarze Säulen stellen eine Verkehrsampel und eine Fußgängerampel dar. Daneben befindet sich ein metallisch schimmernder Block. Er dient als Schalter für die Ampel. Schlägt die Spielfigur mit dem Schwert darauf, wird der Ampelzy­klus gestartet, bis die Fußgängerampel für 2 Sekunden grün leuchtet. Der Ampelzyklus wird auf den Ampeln in der MinecraftTM-Welt dargestellt. Zu­sätzlich leuchten auch die LEDs.
Straße mit Ampel und Fußgängerampel.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
2 RGB-LEDs mit eingebauten Vorwiderständen
6 GPIO-Verbindungskabel
Von beiden RGB-LEDs wird nur jeweils eine Farbe für die Fußgängerampel verwendet. Die Verkehrsampel besteht aus drei einfarbigen LEDs.
mc = minecraft.Minecraft.create() r = 18 o = 23 g = 24 rf = 7 gf = 12 r1 = 14 o1 = 4 g1 = 5 sw = 15 ax = -14 az = -27 fx = -12 fz = -31
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(o, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=True) GPIO.setup(rf, GPIO.OUT, initial=True) GPIO.setup(gf, GPIO.OUT, initial=False)
mc.setBlock(ax, 0, az, block.WOOL.id, g1) mc.setBlock(fx, 1, fz, block.WOOL.id, r1)
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.IRON_ORE.id: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.GOLD_ORE.id) time.sleep(0.1) mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.IRON_ORE.id) mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) mc.setBlock(ax, 0, az, block.WOOL.id, sw) GPIO.output(g, False) time.sleep(0.6) mc.setBlock(ax, 2, az, block.WOOL.id, r1) GPIO.output(r, True)
Ampel aus LEDs und RGB-LEDs auf dem Steckbrett.
mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6) mc.setBlock(fx, 0, fz, block.WOOL.id, g1) GPIO.output(gf, True) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.output(rf, False) time.sleep(2) mc.setBlock(fx, 1, fz, block.WOOL.id, r1) GPIO.output(rf, True) mc.setBlock(fx, 0, fz, block.WOOL.id, sw) GPIO.output(gf, False) time.sleep(0.6) mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) time.sleep(0.6) mc.setBlock(ax, 0, az, block.WOOL.id, g1) GPIO.output(g, True) mc.setBlock(ax, 2, az, block.WOOL.id, sw)
Page 23
GPIO.output(r, False) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6)
except KeyboardInterrupt: mc.setBlock(ax, 0, az, block.WOOL.id, sw) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.cleanup()
So funktioniert das Programm
r = 18 o = 23 g = 24 rf = 7 gf = 12
Auch hier werden am Anfang Bibliotheken importiert und Variablen ange­legt. r, g und b enthalten die Nummern der verwendeten GPIO-Pins der Verkehrsampel (Rot, Orange, Grün). Die Variablen rf und gf enthalten die Nummern der verwendeten GPIO-Pins der Fußgängerampel.
r1 = 14 o1 = 4 g1 = 5 sw = 15
Die Variablen r1, o1 und g1 enthalten die Farbnummern der eingeschalte­ten Blöcke der Ampeln (Rot, Orange, Grün). sw ist die Farbe Schwarz, die für alle ausgeschalteten Blöcke verwendet wird.
ax = -14 az = -27 fx = -12 fz = -31
ax und az sind die Koordinaten der Verkehrsampel, fx und fz die Koordi-
naten der Fußgängerampel.
mc.setBlock(ax, 0, az, block.WOOL.id, g1) mc.setBlock(fx, 1, fz, block.WOOL.id, r1)
Nachdem alle verwendeten GPIO-Pins als Ausgänge gesetzt wurden – wo­bei die grüne LED der Verkehrsampel und die rote LED der Fußgängerampel eingeschaltet werden –, werden noch zwei Blöcke auf den Ampeln farbig eingeschaltet, das Grün der Verkehrsampel Grün und das Rot der Fußgän­gerampel Rot.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.IRON_ORE.id:
Die Endlosschleife wartet darauf, dass die Spielfigur auf einen Block schlägt. Besteht dieser aus dem Material IRON.ORE, wird der Ampelzyklus ausge­löst.
mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.GOLD_ORE.id) time.sleep(0.1) mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.IRON_ORE.id)
Als Erstes wird das Material des Blocks für 0,1 Sekunden in GOLD_ORE ver­ändert, damit er kurz aufleuchtet und so den erfolgreichen Schlag anzeigt.
mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) mc.setBlock(ax, 0, az, block.WOOL.id, sw) GPIO.output(g, False) time.sleep(0.6)
Dann bekommt der mittlere Block auf y-Höhe 1 der Verkehrsampel die Far­be o1. Er leuchtet orange. Gleichzeitig wird die gelbe LED an GPIO-Pin o eingeschaltet. Unmittelbar danach wird der untere Block auf y-Höhe 0 auf die Farbe sw gesetzt und damit ausgeschaltet. Die grüne LED an GPIO-Pin
g wird ebenfalls ausgeschaltet. Das Programm wartet 0,6 Sekunden bis zum
nächsten Schaltzyklus.
mc.setBlock(ax, 2, az, block.WOOL.id, r1) GPIO.output(r, True) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6)
Nach dem gleichen Schema werden die rote Lampe der Verkehrsampel auf y-Höhe 2 und die rote LED eingeschaltet. Der gelbe Block und die gelbe LED werden im gleichen Schaltzyklus ausgeschaltet.
Zwischen allen Schaltzyklen wartet die Ampel 0,6 Sekunden. Nur wenn die grüne LED der Fußgängerampel und die rote LED der Verkehrsampel leuch­ten, dauert die Wartezeit 2 Sekunden.
Nachdem die Verkehrsampel wieder auf Grün und die Fußgängerampel auf Rot stehen, startet die Endlosschleife neu und wartet wieder darauf, dass die Spielfigur auf den Block schlägt.
except KeyboardInterrupt: mc.setBlock(ax, 0, az, block.WOOL.id, sw) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.cleanup()
Bricht man das Programm mit der Tastenkombination [Strg]+[C] ab, wer­den der grüne Block der Verkehrsampel und der rote der Fußgängerampel auf Schwarz gesetzt, und danach werden die GPIO-Pins zurückgesetzt.
Der Ampelzyklus
Farbe(n) Verkehrs ampel
Gelb Rot 0.6 sek. Rot Rot 0.6 sek. Rot Grün 2.0 sek. Rot Rot 0.6 sek. Rot/Gelb Rot 0.6 sek. Grün Rot 2.0 sek.
Die Spielfigur Steve steuert die Fußgängerampel
Tag 13 in der MinecraftTM-Welt
Farbe Fußgängerampel
Zeit
Page 24
Heute im Adventskalender
1 GPIO-Verbindungskabel
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(o, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=True) GPIO.setup(rf, GPIO.OUT, initial=True) GPIO.setup(gf, GPIO.OUT, initial=False) GPIO.setup(t1, GPIO.IN, GPIO.PUD_DOWN)
mc.setBlock(ax, 0, az, block.WOOL.id, g1) mc.setBlock(fx, 1, fz, block.WOOL.id, r1)
Ampel mit Fußgängerampel und Taster
Das Experiment des 14. Tags steuert die gleiche Ampel über einen Taster auf dem Steckbrett anstatt über eine Aktion in Minecraft
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
2 RGB-LEDs mit eingebauten Vorwiderständen
1 Taster
8 GPIO-Verbindungskabel
TM
.
Das Programm
Das Programm 14mc_ampel03.py steuert die Fußgängerampel über ei­nen Taster auf dem Steckbrett.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() r = 18 o = 23 g = 24 t1 = 21 rf = 7 gf = 12 r1 = 14 o1 = 4 g1 = 5 sw = 15 ax = -14 az = -27 fx = -12 fz = -31
try: while True: if GPIO.input(t1)==True: mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) mc.setBlock(ax, 0, az, block.WOOL.id, sw) GPIO.output(g, False) time.sleep(0.6) mc.setBlock(ax, 2, az, block.WOOL.id, r1) GPIO.output(r, True) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6) mc.setBlock(fx, 0, fz, block.WOOL.id, g1) GPIO.output(gf, True) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.output(rf, False) time.sleep(2) mc.setBlock(fx, 1, fz, block.WOOL.id, r1) GPIO.output(rf, True) mc.setBlock(fx, 0, fz, block.WOOL.id, sw) GPIO.output(gf, False) time.sleep(0.6) mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) time.sleep(0.6) mc.setBlock(ax, 0, az, block.WOOL.id, g1) GPIO.output(g, True) mc.setBlock(ax, 2, az, block.WOOL.id, sw) GPIO.output(r, False) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6)
except KeyboardInterrupt: mc.setBlock(ax, 0, az, block.WOOL.id, sw) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.cleanup()
Ampel aus LEDs und RGB-LEDs mit Taster auf dem Steckbrett.
So funktioniert das Programm
t1 = 21 ... GPIO.setup(t1, GPIO.IN, GPIO.PUD_DOWN)
Das Programm 14mc_ampel03.py ähnelt stark dem Programm von ges­tern. Am Anfang wird zusätzlich eine Variable t1 angelegt, in der der GPIO­Pin des Tasters gespeichert ist. Der GPIO-Pin für den Taster wird als Eingang mit Pull-down-Widerstand gesetzt.
try: while True: if GPIO.input(t1)==True:
Die Endlosschleife wartet in dieser Programmversion darauf, dass der Taster gedrückt wird und dadurch am GPIO-Pin ein True-Signal anliegt. In diesem Fall läuft der gleiche Ampelzyklus wie im Programm von gestern durch. Nur der metallische Block leuchtet nicht auf, da er auch nicht angeschlagen wird.
Page 25
Heute im Adventskalender
1 × K nete
Ampel mit Fußgängerampel und Knetekontakt
Das Experiment des 15. Tags steuert die gleiche Ampel über einen Knete­kontakt anstatt über einen Taster oder eine Aktion in Minecraft Knete der zweiten Farbe können Sie den Massekontakt (falls Sie ihn benöti­gen) besser unterscheidbar machen.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
2 RGB-LED mit eingebauten Vorwiderständen
1 20-MOhm-Widerstand (rot-schwarz-blau)
8 GPIO-Verbindungskabel
2 Knetekontakte
TM
. Mit der
Das Programm
Das Programm 15mc_ampel04.py steuert die Fußgängerampel über ei­nen Knetekontakt.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() r = 18 o = 23 g = 24 t1 = 21 rf = 7 gf = 12 r1 = 14 o1 = 4 g1 = 5 sw = 15 ax = -14
az = -27 fx = -12 fz = -31
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(o, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=True) GPIO.setup(rf, GPIO.OUT, initial=True) GPIO.setup(gf, GPIO.OUT, initial=False) GPIO.setup(t1, GPIO.IN)
mc.setBlock(ax, 0, az, block.WOOL.id, g1) mc.setBlock(fx, 1, fz, block.WOOL.id, r1)
try: while True: if GPIO.input(t1)==False: mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) mc.setBlock(ax, 0, az, block.WOOL.id, sw) GPIO.output(g, False) time.sleep(0.6) mc.setBlock(ax, 2, az, block.WOOL.id, r1) GPIO.output(r, True) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6) mc.setBlock(fx, 0, fz, block.WOOL.id, g1) GPIO.output(gf, True) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.output(rf, False) time.sleep(2) mc.setBlock(fx, 1, fz, block.WOOL.id, r1) GPIO.output(rf, True) mc.setBlock(fx, 0, fz, block.WOOL.id, sw) GPIO.output(gf, False) time.sleep(0.6) mc.setBlock(ax, 1, az, block.WOOL.id, o1) GPIO.output(o, True) time.sleep(0.6) mc.setBlock(ax, 0, az, block.WOOL.id, g1) GPIO.output(g, True) mc.setBlock(ax, 2, az, block.WOOL.id, sw) GPIO.output(r, False) mc.setBlock(ax, 1, az, block.WOOL.id, sw) GPIO.output(o, False) time.sleep(0.6)
except KeyboardInterrupt: mc.setBlock(ax, 0, az, block.WOOL.id, sw) mc.setBlock(fx, 1, fz, block.WOOL.id, sw) GPIO.cleanup()
So funktioniert das Programm
Das Programm 15mc_ampel04.py entspricht dem Programm von ges­tern bis auf zwei Kleinigkeiten, die den Unterschied zwischen Taster und Knetekontakt ausmachen.
GPIO.setup(t1, GPIO.IN)
Der GPIO-Pin für den Knetekontakt wird als Eingang ohne Pull-down-Wider­stand gesetzt.
if GPIO.input(t1)==False:
Die if-Abfrage in der Endlosschleife wartet darauf, dass der Eingang den Wert False annimmt.
Ampel aus LEDs und RGB-LEDs mit Knetekontakten auf dem Steckbrett. Der zweite Knetekontakt an der Masseschiene wird nicht in jedem Fall benötigt.
Page 26
Heute im Adventskalender
1 20-MOhm-Widerstand (rot-schwarz-blau)
RGB-Farbmischung mit Knete­kontakten
Im Experiment des 16. Tags werden die Farben einer RGB-LED durch mehr­faches Antippen dreier Knetekontakte gesteuert. Die bereits am 11. Tag verwendeten farbigen Balken in der MinecraftTM-Welt werden heute nur zur Anzeige verwendet und nicht von der Spielfigur mit dem Schwert an­geschlagen.
Balkenanzeige für die Farben der RGB-LED.
Bauteile
1 Steckbrett
1 RGB-LED mit eingebautem Vorwiderstand
3 20-MOhm-Widerstände (rot-schwarz-blau)
8 GPIO-Verbindungskabel
4 Knetekontakte
Das Programm
Das Programm 16mc_rgb05 verändert die PWM-Signale der drei Farben der RGB-LED zyklisch durch mehrfaches Antippen der Knetekontakte.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block
import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() r = 24 g = 23 b = 18 rk = 12 gk = 16 bk = 21 r0 = 14 g0 = 13 b0 = 11 r1 = 1 g1 = 5 b1 = 3 rx = -8 gx = -9 bx = -10 y = 3 z = 21 rl = 0 bl = 0 gl = 0
GPIO.setmode(GPIO.BCM) GPIO.setup(r, GPIO.OUT, initial=False) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False) GPIO.setup(rk, GPIO.IN) GPIO.setup(gk, GPIO.IN) GPIO.setup(bk, GPIO.IN)
rp = GPIO.PWM(r, 50) gp = GPIO.PWM(g, 50) bp = GPIO.PWM(b, 50) rp.start(rl) gp.start(gl) bp.start(bl)
try: while True: if GPIO.input(rk) == False: if rl < 10: rl += 1 else: rl = 0 for i in range(rl): mc.setBlock(rx, y, z+i, block.WOOL.id, r1) for i in range(10-rl): mc.setBlock(rx, y, z+rl+i, block.WOOL. id, r0) rp.ChangeDutyCycle(rl*10) time.sleep(0.05)
Drei Knetekontakte zur Steuerung einer RGB-LED und ein Massekontakt.
if GPIO.input(gk) == False: if gl < 10: gl += 1 else: gl = 0 for i in range(gl): mc.setBlock(gx, y, z+i, block.WOOL.id, g1) for i in range(10-gl): mc.setBlock(gx, y, z+gl+i, block.WOOL. id, g0) gp.ChangeDutyCycle(gl*10) time.sleep(0.05) if GPIO.input(bk) == False: if bl < 10: bl += 1 else: bl = 0 for i in range(bl): mc.setBlock(bx, y, z+i, block.WOOL.id, b1) for i in range(10-bl): mc.setBlock(bx, y, z+bl+i, block.WOOL. id, b0) bp.ChangeDutyCycle(bl*10) time.sleep(0.05)
except KeyboardInterrupt: GPIO.cleanup()
Page 27
So funktioniert das Programm
r = 24 g = 23 b = 18 rk = 12 gk = 16 bk = 21
Dieses Programm verwendet mehr Variablen als die vorherigen Programme. Auch hier werden am Anfang Bibliotheken importiert und Variablen ange­legt. r, g und b enthalten die Nummern der verwendeten GPIO-Pins der RGB-LED, rk, gk und bk die Nummern der GPIO-Pins der Knetekontakte.
r0 = 14 g0 = 13 b0 = 11 r1 = 1 g1 = 5 b1 = 3
Die Variablen r0, g0 und b0 enthalten die Farben der ausgeschalteten Blö­cke und r1, g1 und b1 die der eingeschalteten.
rx = -8 gx = -9 bx = -10 y = 3 z = 21
Die Lage der Blöcke wird ebenfalls in Variablen gespeichert. Jede Farbe hat ihre eigene x-Koordinate, die Variable z bezeichnet den Anfang der Reihen links und y die Höhe im Raum.
rl = 0 bl = 0 gl = 0
Die Variablen rl, gl und bl enthalten später die eingestellten Werte für die drei Farbkomponenten.
Nach der Definition der Variablen werden die GPIO-Pins initialisiert, und für jede Farbe der RGB-LED wird ein PWM-Objekt gestartet.
try: while True: if GPIO.input(rk) == False: if rl < 10: rl += 1 else: rl = 0
Die Endlosschleife prüft als Erstes, ob der rote Knetekontakt berührt wurde. Hat die Variable rl den Maximalwert 10 noch nicht erreicht, wird sie um 1 erhöht. Beim nächsten Antippen des Knetekontakts nach dem Wert 10 wird sie auf 0 zurückgesetzt.
for i in range(rl): mc.setBlock(rx, y, z+i, block.WOOL.id, r1)
for i in range(10-rl): mc.setBlock(rx, y, z+rl+i, block.WOOL. id, r0)
Zwei Schleifen setzen die Blöcke der roten Blockreihe passend zum einge­stellten Wert.
rp.ChangeDutyCycle(rl*10) time.sleep(0.05)
Jetzt wird noch der PWM-Wert der roten Farbe der RGB-LED auf das Zehn­fache des eingestellten Werts gesetzt. Die Werte auf den Blockleisten be­wegen sich zwischen 0 und 10, PWM-Werte liegen dagegen im Bereich zwischen 0 und 100. Zum Schluss wartet das Programm 0,05 Sekunden, um zu lange Berührungen des Knetekontakts nicht mehrfach auszuwerten. Bei Bedarf können Sie diese Zeit verlängern.
Nach dem gleichen Schema werten zwei weitere if-Abfragen die Knete­kontakte für die grüne und die blaue Farbe der RGB-LED aus.
Jetzt wird geprüft, ob der grüne Knetekontakt berührt wird. Hat die Variab­le gl den Maximalwert 10 noch nicht erreicht, wird sie um 1 erhöht. Beim nächsten Antippen des Knetekontakts nach dem Wert 10 wird sie auf 0 zu­rückgesetzt.
if GPIO.input(gk) == False: if gl < 10: gl += 1 else: gl = 0
Eine Schleife setzt alle Blöcke vom linken Ende der Reihe bis zum Block, der der Variable gl entspricht, auf die Farbe g1, was einem leuchtenden Grün entspricht.
for i in range(gl): mc.setBlock(gx, y, z+i, block.WOOL.id, g1)
Eine zweite Schleife setzt alle Blöcke vom Block, der der Variable gl ent­spricht bis zum rechten Ende der Reihe auf die Farbe g0, was einem ausge­schalteten Grün entspricht.
for i in range(10-gl): mc.setBlock(gx, y, z+gl+i, block.WOOL. id, g0)
Am Ende wird der PWM-Wert der grünen Farbe der RGB-LED auf das Zehnfa­che des eingestellten Werts gesetzt.
gp.ChangeDutyCycle(gl*10) time.sleep(0.05)
Bei der blauen Reihe bezeichnet die Variable bl den Helligkeitswert, b1 und
b0 sind die beiden Farben der blauen Blöcke.
if GPIO.input(bk) == False: if bl < 10: bl += 1 else: bl = 0
for i in range(bl): mc.setBlock(bx, y, z+i, block.WOOL. id, b1) for i in range(10-bl): mc.setBlock(bx, y, z+bl+i, block.WOOL. id, b0) bp.ChangeDutyCycle(bl*10) time.sleep(0.05)
Der Tag 16 in der MinecraftTM-Welt
Schon gewusst...?
MinecraftTM ist in verschiedenen Editionen für zahlreiche Hard­wareplattformen erhältlich.
Edition Plattform Aktuelle Version
Windows 10 Windows 10 1.0.5 Java Windows 1.11.2 Java Mac 1.11.2 Java Linux 1.11.2 Konsole Xbox One CU41 Konsole Xbox 360 TU51 Konsole Playstation 3 1.44 Konsole Playstation 4 1.44 Konsole Playstation Vita 1.44 Konsole Wii U Patch 20 Pocket Android 1.0.5 Pocket iOS 1.0.5 Pocket Windows Phone 1.0.5 Pocket Kindle Fire 1.0.5 Pocket (VR) Gear VR 1.0.5 Pocket Apple TV 1.0.5 Pi Raspberry Pi 0.1.1
Page 28
Heute im Adventskalender
1 Piezo-Summer
Töne mit dem Piezo-Summer
Der im Paket enthaltene Piezo-Summer macht elektrische Schwingungen hörbar. Legt man eine pulsierende Gleichspannung zwischen die beiden Pole des Summers, wird er in Schwingung versetzt. Je nach Frequenz sind einzelne Klicks oder ein durchgängiger Ton zu hören. Frequenzen von weni­gen Hertz (Schwingungen pro Sekunde) nimmt das menschliche Ohr noch als einzelne Töne wahr, Frequenzen zwischen etwa 20 Hertz und 16 Kilo­hertz werden als durchgehender Ton unterschiedlicher Tonhöhe wahrge­nommen.
Bauteile
1 Steckbrett
1 LED gelb mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
1 Piezo-Summer
4 GPIO-Verbindungskabel
gf = 500 bf = 1000 p = GPIO.PWM(pi, 1)
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.id == block.IRON_ORE.id: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.GOLD_ORE.id) GPIO.output(g,True) p.ChangeFrequency(gf) p.start(1) time.sleep(0.2) mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.IRON_ORE.id) GPIO.output(g,False) p.stop() if bl.id == block.COAL_ORE.id: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.DIAMOND_ORE.id) GPIO.output(b,True) p.ChangeFrequency(bf) p.start(1) time.sleep(0.2) mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.COAL_ORE.id) GPIO.output(b,False) p.stop()
Zwei Blöcke, die verschiedene Töne erzeugen.
Das Programm
Neben der Zahl 17 in der MinecraftTM-Welt befinden sich zwei metallische Blöcke. Schlägt die Spielfigur mit dem Schwert darauf, leuchten sie auf, und das Programm 17mc_beep01.py erzeugt zwei verschiedene Töne.
Piezo-Summer und zwei LEDs.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() g = 23 b = 18 pi = 12
GPIO.setmode(GPIO.BCM) GPIO.setup(g, GPIO.OUT, initial=False) GPIO.setup(b, GPIO.OUT, initial=False) GPIO.setup(pi, GPIO.OUT, initial=False)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
g = 23 b = 18 pi = 12
Nachdem die Bibliotheken importiert sind, werden drei Variablen für die GPIO-Pins der gelben und blauen LED sowie für den Piezo-Summer ange­legt. Die Pins werden als Ausgänge initialisiert und ausgeschaltet.
gf = 500 bf = 1000
Die Variablen gf und bf legen die Frequenzen der beiden Töne fest, die beim Schlag auf den gelben und den blauen Klotz zu hören sind.
p = GPIO.PWM(pi, 1)
Page 29
Danach wird ein PWM-Signal auf dem GPIO-Pin des Piezo-Summers einge­richtet.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Die Hauptschleife des Programms wartet nach bekanntem Schema darauf, dass die Spielfigur auf einen Block schlägt, und speichert diesen dann im Objekt bl.
if bl.id == block.IRON_ORE.id: mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.GOLD_ORE.id)
Besteht der Block aus dem Material IRON_ORE (Dunkelbraun), wird er durch einen Block aus dem gelb leuchtenden Material GOLD_ORE überschrieben.
GPIO.output(g,True)
Die gelbe LED an GPIO-Pin g wird eingeschaltet.
p.ChangeFrequency(gf) p.start(1)
Die Frequenz des PWM-Signals wird auf die in der Variablen gf gespeicherte Frequenz gesetzt und das PWM-Signal gestartet. Damit ertönt ein Ton auf dem Piezo-Summer.
time.sleep(0.2) mc.setBlock(hit.pos.x, hit.pos.y, hit. pos.z, block.IRON_ORE.id)
GPIO.output(g,False) p.stop()
Das Programm wartet 0,2 Sekunden. Danach wird alles zurückgesetzt. Der Block erscheint wieder im Material IRON_ORE, die LED wird ausgeschaltet und das PWM-Signal gestoppt.
Nach dem gleichen Schema leuchtet der dunkelgraue Block beim Schlag im hellblauen Material DIAMOND_ORE auf, die blaue LED leuchtet, und ein Ton der Frequenz bf ertönt.
Typische Frequenzen
Schallquelle Frequenzbereich (Hz)
Menschliche Stimme 80 - 1200 Klavier 27,5 - 4186 Violine 196 - 3726 Flöte 267 - 4698 Basstuba 43 - 349 Klassischer Telefonwählton 425 Telefontastentöne (MFV) 697 - 1633 Wechselstrombrummen 50 Hundepfeife 16.000 - 22.000
Der Tag 17 in der MinecraftTM-Welt
Schon gewusst...?
Interessante Fakten zu Minecraft
Die erste MinecraftTM-Version wurde am 17.05.2009 veröffentlicht.
TM
wurde in allen Editionen insgesamt über 120 Millionen
mal verkauft. Im September 2014 kaufte Microsoft Minecraft
Lizenzen für 2,5 Milliarden US-Dollar. Der wichtigste Grund für den Kauf war: Microsoft brauchte ein
Vorzeigeprodukt für die technischen Möglichkeiten seiner neuen VR-Brille HoloLens.
Der Minecraft
TM
-Erfinder Markus Notch Persson tauchte nach dem Verkauf seiner Firma Mojang an Microsoft erstmals auf der Forbes-Liste der reichsten Menschen der Welt auf.
Die Firma Mojang entwickelte auch noch die Spiele Cobalt und
Scrolls, die aber nicht annähernd die Bekanntheit von Minecraft erreichten.
Die Musik der PC- und Konsolenedition stammt vom deutschen
Komponisten Daniel Rosenfeld. Voraussichtlich im Jahr 2018 startet der erste offizielle Minecraft
Film in den Kinos. Unter dem Stichwort Minecraft
155.000.000 Videos. In der Viktor-Rydberg-Schule in Stockholm ist Minecraft
fach.
TM
TM
einschließlich aller
TM
gibt es auf YouTube etwa
TM
Pflicht-
TM
TM
-
Hörbare Töne
Der tiefste hörbare Ton liegt bei 16 - 20 Hz, der höchste hörbare Ton hängt vom Lebensalter des Menschen ab. Bei Kleinkindern liegt er etwa bei 20 kHz, bei alten Menschen unter 10 kHz, wobei es allerdings von Mensch zu Mensch große Schwankungen gibt.
Die Spielfigur Steve erzeugt Töne durch Schlagen auf zwei Klötze
Page 30
Heute im Adventskalender
1 20-MOhm-Widerstand (rot-schwarz-blau)
Gamepad aus Knete steuert Steve
Die Spielfigur Steve in MinecraftTM lässt sich zwar mit der Maus drehen, aber nicht bewegen. In der Konsolenversion des Spiels funktioniert das über Tasten auf dem Gamepad. Das Experiment des 18. Tags stellt ein Gamepad mit vier Sensorkontakten aus Knete her, womit die Spielfigur gesteuert werden kann.
Bauteile
1 Steckbrett
4 20-MOhm-Widerstände (rot-schwarz-blau)
5 GPIO-Verbindungskabel
4 Knetekontakte
Legen Sie die vier Knetekontakte in der in der Abbildung gezeigten Anord­nung auf den Tisch. Sie entsprechen den vier Richtungstasten auf einem Gamepad.
Da die Python-Schnittstelle in Minecraft Spielfigur auf eine bestimmte Koordinate zu versetzen, nicht aber, wie über die Tasten, vorwärts, rückwärts oder seitwärts relativ zur aktuellen Blickrich­tung zu gehen, installieren wir ein zusätzliches Python-Modul, das Tastatur­eingaben simuliert. Dazu ist eine Internetverbindung auf dem Raspberry Pi nötig.
Öffnen Sie zur Installation der zusätzlichen Pakete mit einem Klick auf dieses Symbol in der Startleiste eine Linux-Shell. Geben Sie dort ein:
sudo pip3 install python3-xlib
Nachdem diese Installation durchgelaufen ist, was je nach Geschwindigkeit der Internetverbindung einige Sekunden dauern kann, geben Sie ein:
sudo pip3 install pyautogui
Warten Sie auch hier, bis die Installation abgeschlossen ist. Danach können Sie das Shell-Fenster wieder schließen.
TM
nur die Möglichkeit bietet, die
Das Programm
Das Programm 18mc_gamepad01.py steuert die Spielfigur, indem es die vier Knetekontakte abfragt und entsprechende Tastendrücke simuliert. Für dieses Programm gibt es keine spezielle Spielfläche in der MinecraftTM-Welt, es steuert einfach nur die Spielfigur.
#!/usr/bin/python import mcpi.minecraft as minecraft import pyautogui import RPi.GPIO as GPIO
mc = minecraft.Minecraft.create() kw = 16 ka = 21 ks = 12 kd = 7
GPIO.setmode(GPIO.BCM) GPIO.setup(kw, GPIO.IN) GPIO.setup(ka, GPIO.IN) GPIO.setup(ks, GPIO.IN) GPIO.setup(kd, GPIO.IN)
try: while True: if GPIO.input(kw) == False: pyautogui.keyDown('w') else: pyautogui.keyUp('w') if GPIO.input(ka) == False: pyautogui.keyDown('a') else: pyautogui.keyUp('a') if GPIO.input(ks) == False: pyautogui.keyDown('s') else: pyautogui.keyUp('s') if GPIO.input(kd) == False: pyautogui.keyDown('d') else: pyautogui.keyUp('d')
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
import pyautogui
Das Modul pyautogui ermöglicht es unter anderem, das Drücken und Loslassen von Tasten auf der Tastatur über Programmereignis- se zu simulieren. Dieses Modul wird am Anfang mit den anderen Modulen importiert.
Die Variablen kw, ka, ks, kd enthalten die Pinnummern der GPIO-Pins der Knetekontakte, die die Tasten w, a, s, d simulieren.
Die vier Pins werden als Eingänge ohne Pull-down-Widerstände eingerichtet.
try: while True: if GPIO.input(kw) == False: pyautogui.keyDown('w')
Die Hauptschleife des Programms prüft nacheinander, ob einer der Kne­tekontakte berührt wird. Wird der Kontakt an Pin kw berührt, simuliert
pyautogui.keyDown() das Drücken der Taste w.
else: pyautogui.keyUp('w')
Wird der Pin dagegen im Moment der Abfrage nicht berührt, simuliert
pyautogui.keyUp() das Loslassen der Taste w.
if GPIO.input(ka) == False: pyautogui.keyDown('a') else: pyautogui.keyUp('a') if GPIO.input(ks) == False: pyautogui.keyDown('s') else: pyautogui.keyUp('s') if GPIO.input(kd) == False: pyautogui.keyDown('d') else: pyautogui.keyUp('d')
Nach dem gleichen Schema werden auch die Tasten a, s, d über Knetekon­takte simuliert.
Ein Gamepad mit vier Sensorkontakten aus Knete steuert die Spielfigur.
Page 31
Heute im Adventskalender
1 Taster
Gamepad aus Knete mit Tastern
Das Experiment des 19. Tags erweitert das Gamepad um zwei Taster, mit de­nen die Spielfigur springen und fliegen kann.
Bauteile
1 Steckbrett
2 Taster
4 20-MOhm-Widerstände (rot-schwarz-blau)
7 GPIO-Verbindungskabel
2 Drahtbrücken
4 Knetekontakte
Das Programm
Das Programm 19mc_gamepad02.py steuert die Spielfigur über die vier Knetekontakte. Die beiden Taster erfüllen die Funktion der [Leertaste]. Damit kann die Spielfigur springen und fliegen. Auch für dieses Programm gibt es in der MinecraftTM-Welt keine spezielle Spielfläche.
#!/usr/bin/python import mcpi.minecraft as minecraft import pyautogui import RPi.GPIO as GPIO
mc = minecraft.Minecraft.create() kw = 16 ka = 21 ks = 12 kd = 7 tl = 24 tr = 18
try: while True: if GPIO.input(kw) == False: pyautogui.keyDown('w') else: pyautogui.keyUp('w') if GPIO.input(ka) == False: pyautogui.keyDown('a') else: pyautogui.keyUp('a') if GPIO.input(ks) == False: pyautogui.keyDown('s') else: pyautogui.keyUp('s') if GPIO.input(kd) == False: pyautogui.keyDown('d') else: pyautogui.keyUp('d') if GPIO.input(tl) == True: pyautogui.keyDown(' ') else: pyautogui.keyUp(' ') if GPIO.input(tr) == True: pyautogui.keyDown(' ') pyautogui.PAUSE = 0.1 pyautogui.keyUp(' ') pyautogui.PAUSE = 0.1 pyautogui.keyDown(' ') pyautogui.PAUSE = 0.1 pyautogui.keyUp(' ')
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
Das Programm basiert auf dem Programm des 18. Tags und wurde lediglich um die Abfragen der beiden Taster erweitert.
tl = 24 tr = 18
Nach den GPIO-Pins für die Knetekontakte werden in den beiden Variablen
tl und tr noch zwei GPIO-Pinnummern für den linken und rechten Taster
gespeichert.
GPIO.setup(tl, GPIO.IN, GPIO.PUD_DOWN) GPIO.setup(tr, GPIO.IN, GPIO.PUD_DOWN)
Diese beiden GPIO-Pins werden als Eingänge mit Pull-down-Widerständen eingerichtet.
if GPIO.input(tl) == True: pyautogui.keyDown(' ') else: pyautogui.keyUp(' ')
Wird der linke Taster gedrückt, simuliert pyautogui.keyDown(' ') das Drücken der [Leertaste], lässt man den Taster wieder los, simuliert
pyautogui.keyUp(' ') das Loslassen der [Leertaste]. Bei Tastern
muss im Gegensatz zu Knetekontakten der Status True abgefragt wer­den.
if GPIO.input(tr) == True: pyautogui.keyDown(' ') pyautogui.PAUSE = 0.1 pyautogui.keyUp(' ') pyautogui.PAUSE = 0.1 pyautogui.keyDown(' ') pyautogui.PAUSE = 0.1 pyautogui.keyUp(' ')
Der rechte Taster simuliert ein kurzes doppeltes Antippen der [Leertaste], um zu fliegen. Hier wird das Loslassen des Tasters nicht extra überprüft, da das Drücken bereits den kompletten Schaltzyklus auslöst.
GPIO.setmode(GPIO.BCM) GPIO.setup(kw, GPIO.IN) GPIO.setup(ka, GPIO.IN) GPIO.setup(ks, GPIO.IN) GPIO.setup(kd, GPIO.IN) GPIO.setup(tl, GPIO.IN, GPIO.PUD_DOWN) GPIO.setup(tr, GPIO.IN, GPIO.PUD_DOWN)
Ein Gamepad mit vier Sensor­kontakten aus Knete und zwei Tastern steuert die Spielfigur.
Page 32
for i in range(3): GPIO.setup(LED1[i], GPIO.OUT, initial=False) GPIO.setup(LED2[i], GPIO.OUT, initial=False)
Heute im Adventskalender
1 GPIO-Verbindungskabel
RGB-LEDs zeigen Material und Höhe eines Blocks
Zwei RGB-LEDs zeigen an, wo die Spielfigur steht. Durch kurzes Antippen eines Knetekontakts lässt sich das Material des Blocks verändern, auf dem Steve steht.
Bauteile
1 Steckbrett
2 RGB-LEDs mit eingebauten Vorwiderständen
1 20-MOhm-Widerstand (rot-schwarz-blau)
9 GPIO-Verbindungskabel
1 Knetekontakt
Das Programm
Neben der Zahl 20 in der MinecraftTM-Welt befindet sich ein Abhang mit farbig gestaffelten Höhenschichten. Wandern Sie mit der Spielfigur darauf entlang, zeigen die beiden RGB-LEDs die typischen Farben des jeweiligen Untergrunds (angenähert). Beide RGB-LEDs zeigen die gleiche Farbe, ver­wenden aber unterschiedliche Algorithmen, um diese zu erkennen. Die eine RGB-LED ermittelt die Farbe anhand der Höhe, also der y-Koordinate des Blocks, die andere liest das Material aus.
Beim Antippen des Knetekontakts ändert sich das Material des Blocks, auf dem die Spielfigur steht. Dann zeigen beide LEDs unterschiedliche Farben.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
mc = minecraft.Minecraft.create() k = 21 LED1 = [7, 8, 25] LED2 = [24, 23, 18]
GPIO.setmode(GPIO.BCM) GPIO.setup(k, GPIO.IN)
lf = [[0, 0, 1],[0, 1, 0],[1, 1, 1],[1, 0, 0], [1, 0, 1]] mf = {3: 0, 5: 1, 4: 2, 1: 3, 14: 4} nf = {3: 5, 5: 4, 4: 1, 1: 14, 14: 3}
try: while True: p = mc.player.getTilePos() bl = mc.getBlockWithData(p.x, p.y-1, p.z) if bl.id == block.WOOL.id: for i in range(3): GPIO.output(LED1[i], lf[p.y][i]) for i in range(3): GPIO.output(LED2[i], lf[mf[bl.data]][i]) if GPIO.input(k) == False: mc.setBlock(p.x, p.y-1, p.z, block.WOOL. id, nf[bl.data]) time.sleep(0.1)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
k = 21 LED1 = [7, 8, 25] LED2 = [24, 23, 18]
Nachdem die bereits bekannten Module importiert wurden, werden Variab­len für die verwendeten GPIO-Pins angelegt. Die Variable k enthält den Pin für den Knetekontakt, die beiden Listen LED1 und LED2 die je drei Pins für die RGB-LEDs.
for i in range(3): GPIO.setup(LED1[i], GPIO.OUT, initial=False) GPIO.setup(LED2[i], GPIO.OUT, initial=False)
Zwei Schleifen initialisieren die GPIO-Pins der RGB-LEDs als Ausgänge und schalten diese aus.
lf = [[0, 0, 1],[0, 1, 0],[1, 1, 1],[1, 0, 0], [1, 0, 1]]
Die Liste lf definiert die fünf verwendeten Lichtfarben. Jede Farbe besteht aus den drei Komponenten Rot, Grün und Blau. Durch Kombination entste­hen daraus die Farben Blau, Grün, Weiß, Rot und Lila.
mf = {3: 0, 5: 1, 4: 2, 1: 3, 14: 4}
Zwei RGB-LEDs und ein Sensorkontakt aus Knete.
Für die Zuordnung des Materials zur Anzeige der Lichtfarbe wird eine Va­riable mf vom Typ Dictionary verwendet, dies ist eine besondere Form der Liste. In einem Dictionary werden die einzelnen Elemente nicht über ihre Nummer ausgewählt, sondern über ein beliebiges Wort, den sogenannten Schlüssel, der auch aus einem einzigen Buchstaben oder einer Zahl beste­hen kann. Im Gegensatz zu einer einfachen Liste steht ein Dictionary in ge­schweiften Klammern. Es kann beliebig viele Paare aus Schlüssel und Wert enthalten.
In unserem Fall ist der Schlüssel der jeweilige Data-Wert des block.WOOL­Materials, der Wert dahinter die zugehörige Farbnummer aus der Liste lf.
nf = {3: 5, 5: 4, 4: 1, 1: 14, 14: 3}
Nach ähnlichem Schema enthält das Dictionary nf bei einer zyklischen Ver­änderung die jeweils nächste Farbe. Jedes Antippen des Knetekontakts soll die Farbe des Blocks, auf dem die Spielfigur steht, zyklisch um eine Farbe weiterschalten. So wird aus einem Block der Farbe 3 (Blau) beim Antippen die Farbe 5 (Grün). Die Tabelle zeigt die verwendeten Farben:
Page 33
Data-Wert für block.WOOL Farbe
3 Blau 5 Grün 4 Gelb 1 Orange
14 Rot
Danach startet die Hauptschleife des Programms.
try: while True: p = mc.player.getTilePos() bl = mc.getBlockWithData(p.x, p.y-1, p.z)
Nach bereits bekanntem Schema wird der Block, auf dem die Spielfigur steht, in der Variablen bl gespeichert.
if bl.id == block.WOOL.id: for i in range(3): GPIO.output(LED1[i], lf[p.y][i])
Besteht der Block aus dem Material block.WOOL, werden über eine Schlei­fe die drei Pins der ersten RGB-LED auf die passende Farbe gesetzt. Die drei Farbkomponenten werden anhand der in p.y ausgelesenen Höhe, auf der die Spielfigur steht, aus der Liste lf übernommen.
for i in range(3): GPIO.output(LED2[i], lf[mf[bl.data]][i])
Die Farbe der zweiten RGB-LED wird aus der Dictionary-Variablen mf an­hand des Data-Werts des Blocks übernommen, auf dem die Spielfigur steht. Über die so ermittelte Farbnummer werden aus der Liste lf die Farbkompo­nenten für die RGB-LED übernommen.
if GPIO.input(k) == False: mc.setBlock(p.x, p.y-1, p.z, block.WOOL. id, nf[bl.data])
time.sleep(0.1)
Wird der Knetekontakt berührt, wird die Farbe des Blocks, auf dem die Spiel­figur steht, verändert. Dazu wird an der gleichen Position ein neuer Block gesetzt, der ebenfalls aus dem Material block.WOOL besteht, aber einen anderen Data-Wert hat. Er wird anhand der aktuellen Farbe bl.data aus der Dictionary-Variablen nf ermittelt. Diese enthält für jede Farbe beim An­tippen die nächste Farbe.
Nach dem Berühren des Knetekontakts wartet das Programm 0,1 Sekunden, um längeres Berühren nicht als mehrere Aktionen auszuwerten.
Drückt der Spieler die Tastenkombination [Strg]+[C], wird wie üblich das Programm beendet, und die GPIO-Pins werden zurückgesetzt.
Die Spielfigur Steve auf dem farbigen Hanggelände
Wahr oder nicht...?
Rund um MinecraftTM ranken sich diverse Mythen und angebliche Fak­ten.
Ein Minecraft
Welt. Die Minecraft
64.000.000 Blöcken Kantenlänge, das entspricht einer Fläche von
4.096.000.000 km². Das entspricht etwa dem Achtfachen der Erd­oberfläche.
Ein Tag dauert in Minecraft
Ein goldener Apfel in Minecraft
Welt wiegen. Hört man die Laute des ‚Enderman‘ (nicht Pi Edition) rückwärts, hört
man unter anderem ‚Hi‘, ‚Hello‘ und ‚What‘s up‘. Der Creeper in Minecraft
Schwein werden und entstand versehentlich durch Vertauschen der Koordinatenachsen.
Der Codename während der Entwicklung von Minecraft
Game‘. Bewirft man eine Spinne mit einem Unsichtbarkeitstrank, bleiben
nur noch die leuchtenden Augen zu sehen. Ein TNT-Block fällt 27 Blöcke, bevor er explodiert.
Man braucht 3.000.000.000 TNT-Blöcke, um einen Block Bedrock zu
zerschlagen. Ein Schaf mit Namen ‚jeb_‘ verändert ständig seine Farbe (nicht Pi
Edition). Skelette und Zombies (nicht Pi Edition) verbrennen am Tag nicht,
wenn sie auf Seelensand stehen. Als Gegenstück zum Nether, der unterirdischen Höllenwelt, sollte
eine Himmelsdimension ins Spiel kommen, was aber in einer der Beta-Versionen verworfen wurde.
Angeblich wächst Zuckerrohr auf Sand schneller als auf anderen
Landschaften. Es gibt weniger Kürbisse als Diamanten in der Minecraft
TM
-Block hat einen Meter Kantenlänge in der realen
TM
-Welt hat eine quadratische Fläche von maximal
TM
20 Minuten (nicht Pi Edition).
TM
würde 154 Tonnen in der realen
TM
(nicht Pi Edition) sollte ursprünglich ein
TM
war ‚Cave
TM
-Welt.
Hier ist der Tag 20 in der MinecraftTM-Welt
Page 34
Heute im Adventskalender
1 GPIO-Verbindungskabel
Neben der Zahl 21 in der Minecraft Eisschollen der Spielfigur entgegenkommen.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import time import random import pyautogui import RPi.GPIO as GPIO
TM
-Welt beginnt eine Straße, auf der die
Gamepad aus Knete mit LEDs
Die Spielfigur Steve wird über ein Gamepad aus Knetekontakten gesteuert und muss entgegenkommenden Eisschollen ausweichen.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
4 20-MOhm-Widerstände (rot-schwarz-blau)
10 GPIO-Verbindungskabel
3 Drahtbrücken
4 Knetekontakte
Das Programm
Das Programm 21mc_schnee01.py verwendet das bereits bekannte Modul pyautogui, um die Spielfigur über Knetekontakte zu steuern. Be­rührt man den einen Knetekontakt, blinkt die zugehörige LED zur Bestäti­gung kurz auf. Betritt die Spielfigur eine Eisscholle, wird das Wort Schnee in MinecraftTM eingeblendet.
mc = minecraft.Minecraft.create() kw = 16 ka = 21 ks = 12 kd = 7 lw = 27 la = 24 ls = 18 ld = 4
x = 3 z = -30 mc.player.setPos(x-30, 0, z+1) bx = [0, 0, 0, 0, 0, 0, 0] bz = [0, 0, 0, 0, 0, 0, 0]
GPIO.setmode(GPIO.BCM) GPIO.setup(kw, GPIO.IN) GPIO.setup(ka, GPIO.IN) GPIO.setup(ks, GPIO.IN) GPIO.setup(kd, GPIO.IN) GPIO.setup(lw, GPIO.OUT, initial=False) GPIO.setup(la, GPIO.OUT, initial=False) GPIO.setup(ls, GPIO.OUT, initial=False) GPIO.setup(ld, GPIO.OUT, initial=False)
for i in range(7): bx[i] = x-2*i bz[i] = z+random.randrange(3) mc.setBlock(bx[i], 0, bz[i], block.SNOW)
Die Spielfigur muss dem Schnee auf der Straße ausweichen.
for j in range(35): for i in range(7): mc.setBlock(bx[i], 0, bz[i], block.AIR) bx[i] -= 1 mc.setBlock(bx[i], 0, bz[i], block.SNOW) if GPIO.input(kw) == False: pyautogui.keyDown('w') GPIO.output(lw, True) else: pyautogui.keyUp('w') GPIO.output(lw, False)
Ein Gamepad mit vier Sensorkontakten aus Knete und vier LEDs.
if GPIO.input(ka) == False: pyautogui.keyDown('a') GPIO.output(la, True) else: pyautogui.keyUp('a') GPIO.output(la, False) if GPIO.input(ks) == False: pyautogui.keyDown('s') GPIO.output(ls, True)
Page 35
else: pyautogui.keyUp('s') GPIO.output(ls, False) if GPIO.input(kd) == False: pyautogui.keyDown('d') GPIO.output(ld, True) else: pyautogui.keyUp('d') GPIO.output(ld, False) p = mc.player.getTilePos() if mc.getBlock(p.x, p.y, p.z) == block. SNOW.id: mc.postToChat("Schnee") time.sleep(0.05)
So funktioniert das Programm
import random
Zusätzlich zu den bereits bekannten Modulen wird das Modul random importiert, um Zufallszahlen zu erzeugen. Die Eisschollen sollen zufällig er­scheinen.
Wie entstehen Zufallszahlen?
Gemeinhin denkt man, in einem Programm könne nichts zufällig ge­schehen – wie also kann ein Programm dann in der Lage sein, zufällige Zahlen zu generieren? Teilt man eine große Primzahl durch irgend­einen Wert, ergeben sich ab der x-ten Nachkommastelle Zahlen, die kaum noch vorhersehbar sind. Sie ändern sich auch ohne jede Regel­mäßigkeit, wenn man den Divisor regelmäßig erhöht. Dieses Ergebnis ist zwar scheinbar zufällig, lässt sich aber durch ein identisches Pro­gramm oder den mehrfachen Aufruf des gleichen Programms jederzeit reproduzieren. Nimmt man aber eine aus einigen dieser Ziffern zusam­mengebaute Zahl und teilt sie wiederum durch eine Zahl, die sich aus der aktuellen Uhrzeitsekunde oder dem Inhalt einer beliebigen Spei­cherstelle des Computers ergibt, kommt ein Ergebnis heraus, das sich nicht reproduzieren lässt und daher als Zufallszahl bezeichnet wird.
kw = 16 ka = 21 ks = 12 kd = 7 lw = 27 la = 24 ls = 18 ld = 4
Nach dem Import der Bibliotheken und der Initialisierung der Minecraft Verbindung werden die acht verwendeten GPIO-Pins in Variablen gespei­chert. kw, ka, ks, kd sind die GPIO-Pins der Knetekontakte, die die Tasten w,
a, s, d simulieren. lw, la, ls, ld sind die GPIO-Pins der zugehörigen LEDs.
Weitere Variablen werden für die Koordinaten der Eisschollen benötigt.
TM
x = 3 z = -30
Die Variablen x und z bezeichnen die Koordinaten des Felds, von dem aus das Erstellen der Eisschollen berechnet wird.
mc.player.setPos(x-30, 0, z+1)
Die Spielfigur wird an den Anfang der Straße bei der Zahl 21 gesetzt.
bx = [0, 0, 0, 0, 0, 0, 0] bz = [0, 0, 0, 0, 0, 0, 0]
Diese beiden Listen enthalten später die Koordinaten der insgesamt sieben Eisschollen. Solche Listen müssen in Python einmal komplett angelegt wer­den.
GPIO.setmode(GPIO.BCM) GPIO.setup(kw, GPIO.IN) GPIO.setup(ka, GPIO.IN) GPIO.setup(ks, GPIO.IN) GPIO.setup(kd, GPIO.IN) GPIO.setup(lw, GPIO.OUT, initial=False) GPIO.setup(la, GPIO.OUT, initial=False) GPIO.setup(ls, GPIO.OUT, initial=False) GPIO.setup(ld, GPIO.OUT, initial=False)
Die GPIO-Pins für die Knetekontakte werden als Eingänge ohne Pull-down-Widerstände eingerichtet, die GPIO-Pins für die LEDs werden als Ausgänge eingerichtet und ausgeschaltet.
for i in range(7): bx[i] = x-2*i bz[i] = z+random.randrange(3) mc.setBlock(bx[i], 0, bz[i], block.SNOW)
Eine Schleife erzeugt zufällig die sieben Eisschollen vom Typ block.SNOW, die sich dann auf den Spieler zubewegen. Die x-Koordinaten werden in der Liste bx[] gespeichert. Alle Eisschollen haben einen Abstand von zwei Fel­dern zur nächsten. Die z-Koordinaten werden in der Liste bz[] gespeichert. Sie sind zufällig auf die drei Felder breite Straße verteilt.
for j in range(35): for i in range(7):
Die Hauptschleife des Programms läuft diesmal nicht endlos, sondern 35­mal. So lange dauert es, bis die Eisschollen die ganze Straße entlang und am Ende ins Wasser gerutscht sind.
Innerhalb der Schleife läuft eine weitere Schleife siebenmal, um alle sieben Eisschollen zu bewegen.
mc.setBlock(bx[i], 0, bz[i], block.AIR) bx[i] -= 1
-
mc.setBlock(bx[i], 0, bz[i], block.SNOW)
Die aktuelle Eisscholle wird gelöscht und durch einen Block vom Typ
block.AIR ersetzt. Danach wird die x-Koordinate um 1 in negativer Rich-
tung verändert, da die Straße in dieser Richtung verläuft, und dort wird eine neue Eisscholle vom Typ block.SNOW angelegt.
if GPIO.input(kw) == False: pyautogui.keyDown('w') GPIO.output(lw, True) else: pyautogui.keyUp('w') GPIO.output(lw, False)
Nach dem gleichen Schema werden alle vier Knetekontakte abgefragt. Wird ein Kontakt berührt, simuliert pyautogui einen Tastendruck auf die ent­sprechende Taste. Danach wird die zugehörige LED eingeschaltet. Bei allen nicht berührten Knetekontakten simuliert pyautogui das Loslassen der entsprechenden Taste, und die LED wird ausgeschaltet. Diese Überprüfung aller Knetekontakte findet in der inneren Schleife statt, also nach jeder Be­wegung einer einzelnen Eisscholle.
p = mc.player.getTilePos() if mc.getBlock(p.x, p.y, p.z) == block.SNOW.id: mc.postToChat("Schnee")
Danach wird die Position der Spielfigur in der Variablen p gespeichert, und es wird geprüft, ob die Spielfigur auf einem Eisblock steht. Ist das der Fall, gibt die Funktion mc.postToChat() eine Nachricht in Minecraft Diese Nachrichten verschwinden nach einiger Zeit automatisch.
time.sleep(0.05)
Die Wartezeit am Ende jedes Schleifendurchlaufs sorgt dafür, dass sich die Eisschollen in einer Geschwindigkeit bewegen, bei der man ihnen noch aus­weichen kann
Hier ist der Tag 21 in der MinecraftTM-Welt
TM
aus.
Page 36
Heute im Adventskalender
1 LED orange mit eingebautem Vorwiderstand
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import time import random import math import pyautogui import RPi.GPIO as GPIO
Minispiel Goldsuche
In dem Minispiel des 22. Tags soll mit der Spielfigur ein unter der Wiese zufäl­lig versteckter Schatz gefunden werden. Die vier LEDs helfen dabei, indem sie den Abstand zum Schatz zeigen.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED orange mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
4 20-MOhm-Widerstände (rot-schwarz-blau)
10 GPIO-Verbindungskabel
4 Knetekontakte
Das Programm
Neben der Zahl 22 befindet sich eine große Wiese, unter der das Programm
22mc_spiel01.py einen Schatz versteckt. Bewegen Sie die Spielfigur mit
den Knetekontakten. Wenn alle vier LEDs leuchten, stehen Sie genau über dem Schatz. Schlagen Sie dann mit dem Schwert den Grasblock weg, um den Schatz freizulegen.
Das Spielfeld für die Schatzsuche.
mc = minecraft.Minecraft. create() kw = 16 ka = 21 ks = 12 kd = 7 LED = [18, 23, 24, 25] a = [7, 5, 2, 1]
GPIO.setmode(GPIO.BCM) GPIO.setup(kw, GPIO.IN) GPIO.setup(ka, GPIO.IN) GPIO.setup(ks, GPIO.IN) GPIO.setup(kd, GPIO.IN)
for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
ende = 0 x = random.randrange(-30,-19) z = random.randrange(8,26) mc.setBlock(x, 2, z, block.DIAMOND_ORE) mc.player.setPos(-25, 4, 16)
while ende == 0: p = mc.player.getTilePos() d = math.sqrt((p.x-x)*(p.x-x)+(p.z-z)*(p.z-z)) for i in range(4): if d < a[i]: GPIO.output(LED[i], True) else: GPIO.output(LED[i], False) if GPIO.input(kw) == False: pyautogui.keyDown('w') else: pyautogui.keyUp('w') if GPIO.input(ka) == False: pyautogui.keyDown('a') else: pyautogui.keyUp('a') if GPIO.input(ks) == False: pyautogui.keyDown('s') else: pyautogui.keyUp('s')
Ein Gamepad mit vier Sensorkontakten aus Knete und vier LEDs.
if GPIO.input(kd) == False: pyautogui.keyDown('d') else: pyautogui.keyUp('d') bl = mc.getBlock(x, 3, z) if bl == block.AIR.id: ende = 1 time.sleep(0.05)
for j in range(10): for i in LED: GPIO.output(i, True) time.sleep(0.2) for i in LED: GPIO.output(i, False) time.sleep(0.2) mc.setBlock(x, 2, z, block.SAND) mc.setBlocks(-20, 3, 8, -30, 3, 25, block.GRASS) GPIO.cleanup()
So funktioniert das Programm
import math
Zusätzlich zu den bereits bekannten Modulen wird das Modul math impor­tiert. Es enthält die Wurzelfunktion math.sqrt() für die Abstandsberech­nung nach Pythagoras.
kw = 16 ka = 21 ks = 12
Page 37
kd = 7 LED = [18, 23, 24, 25]
Für die GPIO-Pins der vier Knetekontakte werden wieder vier Variablen an­gelegt. Die Liste LED[] beinhaltet die GPIO-Pins der vier LEDs.
a = [7, 5, 2, 1]
Diese Liste enthält vier Grenzwerte für den Abstand. Ist der Abstand zwi­schen Spielfigur und Schatz kleiner als einer der Werte, leuchtet die zuge­hörige LED.
for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
Eine Schleife setzt die GPIO-Pins der LEDs als Ausgänge und schaltet sie aus.
ende = 0
Die Variable ende definiert das Spielende. Die Hauptschleife des Pro­gramms läuft in diesem Spiel nicht endlos, sondern nur so lange, bis der Schatz gefunden ist.
x = random.randrange(-30,-19) z = random.randrange(8,26) mc.setBlock(x, 2, z, block.DIAMOND_ORE)
Die Koordinaten x und y des Schatzes werden zufällig innerhalb der Spielflä­che festgelegt. Ein Block aus dem Material block.DIAMOND_ORE wird an dieser Stelle in einer y-Höhe von 2 gesetzt, das ist eine Einheit unterhalb der Spielfläche. Die Wiese hat an dieser Stelle die y-Höhe 3.
mc.player.setPos(-25, 4, 16)
Die Spielfigur wird mitten auf die Wiese gestellt.
while ende == 0: p = mc.player.getTilePos() d = math.sqrt((p.x-x)*(p.x-x)+(p.z-z)*(p.z-z))
Die Hauptschleife des Programms läuft, solange die Endbedingung noch nicht erreicht ist. In jedem Durchlauf wird die Position der Spielfigur in der Variablen p gespeichert, und dann wird nach Pythagoras der Abstand in der x/z-Ebene zwischen Spielfigur und Schatz errechnet.
for i in range(4): if d < a[i]: GPIO.output(LED[i], True) else: GPIO.output(LED[i], False)
Eine Schleife prüft die vier in der Liste a[] gespeicherten Abstandswerte. Ist der Abstand kleiner als der geprüfte Wert, leuchtet die zugehörige LED. Ist der Abstand also kleiner als 1, leuchten alle LEDs, ist er dagegen größer gleich 7, leuchtet keine.
if GPIO.input(kw) == False: pyautogui.keyDown('w') else: pyautogui.keyUp('w')
Anschließend werden in jedem Durchlauf der Hauptschleife die vier Knete­kontakte abgefragt. Wird einer davon berührt, simuliert pyautogui einen entsprechenden Tastendruck und bewegt die Spielfigur.
bl = mc.getBlock(x, 3, z) if bl == block.AIR.id: ende = 1
Um das Spiel zu beenden, muss der Spieler den Schatz freilegen. Dazu wird in jedem Schleifendurchlauf der Hauptschleife geprüft, ob der Block ober­halb des Schatzes das Material block.AIR hat, also nicht vorhanden ist. In diesem Fall wird die Variable ende auf 1 gesetzt und dadurch die Haupt­schleife nicht mehr wiederholt.
time.sleep(0.05)
Die Zeitverzögerung dient auch hier wieder dazu, das Spiel spielbar zu ma­chen.
Hat der Spieler den Schatz freigelegt, wird die Hauptschleife nicht mehr wie­derholt. Jetzt wird kurz der Sieg angezeigt.
for j in range(10): for i in LED: GPIO.output(i, True) time.sleep(0.2) for i in LED: GPIO.output(i, False) time.sleep(0.2)
Die LEDs blinken zehnmal hintereinander gleichzeitig. Dazu werden alle vier LEDs für 0,2 Sekunden eingeschaltet und danach für 0,2 Sekunden aus.
mc.setBlock(x, 2, z, block.SAND)
Der Block, in dem sich der Schatz befindet, wird wieder mit Sand gefüllt, damit es beim nächsten Spiel keine zwei Schätze gibt.
mc.setBlocks(-20, 3, 8, -30, 3, 25, block.GRASS)
Die komplette Spielfläche wird erneut als Wiese gesetzt. Auf diese Weise werden auch Blöcke gefüllt, die man weggeschlagen hat, ohne den Schatz zu finden.
GPIO.cleanup()
Zum Schluss werden die GPIO-Pins zurückgesetzt, um Probleme beim nächsten Programmstart zu vermeiden.
Der gesuchte Schatz
Steve sucht den Schatz
Der Tag 22 in der MinecraftTM-Welt
Page 38
Heute im Adventskalender
1 LED lila mit eingebautem Vorwiderstand
Das Programm
Das Programm 23mc_klavier02.py baut das Klavier auf der Wasserflä­che rechts neben der Zahl 23 in der MinecraftTM-Welt.
for i in range(2): mc.setBlocks(x, 2, z+2+i*4, x-7, 2, z+4+i*4, block.WOOL.id, 15) blink() for i in range(3): mc.setBlocks(x, 2, z+14+i*4, x-7, 2, z+16+i*4, block.WOOL.id, 15) blink() GPIO.cleanup()
Wir bauen ein Klavier
Im Experiment des 23. Tags wird ein Klavier gebaut, um damit zu Weihnach­ten Musik zu machen. Damit das Klavier nicht in Sekundenbruchteilen von Geisterhand entsteht, erscheint nach jedem gebauten Teil eine kurze Blink­sequenz aus fünf LEDs.
Bauteile
1 Steckbrett
1 LED rot mit eingebautem Vorwiderstand
1 LED orange mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
6 GPIO-Verbindungskabel
Fünf LEDs zeigen den Aufbau des Klaviers.
Das fertige Klavier.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
LED = [8,25,24,23,18]
GPIO.setmode(GPIO.BCM) for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
def blink(): for i in LED: GPIO.output(i,True) time.sleep(0.05) GPIO.output(i,False)
x = -22 z = 30
mc = minecraft.Minecraft.create() mc.setBlocks(x+1, 0, z-1, x-16, 0, z+27, block. STONE_SLAB_DOUBLE.id) blink() mc.setBlocks(x, 1, z, x-10, 1, z+26, block. STONE_SLAB_DOUBLE.id) blink() for i in range(7): mc.setBlocks(x, 1, z+i*4, x-10, 1, z+2+i*4, block.WOOL.id, 0) blink()
So funktioniert das Programm
LED = [8,25,24,23,18]
GPIO.setmode(GPIO.BCM) for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
Nach dem Import der Module werden die GPIO-Pins der LEDs in der Liste
LED[] gespeichert und über eine Schleife als Ausgänge definiert und aus-
geschaltet.
def blink(): for i in LED: GPIO.output(i,True) time.sleep(0.05) GPIO.output(i,False)
Dann wird eine Funktion blink() definiert, die die LEDs als Lauflicht kurz hintereinander aufleuchten lässt. Mit solchen Funktionen kann man in Py­thon häufig wiederkehrende Programmteile einmal festlegen und dann bei Bedarf immer wieder aufrufen. Funktionen müssen vor ihrer ersten Verwen­dung im Programm mit dem Schlüsselwort def definiert werden.
x = -22 z = 30
Die Koordinaten x und z definieren den Anfangspunkt des Klaviers oben links.
mc.setBlocks(x+1, 0, z-1, x-16, 0, z+27, block. STONE_SLAB_DOUBLE.id)
Auf y-Höhe 0 wird eine Grundplatte gebaut. Sie ist größer als das Klavier selbst, damit sich die Spielfigur vor dem Klavier bewegen kann, ohne ins Wasser zu fallen.
blink()
Nach jedem fertig gebauten Teil wird einmal die Blinksequenz gestartet.
mc.setBlocks(x, 1, z, x-10, 1, z+26, block. STONE_SLAB_DOUBLE.id)
Eine Schicht aus Blöcken aus dem Material block.STONE_SLAB_DOUBLE auf y-Höhe 1 stellt die Klaviertasten und deren Zwischenräume dar. Der Ein­fachheit halber werden sie zunächst als zusammenhängender Block gebaut.
Page 39
for i in range(7): mc.setBlocks(x, 1, z+i*4, x-10, 1, z+2+i*4, block.WOOL.id, 0) blink()
Eine Schleife baut in diesem Block die sieben weißen Klaviertasten mit dem Material block.WOOL und der Farbe 0. Nach jeder Klaviertaste erscheint eine Blinksequenz.
for i in range(2): mc.setBlocks(x, 2, z+2+i*4, x-7, 2, z+4+i*4, block.WOOL.id, 15) blink()
Eine weitere Schleife baut auf y-Höhe 2 die beiden schwarzen Klaviertasten links von der Lücke. Auch hier erscheint nach jeder Klaviertaste eine Blink­sequenz.
for i in range(3): mc.setBlocks(x, 2, z+14+i*4, x-7, 2, z+16+i*4, block.WOOL.id, 15) blink()
Nach dem gleichen Schema werden die drei schwarzen Klaviertasten rechts von der Lücke gebaut.
GPIO.cleanup()
Zum Schluss werden die GPIO-Pins zurückgesetzt, um Probleme beim nächsten Programmstart zu vermeiden.
Klavier zurücksetzen
Möchten Sie den Bau des Klaviers ein weiteres Mal nachvollziehen, brauchen Sie es nicht vorher mit dem Schwert Block für Block abzureißen. Das Pro­gramm 23mc_klavier_reset.py löscht es komplett, indem ein großer Block aus dem Material block.AIR im Bereich des Klaviers gebaut wird.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block
x = -22 z = 30
mc = minecraft.Minecraft.create() mc.setBlocks(x+1, 0, z-1, x-16, 2, z+28, block. AIR.id)
Der Aufbau des Klaviers in einzelnen Schritten.
Page 40
Heute im Adventskalender
1 Downloadcode
Weihnachtsmusik auf dem Klavier
Mit dem Programm des 24. Tags entlocken Sie dem Klavier über den Pie­zo-Summer Töne. Zusätzlich zeigen LEDs die gedrückte Taste an. Da dieser Adventskalender nur sechs LEDs enthält, verwenden wir zusätzlich von ei­ner RGB-LED nur die blaue Farbe. Für die schwarzen Tasten leuchten jeweils die beiden LEDs, die die benachbarten weißen Tasten darstellen.
Bauteile
1 Steckbrett
1 LED lila mit eingebautem Vorwiderstand
1 LED rot mit eingebautem Vorwiderstand
1 LED orange mit eingebautem Vorwiderstand
1 LED gelb mit eingebautem Vorwiderstand
1 LED grün mit eingebautem Vorwiderstand
1 LED blau mit eingebautem Vorwiderstand
1 RGB-LED mit eingebauten Vorwiderständen
1 Piezo-Summer
9 GPIO-Verbindungskabel
Das Programm
Das Programm 24mc_klavier03.py macht Musik mit dem Klavier. Stel­len Sie die Spielfigur am besten auf die weißen Klaviertasten und bewegen Sie sie mit den Tasten [A] und [D] nach links oder rechts. Schlagen Sie mit dem Schwert mithilfe der rechten Maustaste auf die Tasten, um Töne zu er­zeugen. Das Programm geht davon aus, dass das Klavier mit dem Programm des 23. Tags gebaut wurde.
#!/usr/bin/python import mcpi.minecraft as minecraft import mcpi.block as block import RPi.GPIO as GPIO import time
LED = [12,7,8,25,24,23,18] pi = 21 TON = [261,277,293,311,329,349,369,391,415,440, 466,493] x = -22 z = 30
Sieben LEDs zeigen die Töne des Klaviers an.
we = 0 sw = 15
GPIO.setmode(GPIO.BCM) for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
GPIO.setup(pi, GPIO.OUT, initial=False) p = GPIO.PWM(pi, 1)
def ton(t): p.ChangeFrequency(TON[t]) p.start(1) time.sleep(0.2) p.stop()
mc = minecraft.Minecraft.create()
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z) if bl.data == we and hit.pos.z >= z and hit.pos.z <= z+2: GPIO.output(LED[0],True) ton(0) GPIO.output(LED[0],False) if bl.data == sw and hit.pos.z >= z+2 and hit.pos.z <= z+4: GPIO.output(LED[0],True) GPIO.output(LED[1],True) ton(1) GPIO.output(LED[0],False) GPIO.output(LED[1],False) if bl.data == we and hit.pos.z >= z+4 and hit.pos.z <= z+6: GPIO.output(LED[1],True) ton(2) GPIO.output(LED[1],False) if bl.data == sw and hit.pos.z >= z+6 and hit.pos.z <= z+8: GPIO.output(LED[1],True) GPIO.output(LED[2],True) ton(3) GPIO.output(LED[1],False) GPIO.output(LED[2],False) if bl.data == we and hit.pos.z >= z+8 and hit.pos.z <= z+10: GPIO.output(LED[2],True) ton(4) GPIO.output(LED[2],False) if bl.data == we and hit.pos.z >= z+12 and hit.pos.z <= z+14: GPIO.output(LED[3],True) ton(5) GPIO.output(LED[3],False) if bl.data == sw and hit.pos.z >= z+14 and hit.pos.z <= z+16: GPIO.output(LED[3],True) GPIO.output(LED[4],True) ton(6) GPIO.output(LED[3],False) GPIO.output(LED[4],False) if bl.data == we and hit.pos.z >= z+16 and hit.pos.z <= z+18: GPIO.output(LED[4],True) ton(7) GPIO.output(LED[4],False) if bl.data == sw and hit.pos.z >= z+18 and hit.pos.z <= z+20: GPIO.output(LED[4],True)
Page 41
GPIO.output(LED[5],True) ton(8) GPIO.output(LED[4],False) GPIO.output(LED[5],False) if bl.data == we and hit.pos.z >= z+20 and hit.pos.z <= z+22: GPIO.output(LED[5],True) ton(9) GPIO.output(LED[5],False) if bl.data == sw and hit.pos.z >= z+22 and hit.pos.z <= z+24: GPIO.output(LED[5],True) GPIO.output(LED[6],True) ton(10) GPIO.output(LED[5],False) GPIO.output(LED[6],False) if bl.data == we and hit.pos.z >= z+24 and hit.pos.z <= z+26: GPIO.output(LED[6],True) ton(11) GPIO.output(LED[6],False)
except KeyboardInterrupt: GPIO.cleanup()
So funktioniert das Programm
LED = [12,7,8,25,24,23,18] pi = 21
Die Liste LED[] enthält die Nummern der GPIO-Pins für die LEDs, die Varia­ble pi den GPIO-Pin des Piezo-Summers.
TON = [261,277,293,311,329,349,369,391,415,440, 466,493]
Die Liste TON[] enthält die Frequenzen der zwölf verwendeten Töne.
x = -22 z = 30
x und z sind wieder die Koordinaten des Anfangspunkts des Klaviers. Sie
werden benötigt, da die angeschlagene Klaviertaste anhand ihrer Koordi­naten identifiziert wird.
we = 0 sw = 15
Die beiden Farben der Klaviertasten werden, um die Tasten zu identifizieren, in den Variablen we (weiß) und sw (schwarz) gespeichert.
for i in LED: GPIO.setup(i, GPIO.OUT, initial=False)
Die GPIO-Pins der LEDs werden als Ausgänge definiert und ausgeschaltet.
GPIO.setup(pi, GPIO.OUT, initial=False) p = GPIO.PWM(pi, 1)
Der GPIO-Pin des Piezo-Summers wird als Ausgang definiert, ausgeschaltet, und ein PWM-Signal wird darauf eingerichtet.
def ton(t): p.ChangeFrequency(TON[t]) p.start(1) time.sleep(0.2) p.stop()
Um die Töne zu erzeugen, verwenden wir wieder eine Funktion. Funktionen können Parameter enthalten, die bei jedem Aufruf übergeben werden. Die Funktion ton(t) beinhaltet den Parameter t. Dieser enthält bei jedem Funktionsaufruf die Nummer der angeschlagenen Klaviertaste.
Innerhalb der Funktion wird zunächst die Frequenz des PWM-Signals auf die dem jeweiligen Ton entsprechende Frequenz aus der Liste TON[] gesetzt. Danach wird das PWM-Signal für 0,2 Sekunden gestartet, um den Ton über den Piezo-Summer abzuspielen.
try: while True: for hit in mc.events.pollBlockHits(): bl = mc.getBlockWithData(hit.pos.x, hit. pos.y, hit.pos.z)
Die Hauptschleife des Programms ist diesmal wieder eine Endlosschleife, die prüft, ob ein Block mit dem Schwert angeschlagen wurde, und diesen Block dann in der Struktur bl speichert.
Nacheinander werden nun alle Tasten geprüft, um anhand der Koordinaten des angeschlagenen Blocks die richtige Taste zu finden.
if bl.data == we and hit.pos.z >= z and hit.pos.z <= z+2: GPIO.output(LED[0],True) ton(0) GPIO.output(LED[0],False)
Ist die Farbe der Taste Weiß und die z-Koordinate in einem bestimmten Be­reich, wird die der Taste entsprechende LED eingeschaltet, der Ton mithilfe der Funktion ton() erzeugt und danach die LED wieder ausgeschaltet.
if bl.data == sw and hit.pos.z >= z+2 and hit.pos.z <= z+4: GPIO.output(LED[0],True) GPIO.output(LED[1],True) ton(1) GPIO.output(LED[0],False) GPIO.output(LED[1],False)
Die schwarzen Tasten funktionieren prinzipiell gleich, jedoch mit dem Unter­schied, dass zwei LEDs ein- und nach dem Ton wieder ausgeschaltet werden.
except KeyboardInterrupt: GPIO.cleanup()
Das Programm läuft, bis es mit der Tastenkombination [Strg]+[C] abge­brochen wird. Danach werden die GPIO-Pins zurückgesetzt.
Der Downloadcode aus dem Adventskalender heute liefert Noten für ein Weihnachtslied zum Nachspielen. Geben Sie den Code auf www.buch.cd ein.
Steve spielt auf dem Klavier Weihnachtsmusik
Die Klaviertasten und ihre Töne
Page 42
Minecraft ist eine Marke der Mojang Synergies AB mit Sitz in Stockholm, Schweden. Kein offizielles Minecraft-Produkt. Nicht von Mojang genehmigt oder mit Mojang verbunden.
© 2017 Franzis Verlag GmbH, 85540 Haar bei München
Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Das Erstellen und Verbreiten von Kopien auf Papier, auf Datenträgern oder im Internet, insbesondere als PDF, ist nur mit ausdrücklicher Genehmigung des Verlags gestattet und wird widrigenfalls strafrechtlich verfolgt.
Die meisten Produktbezeichnungen von Hard- und Software sowie Firmennamen und Firmenlogos, die in diesem Werk genannt werden, sind in der Regel gleichzeitig auch eingetragene Warenzeichen und sollten als solche betrachtet werden. Der Verlag folgt bei den Produktbezeich­nungen im Wesentlichen den Schreibweisen der Hersteller.
GTIN 4019631150011
Liebe Kunden!
Dieses Produkt wurde in Übereinstimmung mit den geltenden europäischen Richtlinien hergestellt und trägt daher das CE-Zeichen. Der bestimmungsgemäße Gebrauch ist in der beiliegenden Anleitung beschrieben.
Bei jeder anderen Nutzung oder Veränderung des Produktes sind allein Sie für die Einhaltung der geltenden Regeln verantwortlich. Bauen Sie die Schaltungen deshalb genau so auf, wie es in der Anleitung beschrieben wird. Das Produkt darf nur zusammen mit dieser Anleitung weitergegeben werden.
Das Symbol der durchkreuzten Mülltonne bedeutet, dass dieses Produkt getrennt vom Hausmüll als Elektroschrott dem Recycling zugeführt werden muss. Wo Sie die nächstgelegene kostenlose Annahmestelle finden, sagt Ihnen Ihre kommunale Verwaltung.
Achtung! Augenschutz und LEDs:
Blicken Sie nicht aus geringer Entfernung direkt in eine LED, denn ein direkter Blick kann Netzhautschäden verursachen! Dies gilt besonders für helle LEDs im klaren Gehäuse sowie in besonderem Maße für Power-LEDs. Bei weißen, blauen, violetten und ultravioletten LEDs gibt die scheinbare Helligkeit einen falschen Eindruck von der tatsächlichen Gefahr für Ihre Augen. Besondere Vorsicht ist bei der Verwendung von Sammellinsen geboten. Betreiben Sie die LEDs so wie in der Anleitung vorgesehen, nicht aber mit größeren Strömen.
Alle in diesem Buch vorgestellten Schaltungen und Programme wurden mit der größtmöglichen Sorgfalt entwickelt, geprüft und getestet. Trotzdem können Fehler im Buch und in der Software nicht vollständig ausgeschlossen werden. Verlag und Autor haften in Fällen des Vorsatzes oder der groben Fahrlässigkeit nach den gesetzlichen Bestimmungen. Im Übrigen haften Verlag und Autor nur nach dem Produkthaftungsgesetz wegen der Verletzung des Lebens, des Körpers oder der Gesundheit oder wegen der schuldhaften Verletzung wesentlicher Vertragspflichten. Der Scha­densersatzanspruch für die Verletzung wesentlicher Vertragspflichten ist auf den vertragstypischen, vorhersehbaren Schaden begrenzt, soweit nicht ein Fall der zwingenden Haftung nach dem Produkthaftungsgesetz gegeben ist.
15001-1 Titlei_S3.qxp_Layout 1 27.04.17 09:59 Seite 1
Page 43
Page 44
Du bist Minecraft™-Fan oder interessierst dich für das Spiel? Dann ist dieser Adventskalender genau das Richtige für dich: Verkürze dir die Wartezeit auf Weihnachten mit 24 tollen Minecraft
-Projekten.
Mit Minecraft
verbringst du nicht nur viele kurzweilige Stunden mit spielen, sondern kannst auch programmieren lernen. Erstelle deine eigenen Minispiele und steige so in die Python-Programmierung ein: Zeige Steve, wie er gekonnt den selbstprogrammierten Eisklötzen ausweicht. Im Adventskalender wird die Raspberry-Pi-Edition von Minecraft
eingesetzt, mit der sich wunderbar Elektronik an der GPIO aus
Minecraft
heraus ansteuern lässt. Auch eine Eingabe über Elektronik ist
möglich, z. B. wirst du Steve mit Knete steuern.
Über einen am Raspberry Pi angeschlossenen Piezo kannst du aus Minecraft
heraus Töne wiedergeben.
Mit Hilfe des farbig illustrierten Handbuchs lassen sich alle 24 Experimente auch ganz ohne Vorkenntnisse aufbauen und programmieren. Alle not­wendige Software wird kostenlos zum Download angeboten, darunter auch eine eigens für den Adventskalender erstellte Minecraft
-Welt.
Die Experimente funktionieren mit dem Raspberry Pi 2 Modell B und dem Raspberry Pi 3 Modell B. Der Raspberry Pi ist nicht enthalten. Für die Durchführung der Experimente ist ein Internetzugang erforderlich.
DER ADVENTSKALENDER FUR MINECRAFT
TM
-FANS UND SOLCHE,
DIE ES WERDEN WOLLEN
In 24 Tagen vom Spieler zum Programmierer: So sinnvoll war Minecraft
spielen noch nie.
STEUERN SIE
ELEKTRONIK MIT
MINECRAFT
TM
Für Kinder unter 14 Jahren nicht geeignet!
Zusätzlich benötigt: Raspberry Pi
© 2017 Franzis Verlag GmbH, Richard-Reitzner-Allee 2, D-85540 Haar, Germany
Innovation, Irrtümer und Druckfehler vorbehalten 2017/01
GTIN 4019631150011
TM
15001-1 HB_U4.qxp_Layout 1 27.04.17 10:04 Seite 1
Loading...