[ Home ] [ Seitenende ] [ Teil 1 ] [ Teil 2b ] [ Teil 3 ]

 

 

 

Roboter-Auto „Joy-Car“ - Teil 2a

 

 

Vom schillernden Regenbogen hin zu Stars mit NeoPixel

 

Wir greifen das Programm „joy-car_teil_01_prog_14.py aus dem ersten Teil auf und erweitern die NeoPixel“-Anzeige der Funktion <NeoPixel_anzeigen(anzeigen_ja_nein, Helligkeit_LEDs)> dahingehend, dass wir dieser über den Parameter <anzahlNeoPixel> mitteilen, wie viele von den insgesamt 8 bunten RGB-LEDs angezeigt werden sollen (siehe roter Kasten).

 

Anstelle der Regenbogenfarben mit dem Statement <strip.show_rainbow(1, 360)> wird nun das

 

1.     Statement <strip.show_color(neopixel.colors(NeoPixelColors.RED))>

 

verwendet. Später werden wir dann noch sehen, wie sich Farben im laufenden Programm jederzeit ändern lassen. -

 

Wie man weiter unten im grünen Kasten sieht, wird die erweiterte Anzeige-Funktion <NeoPixel_anzeigen(anzeigen_ja_nein, Helligkeit_LEDs, anzahlNeoPixel)> in einer sogenannten kopfgesteuerten Do … while“-Schleife gleich mehrfach aufgerufen und ausgeführt, wobei sich jedes Mal die anzuzeigende Anzahl von NeoPixeln um +1 erhöht, sodass sich die NeoPixel-Reihe wie folgt darstellt: [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_01.py)

Das

 

2.     Statement <schleifenZaehler += 1>

 

bedeutet, dass der Wert der Variablen <schleifenZaehler> bei jedem Aufruf um den Wert +1 erhöht wird. Dabei ist das Statement eine Kurzform vom

 

3.     Statement <schleifenZaehler = schleifenZaehler + 1>

 

Mathematisch wird dabei der Wert der Variablen <schleifenZaehler> bei jedem Aufruf inkrementiert, d.h. um +1 erhöht.

 

Ein weiteres, zukünftig 7  anzuwendendes Statement ist das Ermitteln der Anzahl angeschlossener NeoPixel“-LEDs mit dem

 

4.     Statement <anzahlNeoPixel = strip.length()>

 

Mit engl. strip ist der NeoPixel“-LED-Streifen gemeint, der im vorliegenden Fall aus 4 x 2 LEDs besteht, wobei diese über einen seriellen Datenbus „I2C angesteuert werden (siehe Bild). Dabei steht die engl. Abkürzung „I2C“ für Inter-Integrated Circuit, d.h. Inter-integrierte Schaltung bzw. integrierter Schaltkreis (für die Datenkommunikation zwischen [= „Inter“] elektronischen Komponenten).

 

Programmiertechnisch handelt es sich bei strip um eine Instanz- bzw. Objektvariable, die auf die Klasse <neopixel> zugreift:

 

5.     Statement <strip : neopixel.Strip = None>

 

Fragen wir zu Abwechselung die KI von ChatGPT:

 

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Achtung:

 

Das Ermitteln der strip“-Länge, d.h. die Anzahl von NeoPixeln, mit dem

 

6.     Statement <anzahlNeoPixel = strip.length()>

 

lässt sich nur dann fehlerfrei anwenden, wenn zuvor das

 

7.     Statement <strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

mit der Initialisierung der Instanz- bzw. Objektvariablen <strip> durchgeführt wurde.

 

Aus diesem Grund lässt sich das

 

8.     Statement <anzahlNeoPixel = strip.length()>

 

in der Zeile 76 im obenstehenden Programm wider Erwarten nicht anwenden! -

 

 

NeoPixel in Form einzelner bunter RGB-LEDs lassen sich aber nicht nur der Reihe nach einschalten, sondern auch der Reihe nach ausschalten. Und zwar mittels des

 

9.     Statements <strip.shift(1)>

 

in der <fornext>-Schleife (siehe pinkfarbener Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_02.py)

 

Wie der Parameter 1 im

 

10. Statements <strip.shift(1)>

 

bereits nahelegt, lassen sich auch mehrere NeoPixel als Ganzes ausschalten:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_03.py)

 

Bei dem Joy-Car“-Roboterauto wurden bekanntlich bis zu acht farbigen RGB-LEDs verbaut. Und zwar jeweils in vier Zweiergruppen, davon je zwei Zweiergruppen vorn und zwei Zweiergruppen hinten.

 

Wenn man die acht farbigen RGB-LEDs der Reihe nach einschaltet, dann wird als Erstes eine einzelne RGB-LEDs vorn links und als Letztes eine einzelne RGB-LEDs hinten rechts eingeschaltet.

 

Das nächste Programm „joy-car_teil_02_prog_04.py“ soll so programmiert werden, dass von den acht farbigen RGB-LEDs nur eine einzige LED übrig bleibt, die leuchtet. Und zwar die LED Nr. 4 vorn rechts.

 

Zu diesem Zweck soll eine <fornext>-Schleife mit dem Schleifenkopf

 

11. Statement <for Index in range(1, anzahlNeoPixel + 1):>

 

programmiert werden. Dabei stellt sich gleich die Frage, weshalb der engl. range, d.h. der Bereich des Index bei 1 beginnt und nicht wie üblich bei 0.

 

Wenn man sich das

 

12. Statement <strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

in der Funktion NeoPixel_anzeigen(  anzeigen_ja_nein,

                                                          Helligkeit_LEDs,

                                                          anzahlNeoPixel)

 

anschaut, dann fällt auf, dass es im vorliegenden Fall insgesamt 8 NeoPixel gibt, die sich ansteuern lassen. Und zwar im Bereich [ 1, …, 8 ] und nicht wie sonst üblich im Bereich [ 0, …, 7 ] = 8 unterschiedliche Werte. Und trotzdem gibt es bei den 8 NeoPixeln im Bereich [ 1, …, 8 ] einen Wert 0 im Gesamtbereich [ 0, 1, …, 8 ] = 9 Werte.

 

 

Dazu muss man wissen, dass sich mit dem Wert 0 im

 

13. Statement <strip = neopixel.create(DigitalPin.P0, 0, NeoPixelMode.RGB)>

 

die Anzeige der NeoPixel nicht ausschalten lässt!

 

 

Bemühen wir in diesem Zusammenhang wieder die KI von ChatGPD:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Wenden wir uns wieder der <fornext>-Schleife mit dem Schleifenkopf

 

14. Statement <for Index in range(1, anzahlNeoPixel + 1):>

 

zu. Dazu muss man wissen, dass die Variable <Index> als Schleifenzähler der <fornext>-Schleife stets mit dem Wert Index = 0 beginnt! Da aber die NeoPixel immer von 1 an gezählt werden, überspringen wir quasi den Wert Index = 0 und starten den NeoPixel“-Zählbereich erst mit [ 1, …, 8 + 1 ]:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_04.py)

 

Obwohl beim Joy-Car“-Roboterauto bekanntlich bis zu acht farbige RGB-LEDs verbaut wurden, bedeutet das nicht zwangsläufig, dass wir bei der NeoPixel“-Anzeige auch mit diesen acht LEDs rechnen bzw. diese auch anzeigen müssen! Im Gegenteil! Da nur die LED Nr. 4 vorn rechts leuchten soll, müssen wir von den vier vorderen NeoPixel“-LEDs insgesamt drei ausschalten! Und zwar rückwärts von der ersten RGB-LED vorn links (siehe pinkfarbener Kasten).

 

Der Nachteil vom Programm „joy-car_teil_02_prog_04.hex ist noch der, dass man die vier vorderen NeoPixel“-LEDs erst einschalten und zum Leuchten bringen muss, bevor man drei von ihnen ausschalten kann, damit am Ende nur noch die erste RGB-LED vorn links leuchtet.

 

Aber das Problem lässt ähnlich wie beim Versteck spielen der Kinder lösen:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Kurz und gut, bei der Programmierung der NeoPixel“-Anzeigen muss man es so machen wie die Dreijährigen. Zwar kann sich der Joy-Car“-Roboter nicht die Augen zuhalten, weil er keine Webcam hat. Aber er kann seine NeoPixel quasi verstecken, d.h. sie unsichtbar machen. Wie aber kann sich eine RGB-LED unsichtbar machen?

 

Schwarz ist zwar auch eine Farbe, die aber im Gegensatz zu anderen Farben praktisch alle Farbspektren des sichtbaren Lichts absorbiert, quasi verschluckt. Das hat z.B. bei schwarz lackierten Autos zur Folge, dass sich diese im Sommer am stärksten aufheizen, weil der schwarze Lack alle Photonenstrahlung der Sonne samt aller Farbspektren absorbiert.

 

Demzufolge wäre eine schwarze LED praktisch unsichtbar. Aber schwarz leuchtende LEDs gibt es nicht, auch nicht zu kaufen. Das macht auch nichts, weil man eine schwarz leuchtende LED einfach nur ausgeschaltet sein lassen muss, damit sich quasi unsichtbar ist:

 

15. Statement <strip.show_color(neopixel.colors(NeoPixelColors.BLACK))>

 

Aber eine schwarz leuchtende LED ist nicht wirklich ausgeschaltet, nur weil sie nicht leuchtet! Eine schwarz leuchtende LED, die kein Licht ausstrahlt, muss aber wegen der elektronischen Ansteuerung über den seriellen Datenbus „I2C ständig erreichbar sein, damit man sie z.B. von schwarz auf rot umschalten kann, sie wieder sichtbar machen kann!

 

Zeit also, dass wir die Anzeige-Funktion <NeoPixel_anzeigen(anzeigen_ja_nein, Helligkeit_LEDs, anzahlNeoPixel)> um den Parameter <Farbe_LEDs> wie folgt erweitern (siehe roter Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_05.py)

 

Wenn man das obenstehende Programm „joy-car_teil_02_prog_05.hex startet, dann wird nach dem Betätigen des Tasters A nur die Laufschrift mit der Ziffer 4 angezeigt, um zu signalisieren, dass nur 4 NeoPixel eingeschaltet sind und „schwarz leuchten“, sodass man diese nicht sieht:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Sichtbar wird dann abschließend nur die vierte RGB-LED auf der rechten Seite des Joy-Car“-Roboterautos, die für drei Sekunden in strahlendem Grün leuchtet, weil sie als einzige nicht abgeschaltet wurde (siehe grüner Kasten)!

 

Bei dem obenstehende Programm „joy-car_teil_02_prog_05.hex ging es darum nur die LED Nr. 4 vorn rechts leuchten zu lassen, wozu es notwenig wurde, von den vier vorderen NeoPixel“-LEDs insgesamt drei ausschalten! Und zwar rückwärts von der ersten RGB-LED vorn links.

 

Beim nächsten Programm, das auf dem vorherigen aufbaut, geht es darum nur die LED Nr. 3 vorn rechts leuchten zu lassen. Da aber wegen des Vorgängerprogramms im Moment noch die LED Nr. 4 leuchtet, müssen wir das Programm dahingehend ändern, dass die Adressierung der aktuellen LED Nr. 4 auf diejenige der LED Nr. 3 geändert wird.

 

Da wir, obwohl die NeoPixel“-LEDs alle über den seriellen „I2C“-Steuer- und Datenbus angesteuert werden, zum Glück nichts mit der Adressierung der NeoPixel“-LEDs zu tun haben, nur die Anzeigeposition von LED Nr. 4 auf LED Nr. 3 mittels des

 

16. Statements <strip.rotate(-1)>

 

ändern, indem wir bei der Anzeigeposition der LED gerade einmal einen Schritt nach links verschieben bzw. „rotieren“ (siehe pinkfarbener Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_06.py)

 

Wichtig dabei ist, dass sich zwischen dem roten Kasten und dem pinkfarbenen Kasten kein weiterer Quellkode, insbesondere kein

 

17. Statement <strip.show_color(neopixel.colors(NeoPixelColors.BLUE))>

 

oder mit einer anderen Farbe befindet, da das Ausführen des Statements dazu führt, dass plötzlich wieder alle vier NeoPixel“-LEDs zu leuchten anfangen!

 

 

Jetzt wo wir wissen, dass die beiden Statements im roten Kasten und im pinkfarbenen Kasten in der logischen Abfolge zusammengehören, können wir diese wie folgt zusammenfassen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_07.py)

 

Als nächstes kann man sich daran machen und die Statements im pinkfarbenen Kasten des Tasters A im Notepad++“-Editor mittels der Tastenfolge <Strg>, <X> ausschneiden und in der Funktion <NeoPixel_anzeigen(anzeigen_ja_nein, Helligkeit_LEDs, anzahlNeoPixel)> mittels der Tastenfolge <Strg>, <V> am Quelltextende der Funktion wieder einfügen (siehe pinkfarbenen Kasten).

 

Darüber hinaus muss man auch noch den Funktionskopf um die neuen Parameter wie folgt erweitern (siehe roter Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_08.py)

 

Damit das veränderte Programm „joy-car_teil_02_prog_08.hex auch tatsächlich funktioniert, muss man im Hauptprogramm noch die neu hinzugekommenen Variablen <ausschalten_NeoPixel = 0> und <verschieben_NeoPixel = 0> hinzufügen und in den Funktionen mittels der Angabe <global> zugänglich machen (siehe kleiner blauer Kasten).

 

Da die neu hinzugekommenen Variablen mit dem Anzeigeverhalten der

 

18. Funktion <NeoPixel_anzeigen(anzeigen_ja_nein, Helligkeit_LEDs, anzahlNeoPixel)>

 

zu tun haben, muss man diese auch im Funktionkopf als Parameter hinzufügen

 

19. Funktion <NeoPixel_anzeigen(      anzeigen_ja_nein,

                                                      Helligkeit_LEDs,

                                                      anzahlNeoPixel,

                                                      FarbeLEDs,

                                                      NeoPixel_ausschalten,

                                                      NeoPixel_verschieben)>

 

(siehe kleiner pinkfarbener Kasten).

 

Wir wissen ja inzwischen, dass bei der Programmierung von Variablen zwischen globalen und lokalen Variablen unterschieden wird. Dabei müssen Variablen im Hauptprogramm, engl. main, nicht zwangsläufig als „global“ deklariert werden, weil sie es von Haus aus automatisch sind!

 

Demzufolge kann man bei der Programmierung auf (globale) Variablen von überall her darauf zugreifen und diese auch wertmäßig oder inhaltlich jederzeit ändern, was u.U. zu Problemen führt!

 

Dass die Trennung von globalen und lokalen Variablen programmiertechnisch absolut sinnvoll ist, dürfte klar. Schließlich sind lokale Variablen z.B. in einer Funktion gegenüber Zugriffen vom Hauptprogramm oder anderen Funktionen aus geschützt, im Sinne von (ab-) gekapselt, sodass man auf diese eben nicht von „außen“ einfach so zugreifen kann!

 

Damit man globale und lokale Variablen besser unterscheiden und auseinanderhalten kann, sollten für diese stets unterschiedliche Variablennamen verwendet werden!

 

Wie man in der nachfolgende Tabelle der Variablennamen sieht, kommt der Variablenname <anzahlNeoPixel> doppelt vor. Und zwar in der linken Spalte als globale Variable im Hauptprogramm und in der rechten Spalte als lokale Variable in der Funktion <NeoPixel_anzeigen()>:

 

Lfd.

Globaler Variablenname

 

Lokaler Variablenname

 

Bemerkung

Nr.

im Hauptprogramm

 

in der Funktion NeoPixel_anzeigen()

 

 

 

 

 

 

 

 

1

schalte_Ein_Aus

 

anzeigen_ja_nein

 

 

2

NeoPixel_Helligkeit

 

Helligkeit_LEDs

 

 

3

anzahlNeoPixel

 

anzahlNeoPixel

 

Identische Var.namen!

4

LED_Farbe

 

Farbe_LEDs

 

 

5

ausschalten_NeoPixel

 

NeoPixel_ausschalten

 

 

6

verschieben_NeoPixel

 

NeoPixel_verschieben

 

 

 

Das nachfolgende Programm „joy-car_teil_02_prog_09.hex wurde noch weiter verbessert, wobei die boolesche Variable <anzeigen_ja_nein> nach dem Aufrufen der Funktion <NeoPixel_anzeigen()> den Wert <anzeigen_ja_nein> = False an die aufrufende Funktion <on_button_pressed_a()> zurückliefert (siehe kleiner roter Kasten).

 

Die Rückgabe des Wertes <anzeigen_ja_nein> = False an die aufrufende Funktion <on_button_pressed_a()> ist dem Umstand geschuldet, damit der Taster A als Wechseltaster arbeiten kann (siehe großer blauer Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_09.py)

 

Als nächstes geht es darum, Klarheit und Einheitlichkeit bei der Namensvergabe der globalen und lokalen Variablen zu bringen.

 

Und zwar der Gestalt, dass die Namen der globalen Variablen stets mit dem Verb anfangen, d.h. mit dem was zu tun ist, gefolgt vom grammatikalischen Objekt auf das sich das Tun, das was zu bewerkstelligen ist, bezieht (siehe linke Spalte).

 

Bei den Namen der lokalen Variablen (= Parameter im Funktionskopf) ist es umgekehrt. Da wird zuerst das grammatikalische Objekt (= „NeoPixel“) genannt, um das es geht, gefolgt vom Verb, was zu tun ist bzw. zu bewerkstelligen ist (siehe rechte Spalte):

 

Lfd.

Globaler Variablenname

 

Lokaler Variablenname

 

Bemerkung

Nr.

im Hauptprogramm

 

in der Funktion NeoPixel_anzeigen()

 

 

 

 

 

 

 

 

1

anzeigen_NeoPixel

 

Neopixel_anzeigen

 

 

2

helligkeit_NeoPixel

 

NeoPixel_Helligkeit

 

 

3

anzahl_NeoPixel

 

NeoPixel_Anzahl

 

 

4

farbe_NeoPixel

 

NeoPixel_Farbe

 

 

5

ausschalten_NeoPixel

 

NeoPixel_ausschalten

 

 

6

verschieben_NeoPixel

 

NeoPixel_verschieben

 

 

 

Selbstverständlich lässt sich bei der obenstehenden Liste der Variablennamen die Reihenfolge derselben jederzeit verändern. Wenn man aber die Reihenfolge der Variablennamen ändert, dann muss man tunlichst darauf achten, dass man die Reihenfolge der Variablennamen auf beiden Seiten der Liste ändert. Also bei den globalen und lokalen Variablen gleichermaßen!

 

Das nachfolgende Programm „joy-car_teil_02_prog_10.hex beinhaltet nicht nur die vereinheitlichen globalen und lokalen Variablennamen und deren Reihenfolge, sondern auch noch dahingehend vereinfacht, indem auf die drei <if>-Abfragen in der Funktion <NeoPixel_anzeigen()> verzichtet wurde (siehe pinkfarbener Kasten weiter oben):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_10.py)

 

Bei den bisherigen Joy-Car“-Programmen bei denen ein paar NeoPixel abgeschaltet oder verschoben wurden, fällt auf, dass die abzuschaltenden NeoPixel beim Abschalten oder Verschieben stets kurz aufblitzten, wobei dieses besonders auffiel, wenn die NeoPixel mit maximaler Helligkeit (= 255) leuchten sollten.

 

Beim Programm „joy-car_teil_02_prog_11.py wird dem kurzen Aufblitzen von abgeschalteten NeoPixeln versucht entgegenzuwirken, indem vor dem Abschalten von NeoPixeln

 

1.     die Variable <NeoPixel_Helligkeit> auf den Wert = 0

 

2.     und die Variable <NeoPixel_Farbe> auf den Wert = schwarz (" NeoPixelColors.BLACK)

 

gesetzt werden (siehe pinkfarbener Kasten). Dabei werden die Einstellungen der Variablen im ersten Schleifendurchlauf der <fornext>-Schleife umgesetzt und beim zweiten Schleifendurchlauf, nachdem die NeoPixel auf schwarz und dunkel gesetzt wurden, wieder rückgängig gemacht. Dazu ist es erforderlich, dass die Variableninhalte der Variablen <NeoPixel_Helligkeit> und <NeoPixel_Farbe> zuvor gesichert wurden (siehe grüner Kasten).

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_11.py)

 

Auch das obenstehende Programm „joy-car_teil_02_prog_11.hex lässt sich noch optimieren im Sinne von vereinfachen. Und zwar indem wir auf die globalen Variablen in dem Funktionsaufruf der Funktion <NeoPixel_anzeigen()> verzichten:

 

       anzeigen_NeoPixel = NeoPixel_anzeigen(    anzeigen_NeoPixel,

                                                                             helligkeit_NeoPixel,

                                                                             anzahl_NeoPixel,

                                                                             farbe_NeoPixel,

                                                                             ausschalten_NeoPixel,

                                                                             verschieben_NeoPixel)

 

Wie im richtigen Leben hat die Medaille zwei Seiten. Einerseits spart man sich einen Großteil der globalen Variablen im Hauptprogramm, andererseits ist der nachfolgende Funktionsaufruf der Funktion <NeoPixel_anzeigen()> nur mit den reinen Parametern nicht mehr selbsterklärend, weil man den Parametern nicht ansieht, worauf sie sich beziehen:

 

       anzeigen_NeoPixel = NeoPixel_anzeigen(    True,

                                                                             8,

                                                                             4,

                                                                             NeoPixelColors.RED,

                                                                             0,

                                                                             0 )

 

Abhilfe schafft man da nur, indem man die nichtssagenden Parameter entsprechend kommentiert:

 

       anzeigen_NeoPixel = NeoPixel_anzeigen(    True,                                        # NeoPixel_anzeigen

                                                                             8,                                             # NeoPixel_helligkeit

                                                                             4,                                             # NeoPixel_anzahl

                                                                             NeoPixelColors.RED,              # NeoPixel_Farbe

                                                                             0,                                             # NeoPixel_ausschalten

                                                                             0)                                             # NeoPixel_verschieben

 

Im MakeCode“-Editor von Microsoft oder einem anderen Editor wie z.B. Notepad++ lassen sich die Quelltextzeilen selbstverständlich nicht fett, kursiv, unterstrichen oder farbig formatieren.

 

Der micro:bit“-Rechner in der Version 2.x verfügt gegenüber seinem Vorgänger des Weiteren u.a. über einen Touch-Sensor,

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

den als nächstes im Programm „joy-car_teil_02_prog_12.py so programmieren, dass dieser bei Berührung mit dem Finger die aktuelle Batteriespannung UBatt von [ 2,7 V, … 3,2 V ] oder von [ 4,5 V … 6 V ] anzeigt. Welche von den Spannungen angezeigt wird hängt davon ab, ob das Joy-Car“-Mainboard zusammen mit dem 6 V Batteriefach eingeschaltet ist oder nicht.

 

Wenn nur der micro:bit“-Rechner über das angeschlossene „USB 2.0“-Kabel, das auch der seriellen Datenübertragung dient, an die Stromversorgung des Windows-PCs angeschlossen wird, das Joy-Car“-Mainboard also ausgeschaltet ist, dann wird nur die niedrigere Batteriespannung UBatt von [ 2,7 V, … 3,2 V ] des micro:bit“-Rechners angezeigt.

 

Demzufolge wird die höhere Batteriespannung UBatt von [ 4,5 V … 6 V ] nur angezeigt, wenn das Joy-Car“-Mainboard zusammen mit dem 6 V Batteriefach eingeschaltet ist. Dazu muss man wissen, dass z.B. die Beleuchtung des Joy-Car“-Roboters nur funktioniert, wenn das Joy-Car“-Mainboard eingeschaltet ist (siehe grüner Kasten):

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Werfen wir abschließend noch einen Blick auf den Quellkode des Programms „joy-car_teil_02_prog_12.py. Anhand der pinkfarbenen Kästen erkennt man, wie Funktion <NeoPixel_anzeigen()> nebst der Parameter von den anderen Funktionen des Tasters A oder B aufruft:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_12.py)

 

 

Tagfahr- und Standlicht

 

Früher gab es bei den Kraftfahrzeugen in Deutschland drei Arten von Licht: das Standlicht, das Fahrlicht und das Fernlicht. Dabei mussten tagsüber bei den Kraftfahrzeugen kein Licht eingeschaltet werden. Also weder das Standlicht noch das Fahrlicht.

 

Heutzutage, wo neue Fahrzeuge über eine LED-Beleuchtung verfügen, fahren diese tagsüber mit Tagfahrlicht und bei Regen, Schnee und nachts mit Fahrlicht (= Abblendlicht). Während sich das Standlicht auf alle vier Lampen vorn und hinten bezieht, bezieht sich das Parklicht jeweils nur auf zwei Lampen rechts oder links. An Bahnübergängen z.B. muss das Fahrlicht ausgeschaltet und das Standlicht eingeschaltet bleiben oder eingeschaltet werden.

 

Mit dem Programm „joy-car_teil_02_prog_13.hex programmieren wir zunächst das Tagfahr- und Standlicht. Und zwar als Funktion <Tagfahr_oder_Standlicht()>.

 

Beim Vergleich des Quellkodes vom Tagfahrlicht mit dem vom Standlicht fällt auf, dass sich der Quellkode vom Tagfahrlicht beim Standlicht wiederholt. Der Grund dafür ist ganz einfach, nämlich der, dass beim Tagfahrlicht nur die beiden vorderen weiß leuchtenden LEDs in Betrieb sind, während beim Standlicht noch die beiden hinteren rot leuchtenden LEDs hinzukommen.

 

Interessant dabei ist, dass die Beleuchtung für das Standlicht rückwärts von hinten nach vorn vorgenommen wird. Ganz einfach deshalb, weil sich die roten Rückleuchten am Ende der NeoPixel-Kette befinden. Aus diesem Grund werden alle acht NeoPixel auf rot leuchtend geschaltet. Dann werden bei den Rückleuchten jeweils zwei dunkel (= schwarz) geschaltet. Im zweiten Schritt werden dann beim Tagfahrlicht die vier vorderen NeoPixel von rot auf weiß leuchtend umgeschaltet und zwei der vorderen NexoPixel werden dunkel (= schwarz) geschaltet (siehe zweiter grüner Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_13.py )

 

Neu im obenstehenden Programm ist das

 

·        Statement <strip.set_pixel_color(0, neopixel.colors(NeoPixelColors.BLACK))>

 

und folgende mit dem es auf einfache Weise möglich ist, einzelnen NeoPixeln eine einzelne Farbe zuzuweisen, die aber wiederum erst mit dem Aufruf des

 

·        Statements <strip.show()>

 

umgesetzt, d.h. ausgeführt wird!

 

Wichtig ist in diesem Zusammenhang noch, dass die Nummerierung der einzelnen NeoPixel mit der Farbgebung auf der linke Seite (= aus der Fahrersicht) bei der Nummer 0 beginnt:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Wie bereits erläutert, erfolgt die Konfiguration, d.h. das Ein- und Ausschalten als auch die Farbgebung, der NeoPixel rückwärts, d.h. von hinten (= Rücklicht) nach vorn (= Frontlicht):

 

1.     Statement <strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

2.     Statement <strip = neopixel.create(DigitalPin.P0, 4, NeoPixelMode.RGB)>

 

Würde man nämlich zuerst das Frontlicht vorn konfigurieren und anschließend das Rücklicht hinten, dann würde die Konfiguration der NeoPixel für das Rücklicht wegen der Nummerierung 8 die vorausgegangene Konfiguration der NeoPixel für das Frontlicht wegen der Nummerierung 4 überschreiben!

 

Wie man im nachfolgenden Quellkode des Programm „joy-car_teil_02_prog_14.hex sieht, wurde dieser weiterhin optimiert, weil sich das Standlicht aus dem roten Rücklicht plus dem weißen Tagfahrlicht zusammensetzt (siehe grüne Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_14.py)

 

Das nachfolgende Programm „joy-car_teil_02_prog_15.hex unterscheidet sich vom vorherigen nur im Hauptprogramm durch die umgekehrte Reihenfolge beim Aufruf der Funktionen <Tagfahr_oder_Standlicht()>:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_15.py)

 

Können Dinge zugleich richtig, engl. True und falsch, engl. False sein?

 

Natürlich nicht!

 

Das ist es ja gerade bei der booleschen Algebra: entweder es ist richtig oder es ist falsch, aber niemals beides zugleich!

 

Bei den beiden Programmen „joy-car_teil_02_prog_14.py und joy-car_teil_02_prog_15.py gibt es quasi eine Wahrheit dazwischen, zwischen richtig und falsch. Wie aber kann das sein bzw. wie kann es dazu kommen?

 

Ganz einfach! Bei den beiden Programmen kann man beim Aufruf der Funktion <Tagfahr_oder_Standlicht()> versehentlich die

 

·        Funktion <Tagfahr_oder_Standlicht(True, True)> oder

·        Funktion <Tagfahr_oder_Standlicht(False, False)>

 

programmieren und auch aufrufen! Niemand hindert einen daran!

 

Und was schiefgehen kann, geht erfahrungsgemäß auch irgendwann schief! Und zwar immer dann, wenn man nicht damit rechnet!

 

Und damit eben nicht das passiert, was passieren kann, ändern wir das Programm ab. Und zwar so, dass es im Funktionskopf der Funktion <Tagfahr_oder_Standlicht()> nur noch einen Parameter <Tagfahrlicht_einschalten> gibt, der wiederum immer nur einen Wert richtig oder falsch annehmen kann:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_16.py)

 

Da das Tagfahrlicht praktisch immer eingeschaltet wird, sobald man den Motor des Kraftfahrzeugs startet, lässt es sich im vorliegenden Fall mittels des Parameters <Tagfahrlicht_einschalten> = <True> im

 

·        Funktionsaufruf <Tagfahr_oder_Standlicht(True)>

 

jederzeit aktivieren und einschalten. Wenn dann einmal das Standlicht z.B. bei geschlossener Schranke an einem Bahnübergang oder beim Parken in einer unbeleuchteten Straße eingeschaltet werden muss, dann kann man dies mittels des Parameters <Tagfahrlicht_einschalten> = <False> im

 

·        Funktionsaufruf <Tagfahr_oder_Standlicht(False)>

 

jederzeit umschalten. -

 

Damit sich das Tagfahr- oder Standlicht auch unabhängig vom Hauptprogramm jederzeit ein- oder ausschalten lässt, wurde das bisherige Programm noch um die nachfolgende

 

·        Funktion <Tagfahr_Standlicht()>

 

erweitert,

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_16.hex)

 

sodass sich das Tagfahr- oder Standlicht ab sofort jederzeit mit dem Touch-Sensor ein- oder ausschalten lässt:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Dabei arbeitet der Touch-Sensor als Wechsel- bzw. Umschalter mit der booleschen Variablen <schalte_Tagfahr_Standlicht> zusammen (siehe im Hauptprogramm). Das ist dann auch der Grund dafür, weshalb die booleschen Variablen <schalte_Tagfahr_Standlicht> in der Funktion <Tagfahr_Standlicht()> als global deklariert werden muss (siehe blauer Kasten oben).

 

Das Programm „joy-car_teil_02_prog_17.hex unterscheidet sich vom Vorgängerprogramm nur dahingehend, dass im Hauptprogramm die Funktion <Tagfahr_oder_Standlicht()> vom Tagfahrlicht auf Standlicht umgeschaltet wird, um genau das Ein- und Ausschalten, Umschalten oder Zurückschalten zu testen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_17.py )

 

Bei den bisherigen Programmen verhielt es sich so, dass wir beim Einschalten des Standlichts in der Funktion <Tagfahr_oder_Standlicht()> zunächst alle acht NeoPixel in der Farbe Rot aufleuchten ließen (siehe roter Kasten Nr. 1.)), um dann die zwei verbleibenden NeoPixel (5 und 6) der Rückleuchte auf schwarz zu setzen, d.h. auszuschalten.

 

Auch bei den Frontlampen wurden zunächst alle vier NeoPixel auf weiß geschaltet (siehe roter Kasten Nr. 2.)), um dann die zwei verbleibenden NeoPixel (0 und 3) der Frontleuchte auf schwarz zu setzen, d.h. auszuschalten:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_17.hex )

 

Doch es geht anders herum! Nämlich dass man zunächst alle NeoPixel „ausschaltet“, indem man diese auf die Farbe Schwarz setzt (siehe roter Kasten). Anschließend werden dann die vier NeoPixel für das Standlicht eingeschaltet (siehe grüner Kasten).

 

Außerdem wird die Funktion <Standlicht(Standlicht_einschalten)> mittels des

 

·        Statements <return(Standlicht_einschalten)>

 

für den Betrieb als Wechselschalter erweitert (siehe blauer Kasten), sodass die Funktion <Standlicht_schalten()> dafür umso spartanischer, d.h. einfacher ausfällt (siehe pinkfarbener Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_18.py)

 

Im Zusammenhang mit dem Wechselschalter, d.h. der Funktion <Standlicht_schalten()> muss der Anfangszustand eindeutig definiert werden, da dieser ansonsten nicht funktioniert. Diesbezüglich bietet es sich an, den Anfangszustand im Hauptprogramm festzulegen, indem man praktischerweise alle NexoPixel „ausschaltet“, indem man die NeoPixel-Farbe auf Schwarz setzt (siehe brauner Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_18.hex)

 

Wir entwickeln das obenstehende Programm mit der Funktion <Standlicht(Standlicht_einschalten)> weiter, indem wir die Statements weiter oben im grünen Kasten in einem sogenannten Array abspeichern:

 

 

(Vergrößern: auf das Bild klicken! | Quelle: OpenAI, ChatGPT)

 

Anschaulicher und besser verständlich lässt sich ein Array beispielsweise anhand eines Schachspiels und dessen Schachbretts erklären. Demzufolge ist ein Schachbrett in horizontale (= Zeilen) und vertikale (= Spalten) schwarzweiß gefärbte Felder unterteilt. Dabei sind die Zeilen (= waagrecht) mit Ziffern von [ 1, …, 8 ] und die Spalten (= senkrecht) mit Buchstaben von [ A, … H ] gekennzeichnet. Bei einer klassischen Eröffnung setzt man den Bauern vom Feld E2 auf das Feld E3, sodass die Dame und der Läufer freie Bahn zum Ausschwärmen haben.

 

Ein weiteres Beispiel für ein Array ist in der Mathematik die sogenannten Matrizenrechnung mit den Elementen der ersten Zeile a11, a12, a13, a14 und der ersten Spalte a11, a21, a31, a41. Dabei gilt es eine wichtige Regel einzuhalten: Erst die Zeile, dann die Spalte! Diese Regel gilt auch bei der Programmierung eines Arrays!

 

Ein weiteres Beispiel ist ein Kreuzworträtsel, wobei aber nur zwischen 1.) waagrecht und 2.) senkrecht  - man achte auf die Reihenfolge! -  unterschieden wird.

 

Im roten Kasten wird zunächst das Array namens <farbe_NeoPixel> mit dem

 

·        Statement <farbe_NeoPixel = []>

 

deklariert und anschließend initialisiert, d.h. mit Daten gefüllt. Dabei machen wir uns bei der Umsetzung das neue

 

·        Statement <strip.set_pixel_color(1, neopixel.colors(NeoPixelColors.WHITE))>

 

wie folgt zu nutze:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_19.py)

 

Wie man im blauen Kasten im obenstehenden Quellkode sieht, wird das Array <farbe_NeoPixel[ ][ ]> in der <for … next>-Schleife mit dem

 

·        Statement <for i in range(4):>

 

entsprechend angewendet und in die farbig leuchtenden NeoPixel umgesetzt.

 

Das Speichern der laufenden Adressnummern (siehe pinkfarbener Kasten oben) der NeoPixel als auch die betreffenden Farben (siehe grüner Kasten oben), die zum Leuchten gebracht werden sollen, lassen sich zwar gut im Array <farbe_NeoPixel> speichern, schaffen aber nicht zwangsläufig eine gut nachvollziehbare und selbsterklärende Struktur. -

 

Spätestens wenn noch ein dritter Parameter für die Helligkeit mit der ein NeoPixel leuchten soll, hinzukommt, wird es mit dem Array <farbe_NeoPixel> unübersichtlich:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_20.py)

 

Wir entwickeln das obenstehende Programm weiter, verzichten aber auf das Array <farbe_NeoPixel[ ]> und legen stattdessen nachfolgende Struktur an, die aus drei Teilen besteht (siehe hellgrüner und roter Kasten):

 

1.     Adressierung bzw. Nummernangabe, welche NeoPixel leuchten sollen
(siehe auch Bild 20),

2.     Farbangabe in welcher Farbe die betreffenden NeoPixel leuchten sollen und

3.     Helligkeitsangabe, wie hell die betreffenden NeoPixel leuchten sollen.

 

Wichtig bei der Programmierung des Standlichts ist noch, dass man am Anfang der Funktion <Standlicht()> die Helligkeit aller NeoPixel auf einen bestimmten Wert wie z.B. <strip.set_brightness(8)> oder <strip.set_brightness(0)> setzt (siehe pinkfarbener Kasten).

 

Ansonsten kann es nämlich passieren, dass noch die Helligkeitswerte des Vorgängerprogramms angezeigt werden, dessen Werte sich noch im Joy-Car“-Mainboard (siehe Bild) des Joy-Car“-Roboters befinden! Diesbezüglich sollte man wissen, dass alle NeoPixel vom Joy-Car“-Mainboard aus inkl. Stromversorgung angesteuert werden!

 

Bezüglich der Programmierung ist noch das

 

·        Statement <if i in (1, 2)>

 

mit der Bedingung in (1, 2) hinzugekommen, demzufolge der nachfolgende Programmkode nach der <if>-Abfrage nur ausgeführt wird, wenn der Schleifenzähler i einen der Werte (1, 2) (siehe grüner Kasten) oder (4, 7) (siehe pinkfarbener Kasten) enthält:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_21.py)

 

 

Warnblink- und Abbiegeblinker

 

Jetzt wo wir bereits das Tagfahrlicht vorn und das Standlicht vorn und hinten als Funktion mittels Wechselschalter zum Ein- und Ausschalten programmiert haben, ist es nicht sehr schwer, das Warnlicht rundum zu programmieren. Dazu muss man nämlich zunächst nur im Hauptprogramm das Standlicht sozusagen im Sekundentakt ein- und ausschalten:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_22.py)

 

Wie man im obenstehenden Quellkode des roten Kastens sieht, wird das Standlicht (vorn weiß und hinten rot) fortwährend ein- und ausgeschaltet. Und, wenn man etwas einschaltet, dann sollte man auch unbedingt wissen, wie man den Flaschengeist, den man aus der Flasche gelassen hat, dort wieder hineinbekommt, nämlich ausschaltet.

 

Und wie man ferner oben im roten Kasten sieht, befindet sich in der <do … while>-Schleife mit dem

 

·        Statement <while schalteStandlicht == True:>

 

noch ein weiteres

 

·        Statement <input.on_logo_event(TouchButtonEvent.PRESSED, Standlicht_schalten)> 7  

 

mittels dem sich durch mehrfaches Berühren der Touch-Schaltfläche (= micro:bit“-Logo) das Standlicht abwechselnd ein- und wieder ausschalten lässt!

 

Demzufolge arbeitet die Touch-Schaltfläche des micro:bit“-Rechners als Wechselschalter mit dem sich das Standlicht abwechselnd ein- und wieder ausschalten lässt:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_22.hex)

 

Wie man außerdem im Quellkode des grünen Kastens sieht, wird zwar die Funktion <Standlicht()> abwechselnd aufgerufen, wobei es aber tatsächlich um das Umschalten der boolesche Variablen <schalteStandlicht> geht, die sich als globale Variable von jederzeit von überall her umschalten lässt!

 

Wenn wir also als nächstes aus dem blinkenden Standlicht einen fortwährenden Orange farbenen Warnblinker programmieren wollen, dann müssen wir den Quellkode aus dem Hauptprogramm (siehe im obenstehenden roten Kasten) in die entsprechende Funktion <Warnblinker_blinkt()> auslagern bzw. kopieren und dabei die Angabe „Standlicht“ durch „Warnblinker“ ersetzen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_23.py)

 

Wie man im obenstehenden Quellkode sieht (siehe pinkfarbener Kasten), heißt die Warnblink-Funktion selbst <Warnblinker_NeoPixel()>. Dabei beträgt das Blinkfrequenz zweimal 500 ms = 1 s, sodass das Blinken weder zu hektisch noch zu langsam ist.

 

Wenn man sich das Programm „joy-car_teil_02_prog_23.hex in den micro:bit“-Rechner lädt, dann startet sich der Warnblinker automatisch und lässt sich durch Berühren der Touch-Schaltfläche (= micro:bit“-Logo) jederzeit beliebig oft wieder aus- oder einschalten!

 

Diesbezüglich stellt sich noch die Frage, um welche spezielle Funktion es sich dabei handelt, die sich selbst fortwährend aufruft bis der Strom ausfällt oder bis man diese mittels der globalen booleschen Variablen <schalteWarnblinker> ausschaltet.

 

Bei genauerem Hinsehen ist es nämlich wider Erwarten nicht die Funktion <Warnblinker_blinkt()> selbst (siehe roter Kasten oben), die „speziell“ ist, sondern deren Funktionsaufruf mit dem

 

·        Statement <basic.forever(Warnblinker_blinkt)>,

 

der dafür sorgt, das der Warnblinker fortwährend blinkt, wenn dieser denn eingeschaltet ist (siehe globale boolesche Variable <schalteWarnblinker> weiter unten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_23.py)

 

Das Funktionsprinzip des Warnblinkers ist also das, dass dieser wegen des Funktionsaufrufs mit dem

 

·        Statement <basic.forever(Warnblinker_blinkt)>,

 

jederzeit blinkbereit ist, vorausgesetzt, dass die boolesche Variable <schalteWarnblinker> wie zuvor im Hauptprogramm auf True gesetzt wurde! Aber mittels des

 

·        Statements <input.on_logo_event(TouchButtonEvent.PRESSED, Warnblinker)> 7  

 

lässt sich der Warnblinker auch jederzeit beliebig oft ein- und ausschalten (siehe blauer Kasten oben und unten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_23.py)

 

Das Besondere und Charakteristische an den beiden Funktionen im roten und blauen Kasten ist, dass sich bei diesen wider Erwarten keine Parameter in den Funktionsköpfen übermitteln lassen. Ebenso lassen sich keine Parameter mittels <return()> an die Programmteile, die die Funktion aufrufen, zurückgeben!

 

 

Ein Fahrzeug verfügt nicht nur über einen Warnblinker, sondern auch über einen Fahrtrichtungsanzeiger. Obwohl es ja tatsächlich zwei Fahrtrichtungsanzeiger sind. Und zwar einer nach rechts zum Rechtsabbiegen und ein weiterer zum Linksabbiegen. Dabei sind beide Fahrtrichtungsanzeiger bis auf die Richtungsanzeige programmiertechnisch identisch, ist das Rechtsabbieger-Programm der Klon (= Kopie) vom Linksabbieger-Programm und umgekehrt.

 

Rechtsabbieger- und Linksabbieger-Programm wiederum sind programmiertechnisch jeweils eine Seite vom Warnblinker-Programm!

 

Wenn wir also den Teil des Warnblinker-Programms nehmen, kopieren und die Bezeichnung „Warnblinker_ im Quellkode durch die Bezeichnung Blinker_rechts_ ersetzen, dann ist schon ein Großteil der Programmierarbeit erledigt.

 

Das Umbenennen selbst bewerkstelligen wir mit dem sogenannten Notepad++“-Editor und der Funktion „Ersetzen“ mit der Menü“-Reihenfolge: <Suchen>, <Ersetzen> und <Alle ersetzen>.

 

Ferner müssen wir in der neuen Funktion <Blinker_rechts_NeoPixel()> noch neu festlegen, welche NeoPixel jeweils auf der rechten und linken Fahrzeugseite leuchten sollen. Dabei gilt es zu beachten, dass moderne Kraftfahrzeuge tagsüber mit weißem Tagfahrlicht und bei Dunkelheit vorn mit weißem und hinten mit rotem Standlicht fahren!

 

Demzufolge muss beim Tagfahrlicht das vordere linke NeoPixel an der Position 1 weiß leuchten (siehe hellblauer Kasten), während das hintere linke NeoPixel an der Position 4 dunkel bleibt (siehe roter Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_24.py)

 

Wenn man das Programm „joy-car_teil_02_prog_24.hex startet, dann stellt man fest, dass das Tagfahrlicht vorn links weiß blinkt. Der Grund dafür ist aber ganz banal, nämlich der, dass das Blinken noch dem Blinkmodus des ehemaligen Warnblinkers bzw. dem Blinken des Rechtsabbieger-Blinkers geschuldet ist.

 

Diesbezüglich stellt sich die Frage, wie man das Blinken des Tagfahrlichtes abstellen bzw. ausschalten kann!

 

Und zwar durch einen Trick, indem man das Tagfahrlicht auch dann blinken lässt, wenn es quasi ausgeschaltet ist bzw. der Rechtsabbieger-Blinker ausgeschaltet ist (siehe grüne Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_25.py)

 

Wenn man sich den obenstehenden Quellkode anschaut, dann fällt auf, dass sich der Programmkode, der sich auf das linke NeoPixel Nr. 1 mit dem weißen Tagfahrlicht bezieht, maßgeblich zusammenfassen und konzentrieren lässt (siehe grüne Kästen oben).

 

Wenn nämlich das linke NeoPixel Nr. 1 mit dem weißen Tagfahrlicht durchgängig, d.h. ohne Unterbrechung leuchten soll, während sich die orangenen NeoPixel Nr. 2 und Nr. 7 als Blinklicht abwechselnd ein- und ausschalten, dann lässt sich der Programmkode, der sich auf das linke NeoPixel Nr. 1 bezieht (siehe grüne Kästen oben), komplett aus der <ifthenelse>-Abfrage <Blinker_rechts_einschalten> wie folgt entfernen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_26.py)

 

Wenn man in der obenstehenden Funktion <Blinker_rechts_NeoPixel()> verschiedene NeoPixel unterschiedlich konfiguriert, dann werden die entsprechenden Konfigurationen erst mit dem nächsten

 

·        Statement <strip.show()>

 

umgesetzt und angewendet! Und zwar unabhängig von der jeweiligen Reihenfolge der Konfiguration!

 

Trotzdem sollte man es sich angewöhnen, die unterschiedlichen Konfigurationen der verschiedenen NeoPixel möglichst stets in einer logischen Abfolge vorzunehmen, wie beispielsweise

 

·        Statement <strip.set_brightness(helligkeit_weisse_NP)>

 

·        Statement <strip.set_pixel_color(linke_NeoPixel, neopixel.colors(weisse_NeoPixel))> .

 

Wir verbessern die obenstehende Funktion <Blinker_rechts_NeoPixel()> dahingehend, indem wir die unterschiedlichen Beleuchtungssituationen zwischen Tagfahrlicht und Standlicht berücksichtigen (siehe rote Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_27.py)

 

Als nächstes bietet es sich an, das obenstehende Programm um die Funktion des Fahrrichtungsanzeigers für das Linksabbiegen zu erweitern. Zu diesem Zweck ist es am einfachsten, wenn man sich den obenstehenden Quellkode im Programm rückwärts mit der Maus markiert, sodass dieser blau markiert erscheint. Dann kopiert man sich den blau markierten Programmkode mittels der Tastenkombination <Strg> & <C> in die Zwischenablage von Windows.

 

Dann starten wir den Notepad++“-Editor, klicken in der obenstehenden Menüleiste auf <Datei>, <Neu>, sodass sich ein neues, leeres Editorfenster öffnet. In dieses fügen wir den Text aus der Windows-Zwischenablage mittels der Tastenkombination <Strg> & <V> wieder ein.

 

In der Menüleiste kann man dann mittels der Tastenfolge <Suchen> & <Ersetzen> alle Ausdrücke „rechts“ durch „links“ sowie „rechte“ durch „linke“ ersetzen. Ersetzt müssen auch die NeoPixel Nr. „(2, 7)“ durch „(1, 4)“ sowie die einzelnen NeoPixel der rechten Seite Nr. „1“ und „4“ durch Nr. „2“ und „7“ auf der linken Seite (vom Fahrer aus gesehen, siehe nachfolgende rote Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_28.py)

 

Damit sich der Fahrtrichtungsanzeiger „nach links abbiegen“ auch einschalten lässt, müssen wir noch die entsprechenden Funktionsaufrufe mit dem

 

·        Statement <input.on_logo_event(TouchButtonEvent.PRESSED, Blinker_links)>

 

·        Statement <basic.forever(Blinker_links_blinkt)>

 

wie folgt programmieren:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_28.hex)

 

Selbstverständlich lässt der Fahrtrichtungsanzeiger „nach links abbiegen“ auch noch anschaulicher demonstrieren, indem man z.B. das Standlicht (= rundum) mittels des

 

·        Statements <schalteStandlicht = True>

 

oder das Tagfahrlicht (= nur vorn) mittels des

 

·        Statements <schalteTagfahrlicht = True>

 

aktiviert! -

 

 

Eine „NeoPixel“-LED ist kein Glühlämpchen

 

Dass eine NeoPixel“-LED kein Glühlämpchen ist, dürfte klar sein. Allein schon deswegen, weil eine NeoPixel“-LED eine digitale Hardware ist, während es sich bei einer Glühlampe um eine analoge Hardware handelt.

 

Demzufolge lässt sich eine analoge Glühlampe sowohl mit Gleich- als auch mit Wechselspannung betreiben. Dabei ist aber das Entscheidende, dass sich in einem Stromkreis mit nur einem Schalter immer nur eine Hardware ein- oder ausschalten lässt. Dabei kann es sich bei der analogen Hardware um nur eine Glühlampe oder auch mehrere, parallel geschaltete Glühlampen handeln.

 

Früher gab es z.B. in den Wohnzimmern oftmals Deckenlampen mit bis zu fünf Leuchtmitteln in Form von Kerzen oder Kugel förmigen Glühlampen, wobei sich diese meistens mittels zweier Wippschalter an der Wand in einer Zweiergruppe und/oder Dreigruppe schalten ließen, sodass sich die Helligkeit von minimal 2 Glühlampen über 3 Glühlampen bis maximal 5 Glühlampen einstellen ließ. Bei Kugel förmigen, kleinen Glühlampen kam man dabei auf insgesamt 5 * 40 Watt Leistung/Glühlampe auf insgesamt = 200 Watt Gesamtleistung, sodass sich das Wohnzimmer, wenn es sein musste, ziemlich hell ausleuchten ließ.

 

Würde man bei einer solchen 5-„flammigenDeckenleuchte alle analogen Glühlampen, die ja aus Gründen der Energieverschwendung schon seit Jahren in Europa verboten sind, durch smarte, farbige LED-Kugellampen ersetzen, dann ließe sich jede einzelne mittels Smartphone-App (oder Fernbedienung) einzeln ansteuern, d.h. ein- und ausschalten bzw. sich individuell in den Farben, den Farbtönen und der Helligkeit ändern.

 

Damit aber der Anwender nicht jede smarte LED-Lampe einzeln steuern und regeln muss, lassen sich bei der Smarthome-Vernetzung mehrere solche smarten LED-Lampen zu einem einzigen Leuchtmittel zusammenfassen, d.h. gruppieren, sodass die Einstellungen für Farbe und Helligkeit für alle Leuchtmittel gemeinsam, d.h. synchron, vorgenommen werden.

 

Und jetzt sind wir schon bei den NeoPixel“-LEDs angekommen. Demzufolge verfügt der Joy-Car“-Roboter über acht einzelne NeoPixel“-LEDs, wobei sich jede NeoPixel“-LED einzeln oder auch in einer Gruppe steuern und regeln lässt. Dabei ist mit „ansteuern“ die digitale Adressierung und mit „regeln“ das Einstellen von Helligkeit, Farbe oder einer Farbkombination von RGB (= Rot, Grün, Blau) gemeint:

 

·        Statement <neopixel.rgb(100, 35, 0)>

 

·        Statement <set_pixel_color( n, neopixel.colors(neopixel.rgb(100, 35, 0))) >

 

·        Statement <neopixel.colors(NeoPixelColors.RED)>

 

·        Statement <set_pixel_color( n, neopixel.colors(NeoPixelColors.RED))>

 

·        Statement <strip.show_color(neopixel.colors(NeoPixelColors.RED))>

 

·        Statement <set_brightness(8)>

 

Bevor man aber Farbeinstellungen usw. vornehmen kann, muss man die NeoPixel“-LEDs initialisieren:

 

·        Statement <neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

Und an dieser Stelle fangen die Probleme mit den NeoPixeln an. Im vorstehenden Statement werden nämlich insgesamt 8 NeoPixel adressiert, sodass alle nachfolgenden Statements auf diese 8 NeoPixel angewendet werden. Wenn dann aber nachfolgend ein

 

·        Statement <set_pixel_color( 3, neopixel.colors(NeoPixelColors.RED))>

 

auf nur das einzelne NeoPixel Nr. 3 angewendet wird, bleiben die anderen NeoPixel davon unberührt. Und das kann im einen oder anderen Fall zu ganz erstaunlichen, unverständlichen und nicht nachvollziehbaren Effekten führen.

 

Nachfolgend geht es konkret darum, herauszufinden, weshalb die beiden Programmteile mit den Tastern A und B im Programms „joy-car_teil_02_prog_12.py einwandfrei funktionieren,

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_12.py)

 

während diese jetzt im Programm „joy-car_teil_02_prog_28.py nicht mehr richtig funktionieren!

 

Um das obenstehende Programm „joy-car_teil_02_prog_12.py besser verstehen zu können, specken wir dieses ab, indem wir die

 

·        Funktion <NeoPixel_anzeigen(NeoPixel_anzeigen)>

 

einfacher gestalten und im Funktionskopf nur noch einen Parameter, nämlich die lokale Variable <NeoPixel_anzeigen>) verwenden, die wiederum mit der gleichnamigen Funktion <NeoPixel_anzeigen(NeoPixel_anzeigen)> nichts zu tun hat:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_29.py)

 

Wenn man das obenstehende Programm startet und auf den Taster A drückt, dann bekommt man zunächst die Laufschriftanzeige „->a1“ und „->a2“ angezeigt, bevor die Funktion <NeoPixel_anzeigen(True)> aufgerufen wird. Als nächstes wird dann die Laufschriftanzeige „->n1“, „->n2“ und „->n3“ angezeigt, bevor die grüne „NeoPixel“-LED aufleuchtet.

 

Die grüne „NeoPixel“-LED lässt sich wiederum durch erneutes Drücken des Tasters A ausschalten. Dabei wird dann die Laufschriftanzeige „->a1“ und „<-a3“ angezeigt (siehe oben).

 

In diesem Zusammenhang stellt sich noch die Frage, ob der Quellkode im hellblauen Kasten gebraucht wird oder nicht (siehe oben)!

 

Wenn man das obenstehende Programm startet und auf den Taster A drückt, dann wird die Funktion <NeoPixel_anzeigen(True)> aufgerufen und ausgeführt, sodass die grüne „NeoPixel“-LED aufleuchtet. Anschließend wird das Statement <NeoPixel_anzeigen = False> ausgeführt, das aber noch zur <if>-Abfrage des Statements <if NeoPixel_anzeigen == True:> gehört, sodass die <if>-Abfrage damit beendet ist und das Programm im blauen Kasten mittels des Statements <return(NeoPixel_anzeigen)> wieder an die Stelle des aufrufenden Programmteils <anzeigen_NeoPixel = NeoPixel_anzeigen(True)> zurückkehrt (siehe grüner Kasten oben). Demzufolge wird der Programmkode im hellblauen Kasten oben nicht erreicht, d.h. nicht ausgeführt, sodass dieser weggelassen werden kann!

 

Das nächste Programm „joy-car_teil_02_prog_30.hex basiert auf dem Vorgängerprogramm. Allerdings wurde ein wichtiges Statement weggelassen, das das Verhalten des Programms maßgeblich beeinflusst. Um herauszufinden, um welches Statement es sich dabei handelt, muss man das Programm starten und das entsprechende Verhalten beobachten.

 

Nach dem Programmstart leuchten sofort die vorderen vier NeoPixel“-LEDs rot auf. Und zwar noch bevor der Programmname „Prog_30“ angezeigt wird (siehe roter Kasten). Dabei sorgt das

 

·        Statement <strip = neopixel.create(DigitalPin.P0, 4, NeoPixelMode.RGB)>

 

dafür, dass die ersten vier NeoPixel“-LEDs als RGB-farbige LEDs deklariert und nachfolgend initialisiert werden, sodass diese mit der Helligkeit 8 in Rot leuchten (siehe roter Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_30.py)

 

Wenn man dann als nächstes den Taster A drückt, dann wird an der Position 2 (siehe Bild 20) der vorderen vier NeoPixel“-LEDs sofort die NeoPixel“-LED Nr. 2 von Rot auf Grün umgeschaltet. Dabei leuchten die verbleibenden drei NeoPixel“-LEDs weiterhin in Rot. Der Grund dafür ist der, dass es in der Funktion <NeoPixel_anzeigen(NeoPixel_anzeigen)> kein weiteres

 

·        Statement <strip = neopixel.create(DigitalPin.P0, 4, NeoPixelMode.RGB)>

 

gibt, sodass die bisherige Deklaration der NeoPixel“-LEDs weiterhin bestehen bleibt. Mit Ausnahme der grün leuchtenden NeoPixel“-LED Nr. 2., denn deren Farbe wurde ja von Rot auf Grün geändert (siehe hellgrüner Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_30.py)

 

Wenn man also in der obenstehenden Funktion <NeoPixel_anzeigen(NeoPixel_anzeigen)> auf die Deklarierung mittels des

 

·        Statements <strip = neopixel.create(DigitalPin.P0, 4, NeoPixelMode.RGB)>

 

verzichtet, dann bleibt die bisherige Deklarierung und Initialisierung im Hauptprogramm (siehe roter Kasten) unverändert erhalten!

 

 

Bei den älteren Windows“-Betriebssystemen wie z.B. Windows 3.1, Windows 95 usw. von Microsoft gab es gelegentlich eine Fehlermeldung beim Einschalten und Hochfahren des Windows-Rechners, die immer dann auftrat, wenn versehentlich keine Tastatur an den PC angestöpselt war. Sie lautete sinngemäß: „Es ist keine Tastatur angeschlossen! Drücken Sie bitte [die Funktionstaste] F1.“

 

DAUs würden das natürlich sofort machen, auf der Tastatur die Funktionstaste F1 drücken, dann die Kundenhotline anrufen und sich beschweren, dass das Ganze nicht funktioniert.

 

Technik affine Computeranwender wissen natürlich, dass alle herkömmlichen PC-Tastaturen drei Kontrollleuchten in Form kleiner LEDs haben, nämlich für „Num“ (= numerische Tastatur zur Zahleneingabe), „Shift“ (= Umschalttaste für dauerhaftes Schreiben in Großbuchstaben) und „Rollen“ (= Herauf- oder Herunterscrollen, z.B. im Fenster der „Eingabeaufforderung“ im Konsolemodus). Beim Einschalten und Hochfahren des PCs leuchten diese drei LEDs kurz auf, aber eben nur dann, wenn eine entsprechende PC-Tastatur angeschlossen ist! -

 

Wenn man noch sarkastischer ist, könnte man dem DAU auch empfehlen sich einen neuen Rechner zu kaufen, falls weiterhin keine Tastatur an den Windows-PC angeschlossen ist. Und zwar in Form eines Notebooks, weil Notebooks bis jetzt immer über eine Tastatur verfügen. Im Gegensatz zu Tablet-PCs, die nur über eine einblendbare Touch“-Tastatur verfügen, die mit den Fingern bedient werden muss.

 

Was aber hat das alles mit dem

 

·        Statements <strip = neopixel.create(DigitalPin.P0, 4, NeoPixelMode.RGB)>

 

zu tun? Ganz einfach! Das Statement ist so etwas wie eine Art „Eier legende Woll-Milch-Sau. Ein Alleskönner, der immer dann angewendet wird, wenn nichts mehr geht, wenn keine NeoPixel“-LEDs mehr leuchten oder blinken!

 

Obwohl es noch ein weiteres, mächtiges Werkzeug zu den NeoPixel“-LEDs gibt. Um das herauszufinden muss man beim Programm „joy-car_teil_02_prog_30.hex beim Leuchten der grünen „NeoPixel“-LED und der anderen drei rot leuchtenden NeoPixel“-LEDs nur die Taste B drücken, sodass alle vier leuchtenden NeoPixel“-LEDs ausgeschaltet werden. Allerdings leuchtet die grüne „NeoPixel“-LED beim erneuten Drücken der Taste B wieder auf! Aber nur die grüne „NeoPixel“-LED ganz für sich allein!

 

Jetzt wissen wir, dass sich die grüne „NeoPixel“-LED mittels der Taste B immer wieder ein- oder ausschalten lässt! Aber nicht nur das! Der Grund dafür, weshalb zuvor die anderen drei rot leuchtenden NeoPixel“-LEDs ausgeschaltet wurden, findet sich im nachfolgenden Programmkode im hellgrünen Kasten:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_30.py)

 

Fragen wir zu Abwechselung wieder die KI von ChatGPT:

 

 

(Vergrößern: auf das Bild klicken! | Quelle: OpenAI, ChatGPT)

 

Wenn das, was ChatGPT herausgefunden hat, stimmt, dann werden nur die Elemente(!) der strip“-Liste, d.h. die Elemente der Liste mit den NeoPixel“-LEDs, gelöscht, nicht aber die leere strip“-Liste physisch als Ganzes.

 

Dass die leere strip“-Liste physisch nicht als Ganzes gelöscht wird, lässt sich sogar beweisen bzw. zeigen, indem im obenstehenden Programm „joy-car_teil_02_prog_30.hex nach dem Programmstart abwechselnd den Taster A (= 1.), den Taster B (= 2.) und wieder den Taster A (= 3.) betätigt.

 

Hätten nämlich die beiden Statements im obenstehenden hellgrünen Kasten die strip“-Liste komplett, d.h. auch physisch gelöscht, dann ließe sich die grüne „NeoPixel“-LED weiter oben im hellgrünen Kasten nicht ein weiteres Mal zum Leuchten bringen!

 

In diesem Zusammenhang gibt es noch ein weiteres, interessantes Phänomen. Starte dazu das Programm „joy-car_teil_02_prog_31.hex und finde heraus, weshalb sich die grüne „NeoPixel“-LED jetzt nicht mehr zum Leuchten bringen lässt. Und zwar egal, welche der Tasten A oder B man betätigt!

 

Tipp: Der Programmierfehler lässt sich leicht herausfinden, indem man den Quellkode der beiden Programm „joy-car_teil_02_prog_30.py und joy-car_teil_02_prog_31.py miteinander vergleicht. Und zwar den im Hauptprogramm (siehe roter Kasten unten).

 

Auch wenn wir wieder eine Menge über das Programmieren der NeoPixel“-LEDs gelernt haben, so haben wir dennoch im Zusammenhang mit dem Programm „joy-car_teil_02_prog_28.py oder joy-car_teil_02_prog_30.py noch nicht gelernt, worin sich die Taster A und B vom Touch-Panel (= Antippen/Berühren des micro:bit“-Logos – siehe Bild 17)

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_30.py)

 

nun tatsächlich bzw. maßgeblich unterscheiden! Dabei gilt es zunächst festzustellen, dass sich alle drei Statements zu den Tastern A und B sowie zum Touch-Panel (siehe blauer Kasten) im statischen Hauptprogramm (siehe roter Kasten) befinden!

 

Also nichts von wegen endloser Wiederholung der Programmausführung bei Funktionen usw.:

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

Aber auf welche der drei Statements zu den Tastern A und B sowie zum Touch-Panel (siehe blauer Kasten) lässt sich das

 

·        Statement <basic.forever(Name der Funktion)>

 

denn nun tatsächlich fehlerfrei anwenden?

 

Man höre und staune: nur auf das Touch-Panel, da es sich bei diesem um einen Ereignis gesteuerten Sensor handelt.

 

Wenn man die anderen beiden Taster A und B mit in die dynamische Programmierung bzw. das Ereignis gesteuerte Programmierung einbinden will, dann muss man deren Statements nebst weiterer Auslöse- und Reaktions-Funktionen innerhalb des sich endlos wiederholenden Programmblocks <basic.forever()> platzieren:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_32.py)

 

Eigentlich verhält es sich so, dass sich die beiden Taster A und B Ereignis gesteuert verhalten und demzufolge verzögerungsfrei und sofort reaktiv verhalten, sodass sich diese jederzeit betätigen lassen. Demzufolge wäre es eigentlich nicht erforderlich, diese explizit in die Funktion <on_forever()> aufzunehmen (siehe rosaroter Kasten). Später, wenn beide Fahrrichtungsanzeiger, d.h. die beiden Blinker rechts und links, ordnungsgemäß funktionieren, werden wir deshalb nochmals die Frage nach der „real time“-Funktion (= Echtzeitverhalten) der beiden Taster A und B aufgreifen. –

 

Auch wenn das Programm „joy-car_teil_02_prog_32.py noch nicht so funktioniert, wie es letztlich funktionieren soll, so bietet es trotzdem noch einen weiteren Erkenntnisgewinn. Und zwar den einer sogenannten „Do … while“-Schleife, die es so in Python  - im Gegensatz zu anderen, höheren Programmiersprachen -  nicht gibt.

 

Mal sehen was das neue „ChatGPT 4.0“ mit der KI von Open AI in der neuen bing“-Suchmaschine von Microsoft dazu heraus findet:

 

 

(Vergrößern: auf das Bild klicken! | Bing“-Suchmaschine mit KI " Chat)

 

Dabei handelt es sich bei der „Do … while“-Schleife um eine fußgesteuerte Endlos“-Schleife, die so oft „im Kreis“ läuft bis der Strom ausfällt oder die Abbruchbedingung <schalteBlinker_rechts = False> erfüllt ist (siehe roter Kasten):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_32.py)

 

Obwohl wir jetzt wissen, wie man eine fußgesteuerte „Do … while“-Schleife programmiert und den Vorteil zu schätzen wissen,

 

·        dass diese auf jeden Fall mindestens einmal durchlaufen wird und sich mittels

 

·        der Abbruchbedingung <if input.button_is_pressed(Button.A)>

 

jederzeit beenden lässt, verhält es sich dennoch so, dass diese nicht mit der endlosen Wiederholung in Echtzeit der Funktion <on_forever()>

 

 

(Zum Vergrößern bitte auf das Bild klicken!)

 

vergleichbar ist.

 

Wenn man nämlich das Programm „joy-car_teil_02_prog_32.hex startet und mittels einer die beiden Taster A oder B den Fahrrichtungsanzeiger (= Blinker) entweder nach links (= Taster B) oder nach rechts (= Taster A) auslöst, dann schaltet sich dieser sofort verzögerungsfrei ein und beginnt zu blinken, weil die beiden Taster A oder B innerhalb der Funktion <on_forever()> fortwährend abgefragt werden!

 

Anders verhält es sich hingegen, wenn man den Blinker mittels eines der entsprechenden Taster A oder B wieder ausschalten will, da das Ausschalten nicht direkt, sondern nur indirekt über die globale, boolesche Variable <schalteBlinker_rechts> oder die globale, boolesche Variable <schalteBlinker_links> erfolgt!

 

Demzufolge erfolgt das Ausschalten des Blinkers entweder sofort oder aber nur verzögert nach längerem Drücken eines der entsprechenden Taster A oder B, je nachdem in welcher Funktion sich das Programm gerade befindet. Im ungünstigen Fall kann das dann schon mal einen andauernden Tastendruck von mehr als einer Sekunde erfordern:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_32.py)

 

Wenn man später bei dem Joy-Car“-Roboter die Bewegung, insbesondere das Abbiegen nach links oder rechts, programmieren will, dann kann man für den Abbiegevorgang den im micro:bit“-Rechner integrierten Kompass für die jeweilige Richtungsänderung hinzuziehen und das Setzen des Fahrrichtungsanzeigers (= Blinker) automatisch veranlassen. Und sobald der Joy-Car“-Roboter die eingeschlagene Richtung für ein paar Sekunden beibehält, kann man wiederum den Blinker automatisch ausschalten.

 

Denkbar wäre aber auch, dass der Joy-Car“-Roboter immer nur dann eine Richtungsänderung nach links oder rechts vornehmen kann, wenn zuvor der Blinker entsprechend per Taster A oder B gesetzt wurde. Damit man nicht jedes Mal bei der geringsten Richtungsänderung den Blinker vorher setzen muss, kann man die Richtungsänderung vom eingeschlagenen Lenkradeinschlag bzw. Lenkwinkel abhängig machen.

 

Denkbar wäre aber auch, dass sich der Blinker immer erst dann automatisch ein- oder ausschaltet, wenn die Änderung des Lenkwinkels mehr als 30 Grad beträgt.

 

Demzufolge wäre bei allen Richtungsänderungen nebst Lenkwinkeleinschlag, dass sich der Blinker je nach Programmierung auf jeden Fall ohne Zeitverzögerung, d.h. in Echtzeit aktivieren oder deaktivieren lässt! Das ist dann auch der Grund dafür, weshalb wir die fußgesteuerte „Do … while“-Schleife wieder aus dem obenstehenden Programm entfernen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_33.py)

 

Wie man im obenstehenden Programmkode sieht, wird der Blinkvorgang jetzt nur noch ein einziges Mal durchgeführt (siehe roter Kasten).

 

Da der Blinkvorgang aber so lange andauern soll bis der Taster A (= rechts blinken aus Fahrersicht) zwecks Ausschaltens ein weiteres Mal gedrückt wird, muss man sich um das wiederholte Blinken selbst kümmern bzw. dieses in der Funktion <on_forever()> explizit programmieren. Und zwar für beide Taster A und B (siehe rote Kästen):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_33.hex)

 

Spätestens jetzt dürfte man die Endlosschleife der Funktion <on_forever()> in Echtzeit zu schätzen wissen!

 

Selbstverständlich lässt sich die Standard-Funktion <on_forever()> auch im logischen Sinnzusammenhang mit der Blinker-Funktion wie folgt umbenennen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_34.py)

 

Wie man im obenstehenden Sourcecode sieht, gehört die umbenannte Funktion <rechts_links_Blinken()> in den Funktionsteil des Programms und nicht in das Hauptprogramm. Schließlich geht es darum, das Hauptprogramm möglichst kompakt und übersichtlich zu halten.

 

Das Programm „joy-car_teil_02_prog_34.hex funktioniert bis auf einen Schönheitsfehler einwandfrei. Dabei handelt es sich bei dem Schönheitsfehler wider Erwarten nicht um einen herkömmlichen Programmier- oder Syntaxfehler, sondern vielmehr um einen, teils logischen, Verständnisfehler, der wiederum eher mit der logischen Abfolge des Blinkvorganges an sich zu tun hat. Aber um welchen logischen Verständnis- und Denkfehler handelt es sich dabei eigentlich? Wie macht sich der Schönheitsfehler überhaupt bemerkbar?

 

Wenn man das obenstehende Programm startet, dann wird als Erstes das Tagfahrlicht gestartet, sodass die vorderen NeoPixel-LEDs Nr. 1 und 2 weiß und die hinteren NeoPixel-LEDs Nr. 4 und 7 rot leuchten.

 

Wenn man dann den Rechts- oder Links-Blinker per Tastendruck einschaltet, dann müssen dazu die entsprechenden NeoPixel-LEDs Nr. 1 und 4 beim Linksblinken (= Taster B) oder die NeoPixel-LEDs Nr. 2 und 7 beim Rechtsblinken (= Taster A) aus- und umgeschaltet werden.

 

Dabei macht sich beim Rechtsblinken (= Taster A) der Schönheitsfehler in der Form bemerkbar, dass beim Ein- und Ausschalten der orangenen NeoPixel-LED Nr. 2 ein unangenehmes weißes Aufblitzen störend bemerkbar macht:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_34.hex)

 

Das unangenehme weiße Aufblitzen (siehe mittleres Bild) lässt sich aber auch ausschalten,

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_34.hex)

 

indem man durch Berühren des Touch-Sensors (siehe Bild 17) das Stand- oder Tagfahrlicht einfach deaktiviert, d.h. ausschaltet!

 

Damit wäre bewiesen, dass es zwischen den obenstehenden Funktionen

 

1.     Funktion <Blinker_links_blinkt(schalte_Ein_Aus)>,

2.     Funktion <Blinker_rechts_blinkt(schalte_Ein_Aus)> und der

3.     Funktion <Standlicht(schalteStandlicht)> oder auch der

4.     Funktion <Tagfahrlicht(schalteTagfahrlicht)>

 

hinsichtlich des unangenehmen weißen Aufblitzens einen Zusammenhang gibt! Und zwar den, dass die beiden Funktionen 1.) und 2.) jeweils die im <else>-Programmteil enthaltenen Funktionsaufrufe 3.) und 4.) aufrufen und diese miteinander funktional verschachteln.

 

Da das unangenehme und störende weiße Aufblitzen wider Erwarten nicht beim Linksblinken auftritt, können wir die Funktion 1.) als Fehlerursache ausschließen.

 

Des Weiteren können wir die Funktionen(!) 3.) und 4.) ebenfalls als Fehlerursache ausschließen, da weder beim Tagfahrlicht noch beim Standlicht ein weiß leuchtendes Aufblitzen programmiert wurde.

 

Und überhaupt, was bedeutet denn der Vorgang des Aufblitzens beim Leuchten des Lichts?

 

Es bedeutet nichts anderes als dass der Lichtstrahl bzw. das Licht fortwährend unterbrochen wird, so als würde der Lichtstrahl von einer rotierenden Lochkranzscheibe wie beim analogen Filmprojektor ständig, d.h. periodisch wiederkehrend, ein- und ausgeschaltet wird. Und da es bei den NeoPixel“-LEDs und deren Leuchtbefehlen keine Statements oder Funktionen zum Aufblitzenlassen der LEDs gibt, kann es sich bei dem weiß leuchtenden Aufblitzen auch nicht um einen Programmierfehler im Sinne eines speziellen NeoPixel“-Befehls handeln.

 

Wenn es aber keinen NeoPixel“-Befehl zum Aufblitzen, kurzen Aufleuchten oder dem Blinken z.B. für das Links- oder Rechtsabbiegen gibt, wie programmiert man dann das Blinken einer oder mehrerer NeoPixel“-LEDs?

 

Ganz einfach ähnlich wie bei einer Taschenlampe, d.h. einer modernen, elektronischen Taschenlampe, die z.B. anstelle eines herkömmlichen Ein-/Aus-Schiebe- oder eines Drucktasten-Schalters über einen Multifunktionstaster verfügt mit dem sich u.a. die Helligkeit einer oder mehrerer, weißer LEDs in bis zu drei Stufen einstellen lässt. Darüber hinaus sollte diese auch über eine Tasterfunktion zum Morsen, d.h. zum schnellen Ein- und Ausschalten des Lichts verfügen, sodass sich mit dieser auch kurze Lichtblitze erzeugen lassen.

 

Wie aber lassen sich solche oder ähnliche Lichtblitze nebst des schnellen Ein- und Ausschaltens einzelner oder mehrerer NeoPixel“-LEDs programmieren, obwohl es doch keinen einzelnen NeoPixel“-Befehl gibt?

 

Keine Sorge, wir müssen die Lichtblitze nicht explizit programmieren, da wir diese bereits programmiert haben! Allerdings sind diese Lichtblitze ziemlich träge und noch dazu langsam. Demzufolge „blitzen“ die Lichtblitze mit einer langsamen, symmetrischen Blitzfrequenz von fBlitz = 1 Hz, d.h. einer Schwingung pro Sekunde. Dabei gilt: fBlitz = 1 / TBlitz oder

 

TBlitz     = 1 / fBlitz

 

            = 1 / 1 Hz = 1 / ( 1 Schwingung/s ) = 1 s   "   T = Periodendauer

 

Wie man sieht, ist dabei eine (Rechteck-) Schwingung mit n = 1 dimensionslos:

 

TBlitz     = n / fBlitz = 1 / 1 Hz = 1 s

 

Dabei ist die langsame Blitzfrequenz im vorliegenden Fall symmetrisch, weil die Leuchtdauer des Blitzes (= Einschaltdauer tEin) zeitlich eben so lang ist wie die Leuchtpause (= Ausschaltdauer tAus).

 

Demzufolge berechnet sich die Leucht- bzw. Impulsdauer t (= griechischer Buchstabe Tau) des Blitzes wie folgt:

 

t        = D * T   "   D = Tastgrad bzw. Tastverhältnis zwischen Ein- und Ausschaltzeit

 

D       = t / T

 

         = 500 ms / 1 s = 0,500 s / 1 s = 0,5   "   50 %

 

Wie man unschwer sieht, beträgt das Tastverhältnis D zwischen Ein- und Ausschaltzeit (=t / T )

 

 

(Vergrößern: auf das Bild klicken! | Wikipedia „Rechtecksignal)

 

tatsächlich 50 % oder 500 ms:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_35.py)

 

Das symmetrische Tastverhältnis D zwischen Ein- und Ausschaltzeit (=t / T ) von 50 % hat den Vorteil, dass das relativ langsame Blinken des Fahrtrichtungsanzeigers (= Blinker) im Sekundentakt als angenehm und nicht als aggressiv empfunden wird.

 

Während also das langsame Blinken des Fahrtrichtungsanzeigers (= Blinker) über ein symmetrische Tastverhältnis D zwischen Ein- und Ausschaltzeit (=t / T ) von 50 % verfügt, kann man das von dem unangenehmen weißen Aufblitzen nicht behaupten.

 

Da aber das störende und unangenehm weiße Aufblitzen ebenfalls im Sekundenrhythmus aufblitzt, muss es zwangsläufig über den Programmkode mit den Zwangspausen, der damit verbundenen Periodendauer T = 1 s und den Statements <basic.pause(500)> laufen (siehe grünes und rotes Fenster im Bild oben).

 

Allerdings erfolgt das Aufblitzen mit einem wesentlich kürzeren und vor allem asymmetrischen Tastverhältnis, was ja gerade den Blitzeffekt, ähnlich eines Foto- oder Gewitterblitzes, ausmacht.

 

Gemäß dem obenstehenden Programmkode muss dabei das unangenehme und störend weiße Aufblitzen zeitlich nach dem roten Blinken des Fahrtrichtungsanzeigers für das Rechtsabbiegen erfolgen. Wegen der Trägheit des menschlichen Auges lässt sich aber die zeitliche Abfolge und Reihenfolge des Blinkvorgangs und des Aufblitzens wider Erwarten nicht nachvollziehen.

 

Was es aber an dieser Stelle und in diesem Zusammenhang noch aufzuklären gilt, ist der Umstand, dass das unangenehme und störend weiße Aufblitzen nur bei der NeoPixel“-LED Nr. 2 auftritt, obwohl sich das Tagfahr- oder Standlicht entsprechend der Programmierung auf beide NeoPixel“-LEDs Nr. 1 und Nr. 2 bezieht! Und genau dieser Umstand ist es, der die erfolgreiche Fehlersuche praktisch unmöglich macht!

 

Was also tun? Um bei der Fehlersuche trotzdem erfolgreich zu sein, muss man die unterschiedlichen Lichter und Lichteffekte von Tagfahr- und Standlicht sowie vom Rechts- und Linksblinken unterscheidbar machen, indem man diesen unterschiedliche Farben zuweist! Demzufolge bekommt das Standlicht nicht mehr die Farbe Weiß zugewiesen, sondern die Farbe Blau! Außerdem wird das orangefarbene Blinklicht für das Rechtsblinken der NeoPixel“-LED Nr. 2 in der Funktion <Blinker_rechts_NeoPixel(Blinker_rechts_einschalten)> kurzerhand mit (7, 7) anstelle von vormals (2, 7) ausgeschaltet:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_35.hex)

 

Wenn man jetzt das obenstehende Programm startet, dann stellt man fest, dass jetzt das Standlicht nicht mehr wie zuvor weiß, sondern vielmehr blau leuchtet. Wenn man dann den Taster A drückt, um das Rechtsabbiegen zu signalisieren, dann stellt man ferner fest, dass das Standlicht jetzt plötzlich blau aufblitzt! Und zwar bei beiden NeoPixel“-LEDs der Nr. 1 (= links) und Nr. 2 (= rechts) aus Fahrersicht.

 

Dabei verhält es sich ferner so, dass das orangefarbene Blinklicht für das Rechtsblinken der NeoPixel“-LED Nr. 2 nicht mehr blinkt, da dieses zuvor abgeschaltet wurde (siehe rote Kästen im Bild oben), während das hintere orangefarbene Blinklicht für das Rechtsabbiegen der NeoPixel“-LED Nr. 7 weiterhin wie gehabt, blinkt. Schaltet man das Rechtsblinken mittels des Tasters A wieder aus, verschwindet das blaue Aufblitzen wieder!

 

Mittels des Touch-Sensors (siehe Bild 17) lässt sich das Stand- oder Tagfahrlicht jederzeit beliebig oft aus- oder wieder einschalten und auf diese Weise der Effekt des blauen Aufblitzen verdeutlichen!

 

Jetzt wird auch verständlich, weshalb man das unangenehm weiße Aufblitzen beim Rechtsblinken der NeoPixel“-LED Nr. 1 auf der linken Fahrerseite nicht sehen konnte!

 

Und zwar deshalb, weil man das Aufblitzen der linken NeoPixel“-LED Nr. 1 auf der linken Fahrerseite wegen der gleichen weißen Farbe wie beim Stand- oder Tagfahrlicht bisher nicht sehen konnte!

 

Wahnsinn, da muss man erst mal drauf kommen!

 

Wenn man also etwas sehen will, was man sonst nicht sieht, weil beide Anzeigen (= Funktion <Standlicht()> und Funktion <Blinker_rechts_blinkt()> ) ein- und dieselbe NeoPixel“-LED-Farbe verwenden, dann muss man für beide Anzeigen unterschiedliche NeoPixel“-LED-Farben verwenden und, wenn das blaue Aufblitzen kürzer als ein Wimpernschlag ist, dann muss man wegen der Trägheit des menschlichen Auges zwecks besserer Erkennbarkeit eine der beiden Anzeigen vorübergehend ausschalten/deaktivieren (siehe roter, abgewinkelter Pfeil im grünen Kasten im obenstehenden Screenshot). Aber das alles erklärt noch nicht das blaue Aufblitzen an sich!

 

Was aber bedeutet es praktisch bzw. technisch, wenn eine NeoPixel“-LED aufblitzt, d.h. ganz kurz aufleuchtet?

 

Das ganz kurze Aufleuchten einer NeoPixel“-LED bedeutet programmiertechnisch, dass die LED ganz kurz ein- und gleich darauf wieder ausgeschaltet wird (siehe Bild 61). Dabei gibt es aber einen wesentlichen Unterschied bei den beiden Anzeigen. Während das Rechtsblinken der NeoPixel“-LED Nr. 2 auf der rechten Fahrerseite im Sekundentakt erfolgt, erfolgt das blaue Aufblitzen im Bereich einiger Millisekunden (= 1/1000 Sekunden)! Aber weshalb?

 

Knackpunkt ist, dass wir es mit zwei Anzeigen (= Funktion <Standlicht()> und Funktion <Blinker_rechts_blinkt()> ) zu tun haben, die nacheinander ablaufen, wobei sich das blaue Aufblitzen auf den Vorgang und die Funktion <Standlicht()> bezieht. Wenn man also das Programm „joy-car_teil_02_prog_35.hex startet, dann wird als erstes das blaue Standlicht eingeschaltet und anschließend auf Tastendruck des Tasters A das Blinklicht für das Rechtsabbiegen. Dabei gilt es zu beachten, dass das Standlicht dauerhaft angezeigt wird, gleichzeitig aber vom Blinklicht unterbrochen wird! Und die Unterbrechung des Blinklichts ist es schließlich, die das blaue Aufblitzen des Standlichts zur Folge hat!

 

Wenn man also das blaue Aufblitzen des Standlichts vermeiden will, dann muss man

 

1.     das Standlicht vor und während des Blinkens für das Rechtsabbiegen ausschalten oder

2.     das Standlicht mit dem Blinklicht „überschreiben“!

 

Da sich die Fehlersuche nach dem blauen Aufblitzen sehr komplex gestaltet, gehen wir jetzt sehr stringent vor, indem wir einzelne Funktionen, die mit dem Standlicht und dem Rechtsblinken zu tun haben, nacheinander gegen intakte, funktionierende Funktionen auswechseln bzw. „auskommentieren“.

 

Doch zunächst gehen wir auf Nummer sicher und kommentieren die anfangs übrig gebliebenen Funktionen wie folgt aus:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_36.py)

 

Da das Auskommentieren des orangefarbenen Quellkodes im roten Kasten im obenstehenden Screenshot bezüglich des blauen Aufblitzens ohne Auswirkung blieb, tauschen wir als nächstes alle Funktionen nebst Funktionsaufrufen aus, die mit dem Standlicht zu tun haben:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_37.py)

 

Wie man im obenstehenden Quellkode sieht, wird die globale Variable <schalteStandlicht> bei beiden Funktionen <Standlicht_schalten()> von <True> auf <False> und umgekehrt umgeschaltet. Weiter nichts. Während bei der alten, auskommentierten orangefarbenen Funktion dem Funktionsaufruf <Standlicht()> lediglich der statische Wert <True> mit auf den Weg gegeben wird, wird bei der neuen Funktion <Standlicht_schalten()> der dynamische Wert der Variablen <schalteStandlicht> übergeben, der je nachdem entweder <True> oder <False> sein kann.

 

Aber zwischen der alten, auskommentierten orangefarbenen Funktion und der neuen Funktion <Standlicht_schalten()> gibt es noch einen weiteren, programmiertechnischen und funktionalen Unterschied. Bei der alten Funktion wird die Funktion <Standlicht(True)> aufgerufen und wegen des Rückgabestatements <return(Standlicht_einschalten)> auch definitiv ausgeführt! Dabei wird der Rückgabewert im Statement <return(Standlicht_einschalten)> an die globale Variable <schalteStandlicht> übergeben. Bei der neuen Funktion <Standlicht_schalten()> wird die Funktion <Standlicht(schalteStandlicht)> ebenfalls aufgerufen und ausgeführt, der eventuell geänderte Rückgabewert im Statement <return(Standlicht_einschalten)> aber nicht an die globale Variable <schalteStandlicht> übergeben, sodass es bei dem zugewiesenen Variableninhalt <schalteStandlicht = False> bleibt.

 

Demzufolge kann es bei der alten, auskommentierten orangefarbenen Funktion passieren, dass sich der Variableninhalt der globalen Variablen <schalteStandlicht> wider Erwarten nicht von <True> auf <False> ändert (und umgekehrt), weil das Rückgabestatement <return(Standlicht_einschalten)> im ungünstigen Fall und mehr oder weniger zufällig den gleichen Wert <True> oder <False> zurückliefert, sodass der boolesche Umschalter mit der globale Variablen <schalteStandlicht> nicht wie erwartet funktioniert!

 

Wir nehmen diese neue Programmiererkenntnis zum Anlass und ändern bei dieser Gelegenheit die auch die Funktion <Tagfahrlicht_schalten()>

 

Da die Funktion <Standlicht_schalten()> nur in Verbindung mit dem Touch-Sensor und dem Statement <input.on_logo_event(TouchButtonEvent.PRESSED, Standlicht_schalten)> gebraucht wird, steht diese in keinem Zusammenhang mit dem blauen Aufblitzen der vorderen NeoPixel“-LEDs.

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_38.py)

 

Wie bereits erwähnt, dient die globale Variable <Standlicht_einschalten> dazu, den Status des Standlichts von <False> auf <True> und umgekehrt umzuschalten oder einfach nur dazu, diesen festzuhalten und abfragen zu können. Demzufolge bedeutet der Statuswechsel von <False> auf <True> nicht zwangsläufig, dass dieser Wechsel auch tatsächlich sofort ausgeführt wird und sich das Standlicht einschaltet!

 

Vielmehr verhält es sich so, dass der Statuswechsel von <False> auf <True> erst dann umgesetzt wird, wenn die Funktion <Standlicht(Standlicht_einschalten)> irgendwann mehr oder weniger zufällig oder gezielt ausgeführt wird. Genaueres über den Zeitpunkt des Statuswechsels weiß man aber nicht!

 

Wenn es aber darauf ankommt, dass der Statuswechsel von <False> auf <True> sofort umgesetzt wird, dann muss man die Funktion <Standlicht(Standlicht_einschalten)> mit der globalen Variablen <Standlicht_einschalten> = <True> explizit, d.h. unverzüglich aufrufen:

 

·        Statement <Standlicht_einschalten = True>

·        Statement <Standlicht(Standlicht_einschalten)>

 

Wenn man darüber hinaus auch den Rückgabewert mit dem

 

·        Statement <return(Standlicht_einschalten)>

 

auswerten will, dann muss das Statement für das Standlicht wie folgt lauten:

 

·        Statement  <Standlicht_einschalten = Standlicht(Standlicht_einschalten)>

 

Dabei wird dann nicht nur die Funktion <Standlicht(Standlicht_einschalten)> unverzüglich ausgeführt, sondern auch der Wert der globalen Variablen <Standlicht_einschalten> an das aufrufende Programm, hier also die Funktion <Standlicht_schalten()> oder an das Hauptprogramm, zurückgeliefert! -

 

 

In diesem Zusammenhang muss noch erwähnt werden, dass sich das Standlicht mit der Funktion <Standlicht(Standlicht_einschalten)> jeweils im Wechsel ein- und ausschalten lassen soll (siehe rote Unterstreichung im obenstehenden Programmkode). Demzufolge darf der Statuswechsel von <True> auf <False> nur in der <else>-Bedingung erfolgen (siehe im obenstehenden Screenshot)!

 

Insgesamt verhält es sich so, dass die Funktion <Standlicht(Standlicht_einschalten)> keinen Einfluss auf das blaue Aufblitzen der vorderen NeoPixel“-LEDs hat! -

 

Die neue Funktion <Blinker_rechts()> unterscheidet sich gegenüber der alten Funktion <Blinker_rechts()> nur dahingehend, dass sich die Reihenfolge vom Umschalten der globalen Variablen <schalteBlinker_rechts> von <False> auf <True> ändert:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_39.py)

 

Dies ist dem Umstand geschuldet, dass das Rechtsblinken mit der Status-Variablen <schalteBlinker_rechts> im Hauptprogramm mittels des

 

·        Statements <schalteBlinker_rechts = False>

 

auf den Anfangsstatus <False> gesetzt wurde!

 

Dabei gilt es zu beachten, dass eine boolesche Variable wie die boolesche Variable <schalteBlinker_rechts> immer von Anfang an auf einen bestimmten Zustand <True> oder <False> gesetzt werden sollte, damit es bei der weiteren Programmierung früher oder später nicht zu einem unerwarteten Statuswechsel kommt, der die Funktionstüchtigkeit des gesamten Programms beeinträchtigt und in Frage stellt!

 

Abschließend verhält es sich so, dass die Funktion <Blinker_rechts()> keinen Einfluss auf das blaue Aufblitzen der vorderen NeoPixel“-LEDs hat! -

 

Die neue Funktion <Blinker_rechts_blinkt(schalte_Ein_Aus)> unterscheidet sich gegenüber der alten Funktion <Blinker_rechts_blinkt(schalte_Ein_Aus)> dahingehend, dass auf das wiederholte Aufrufen des Tagfahrlichtes oder des Standlichtes verzichtet wurde (siehe roter Kasten). Und zwar aus dem einfachen Grund, um unterschiedliche Funktionen nicht miteinander zu vermischen, sondern strikt voneinander zu trennen!

 

Darüber hinaus macht es wenig Sinn, die NeoPixel“-LEDs Nr. 2 und 7 auf der rechten Seite des Joy-Car“-Roboters dunkel zu schalten (siehe blauer Kasten), wenn diese Konfiguration gleich darauf von dem aktivierten und wieder eingeschalteten Standlicht (oder Tagfahrlicht) überschrieben wird:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_40.py)

 

Da es in der <else>-Bedingung nur darum geht, das Rechtsblinken nach dem Einschalten wieder ausschalten zu können, sodass sich der Taster A als Wechseltaster zum Ein- und Ausschalten verwendet lässt, würde man normalerweise die NeoPixel“-LEDs als Ganzes komplett ausschalten. Beispielsweise mit dem

 

·        Statement <JoyCar.light(ToggleSwitch.OFF)>

 

oder mit den Statements

 

·        Statement <strip.clear()>

·        Statement <strip.show()>

 

Aber genau das verbietet sich im vorliegenden Fall, weil zwar das Rechtsblinken ausgeschaltet werden soll, gleichzeitig aber die Anzeigen der NeoPixel“-LEDs als Ganzes wieder in den Modus „Standlicht“ (oder „Tagfahrlicht“) zurückfallen soll! Und zwar verzögerungsfrei, ohne größere Pause und vor allem ohne dass die NeoPixel“-LEDs in irgendeiner Weise aufblitzen! Deshalb gehen wir auf Nummer sicher, nehmen die Helligkeit , engl. „brightness“, aus allen NeoPixel“-LEDs heraus und wechseln zusätzlich noch die NeoPixel“-Farbe auf Schwarz (siehe grüner Kasten oben).

 

Wendet man das Programm „joy-car_teil_02_prog_40.hex praktisch an, indem man dieses startet, dann stellt man fest, dass auch die neue Funktion <Blinker_rechts_blinkt(schalte_Ein_Aus)> keinen Einfluss auf das blaue Aufblitzen der vorderen NeoPixel“-LEDs hat! -

 

Als nächstes knöpfen wir uns die alte Funktion <rechts_links_Blinken()> vor, indem wir diese wie folgt auskommentieren und durch die neue Funktion <rechts_links_Blinken()> ersetzen.

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_41.py)

 

Wie man im obenstehenden Quellkode sieht, wird die globale Variable <schalteBlinker_rechts> bei beiden Funktionen <rechts_links_Blinken()> von <True> auf <False> und umgekehrt umgeschaltet. Weiter nichts. Während bei der alten, auskommentierten orangefarbenen Funktion dem Funktionsaufruf <rechts_links_Blinken()> lediglich der statische Wert <True> mit auf den Weg gegeben wird, wird bei der neuen Funktion <rechts_links_Blinken()> der dynamische Wert der Variablen <schalteBlinker_rechts> übergeben, der je nachdem entweder <True> oder <False> sein kann.

 

Gemäß dem

 

·        Statement <basic.forever(rechts_links_Blinken)>

 

im Hauptprogramm ist die Funktion <rechts_links_Blinken()> die einzige im Programm, die nach dem Programmstart fortwährend, d.h. endlos bis zum Stromausfall ausgeführt wird.

 

Dabei dient die Endlos“-Funktion <rechts_links_Blinken()> dazu, die beiden Taster A und B und den Touch-Sensor mit dem Statement <input.on_logo_event(TouchButtonEvent.PRESSED, Standlicht_schalten)> permanent, d.h. ununterbrochen aufzurufen und abzufragen, ob diese ggf. betätigt wurden.

 

Außerdem dient die Endlos“-Funktion <rechts_links_Blinken()> dazu, dass sich die Funktionen

 

·        <Blinker_rechts_blinkt(schalteBlinker_rechts)>,

·        <Blinker_links_blinkt(schalteBlinker_links)>,

·        <Warnblinker_blinkt(schalteWarnblinker)> und

·        <Standlicht_schalten()>

 

per Tastendruck bzw. Berühren, engl. „touch“, ähnlich einem einpoligen Wechselschalter im Flur oder Treppenhaus wechselseitig von <True> auf <False> und umgekehrt hin- und herschalten lassen, sodass zum Ein- oder Ausschalten kein zweiter Schalter oder Touch-Sensor benötigt wird!

 

Wendet man das Programm „joy-car_teil_02_prog_41.hex praktisch an, indem man dieses startet, dann stellt man fest, dass auch die neue Funktion <rechts_links_Blinken()> keinen Einfluss auf das blaue Aufblitzen der vorderen NeoPixel“-LEDs hat! -

 

So, nun bleibt bezüglich der Fehlersuche nach der Ursache für blaue Aufblitzen nur noch die Funktion <Blinker_rechts_NeoPixel(Blinker_rechts_einschalten)> übrig. Diesbezüglich erinnern wir uns an den Vorsatz, nur noch Funktionen zu programmieren, die keine anderweitigen Funktionalitäten wie z.B. das Konfigurieren von diversen NeoPixel“-LEDs für das Tagfahrlicht oder Standlicht vorzunehmen!

 

Demzufolge werden alle Programmteile, die mit dem Konfigurieren diverser NeoPixel“-LEDs für das Tagfahrlicht oder Standlicht zu tun haben, auskommentiert (siehe organgefarbenen Text):

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_42.py)

 

Auch das abschließende Umschalten der booleschen Variablen <Blinker_rechts_einschalten> von <True> auf <False> und umgekehrt, wird auskommentiert (siehe blauer Kasten), da dieses bereits in der Endlos“-Funktion <rechts_links_Blinken()> erfolgt. Zu guter Letzt werden noch ein paar kleine Korrekturen vorgenommen (siehe rote Unterstreichung).

 

Wenn man das Programm „joy-car_teil_02_prog_42.hex startet, dann stellt man fest, dass die auskommentierten Programmteile keinen Einfluss auf das blaue Aufblitzen der vorderen NeoPixel“-LEDs haben! -

 

Damit die Funktion <Blinker_rechts_NeoPixel(Blinker_rechts_einschalten)> (siehe oben) übersichtlicher wird, entfernen wir alle zuvor auskommentierten, orangefarbenen Programmzeilen, sodass nur noch der nachfolgende Sourcecode übrig bleibt:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_43.py)

 

Wir starten das neue Programm „joy-car_teil_02_prog_43.hex, um zu überprüfen, ob dies noch ordnungsgemäß funktioniert und stellen dabei fest, dass das blaue Aufblitzen der vorderen NeoPixel“-LEDs noch immer besteht!

 

Als letzte Maßnahme sozusagen, kommentieren wir

 

·        die alte Funktion <Blinker_rechts_NeoPixel(Blinker_rechts_einschalten)>

 

aus und fügen unterhalb deren Stelle die

 

·        die neue Funktion <Blinker_rechts_NeoPixel(Blinker_rechts_einschalten)>

 

wie folgt ein:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_44.py)

 

Beim Vergleich der alten, auskommentierten Funktion mit der neuen Funktion (siehe im Bild oben), fällt sofort auf, dass das

 

·        Statement <strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

in der neuen Funktion nicht mehr vorkommt (siehe pinkfarbener Kasten oben im Bild)!

 

Wenn man das neue Programm „joy-car_teil_02_prog_44.hex startet, dann stellt man nicht nur fest, dass dieses ordnungsgemäß funktioniert, sondern auch, dass das blaue Aufblitzen der vorderen NeoPixel“-LEDs plötzlich nicht mehr auftritt!

 

Jetzt wo der Fehler, der das blaue Aufblitzen der vorderen NeoPixel“-LEDs verursachte, gefunden ist, räumen wir das Programm „joy-car_teil_02_prog_44.py auf, indem wir alle auskommentierten Programmteile, die mit dem Standlicht und dem Rechtsblinken zu tun haben, löschen. Dabei bleiben aber die Programmteile in den Zeilen 12 bis 65 mit den Funktionen

 

·        NeoPixel_anzeigen(),

·        on_button_pressed_a(),

·        on_button_pressed_b()

 

weiterhin erhalten, werden also nicht gelöscht (siehe Programm „joy-car_teil_02_prog_45.py)!

 

Im Zusammenhang mit dem fehlerhaften blauen Aufblitzen der vorderen NeoPixel“-LEDs muss noch erwähnt werden, dass das ursprüngliche, fehlerhafte

 

·        Statement <strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

nur durch das korrekte

 

·        Statement neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)>

 

hätte ersetzt bzw. eingetastet werden müssen:

 

 

(Vergrößern: auf das Bild klicken! | Programm „joy-car_teil_02_prog_45.py)

 

Weiter zum [ Teil 2b ] mit der Objekt orientierten Programmierung (OOP).

 

 

 

[ Home ] [ Seitenanfang ] [Teil 1 ] [ Teil 2b ] [ Teil 3 ]