[ 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:

 

Index

Zeitdauer [s100]

 

 

8

            10,35

7

            10,33

6

            10,30

5

            10,28

4

            10,26

3

            10,24

Mittelwert

            10,29

2

              0,04

1

              0,02

Mittelwert

              7,72

 

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?

 

Ganz einfach! Immer dann, wenn die Zeitaufnahme mittels des Statements

 

 

gestartet wird, dann läuft die Zeit in Form des Prozesstaktes im Hintergrund still und leise unaufhörlich weiter!

 

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!

 

Interessant sind dabei noch die beiden Zeitstempel mit dem Index 1 und 2, die darauf hindeuten, dass die Zeitmessung alle 20 ms stattfindet und bestätigt, dass der Prozessor bei der Zeitaufnahme tatsächlich bis zu zwei Prozessortakte von insgesamt 40 ms benötigt, um den Interrupt in Echtzeit(!) auszuführen!

 

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:

 

Index

Zeitdauer [s100]

 

 

4

            10,34

3

            10,32

2

            10,30

1

            10,28

Mittelwert

            10,31

 

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:

 

Index

Zeitdauer [s100]

 

 

8

            10,35

7

            10,33

6

            10,30

5

            10,28

4

            10,26

3

            10,24

Mittelwert

            10,29

2

              0,04

1

              0,02

Mittelwert

              7,72

 

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:

 

  1. der Anfangs-/Startwert mit index = 0,

  2. die Abbruchbedingung index < max_index_Array
    bei deren Überschreiten keine weiteren Schleifendurchläufe mehr erfolgen und

  3. die schrittweise Erhöhung um den Wert +1 mit index++

 

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!)

 

Nach reiflicher und intensiver Überlegung bin ich zu dem Ergebnis gekommen, dass es beim Messen der Start- und Stoppzeit wegen des Interrupts (= Unterbrechung des laufenden Programms) beim Erfassen des Zeitstempels in Echtzeit(!) und des anschließenden Rücksprungs ins Programm nebst Fortsetzung desselben zu einem offensichtlichen Nachlaufen bzw. Synchronisieren mit dem Prozessortakt kommt, sodass der berechnete Mittelwert stets zu einem größeren Zeitwert führt als der erste Stoppwert im Array <zeitdauer_Array>:

 

Index

Zeitdauer [s100]

Bemerkung

 

 

 

4

            10,34

20 ms Taktsynchronisierung

3

            10,32

20 ms Taktsynchronisierung

2

            10,30

20 ms Taktsynchronisierung

1

            10,28

Drücken Taster <Knopf B>

Mittelwert

            10,31

Entspricht nicht dem Wert von Index 1

 

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!)

 

Wie man im obenstehenden und im nachfolgenden Screenshot sieht, wird die Zählvariable <Index> mit dem Statement <let index = 0>; erst im Schleifenkopf(!) der grünen <for … next>-Schleife initialisiert, sodass es sich bei dieser um eine lokale Variable handelt, die ihre Gültigkeit nur innerhalb(!) der Funktion <anzeigen_Zeitdauer> hat!

 

Variablen, die im Hauptprogramm <beim Start> oder <dauerhaft> deklariert oder initialisiert werden, nennt man globale Variabeln, die ihre Gültigkeit über alle Funktionen hinweg haben und sich demzufolge quasi von überallher im Programm nutzen lassen!

 

Wenn man den Dateninhalt einer lokalen Variable einer Funktion auch nach außen hin für das Hauptprogramm verfügbar machen will, dann muss man den Dateninhalt der lokalen Variable an eine entsprechende globale Variable übergeben. In JavaScript sähe das Statement dann folgendermaßen aus: <let globale_Variable = lokale_Variable>; Dabei müssen natürlich beide Variablen vom gleichen Typ (numerisch, alphanumerisch oder boolesch) sein oder zuvor entsprechend umgewandelt werden!

 

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.

 

Knackpunkt ist nun, dass ein Array z.B. n = 100 Einzelelemente enthält, deren Index bei Index = 0 beginnt und bei Index = 99 endet. Das Ermitteln der Länge eines Arrays mit dem Statement

 

 

bezieht sich dabei zwar auf die Länge eines Arrays, berücksichtigt dabei aber eben nicht, dass der Index des ersten Arrayelements n = 1 beim Index = 0 beginnt! Das ist dann der Grund dafür, dass man von der ermittelten Array-Länge ein Array-Element subtrahieren muss, um den Index des letzten Array-Elements nmax zu erhalten: Index nmax = Länge l – 1.

 

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

    …

}

 

Dadurch dass der Schleifenzähler Index von 0 an bis auf 45 hoch zählt, d.h. sich vergrößert, verringert sich gleichzeitig im Umkehrschluss die aktuelle Stockwerkanzeige schrittweise um den entsprechenden Index-Wert und zwar von 45 bis auf 0 mittels des Algorithmus <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> = 54 = 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)!

 

Was dabei noch wichtig ist, dass man beim Programm im Projekt „proxi-roboter-p-13 stets mit Millisekunden [ms] rechnet, obwohl die Zeitstempel dabei ziemlich lang und in der Laufschrift auch unübersichtlich sind. Der Grund dafür ist der, dass die Umrechnung der Millisekunden [ms] in Sekunden [s] inkl. zweier Nachkommastellen zu ziemlich ungenauen Werten führt, die gerade bei einer kurzen Zeitdauer von nur wenigen Sekunden [s] zu entsprechenden Ungenauigkeiten führt, die man tunlichst vermeiden sollte!

 

Demzufolge werden nur die 30 s der Variablen <zeitdauer_Timer> für den Count down mit 1000 multipliziert, um diese in 30 000 ms umzurechnen:

 

 

 

Alle anderen Variablen rechnen ebenfalls in Millisekunden. Das gilt auch für die Ergebnisanzeige in der Laufschrift, auch wenn diese wegen der Stellenanzahl ungewohnt lang und deshalb schwer lesbar ist! -

 

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.

 

Nachfolgend geht es darum, dass wir aus dem Quellkode zwei verschiedener Programme ein neues Programm durch Zusammenfügen des Quellkodes erzeugen und diesen in einem neuen Programm abspeichern.

 

Leider geht das wider Erwarten nicht mit der „MakeCode“-Programmierumgebung, weil man dazu einen grafischen Editor, ähnlich einem Grafik- oder Design-Programm zum Zeichnen und Malen bräuchte.

 

Außerdem verhält es sich so, dass die sogenannte Copy & Paste“-Funktion unter Windows nur für Text, aber eben nicht für Grafik, zur Verfügung steht! Demzufolge müssen wir die „MakeCode“-Programmierumgebung auf die „JavaScript“-Programmierumgebung umschalten!

 

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

)

let schalter_1 = false

 

basic.forever(function () {

    if (input.buttonIsPressed(Button.A)) {

        schalter_1 = true

    }

    if (input.buttonIsPressed(Button.B)) {

        schalter_1 = false

    }

    if (schalter_1 == true) {

        serial.writeString("#this*")

    }

})

 

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!)

 

Wichtig bei der Programmierung der seriellen Datenübertragung nebst Textstring-Anzeige ist, dass wir anstelle des Statements <serial.writeString("…")> das Statement <serial.writeLine("…")> verwenden, da sich das Statement <serial.writeString("…")> nur in einer Endlosschleife einsetzen lässt (siehe blauer Kasten).

 

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!)

 

>>

Variablen in einer Blockstruktur

 

Ein wichtiges Konzept von Programmiersprachen ist das Unterprogramm, ob es nun Prozedur, Funktion, Methode oder noch anders heißt.

Die allgemeinste Form dieses Konzepts ist der in der Programmiersprache Algol 60 erstmals eingeführte Block. Praktisch alle Programmiersprachen, die dieses Konzept in irgendeiner Form anbieten, erlauben es, dass Blöcke ihre eigenen Variablen besitzen, die sich von den Variablen anderer Blöcke eindeutig unterscheiden lassen. Solche Variablen heißen lokale Variablen. Eine Variable, die im ganzen Programm für alle Blöcke zur Verfügung steht, heißt globale Variable.

 

Die Programmiersprache PHP kennt sogar den Begriff einer superglobalen Variable, die für alle Programme verfügbar sind, die zur selben Zeit von einem PHP-Interpreter bearbeitet werden.

 

Globale Variablen sind scheinbar bequem, weil sie im ganzen Programm sichtbar sind. Es ist nicht notwendig, sie beim Aufruf einer Funktion als Parameter zu übergeben.

 

Sie werden aber auch leicht zur Fehlerquelle, wenn man zum Beispiel eine globale Variable versehentlich oder sogar bewusst für verschiedene Zwecke benutzt.

 

Auch kann es passieren, dass man eine lokale Variable mit dem Namen der globalen Variablen verwendet, von dem man annimmt, dass er im Programm bisher noch nicht benutzt wurde. Wenn es diesen Namen aber schon als Variable mit passendem Typ gibt, sofern dieser überhaupt vom Compiler oder vom Laufzeitsystem geprüft wird, dann wird deren Wert unkontrolliert überschrieben und umgekehrt. Ein schwer zu findender Fehler ist oft die Folge.

 

Erfahrene Entwickler verwenden globale Variablen nur auf modularer Ebene und nur dann, wenn es sich nicht vermeiden lässt. << (Quelle: Wikipedia)

 

 

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.

 

Da wir ja noch Programmier-Anfänger sind und auch Anfänger im Umgang mit dem „micro:bit“-Rechner sind, sollten wir diesen Umstand jetzt zum Anlass nehmen und den Grundlagen-Lehrgang zum „micro:bit“-Rechner und dessen Programmierung von Anfang an grundlegend durcharbeiten!

 

Wer aber meint, er könne sich jetzt an dem Grundlagen-Lehrgang zum „micro:bit“-Rechner einfach so auf die Schnelle vorbeimogeln, wird sehr schnell die Erfahrung machen, dass er wegen der Wissenslücken eher früher als später auf die Nase fällt und fortgeschrittene Dinge nicht versteht, weil er die Grundlagen nicht gelernt hat! -

 

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>.

 

Der Grund dafür ist der, dass die Prozessorleistung des „micro:bit“-Rechners begrenzt ist, sodass dieser nicht beliebig viele Programmfunktionen gleichzeitig, sondern immer nur nacheinander auszuführen vermag.

 

Wenn man aber will, dass der Prozessor sofort einen bestimmten Befehl oder eine bestimmte Programmfunktion ausführt, dann geht das nur, wenn man bereits laufende Programmanwendungen gezielt mittels Interrupt unterbricht, um dann die „Spezialanwendung“ sofort mittels der freigewordenen Rechenkapazität und Rechenleistung auszuführen.

 

In diesem Zusammenhang müsste man halt wissen, ob einer der Taster <Knopf_A> oder <Knopf_B> beim Drücken einen Interrupt auslöst oder nicht.

 

Dies scheint aber eher nicht der Fall zu sein, denn wenn die Laufschrift gerade einen Textstring im LED-Display anzeigt, dann lässt sich diese eben nicht durch einen Tastendruck auf einen der Taster <Knopf_A> oder <Knopf_B> unterbrechen, um eine andere Programmfunktion sofort aufzurufen und auszuführen!

 

Dazu muss man aber wissen, dass die durch den Tastendruck auf einen der Taster <Knopf_A> oder <Knopf_B> initiierte Programmfunktion, wie z.B. das „schnellere“ Hoch- oder Runterzählen, zu einem späteren Zeitpunkt baldmöglichst, d.h. nach der erfolgten Laufschriftanzeige, ausgeführt wird!

 

In diesem Zusammenhang sollte man auch wissen, dass bei einem Windows- oder Linux-PC jeder Tastendruck auf der angeschlossenen Tastatur zunächst in einem sogenannten Tastaturpuffer gespeichert wird, um dann später die ganze Kette von Tastaturanschlägen umgehend auszuführen.

 

Bei dem „micro:bit“-Rechner verhält es sich allerdings so, dass sich zwar während der Laufschriftanzeige im LED-Display jederzeit einer der Taster <Knopf_A> oder <Knopf_B>  - auch mehrfach -  drücken lässt, dies aber wider Erwarten ohne Reaktion bleibt, weil der kleine Rechner offensichtlich über keinen integrierten Tastatur- bzw. Tastenspeicher verfügt!

 

Demzufolge macht es also keinen Sinn, einen der Taster <Knopf_A> oder <Knopf_B> wie wild zu drücken, während noch die Laufschrift im LED-Display angezeigt wird!

 

Vielmehr sollte man die Anzeige der Laufschrift im LED-Display in Ruhe abwarten und erst kurz nachdem der letzte Buchstabe oder die letzte Ziffer angezeigt wurde, einen der Taster <Knopf_A> oder <Knopf_B> drücken!

 

Aufgrund des geschilderten Sachverhalts muss man also beim „Count down“-Programm zum Projekt „proxi-roboter-p-22 jederzeit damit rechnen, dass sich das Programm etwas zickig oder unvorhergesehen verhält.

 

Und dafür gibt es einen weiteren Grund und zwar den, dass die beiden Taster <Knopf_A> und <Knopf_B> offensichtlich weder hardwaremäßig noch softwaremäßig durch das Betriebssystem entprellt wurden. Praktisch bedeutet dies, dass ein einziger Tastendruck dazu führen kann, dass dieser innerhalb eines kleinen Zeitfensters gleich mehrfach ausgelöst werden kann (siehe Screenshot weiter oben)!

 

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:

 

  1. Starten und Ausführen des Programms

 

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.

 

  1. Einstellen des Startzählwertes

 

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!)

 

  1. Starten, Anhalten und Fortsetzen des „Count down“-Timers

 

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!

 

  1. Zwischenzeitliches Anzeigen des Zählwertes

 

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:

 

  1. Starten und Ausführen des Programms

 

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.

 

  1. Einstellen des Startzählwertes

 

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!)

 

  1. Starten, Anhalten und Fortsetzen des „Count down“-Timers

 

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!

 

  1. Starten, Anhalten und Fortsetzen des „Count up“-Timers

 

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!

 

  1. Zwischenzeitliches Anzeigen des Zählwertes

 

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!

 

Beim Statement im roten Kasten handelt es sich um eine engl. <if …then …>-Abfrage, d.h. <wenn … dann…>-Abfrage: <Wenn die Bedingung (input.pinIsPressed(TouchPin.P0)), dass der „Taster“ am Port „Pin P0“ gedrückt wurde, erfüllt ist, dann soll der nachfolgende Programmkode { … } ausgeführt werden>.

 

Und beim Statement im grünen Kasten handelt es sich um die Echtzeit(!)-Abfrage, ob der „Taster“ am Port „Pin 1“ zwischenzeitlich in der Endlosschleife <forever> gedrückt wurde.

 

Während man also im Hauptprogramm bei der <if …then …>-Abfrage in der Endlosschleife <forever> darauf warten muss, bis die <if …then …>-Abfrage zwecks Ausführung an der Reihe ist, wird die Echtzeit(!)-Abfrage im grünen Kasten, ob der „Taster“ am Port „Pin 1“ gedrückt wurde, sofort ohne Wartezeit ausgeführt!

 

Damit sich die Echtzeit(!)-Abfrage im grünen Kasten, ob der „Taster“ am Port „Pin 1“ gedrückt wurde, sofort ohne Wartezeit ausführen lässt, muss diese einen Interrupt auslösen. Dabei verhält es sich so, dass der Interrupt automatisch ausgelöst wird, sodass sich weder der Programmierer noch der Anwender darum kümmern müssen!

 

Da die Echtzeit(!)-Abfrage nebst Interrupt im grünen Kasten den normalen Programmablauf sofort unterbricht, sollte man mit Echtzeit(!)-Abfragen bzw. mit Statements, die einen Interrupt zur Folge haben, möglichst sparsam umgehen und diese nur bei wirklich zeitkritischen Dingen anwenden!

 

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 ]