|
[ Proxi-Roboter
] [ Seitenende ] [ Montage 1 ] [ Coding 1 ] |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
KOSMOS – der programmierbare Proxi-Roboter Auf dem
Weg zur komfortablen Stoppuhr Es geht nach wie vor um die Programmierung des
Proxi-Roboters. Und zwar die der Fortbewegung.
Dabei mussten wir die Erfahrung machen, dass die Fortbewegung des Roboters in
Form von bis zu 60 kleinen Schritten à 60 Winkeln pro „Tortenstück“
eines 3600 Vollkreises
des Antriebmotors, in der zeitlichen Folge von 20 ms/60 pro Einzelschritt wegen möglicher Spannungsschwankungen bei der Stromversorgung
mittels „Micro USB 2.0“-Kabel ziemlich ungenau war (siehe Sprungmarke). Als wesentlich präziser
stellte sich hingegen die Zeiterfassung mittels Stoppuhr heraus, sodass es später
besser ist, die Fortbewegung des Proxi-Roboters
anhand von präzisen Zeitintervallen, die dann einer bestimmten Schrittzahl
zugeordnet wird, vorzunehmen. Obwohl sich mit dem Programm des Projektes „proxi-roboter-p-01“
jetzt mit der Stoppuhr auch mehrere Zeitintervalle nacheinander
erfassen lassen, verhält es sich dennoch so, dass sich mittels der Taste <Taster A>
immer nur die gesamte Zeitdauer aller einzelnen Zeitintervalle anzeigen lässt. Der Grund dafür ist der,
dass beim Erfassen der Startzeit immer der zuerst gestoppte Zeitstempel der
Array-Variablen <zeitdauer_Array> mit
dem Array-Index = 0
zugewiesen wird und der zuletzt gestoppte Zeitstempel der Array-Variablen <zeitdauer_Array> mit
dem höchsten Array-Index.
Und zwar deshalb, weil es im Programm
so programmiert wurde: (Zum
Vergrößern bitte auf das Bild klicken!) Wenn man sich auch für die Zeitstempel als
Zwischenwerte
interessiert, dann muss man das vorherige Programm entsprechend
umprogrammieren. Beim Programm des Projektes „proxi-roboter-p-02“
werden zwar auch nur der zuerst gestoppte Zeitstempel der Array-Variablen <zeitdauer_Array> mit
dem Array-Index = 0 und
der zuletzt gestoppte Zeitstempel der Array-Variablen
<zeitdauer_Array> mit
dem höchsten Array-Index
gespeichert, aber im
Gegensatz zum Vorgängerprogramm lassen sich nun auch die in der Array-Variablen <zeitdauer_Array> zwischengespeicherten Zeitstempel rückwärts durch mehrmaliges
Drücken des Tasters <Knopf A> der
Reihe nach abrufen:
Wie aber kommt es, dass es
zwischen dem gestoppten Start-Zeitstempel und
dem Stopp-Zeitstempel
insgesamt 8 zunächst versteckte Zeitstempel gibt, obwohl mittels
des Tasters <Knopf B> nur
zwei Messwerte, nämlich der Anfangs- und Endwert der gestoppten Zeit, aufgenommen wurden?
Und wie man anhand der
obenstehenden Tabelle sieht,
erfolgt mit ∆tTakt = 20 ms
alle zwanzig Millisekunden eine Zeitmessung nebst Speicherung in der Array-Variablen
<zeitdauer_Array>,
obwohl diese seitens der Programmierung
gar nicht beabsichtigt ist!
Offensichtlich wird das
Ganze aber nur, weil das Statement
im Programm des Projektes „proxi-roboter-p-02“ absichtlich
weggelassen wurde: (Zum
Vergrößern bitte auf das Bild klicken!) Wenn man oben in der Tabelle
vom maximalen Zeitwert = 10,35 ms mit dem Index 8 den
Mittelwert = 10,29
ms subtrahiert, dann kommt man auf die restlichen 60 ms von
insgesamt 100 ms für die Gesamtdauer der Zeitaufnahme. Diesbezüglich muss noch
erwähnt werden, dass die Zeitdauer von 10 s 29/100 = 10,29 s100 mit
der Stoppuhr auf dem Smartphone gestoppt wurde! Im Programm des Projektes „proxi-roboter-p-03“
wurde das Statement wieder hinzugefügt, (Zum
Vergrößern bitte auf das Bild klicken!) damit die 40 ms die
der Prozessor benötigt, um den Interrupt in Echtzeit(!) auszuführen nicht die Zeitmessung wie
bei der obenstehenden Tabelle
mit dem Mittelwert von
7,72 ms
verfälschen. Wie man anhand der
nachfolgenden Tabelle im Programm
des Projektes „proxi-roboter-p-03“
sieht, beträgt die Zeitdauer zwischen der ersten (Index 1) und der letzten (Index 4) Zeitmessung
insgesamt = 10,34 s – 10,28 s = 0,06 s = 60 ms:
Rechnet man die 40 ms die
der Prozessor benötigt, um das Statement mittels Interrupt in Echtzeit(!)
auszuführen, hinzu, dann ergeben sich in
der Summe wieder die 100 ms für das Zeitfenster der Zeitmessung. Diesbezüglich muss noch erwähnt
werden, dass die Zeitdauer von 10 s 32/100 = 10,32 s100 mit
der Stoppuhr auf dem Smartphone gestoppt wurde! Selbstverständlich lässt
sich der Mittelwert aller im Array
der Variablen <zeitdauer_Array> gespeicherten
Zeitwerte
auch mittels entsprechender Programmierung
berechnen. Dazu muss man einfach nur die manuell zu bedienende Schleife
namens Taster <Knopf A> im grünen Kasten weiter unten auswerten.
Denn mit jedem Druck auf den Taster <Knopf A>
wird mittels der Funktion <anzeigen_stoppzeit> ein
weiterer Wert der Variablen <zeitdauer_Array> ausgelesen
und im LED-Display angezeigt.
Dabei ist das Statement sozusagen der Schleifenkopf,
wobei es sich bei der manuell zu bedienenden Schleife
namens Taster <Knopf A> um
eine kopfgesteuerte
Schleife handelt. Diesbezüglich dient die Variable <lfd_index_Array> im Statement als Schleifenzähler,
der wiederum bei jedem Schleifendurchlauf um -1
heruntergezählt wird bis die Schleife bei Null angekommen ist und mittels der beiden Statements wieder von vorne rückwärts(!)
zu zählen beginnt (siehe grüner Kasten im Programm des Projektes „proxi-roboter-p-03“):
(Zum
Vergrößern bitte auf das Bild klicken!) Damit sich gleich alle
im Array der Variablen <zeitdauer_Array> gespeicherten Zeitwerte bei
den Schleifendurchläufen
auch aufsummieren lassen, müssen wir uns bei jedem Funktionsaufruf der
Funktion <anzeigen_stoppzeit> den
entsprechend gespeicherten Zeitwert des Arrays der
Variablen <zeitdauer_Array> an
die manuell zu bedienenden Schleife namens Taster <Knopf A> im grünen Kasten mittels des Statements in der Funktion <anzeigen_stoppzeit> (Zum
Vergrößern bitte auf das Bild klicken!) zurückliefern lassen (siehe grüner Kasten im obenstehenden Screenshot).
Mit der Erweiterung der Funktion <anzeigen_stoppzeit>
lassen sich nun die von der Funktion
zurück gelieferten einzelnen Zeitwerte des Arrays der Variablen <zeitdauer_Array> mit
jedem Schleifendurchlauf (= Schleifenzähler-Variable <loop_Counter>)
auch entsprechend aufsummieren: Dabei gilt es zu beachten,
dass das Aufsummieren der eingelesenen Zeitwerte
mittels der eigenen Schleifenzähler-Variable
<
loop_Counter > erfolgt. Aus welchem Grund, werden wir gleich noch
erfahren. Um nun den Mittelwert der
von der erweiterten Funktion <anzeigen_stoppzeit>
eingelesenen und aufsummierten Zeitwerte berechnen zu können, muss man nur noch den letzten,
aufsummierten Gesamtwert der Variablen <add_zeitdauer_Timer>
durch die Anzahl (= Variable <loop_Counter>)
der eingelesenen und aufsummierten Zeitwerte dividieren: Selbstverständlich darf der Mittelwert der
eingelesenen und aufsummierten Zeitwerte erst dann berechnet und in der Variablen <mittelwert_Array> gespeichert
werden, wenn das Array der Variablen <zeitdauer_Array> vollständig
abgearbeitet und eingelesen wurde. Dies ist dann der Fall, wenn die Variable <lfd_index_Array> den
Wert < 1
angenommen hat: (Zum
Vergrößern bitte auf das Bild klicken!) Wie bereits weiter oben
erläutert, kann es vorkommen, dass die ersten zwei oder drei Zeitstempel Werte im Bereich von 20 ms, 40 ms
oder sogar 60 ms enthalten, die später bei der Mittelwertbildung
dazu führen, dass dieser falsch berechnet wird:
Demzufolge müssen alle
erfassten und gespeicherten Zeitstempel dahingehend überprüft werden, ob diese nicht wider
Erwarten Einzelwerte < 0,1 s
angenommen haben! Demzufolge dürfen also nur Zeitstempel der Variablen <zeitdauer_Timer> größer
als 0,1 s (= 100 ms) in die Berechnung
des Mittelwertes
einfließen (siehe grüner Kasten): (Zum
Vergrößern bitte auf das Bild klicken!) Das ist dann übrigens auch
der Grund dafür, weshalb die innere Zählschleife für das Aufsummieren der
einzelnen Zeitstempel der Variablen <zeitdauer_Timer>
ihre eigene Schleifenzähler-Variable
<loop_Counter>
bekommt. Es sollten nämlich
nur diejenigen Zeitstempel für die Mittelwertbildung herangezogen werden, deren Einzelwerte größer als 0,1
s (= 100 ms) sind! So jetzt haben wir es gleich
geschafft! Was jetzt noch fehlt, ist die Programmierung von der halbautomatischen
Berechnung des Mittelwertes der Variablen <mittelwert_Array> auf die vollautomatische
Mittelwertberechnung,
damit man den Taster <Knopf A> nur
noch ein einziges Mal betätigen muss: (Zum
Vergrößern bitte auf das Bild klicken!) Der grün
umrahmte Programmkode bezeichnet eine
sogenannte kopfgesteuerte <for …
next>-Schleife,
die so oft durchlaufen wird bis die Abbruchbedingung erfüllt bzw. komplett
abgearbeitet wurde. Dabei verhält es sich so,
dass der interne Schleifenzähler mit der internen Variablen <Index> der grünen <for … next>-Schleife
beim Anfangswert index = 0
beginnt und dann inkrementell,
d.h. jeweils in Einserschritten gemäß
der Rechenvorschrift index = index + 1
(Kurzform: index++) bis zum Erreichen der Abbruchbedingung index
< max_index_Array hoch zählt. Demzufolge gibt es im Kopf der grünen <for … next>-Schleife
insgesamt drei Parameter
als da sind:
In der höheren Programmiersprache JavaScript sieht der Quellkode dann folgendermaßen aus: (Zum
Vergrößern bitte auf das Bild klicken!) Während also die grüne <for … next>-Schleife vorwärts
nach oben zählt, wird gleichzeitig das Array
<zeitdauer_Array> mit
seinen Elementen und den jeweiligen Zeitstempeln rückwärts von
oben nach unten, engl. „top down“, mit dem Statement quasi gegenläufig
abgearbeitet. Werfen wir abschließend noch
einen Blick auf das Programm des Projektes „proxi-roboter-p-04“,
das inzwischen nicht nur sehr umfangreich, sondern auch teils komplex geworden
ist: (Zum
Vergrößern bitte auf das Bild klicken!) Wer zwischenzeitlich gut
aufgepasst hat, dem wird aufgefallen sein, dass beim obenstehenden Programm nachträglich noch zwei Statements hinzugefügt wurden (siehe
im grünen Kasten). Der Grund dafür ist der,
dass sich der berechnete Mittelwert M aller Zeitstempel des Arrays <zeitdauer_Array> mit
jedem Tastendruck auf den Taster <Knopf A> verdoppelte,
weil die beteiligten Variablen im grünen Kasten vor jedem erneuten Schleifendurchlauf nicht
auf Null gesetzt wurden! Wenn man will, kann man
abschließend noch den Programmteil
zur Berechnung
des Mittelwertes wie folgt in eine weitere Funktion auslagern (siehe Programm des Projektes „proxi-roboter-p-05“):
(Zum
Vergrößern bitte auf das Bild klicken!)
Aus diesem Grund verzichte
ich ab sofort auf die Berechnung
des Mittelwertes und
arbeite stattdessen nur mit dem ersten Stoppwert im Array <zeitdauer_Array>, sodass sich nun die Funktion <anzeigen_Zeitdauer> entsprechend
vereinfacht (siehe Programm im Projekt „proxi-roboter-p-06“):
(Zum
Vergrößern bitte auf das Bild klicken!) Diesbezüglich sei nochmals
daran erinnert, dass sich die Zählvariable
<lfd_index_Array> im grünen Kasten mit dem Statement nicht auf
die grüne
Zählschleife bezieht, sondern auf das Zeitstempel-Array <zeitdauer_Array> und dessen Rückgabe-Variable <zeitdauer_Timer> der
Funktion <anzeigen_Stoppzeit>. Trotzdem verfügt die grüne Zählschleife (Zum
Vergrößern bitte auf das Bild klicken!) über ihren eigenen Schleifenzähler,
der wiederum nur für die Dauer aller Schleifendurchläufe gültig ist! Und wenn man
sich den Programmkode in der Microsoft | micro:bit Entwicklungsumgebung wie folgt in JavaScript anzeigen
lässt, dann sieht man sofort, dass die <Index>-Variable zur grünen <for … next>-Schleife
gehört: (Zum
Vergrößern bitte auf das Bild klicken!)
Jetzt wo wir wissen, dass es
seitens der Programmierung in Microsoft „MakeCode“ oder der höheren Programmiersprache „JavaScript“
insbesondere bei kopf- oder fußgesteuerten Zählschleifen standardmäßig immer
eines Schleifenzählers
namens der lokalen <Index>-Variablen
bedarf, können wir diese auch innerhalb der grünen <for … next>-Schleife
anderweitig für das Zählen oder Indexieren anderer Variablen oder Arrays verwenden: (Zum
Vergrößern bitte auf das Bild klicken!) Wie man im obenstehenden Sourcecode sieht man,
dass der Schleifenzähler der grünen <for … next>-Schleife in
Form der Variablen <Index> bei
Null beginnt. Das gilt auch für Arrays, deren einzelnen Elemente ebenfalls beim Index Null
beginnen. Nehmen wir als Beispiel ein Metermaß, d.h.
einen Zollstock der Länge l = 1 m = 100 cm mit Zentimetereinteilung, sodass
es n = 100 Elemente der Länge 1 cm gibt. Auch der Zollstock beginnt bei
0 cm. Demzufolge würde das erste Element n = 1 der Länge 1 cm bei Index = 0
beginnen und das letzte Element n = 100 beim Index = 99, sodass gilt: Index =
Länge l – 1 = 100 – 1 = 99 als größter Index.
Aber es geht noch weiter,
kommt es noch „dicker“. Nämlich bei der grünen <for … next>-Schleife mit
der Zählvariablen <Index>,
die ebenfalls bei Index = 0 beginnt, sodass der Schleifenindex wiederum bei Index nmax = Länge
lZählschleife - 1 endet: Index nmax = Länge
lZählschleife - 1 = (
max_index_Array ) - 1
= ( zeitdauer_Array - 1 )
- 1 = zeitdauer_Array - 2 Siehe roter Pfeil von „0“ bis
„2“ im nachfolgenden
Screenshot: In der obenstehenden grünen <for … next>-Schleife des
Programms im Projekt „proxi-roboter-p-07“
gilt es noch zu beachten, dass die Schleifenzähler-Variable <Index> auch beim Aufruf der Funktion <anzeigen_Stoppzeit>
verwendet wird und dabei das erste Arrayfeld
beim Array-Index(!) = 0
startet, sodass zum aktuellen Schleifenzähler-Index(!)
jeweils eine +1 addieren muss: (Zum
Vergrößern bitte auf das Bild klicken!) Nachfolgend noch das Programm zum Projekt „proxi-roboter-p-07“
im Überblick: (Zum
Vergrößern bitte auf das Bild klicken!) Wie wir inzwischen wissen,
handelt es sich bei der grünen <for … next>-Schleife in
der Funktion <anzeigen_Zeitdauer> des
obenstehenden Programms mit dem Microsoft „MakeCode“ tatsächlich um eine
„echte“ <for …
next>-Schleife
vergleichbar z.B. mit der höheren Programmiersprache
„JavaScript“
(siehe Bild
29). In JavaScript
und in anderen höheren Programmiersprachen aber lässt es sich mit der <for … next>-Schleife
nicht nur vom Startwert Index = 0 an
bis zum Maximalwert Index <=
zeitdauer_Array.length - 2 hoch zählen, sondern
auch vom Maximalwert bis Null herunterzählen! Beispiel Wenn man im Freibad vom
Fünf-Meter-Sprungturm ins Wasser springen will, dann muss man erstmal auf den
Sprungturm die Leiter hinauf steigen, bevor man dann ins Wasser springen
kann. Logisch. Unerfahrene und ängstliche Schwimmer zählen dann beim
Hinaufsteigen die Anzahl der Stufen der Leiter des Fünf-Meter-Sprungturms, um
sich abzulenken und keine Panik aufkommen zu lassen. Wenn der unerfahrene und
ängstliche Schwimmer schließlich oben angekommen ist, das Sprungbrett
vorsichtig betritt und in die Tiefe blickt, dann kann es sein, dass ihn
plötzlich der Mut verlässt und er wieder den Fünf-Meter-Sprungturm rückwärts
herunter steigt. Dabei zählt er dann beim Herunterklettern erfurchtsvoll die
Stufen der Leiter, um rechtzeitig zu wissen, wann er unten angekommen ist und
wieder festen Boden unter seinen Füßen hat. Dabei ist es der Sprungturmleiter egal, ob der ängstliche
Schwimmer beim Heruntersteigen die Stufen rückwärts von oben nach
unten zählt oder nicht. Da man das Rückwärtszählen mangels
Praxis nicht so gewohnt ist, und man sich deshalb dabei konzentrieren muss,
kann man natürlich auch von oben nach unten vorwärts zählen, was
gewohnheitsgemäß einfacher ist. Wenn ich aber beim Vorwärtszählen rechtzeitig
wissen will, ob ich schon unten auf dem festen Boden angekommen bin, dann
muss ich zuvor die Stufenanzahl des Fünf-Meter-Sprungturms in Erfahrung
gebracht haben, um zu wissen, wann ich beim Herabsteigen der Sprungturmleiter wieder festen Boden unter den
Füßen habe. Aber es gibt natürlich noch
eine dritte Variante, die Stufenanzahl des
Fünf-Meter-Sprungturms beim Herabsteigen zu zählen. Ich nenne diese Methode
mal das indirekte Zählen, weil bei dieser auch gerechnet wird! Wie aber
geht diese Methode bei der nicht nur gezählt, sondern auch gerechnet wird? Nehmen wir mal an, dass der
unerfahrene und ängstliche Schwimmer tagsüber in der 45. Etage der
Europäischen Zentralbank (EZB) in Frankfurt a.M. arbeitet und dazu meistens
mit dem Fahrstuhl fährt. Dazu muss man wissen, dass es in Frankfurt a.M.
jährlich einen Wettbewerb für Treppensteiger gibt. Nämlich denn sogenannten „SkyRun“. Das
aber nur nebenbei. Eines Tages verspätet sich der
unerfahrene und ängstliche Schwimmer früh morgens auf dem Weg zur Arbeit in
der EZB, besteigt leicht außer Atem und mit Schweißperlen auf der Stirn den
Fahrstuhl und drückt hastig auf den Knopf mit der 45. Etage. Die Türen schließen sich, der
Fahrstuhl fährt nach oben und zählt aber beim Hochfahren wider Erwarten nicht
das laufende Stockwerk an, sondern die verbleibende Anzahl
Stockwerke bis zum Erreichen der
45. Etage, weil dies für den Verspäteten den Vorteil bietet, dass er
schneller einschätzen kann, wie lange er noch braucht, um in die 45. Etage zu
gelangen! Frage: Wie muss die <for … next>-Schleife in Microsoft „MakeCode“ programmiert werden,
damit die Stockwerkanzeige die verbleibende(!) Anzahl Stockwerke
anzeigt, die noch zurückgelegt werden müssen bis die 45. Etage erreicht wird?
Hilfestellung: Die Stockwerksanzeige
beginnt bei Null (= Erdgeschoß). Mit dem Microsoft „MakeCode“ lässt sich keine <for … next>-Schleife
programmieren, die mit dem <Index>-Schleifenzähler rückwärts
zählt! Die Auflösung befindet sich wie gehabt zwischen den beiden Markierungen >> … << . >> Wenn der unerfahrene und ängstliche Schwimmer früh morgens
auf dem Weg zur Arbeit in der EZB den Fahrstuhl betritt und hastig auf den
Knopf mit der 45. Etage drückt, dann weiß das Fahrstuhlprogramm mit der
Fahrstuhlsteuerung in dem Moment, dass das Stockwerk Nr. 45 angefahren werden
soll. Außerdem weiß das Fahrstuhlprogramm, dass sich der Fahrstuhl im
Erdgeschoss mit der Stockwerk Nr. 0 befindet. Da sich mit dem
Microsoft „MakeCode“ keine <for … next>-Schleife programmieren
lässt, die mit dem <Index>-Schleifenzähler rückwärts zählt, muss
die <for … next>-Schleife ganz normal von Index = 0 bis Index <=
max_zahl_Stockwerke ganz normal hoch zählen und dabei den Schleifenzähler
Index jeweils um +1 erhöhen: for (let Index = 0; Index <= max_zahl_Stockwerke; Index++) { … } Während also
die <for … next>-Schleife hoch zählt, muss gleichzeitig die
Stockwerkanzeige von ganz oben (= 45. Etage) schrittweise um jeweils -1 nach
unten bis auf Null (= 0. Etage Erdgeschoß) wie folgt zählen: for (let Index = 0; Index <= max_zahl_Stockwerke; Index++) { … … aktuelles_Stockwerk = max_zahl_Stockwerke - Index … }
Durch Mausklick
auf den Link
kann man sich den Quellkode zum Programm des Projekts „proxi-roboter-p-08“
anschauen. << Wir machen uns die
Erfahrung, nämlich wie man eine aufwärts zählende <for … next>-Schleife zum
Herunterzählen bringt, zu nutze und wenden diese auf das Programm zum Projekt „proxi-roboter-p-09“
an: (Zum
Vergrößern bitte auf das Bild klicken!) Das man im Schleifenkopf der
<for … next>-Schleife von
der Länge des
Arrays <zeitdauer_Array>
insgesamt 2 subtrahieren muss, wurde bereits weiter oben im Tutorial
geklärt. Wie aber sieht es mit der <Index>-Variablen und
der <lfd_index_Array>-Variablen aus,
die sich nämlich nur dann berechnen lassen, wenn man konkret z.B. von einem <zeitdauer_Array> der
Array-Länge = 6 ausgeht. Da das Array <zeitdauer_Array> mit dem Array-Feld = 0 beginnt, berechnet sich das
letzte Array-Feld wie folgt: Array <zeitdauer_Array[x] > =
<Array-Länge(zeitdauer_Array) – 1> = 6 - 1
= 5 " letztes Array-Feld mit x = 5 Demzufolge umfasst das Array <zeitdauer_Array
insgesamt 6 Felder im Bereich [ 0, …, 5 ]. Mit dem Statement aus der Funktion <erfassen_Stoppzeit> wissen wir, dass die
Variable <max_index_Array>
aufgrund der Array-Länge = 6 den max. Wert = 5 hat
und die Variable <Index> in
der Funktion <anzeigen_Zeitdauer> den
Wert = 6 – 2 = 4 mit
insgesamt 5 Feldern im Bereich [ 0, …, 4 ] annimmt, sodass die nachfolgende Variable <lfd_index_Array>
wiederum den Wert <max_index_Array> - <Index> = 5 – 4 = 1 annimmt: Mit dem Wert = 1 der
Variablen <lfd_index_Array>
wird das 1. Feld von
insgesamt 6 Feldern im Bereich [ 0, …, 5 ] des
Arrays <zeitdauer_Array[x] = Array <zeitdauer_Array[1]>
angesprochen, in dem der zweite Zeitstempel als Stoppzeit
gespeichert wurde. Zur Erinnerung: Im Array <zeitdauer_Array[0] >
wurde der erste Zeitstempel als Startzeit gespeichert (siehe Funktion
erfassen_Startzeit Programm zum Projekt „proxi-roboter-p-09“):
(Zum
Vergrößern bitte auf das Bild klicken!) So, damit wäre nun
aufgezeigt, dass das Programm zum Projekt „proxi-roboter-p-09“
mit der hoch zählenden <for … next>-Schleife im
Äußeren und der runter zählenden Schleife im Inneren, die die äußeren
Schleife voraussetzt, tatsächlich ordnungsgemäß funktioniert. Obwohl wir jetzt wissen,
dass sich die hoch zählende <for … next>-Schleife
mittels der inneren Schleife austricksen lässt, möchte ich an dieser Stelle
trotzdem darauf hinweisen, dass es in höheren Programmiersprachen
wie z.B. JavaScript, Java, C/C++ oder Python auch möglich ist, herunter
zählende <for … next>-Schleifen zu
programmieren. Zu diesem Zweck greifen wir auf das Programm zum Projekt „proxi-roboter-p-08“
zurück. Und zwar mit dem Quellkode
von JavaSript: (Zum
Vergrößern bitte auf das Bild klicken!) Wie man im nachfolgenden
Programmkode zum Programm im Projekt „proxi-roboter-p-10“
unschwer sieht, zählt die <for … next>-Schleife mit
der Variablen <max_zahl_Stockwerke> vom
45. Stock bis
zum Erdgeschoß im 0. Stock herunter, indem der Schleifenzähler
<Index> bei
jedem Schleifendurchlauf um eins dekrementiert, d.h. um -1 herabgesetzt wird.
Und zwar so lange der Schleifenzähler noch einen Wert => 0 inne hat ( " Abbruchbedingung Index >= 0 ): (Zum
Vergrößern bitte auf das Bild klicken!) Wie man oben im grünen Kasten sieht, ist es in JavaScript gar nicht so schwer,
eine rückwärts zählende <for … next>-Schleife zu
programmieren! Vielleicht gibt es von der Microsoft „MakeCode“-Block-Programmierung demnächst auch noch
eine neue Version 3.x mit der sich dann auch rückwärts zählende <for … next>-Schleifen
programmieren lassen! Wie man im nachfolgenden Quellkode des Programms im Projekt „proxi-roboter-p-11“
sieht, werden die Programmzeilen
mit JavaScript-Programmkode grau
unterlegt dargestellt, wenn man sich das Programm in der „MakeCode“-Block-Programmierung wie
folgt anzeigen lässt: (Zum
Vergrößern bitte auf das Bild klicken!) Wer will, kann im
obenstehenden JavaScript-Programmkode die
Variable <loop_Counter>,
d.h. den Schleifenzähler, auch nach <index> umbenennen (siehe Programm im Projekt „proxi-roboter-p-12“):
(Zum
Vergrößern bitte auf das Bild klicken!) Jetzt wo wir über ein sehr
gutes Zeitmessprogramm
verfügen, das wie eine Stoppuhr arbeitet, geht es nachfolgend darum, dass wir einen sogenannten
Timer (= Kurzzeitwecker)
programmieren, bei dem eine fest eingestellte Zeitdauer im Sinne eines Count down, engl. „count down“, auf
Null heruntergezählt wird (siehe Programm
im Projekt „proxi-roboter-p-13“):
(Zum
Vergrößern bitte auf das Bild klicken!) Der Knackpunkt beim Count down mit
dem „micro:bit“-Rechner ist
aber der, dass sich die Zeit
oder eine bestimmte Zeitdauer wie
im richtigen Leben nicht rückwärts, d.h. von der Gegenwart in
die Vergangenheit, zurückdrehen lässt. Zwar lässt sich eine
bestimmte Zeitdauer berechnen und von einem Endwert bis
zum Anfangswert
oder auf Null herunterzählen, aber das Herunterzählen in einer <for … next>- oder <do … while>-Schleife
(siehe oben) erfolgt nicht in Echtzeit, engl. „real
time“, d.h. wortwörtlich „reale, echte Zeit“, sondern in der Zeitspanne,
die der Mikroprozessor je
nach Taktgeschwindigkeit und Taktfrequenz eben so braucht. Demzufolge braucht ein Mikroprozessor wie der „ARM
Cortex M0“-Prozessor mit 16 MHz Taktfrequenz entsprechend länger als ein
neuer „ARM
Cortex X2“-Prozessor mit
64 Bit und
3,3 GHz Taktfrequenz in
einem Smartphone der Oberklasse. Ein weiterer Knackpunkt ist
der, dass die Laufzeit,
die an den Prozessortakt gekoppelt ist, in dem Moment quasi
öffentlich zu laufen anfängt, wenn man das Programm im Projekt „proxi-roboter-p-13“
startet und das Statement mit der Systemvariablen <Laufzeit (ms)> auf
die Taktzeit
des Prozessors mittels Interrupt in Echtzeit zu greift (siehe grüner Kasten), sodass
die Laufzeit des Prozessors von da an unermüdlich,
unerbittlich und ohne Unterbrechung im Hintergrund in Echtzeit
läuft: (Zum
Vergrößern bitte auf das Bild klicken!) Da die Laufzeit
still und leise im Hintergrund werkelt und dabei läuft und läuft und läuft,
lässt sich die Zeitdauer bei der
Programmierung am besten zwischen zwei Zeitpunkten wie
z.B. Start- und Stoppzeit berechnen. Und zwar mittels
der Variablen <startzeit_Timer>, <stoppzeit_Timer> und
<zeitdauer_Timer> und deren Zeitstempel als Funktion
der Laufzeit: zeitdauer = stoppzeit - startzeit " mit stoppzeit > startzeit (siehe weiter oben)!
Das Problem mit der langen Ergebnisanzeige in Millisekunden in
der Laufschrift lässt
sich lösen, indem man diese alternativ auch über die integrierte serielle
Schnittstelle des „micro:bit“-Rechners an
die Konsole ( "
Informationstechnik) weiterleitet. Eine der ältesten seriellen Schnittstellen
dürfte die „RS-232“-Schnittstelle mit
dem sogenannten „Sub-D“-Stecker
sein, die aber inzwischen von der USB-Schnittstelle
abgelöst wurde. Alles zum Thema „Serielle Schnittstelle“
findet sich im Tutorial „micro:bit-Programmieren, Teil
5“. Da aber die „micro:bit“-Entwicklungsumgebung mit
dem „MakeCode“-, „JavaScript“- und „Python“-Editor
auch über eine simulierte(!) Konsole für die serielle Datenübertragung
mittels der USB-Schnittstelle verfügt, lassen sich auch Daten direkt
aus dem Programm seriell an diese übertragen
(siehe Programm im Projekt „proxi-roboter-p-14“):
(Zum
Vergrößern bitte auf das Bild klicken!) Wenn man das obenstehende Programm startet und die serielle
Datenübertragung
mittels Tastendruck auf den Taster <Knopf A>
aktiviert, dann wird der Zeichenstring
„#this*“
fortlaufend ohne Zeilenschaltung an die simulierte Konsole wie
folgt übertragen: (Zum
Vergrößern bitte auf das Bild klicken!) Gemäß dem obenstehenden Programm im Projekt „proxi-roboter-p-14“
lässt sich die serielle Datenübertragung durch Tastendruck auf den Taster <Knopf B>
wieder deaktivieren, d.h. abschalten.
Wir wechseln im Programm im Projekt „proxi-roboter-p-14“ von der „MakeCode“-Programmierung in
die „JavaScript“-Programmierung,
markieren mittels der Tastenfolge <Strg> & <A> den kompletten Quellkode
und kopieren diesen mittels der Tastenfolge
<Strg> & <C> in die Windows-Zwischenablage. Dann laden wir das Programm im Projekt „proxi-roboter-p-13“
in die „micro:bit“-Entwicklungsumgebung,
wechseln in die „JavaScript“-Programmierung und
fügen den „JavaScript“-Quellkode aus
der Windows-Zwischenablage
mittels der Tastenfolge <Strg> & <V> ans Ende der
aktuellen „JavaScript“-Programmierung
ein. Vom Quellkode des
Programms im Projekt „proxi-roboter-p-14“
(siehe oben) behalten wir nun den grün markierten Quellkode,
während der durchgestrichene(!) Quellkode aus
dem Programm entfernt wird:
serial.redirect( SerialPin.USB_TX, SerialPin.USB_RX, BaudRate.BaudRate115200 )
Anschließend wird der grün markierte Quellkode (siehe oben) wie folgt in
das bestehende Hauptprogramm
(siehe grüner Kasten) verschoben. Der Quellkode des Programmblocks
<basic.forever(function
() { … })> (siehe roter Kasten) bleibt so wie er ist. Zu guter Letzt wird das serielle
Statement <serial.writeLine(“P
15“)> (siehe blauer Kasten)
wie folgt hinzugefügt: (Zum
Vergrößern bitte auf das Bild klicken!)
Abschließend erweitern wir
noch die Funktion <countdown_Timer>,
indem wir uns auch dort die Laufschriftanzeigen seriell in der Konsole
mittels der Statements <serial.writeLine(„
Textstring “ + Variable)> anzeigen lassen (siehe grüne Unterstreichung): (Zum
Vergrößern bitte auf das Bild klicken!) Neu im obenstehenden Programm des Projekts „proxi-roboter-p-15“
ist übrigens noch, dass sich ein anzuzeigender Textstring wie z.B. im Statement basic.showString(" Funktionszaehler = ")
jederzeit mit der Anzeige eines Variableninhalts wie z.B. der Variablen <count_Loops> wie
folgt mittels „+“ erweitern lässt: Statement basic.showString(" Funktionszaehler =
" +
count_Loops) Das Angenehme und Vorteilhafte dabei ist, dass man als Programmierer keine Typumwandlung von
„numerisch“ (= Zahlenwert) auf „alphanumerisch“ (= Textstring) vorzunehmen braucht.
Aber nur, wenn der numerischen
Variablen <count_Loops> bereits ein Textstring vorangestellt wurde: (Zum
Vergrößern bitte auf das Bild klicken!) Werfen wir in diesem Zusammenhang
noch einen Blick auf die Konsoleanzeige der seriellen Schnittstelle: (Zum
Vergrößern bitte auf das Bild klicken!) Wie man anhand des
nachfolgenden Screenshots des Programms
im Projekt „proxi-roboter-p-15“
sieht, besteht der Quellkode noch
vollständig aus „MakeCode“-Programmblöcken: (Zum
Vergrößern bitte auf das Bild klicken!) Auch beim Programm des Projekts „proxi-roboter-p-16“
sieht, besteht der Quellkode noch
vollständig aus „MakeCode“-Programmblöcken.
Dabei wurden aber die Laufschriftanzeige sowie die Ausgabe der Variableninhalte
an die serielle Schnittstelle nebst Konsoleanzeige in die Funktion <anzeigen_Textausgabe> ausgelagert:
(Zum
Vergrößern bitte auf das Bild klicken!) Dass eine Funktion aus
dem Inneren
heraus auch einen Textstring, einen Zahlenwert oder einen Variablenwert nach Außen an das Hauptprogramm <beim Start> oder <dauerhaft>
zurückliefert, wurde u.a. beim Programm
zum Projekt „proxi-roboter-p-09“
aufgezeigt: (Zum
Vergrößern bitte auf das Bild klicken!) Dabei wird aber noch nicht
zwischen lokalen Variablen innerhalb der Funktion
<anzeigen_Stoppzeit> und
globalen Variablen im Hauptprogramm <beim Start>
bzw. <dauerhaft>
unterschieden, weil das noch nicht beim „MakeCode“-Programmieren implementiert wurde, ganz
im Gegensatz zum „JavaScript“-Programmieren! Wenn aber eine Funktion von
innen nach außen Dateninhalte zurückliefert, dann u.a. deshalb, weil
der Variableninhalt
einer lokalen Variablen sozusagen in der Funktion „gefangen“ ist und eben
genau nicht an das Hauptprogramm
<beim
Start> bzw. <dauerhaft> direkt übertragen werden kann. Es sei
denn mittels des Statements <return (stoppzeit_Timer - startzeit_Timer)> (siehe Programm zum Projekt „proxi-roboter-p-17“):
(Zum
Vergrößern bitte auf das Bild klicken!) Aber eine Funktion
kann nicht nur Daten einer lokalen Variablen an das aufrufende Programm
zurückliefern, sondern auch im Funktionskopf vom aufrufenden Programm
entgegennehmen (siehe oben grüner Kasten und
grüne Bepfeilung). Mit dem Programm zum Projekt „proxi-roboter-p-18“
setzen wir das mit den globalen und lokalen Variablen vollständig
um, indem wir im Programm streng zwischen globalen und lokalen Variablen
unterscheiden. Demzufolge gibt es nach
nachfolgende globale Variablen im Hauptprogramm
(ohne Kennzeichnung) und im Programmblock
<forever> zeitdauer_Timer
count_Loops
dummy_Zeit
start_stopp_Timer_boolean
und nachfolgende lokalen
Variablen in
der Funktion <anzeigen_Textausgabe()> get_Textstring
in
der Funktion <countdown_Time()> startzeit_Timer
zeitdauer_Timer
stoppzeit_Timer
(Zum
Vergrößern bitte auf das Bild klicken!)
Wenn man in der Funktion <anzeigen_Textausgabe()> die
beiden Programmzeilen zwischen /* … */ auskommentiert, dann wird die Laufschriftanzeige im 5 x 5 Matrix LED-Display
abgeschaltet, sodass nur noch die Anzeige in der Konsole aktiv ist. Die schnellere
Bildschirmanzeige im Konsolefenster (Zum Vergrößern bitte
auf das Bild klicken!) hat den Vorteil, dass genügend Zeit für den Count down bleibt, der sozusagen ja immer im
Hintergrund still und leise vor sich hin werkelt, sodass sich dieser
pünktlich nach Ablauf der 30 Sekunden mit dem Signalton
zurückmeldet. - Ein Count down, der immer nur einen festen Wert von 30 Sekunden herunterzählt, ist
auf Dauer natürlich nicht so das Wahre. Deshalb befassen wir uns als Nächstes
mit dem Programm microbit_teil_01_prog_18.hex
aus dem Teil 1 des Tutorials „micro:bit-Programmieren“ zu dem es auch eine Bedienungsanleitung
gibt.
Bei dem nachfolgenden „JavaScript“-Programmkode im grünen Kasten zum Projekt „proxi-roboter-p-19“
fällt auf, dass wir es bei diesem mit den drei Zählvariablen l, m und n
(in alphabetischer Reihenfolge) zu tun haben. Dabei dient die Zählvariable m nur dazu zu zählen,
wie oft der Taster <Knopf A> gedrückt wurde. Und
da die Zählvariable m wegen der Initialisierung bei m = 0
anfängt, muss diese sofort
um +1 erhöht
werden, wenn der Taster <Knopf
A> erstmals oder zum wiederholten
Male gedrückt wird: m = m + 1 oder
besser m++. Damit man sich unter der Zählvariable m auf Anhieb besser
vorstellen kann, worum es bei dieser geht, benennen wir diese kurzerhand um
zur Zählvariablen <Tastendruecke_Knopf_A>. Sobald der Taster <Knopf
A>
mit der Bedingung <if m > 5 { … }> ununterbrochen(!)
mehr als fünf Mal gedrückt wird, wird der Aufwärtszähler Variable <n> nicht mehr nur um n = n + 5 erhöht, sondern gleich um das Fünfzigfache(!). Und zwar mit n = (l + 1) * 50. Dabei dient die Variable <l> mit l = n / 50 dazu, das Vielfache von 50 zu ermitteln! Beispiel:
Der Aufwärtszähler
n hat den Wert n = 57 " l = n / 50 = 57 / 50 = 1.14 " n >= l * 50 = 1.14 * 50 = 57 " n = ( l + 1 ) * 50 = ( 1.14 + 1 ) * 50 = 2.14 * 50 = 107 ↔ = n + 50 = 57 + 50 = 107 Zwecks besserer Verständlichkeit benennen wir
die Variable <n> um in Variable
<Aufwaertszaehler> und die Variable <l> um in Variable <Multiplikator_AZ>. (Zum Vergrößern bitte
auf das Bild klicken!) Im
Zusammenhang mit dem „JavaScript“-Programmkode im grünen Kasten zum Projekt
„proxi-roboter-p-19“
stellt sich noch die Frage was passiert, wenn man den Taster <Knopf_A> während des schnellen
Hochzählens wieder loslässt. Wenn man den Taster <Knopf_A> wieder loslässt, dann
greift die <else>-Bedingung der engl. <if …
then… else …>-Abfrage, d.h. die <Wenn … dann> … <anderenfalls>-Abfrage. Und die besagt, dass die Zählvariable <Tastendruecke_Knopf_A> wieder auf Null
gesetzt wird, sobald man den Taster <Knopf_A> wieder losgelassen
hat. Wenn man sich den nachfolgenden Screenshot vom
Konsolefenster ansieht, dann fällt
auf, dass der Multiplikator des Aufwärtszählers (AZ) ungerade Dezimalwerte aufweist (siehe roter Kasten), (Zum Vergrößern bitte
auf das Bild klicken!) was die Lesbarkeit und das Verständnis, wie
der Aufwärtszähler funktioniert, erschwert. Der Grund dafür ist der, dass der
Ergebniswert l des Statements < l = n / 50 > nicht auf einen ganzzahligen Wert gerundet wird: l = n / 25 = 73 / 25 = 2,92 " Schrittlänge 2 = 25 (bisher 50)! Das aber wird im Programm zum Projekt „proxi-roboter-p-20“
wie folgt geändert: (Zum Vergrößern bitte
auf das Bild klicken!) Wenn man sich den nachfolgenden Screenshot vom
Konsolefenster ansieht, dann fällt
auf, dass der Multiplikator des Aufwärtszählers (AZ) gerade(!) Dezimalwerte aufweist (siehe roter Kasten), (Zum Vergrößern bitte
auf das Bild klicken!) was darauf zurückzuführen ist, dass der Ergebniswert der Variablen <Multiplikator_AZ> bei der Berechnung
mit dem Statement Multiplikator_AZ = Math.round(Aufwaertszaehler / schrittlaenge_2) erstmalig auf einen ganzzahligen Wert gerundet wurde (siehe
auch grüner Kasten weiter oben). Im obenstehenden Screenshot des Konsolefensters sieht man auch
erstmalig einige krumme, ganzzahlige Dezimalwerte der Variablen <Aufwaertszaehler> wie z.B. 24, 23, 33,
38, 43 usw. Dabei stellt sich die Frage, wie sich diese einstellen lassen, wo
wir doch bisher immer nur in 5er
Schritten
und jetzt auch in 25er
Schritten
(vormals 50er Schritte) gezählt und gerechnet haben. Wenn wir noch mal einen Blick auf die Bedienungsanleitung
werfen, da heißt es im Abschnitt „4. Einstellen des Startzählwertes“ u.a., ich zitiere:
„Mit dem Taster B lässt sich nämlich
auch rückwärts nach unten zählen! Und zwar wahlweise in 1er oder 25er
(vormals 50er) Schritten, wenn’s schneller gehen soll.“: (Zum Vergrößern bitte
auf das Bild klicken!) Diesbezüglich stellt sich dann auch gleich die
Frage, was passiert, wenn man z.B. ausgehend von dem Aufwärtszähler = 5 schrittweise
in 1er-Schritten mittels des Tasters <Knopf_B> bis auf den Aufwärtszähler = 0 herunterzählt und dann den Taster <Knopf_B> ein weiteres Mal drückt? Springt dann die
Anzeige in der Laufschrift von 0 auf -1 oder bleibt diese einfach bei 0 stehen? Um diese Frage beantworten zu können, müssen
wir nochmals einen Blick auf den Quellkode werfen! Und zwar
weiter unten: (Zum Vergrößern bitte
auf das Bild klicken!) Wie man im Quellkode des obenstehenden Screenshots sieht, wird nicht nur der Aufwärtszähler beim Erreichen eines negativen Wertes < 0 immer wieder auf = 0 gesetzt, sondern auch
gleichzeitig das Herunterzählen beendet! In diesem Zusammenhang gilt es aber zu
bedenken, dass der Proxi-Roboter
prinzipiell auch rückwärts laufen kann. Dabei stellt sich dann die
Frage, ob man das Rückwärtslaufen anhand negativer
Werte der Variablen <Aufwaertszaehler> symbolisieren bzw.
umsetzen soll, oder ob man für das Rückwärtslaufen extra einen Parameter wie z.B. engl. „backward“ und für das Vorwärtslaufen engl. „forward“ einführt und später in der Bewegungsdatenbank abspeichert. Man könnte natürlich auch zusätzlich zu einem negativen
Wert auch noch das Attribut „backward“ mit in der Bewegungsdatenbank abspeichern. Das wäre
dann sozusagen „doppelt gemoppelt“ oder fachmännisch gesagt „redundant“! Es
kann nämlich durchaus vorkommen, dass sich das Computerprogramm beim Herauf- oder Herunterzählen einer Vor- oder
Rückwärtsbewegung vertut und in den negativen Zahlenbereich „rutscht“. Dann hätte
man mit dem zusätzlichen Parameter
und Attribut „forward / backward“ noch ein weiteres
Merkmal, um auf eventuelle Fehler bei einer Vor- oder
Rückwärtsbewegung rechtzeitig zu reagieren. Mit dem Programm
zum Projekt
„proxi-roboter-p-21“
lassen sich auch negative Zahlenwerte z.B. für das spätere Rückwärtslaufen des Proxi-Roboters realisieren. Zu diesem
Zweck muss man nur den obenstehenden Programmblock (= Zeile 74 bis 79) aus dem Programm entfernen oder mittels Kommentarmarkierung /* … */ auskommentieren, d.h.
außer Kraft setzen. Auch das Programm
zum Projekt
„proxi-roboter-p-22“
arbeitet mit den beiden Tastern
<Knopf_A> und <Knopf_B>, wobei der Taster <Knopf_A> zum Hochzählen und der Taster <Knopf_B> zum Herunterzählen
dient. Dabei zählt der Taster <Knopf_A> in 5er Schritten nach oben und beim längeren Drücken
des Tasters dann in 20er
Schritten
entsprechend schneller. Der Taster <Knopf_B> zählt in 1er Schritten nach unten und beim längeren Drücken
des Tasters dann in 15er
Schritten
entsprechend schneller: (Zum Vergrößern bitte
auf das Bild klicken!) Wie man im obenstehenden Screenshot sieht,
wird bei der Schrittlänge zwischen der Schrittlänge vorwärts (= „v1“, „v2“) und
der Schrittlänge rückwärts (= „r1“, „r2“)
unterschieden. Darüber hinaus lassen sich durch das asymmetrische
Herauf- und Herunterzählen in 5er und 20er Schritten nach oben und in 1er und 15er Schritten nach unten praktisch alle ein-
und zweistelligen Werte einstellen: (Zum Vergrößern bitte
auf das Bild klicken!) Wie man im
obenstehenden Screenshot sieht, kommt es beim Runterzählen, engl. „count down“, insbesondere beim Umschalten von einer niedrigen zur nächst höheren
Schrittlänge zu weiteren Schaltimpulsen einer der entsprechenden Taster <Knopf_A> oder <Knopf_B>.
Werfen wir der Vollständigkeit halber noch
einen Blick auf den Quellkode zum „Count down“-Programm zum Projekt
„proxi-roboter-p-22“:
(Zum Vergrößern bitte
auf das Bild klicken!) Bedienungsanleitung zum „Count down“-Programm des Projektes
„proxi-roboter-p-22“:
Das in den Arbeitsspeicher
des „micro:bit“-Rechners geflashte Programm wird vom System automatisch
gestartet und ausgeführt! Wenn bei dem in den
Arbeitsspeicher geladenen Programm nichts anderweitiges programmiert wurde,
wie z.B. ein kleiner Begrüßungstext als Laufschrift auf dem „5 x 5
LED-Matrix“-Display, dann bleibt das Display dunkel, sieht
man nicht, dass das geladene Programm gestartet wurde! Dies ist
auch der Fall, wenn die Laufschrift
durchgelaufen ist! Im vorliegenden Fall,
d.h. beim Programm „proxi-roboter-p-22“
wird der Anfangszählerstand „0“ auf dem „5 x 5 LED-Matrix“-Display angezeigt, da es sich
beim Programm ja um einen „Count down“-Timer, d.h. ein Programm
zum Herunterzählen eines eingestellten Startzählwertes handelt.
Ein „Count down“-Timer, der vom Startzählwert
„0“
aus herunter zählt, macht natürlich keinen Sinn. Deshalb muss man mittels Tastendruck
auf den Taster <Knopf_A> oder <Knopf_B> erst vom Startzählwert
„0“
aus diesen auf den gewünschten Startzählwert „420“ (z.B. zum Kochen
eines 7-Minuten-Eies) hoch zählen! Damit das Hochzählen nicht zu lange dauert, wird beim längeren
Tastendruck auf den Taster <Knopf_A> in 20er Schritten (siehe Variable <schrittlaenge_v2>) und beim Taster
<Knopf_B> in 15er Schritten (siehe Variable <schrittlaenge_r2>) hoch bzw. runter
gezählt! Lässt
man den gedrückten Taster <Knopf_A> oder
Taster <Knopf_B> beim Hochzählen in 20er oder 15er Schritten
wieder los, dann fällt der Zählalgorithmus wieder auf 5er oder 1er Schritte zurück,
sodass wieder langsamer hoch oder runter gezählt wird! Da
sich mit dem Taster <Knopf_A> nur
in 5er oder 20er Schritten hoch zählen lässt,
lassen sich mit diesem nur Werte wie z.B. 5, 10, 15, …, 20, 40, 60, …105,
110, 125, … einstellen. Wer aber einen Wert wie z.B. 133 einstellen will,
muss nicht verzweifeln, weil er mit dem Taster <Knopf_A> nur
den Wert 130 oder 135 einstellen kann. Mit dem Taster
<Knopf_B> lässt sich nämlich auch rückwärts
nach unten zählen! Und zwar wahlweise in 1er oder
15er Schritten, wenn’s schneller gehen soll: (Zum Vergrößern bitte
auf das Bild klicken!)
Nachdem man mit den Tastern
<Knopf_A> und Taster <Knopf_B> den gewünschten Startzählwert = 133 eingestellt hat, muss man den Rückwärtszähler, engl. „count down“,
noch starten, damit dieser loslegt und vom zuvor eingestellten Startzählwert aus rückwärts
bis auf Null zählt. Und zwar durch
einfaches Drücken des „Tasters“ am Port „Pin P1“ (siehe oben links im
Screenshot). Durch einfaches Drücken des „Tasters“ am Port „Pin P2“ lässt sich das Herunterzählen des „Count down“-Timers auch jederzeit wieder
anhalten, zwischendurch unterbrechen oder durch einfaches Drücken des „Tasters“ am Port „Pin P1“wieder fortsetzen. Wenn man das Herunterzählen des „Count down“-Timers mittels
des „Tasters“ am Port „Pin P2“ stoppt, dann lässt sich der aktuelle
Zählwert für den Count down mittels
der Taster <Knopf_A> oder Taster <Knopf_B> nachträglich verändern,
d.h. rauf- oder herunterzählen. Anschließend lässt sich der Count down mittels des mittels des „Tasters“ am Port „Pin P2“ wieder aufnehmen und fortsetzen! Das Herunterzählen des Count down lässt sich zwar anhalten, endet
aber von sich aus wider Erwarten nicht bei Null,
sondern setzt sich ins Negative bis ins Unendliche oder bis zum nächsten Stromausfall
oder der Stromunterbrechung fort, da das Anhalten des Count down beim Erreichen des Zählwertes Null
noch nicht programmiert wurde!
Wie bereits bekannt
ist, ist die LED-Anzeige mit der Laufschriftanzeige im „5 x 5
LED-Matrix“-Display immer nur einstellig, sodass sich in
der Laufschrift immer nur ein(!)
Zeichen in Form eines Buchstabens,
eines Sonderzeichens, einer Ziffer oder der letzten Stelle einer Zahl darstellen lässt. Je nach Programmierung kann es nach dem Einstellen des Startzählwertes
durch Hochzählen (= Taster <Knopf_A>)
und/oder Runterzählen (= Taster <Knopf_B>) dazu
kommen, dass die die Laufschriftanzeige im „5 x 5 LED-Matrix“-Display
gelöscht wird, oder dass nur die letzte(!) Stelle eines ganzzahligen, zweistelligen Wertes angezeigt wird,
sodass man eventuell nicht mehr weiß, welcher Zählwert
momentan aktuell gültig ist. Ebenso
verhält es sich, wenn das Herunterzählen des „Count down“-Timers
angehalten wurde! Auch dabei erlischt je nach Programmierung die Anzeige,
weiß man später nicht mehr, welcher Zählwert
momentan aktuell gültig ist. Mittels des „Tasters“ am Port „Pin P0“ lässt sich der aktuelle Zählwert jederzeit wieder in der Laufschrift des LED-Displays anzeigen! Softwaremäßig, d.h. im Programm selbst, lässt sich der „Taster“ am Port „Pin P0“ mittels Mausklick direkt anklicken, sodass kein externer Taster erforderlich ist! Wenn man den „Taster“ als Hardware am Port „Pin P0“ des „micro:bit“-Rechners benutzen möchte, dann müsste man zusätzlich einen echten
Taster oder Schalter elektrisch
zwischen dem Port „Pin P0“ und dem Port „Pin GND“ ( = Masse, „^“) hinzu schalten. Das „Count down“-Programm des Projektes
„proxi-roboter-p-22“ wird weiter ausgebaut. Und zwar dahingehend,
dass das Herunterzählen eines positiven
Wertes nun nur bis auf Null erfolgt. Ebenso das Hochzählen eines negativen Wertes (siehe Programm
des Projektes
„proxi-roboter-p-23“):
(Zum Vergrößern bitte
auf das Bild klicken!) Dabei handelt es sich beim Herunterzählen eines negativen Wertes eigentlich um das Heraufzählen vom eingestellten, negativen Zählwert als Startwert bis gegen Null. Denn schließlich
bewegen wir uns auf der Zahlengeraden von
links nach rechts! Damit sich das „Count down“-Programm zum Projekt
„proxi-roboter-p-23“
möglichst fehlerfrei bedienen lässt, nachfolgend noch die ausführliche Bedienungsanleitung: zum „Count down“-Programm des Projektes
„proxi-roboter-p-23“:
Das in den Arbeitsspeicher
des „micro:bit“-Rechners geflashte Programm wird vom System automatisch
gestartet und ausgeführt! Wenn bei dem in den
Arbeitsspeicher geladenen Programm nichts anderweitiges programmiert wurde,
wie z.B. ein kleiner Begrüßungstext als Laufschrift auf dem „5 x 5
LED-Matrix“-Display, dann bleibt das Display dunkel, sieht
man nicht, dass das geladene Programm gestartet wurde! Dies ist
auch der Fall, wenn die Laufschrift
durchgelaufen ist! Im vorliegenden Fall,
d.h. beim Programm „proxi-roboter-p-22“
wird der Anfangszählerstand „0“ auf dem „5 x 5 LED-Matrix“-Display angezeigt, da es sich
beim Programm ja um einen „Count down“-Timer, d.h. ein Programm
zum Herunterzählen eines eingestellten Startzählwertes handelt.
Ein „Count down“-Timer, der vom Startzählwert
„0“ aus
herunter zählt, macht natürlich keinen Sinn. Deshalb muss man mittels Tastendruck
auf den Taster <Knopf_A> oder <Knopf_B> erst vom Startzählwert
„0“
aus diesen auf den gewünschten Startzählwert „420“ (z.B. zum Kochen
eines 7-Minuten-Eies) hoch zählen! Damit das Hochzählen nicht zu lange dauert, wird beim längeren
Tastendruck auf den Taster <Knopf_A> in 20er Schritten (siehe Variable <schrittlaenge_v2>) und beim Taster
<Knopf_B> in 15er Schritten (siehe Variable <schrittlaenge_r2>) hoch bzw. runter gezählt!
Lässt
man den gedrückten Taster <Knopf_A> oder
Taster <Knopf_B> beim Hochzählen in 20er oder 15er Schritten
wieder los, dann fällt der Zählalgorithmus wieder auf 5er oder 1er Schritte
zurück, sodass wieder langsamer hoch oder runter gezählt wird! Da
sich mit dem Taster <Knopf_A> nur
in 5er oder 20er Schritten hoch zählen lässt,
lassen sich mit diesem nur Werte wie z.B. 5, 10, 15, …, 20, 40, 60, …105,
110, 125, … einstellen. Wer aber einen Wert wie z.B. 133 einstellen will,
muss nicht verzweifeln, weil er mit dem Taster <Knopf_A> nur
den Wert 130 oder 135 einstellen kann. Mit dem Taster
<Knopf_B> lässt sich nämlich auch rückwärts
nach unten zählen! Und zwar wahlweise in 1er oder
15er Schritten, wenn’s schneller gehen soll: (Zum Vergrößern bitte
auf das Bild klicken!)
Nachdem man mit den Tastern
<Knopf_A> und Taster <Knopf_B> den gewünschten Startzählwert = 133 eingestellt hat, muss man den Rückwärtszähler, engl. „count down“,
noch starten, damit dieser loslegt und vom zuvor eingestellten Startzählwert aus rückwärts
bis auf Null runterzählt. Und zwar durch
einfaches Drücken des „Tasters“ am Port „Pin P1“ (siehe oben links im
Screenshot). Da der „Taster“ am Port „Pin P1“ jetzt als Wechselschalter
im Sinne eines Umschalters arbeitet , lässt sich
das Herunterzählen des „Count down“-Timers mit diesem auch
jederzeit wieder anhalten, zwischendurch unterbrechen oder
durch erneutes, einfaches Drücken
des „Tasters“ am Port „Pin P1“wieder fortsetzen. Wenn man das Herunterzählen des „Count down“-Timers mittels
des „Tasters“ am Port „Pin P1“ stoppt, dann lässt sich der aktuelle
Zählwert für den Count down mittels
der Taster <Knopf_A> oder Taster <Knopf_B> nachträglich verändern,
d.h. rauf- oder herunterzählen. Anschließend lässt sich der Count down mittels des mittels des „Tasters“ am Port „Pin P1“ wieder aufnehmen und fortsetzen! Das Herunterzählen des Count down lässt sich
zwischendrin nicht nur anhalten, der Zählwert herauf- oder heruntersetzen und der Count down anschließend wieder fortsetzen, sondert endet auch automatisch, sobald der Zählwert Null erreicht wurde!
Nachdem man mit den Tastern
<Knopf_A> und Taster <Knopf_B> den gewünschten Startzählwert = -133 eingestellt hat, muss man den Vorwärtszähler, engl. „count up“,
noch starten, damit dieser loslegt und vom zuvor eingestellten Startzählwert aus vorwärts
bis auf Null hochzählt. Und zwar durch
einfaches Drücken des „Tasters“ am Port „Pin P2“ (siehe oben links im
Screenshot). Da der „Taster“ am Port „Pin P2“ jetzt als Wechselschalter
im Sinne eines Umschalters arbeitet , lässt sich
das Hochzählen des „Count up“-Timers mit diesem auch
jederzeit wieder anhalten, zwischendurch unterbrechen oder
durch erneutes, einfaches Drücken
des „Tasters“ am Port „Pin P2“ wieder fortsetzen. Wenn man das Hochzählen des „Count up“-Timers
mittels des „Tasters“ am Port „Pin P2“ stoppt, dann lässt sich der aktuelle
Zählwert für den Count up mittels der Taster <Knopf_A> oder Taster <Knopf_B>
nachträglich verändern, d.h. rauf- oder herunterzählen. Anschließend
lässt sich der Count up mittels des mittels des „Tasters“ am Port „Pin P2“ wieder aufnehmen und fortsetzen! Das Hochzählen des Count up lässt sich zwischendrin nicht nur anhalten, der Zählwert herauf- oder heruntersetzen und der Count up anschließend wieder fortsetzen, sondert endet auch automatisch, sobald der Zählwert Null erreicht wurde!
Wie bereits bekannt
ist, ist die LED-Anzeige mit der Laufschriftanzeige im „5 x 5
LED-Matrix“-Display immer nur einstellig, sodass sich in
der Laufschrift immer nur ein(!)
Zeichen in Form eines
Buchstabens, eines Sonderzeichens, einer Ziffer oder der letzten Stelle einer Zahl darstellen lässt. Je nach Programmierung kann es nach dem Einstellen des Startzählwertes
durch Hochzählen (= Taster <Knopf_A>)
und/oder Runterzählen (= Taster <Knopf_B>) dazu
kommen, dass die die Laufschriftanzeige im „5 x 5 LED-Matrix“-Display
gelöscht wird, oder dass nur die letzte(!) Stelle eines ganzzahligen, zweistelligen Wertes angezeigt wird,
sodass man eventuell nicht mehr weiß, welcher Zählwert
momentan aktuell gültig ist. Ebenso
verhält es sich, wenn das Herunterzählen des „Count down“-Timers
angehalten wurde! Auch dabei erlischt je nach Programmierung die Anzeige,
weiß man später nicht mehr, welcher Zählwert
momentan aktuell gültig ist. Mittels des „Tasters“ am Port „Pin P0“ lässt sich der aktuelle Zählwert jederzeit wieder in der Laufschrift des LED-Displays anzeigen! Softwaremäßig, d.h. im Programm selbst, lässt sich der „Taster“ am Port „Pin P0“ mittels Mausklick direkt anklicken, sodass kein externer Taster erforderlich ist! Wenn man den „Taster“ als Hardware am Port „Pin P0“ des „micro:bit“-Rechners benutzen möchte, dann müsste man zusätzlich einen echten
Taster oder Schalter elektrisch
zwischen dem Port „Pin P0“ und dem Port „Pin GND“ ( = Masse, „^“) hinzu schalten. Das „Count down“-Programm zum Projekt
„proxi-roboter-p-23“
wird weiter ausgebaut und verbessert. Und zwar in der Weise, dass wichtige
funktionale Programmteile jeweils in eine eigene Funktion
ausgelagert werden, um auf diese Weise die Lesbarkeit und Übersichtlichkeit
zu verbessern. Dabei werden dann auch vormals globale Variablen als lokale Variablen in die Funktionen verschoben: (Zum Vergrößern bitte
auf das Bild klicken!) Wie man im obenstehenden Programmkode sieht,
besteht das Programm zum Projekt
„proxi-roboter-p-24“
jetzt hauptsächlich aus zwei Funktionen: 1. function druecken_Knopf_Pin_X(druecken_Knopf_Pin:number) { … return (Aufwaertszaehler) } Dabei dient die Funktion dazu, die Tastendrücke der beiden Taster <Knopf_A> (Pin = 1) und <Knopf_B> (Pin = 2) sowie der Ports „Pin P0“ (Pin = 100), „Pin P1“ (Pin = 101) und „Pin P2“ (Pin = 102) über den Funktionskopf mit der numerischen Variablen <druecken_Knopf_Pin> entgegenzunehmen und
entsprechend dem Programm zu verarbeiten. Mittels des Statements return (Aufwaertszaehler)
wird dann der bearbeitete und berechnete Wert der Variablen <Aufwaertszaehler> wieder an das Hauptprogramm zurückgegeben: (Vergrößern: auf das
Bild klicken! | Projekt „proxi-roboter-p-25“)
und 2.
function auswerten_Knopf_Pin_X(get_schrittlaenge_r1: number) Die zweite Funktion dient dazu, den „Count down“-Zähler zum Herunterzählen
als auch den „Count
up“-Zähler zum Hochzählen in der
LED-Laufschrift und Konsole anzuzeigen: (Vergrößern: auf das
Bild klicken! | Projekt „proxi-roboter-p-25“)
Anhand des Programms zum Projekt „proxi-roboter-p-26“
gilt es noch etwas ganz Wichtiges zu klären. Nämlich die Frage, worin sich
die beiden Statements im roten und grünen Kasten im
Hauptprogramm unterscheiden! Dabei kommt es aber nicht darauf an, dass im roten Kasten der Taster am Port „Pin 0“ und im grünen Kasten der Taster am Port „Pin 1“ abgefragt wird, (Vergrößern: auf das
Bild klicken! | Projekt „proxi-roboter-p-26“) sondern worin sich die beiden Statements im roten und grünen Kasten im
Hauptprogramm funktional unterscheiden!
Wie
bereits bekannt sein dürfte, lassen sich beim „micro:bit“-Rechner die beiden Taster <Knopf_A> und <Knopf_B> auch zusammen, d.h. quasi gleichzeitig,
betätigen (siehe blauer Kasten): (Zum Vergrößern bitte
auf das Bild klicken!) Bei Computern
und elektronischen Geräten wie z.B. Waschmaschinen, Wäschetrockner,
Geschirrspülmaschinen, Küchenradios, elektronischen (Funk-) Uhren und Eieruhren,
in den ein Mikrocontroller
nebst kleinem Betriebssystem verbaut ist, lassen sich Taster zwecks Bedienung nicht wirklich
gleichzeitig drücken! Das gilt z.B. auch für Windows-PCs bei den sich der berühmte „Affengriff“ mit den angeblich
gleichzeitig zu drückenden Tasten <Alt>, <Strg> & <Entf> praktisch nicht anwenden lässt, weil
der Mensch eben nur zwei Hände hat. Deshalb drückt man bei der Tastenkombination <Alt>, <Strg> & <Entf> als erstes mit der linken Hand die <Alt>-Taste, hält diese dauerhaft
gedrückt, drückt als nächstes mit der linken Hand die <Strg>-Taste (= Steuerungstaste, nicht
String-Taste), hält diese ebenfalls dauerhaft gedrückt, während man
als letztes mit der rechten Hand die <Entf>-Taste (= Entfernen-Taste) einmalig
kurz drückt. Der Grund für das Drücken der Tastenkombination <Alt>, <Strg> & <Entf> in Reihe, d.h. nacheinander,
ist aber der, dass sich elektrische Taster, Schalter oder Sensoren oder eben auch die Taster <Knopf_A> und <Knopf_B> sowie die Pins <P0>, <P1> und <P2> des „micro:bit“-Rechners elektrisch/elektronisch immer nur nacheinander
abfragen lassen. Das aber mit sehr schneller Taktfolge, sodass es einem vorkommt, als würde man mehrere
Taster gleichzeitig drücken!
Bei der Programmierung
des Tasters <Knopf_AB> (siehe blauer
Kasten
weiter oben) gibt es das Problem, dass sich der Taster <Knopf_AB> mittels der <if …then …>-Abfrage in der Endlosschleife
<forever> wider Erwarten nicht
richtig abfragen ließ. Immer wenn
man den Taster <Knopf_AB> im Programm zum Projekt
„proxi-roboter-p-26“
einmal mit der Maus kurz anklickt, dann hört man sofort den Signalton und sieht kurz darauf in der LED-Laufschrift als auch in der Konsole, dass die Variable
<Aufwaertszaehler> um einen 5er Schritt heraufgesetzt wurde, so als
hätte man den Taster <Knopf_A> mit der Funktion
<druecken_Knopf_Pin_X(Button.A)> angeklickt! Erst wenn
man den Taster <Knopf_AB> mit der Maus etwas länger anklickt, hört man zunächst
den doppelten Signalton mit der
anschließenden Anzeige „>
Knopf_AB = 3“ in der LED-Laufschrift und in der Konsole, gefolgt
von der Anzeige „Aufwaertszaehler
= 4“, so als
hätte man zunächst den Taster <Knopf_A> angeklickt mit der Erhöhung der Variablen <Aufwaertszaehler> um einen 5er Schritt und
anschließend den Taster <Knopf_B> mit der Verringerung der Variablen <Aufwaertszaehler> um einen 1er Schritt mit dem Ergebniswert
„Aufwaertszaehler = 4“: (Vergrößern: auf das
Bild klicken! | Projekt „proxi-roboter-p-26“) Aber selbst
wenn man die <if …then …>-Abfrage in der Endlosschleife
<forever> im Programm zum Projekt „proxi-roboter-p-26“
gegen die <Echtzeit>-Abfrage ersetzt, (Vergrößern: auf das
Bild klicken! | Projekt „proxi-roboter-p-27“) ändert das nichts an der Fehlerhaftigkeit der Tasterabfrage des Tasters <Knopf_AB> im Programm
zum Projekt
„proxi-roboter-p-27“.
- Da das „Count down“-Programm zum Projekt
„proxi-roboter-p-25“
praktisch ausgereift ist und gut funktioniert, wir also einen beliebigen
ganzzahligen positiven Zeitwert für die spätere Vorwärtsbewegung oder einen negativen
Zeitwert für die spätere Rückwärtsbewegung des Proxi-Roboters einstellen können, können
wir uns wieder dem ursprünglichen „Zeitmess“-Programm im Projekt
„proxi-roboter-p-27“
aus dem Abschnitt „Coding
1“
zuwenden. Zu diesem Zweck speichern wir das „Zeitmess“-Programm hier im Abschnitt „Coding 2“ als Programm zum Projekt
„proxi-roboter-p-28“.
Obwohl das „Zeitmess“-Programm komplett in der Microsoft „MakeCode“-Entwicklungsumgebung programmiert wurde
und demzufolge noch keinerlei Funktionen enthält, |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
[
Proxi-Roboter ] [ Seitenanfang ] [ Montage 1 ] [ Coding 1 ] |
|