[ electronic 159 ] [ Seitenende ] [ zurück ]

 

 

 

electronic 159 – Programmieren 3

 

 

Der analoge/digitale Batterie-Tester

 

Bei dem micro:bit“-Rechner ist nicht zu übersehen, dass dieser an seiner Unterseite der Vorder- und Rückseite über eine Kontaktleiste mit vielen schmalen Kontaktzungen und fünf großen Rundbuchsen „ verfügt, sodass sich in diese sogenannte Bananenstecker einstecken lassen:

 

    

 

(Zum Vergrößern bitte auf eines der Bilder klicken!)

 

Dabei sind die fünf großen Rundbuchsen „ der Reihe nach von links nach rechts mit „0“, „1“, „2“, „3V“ und „GND“ beschriftet.

 

Die Beschriftung „3V“ bedeutet, dass an dieser Rundbuchse eine externe Versorgungsspannung von Uext = 3 V zur Verfügung steht, aber nur dann, wenn der micro:bit“-Rechner nicht über das Micro-USB-Kabel mit Strom versorgt wird, sondern über ein externes Batteriepack mit zwei in Reihe geschalteten 1,5 Volt Batterien vom Typ „Micro AAA.

 

Die Beschriftung „GND“ bedeutet, dass an dieser Rundbuchse die sogenannte Masse, engl. „ground“, als gemeinsames Bezugspotential „ mit dem neutralen Spannungspotential „0 Volt“ zur Verfügung steht! Sozusagen im Gegensatz zur Rundbuchse mit der Beschriftung „3V“ und dem positiven (+) Spannungspotential „3 Volt“, d.h. Uext = 3 V.

 

Wie man oben in den beiden Bildern des micro:bit“-Rechners sieht, handelt es sich bei der linken Rundbuchse „0“ um den analogen Eingang Pin „P0“. Diesbezüglich muss man wissen, dass der micro:bit“-Rechner sowohl über analoge als auch digitale Ein- und Ausgänge verfügt, die sich auch programmieren lassen!

 

Was aber ist ein analoger Eingang?

 

An einen analogen Eingang lässt sich ein analoges Eingangssignal, wie z.B. eine Gleichspannung, eine Wechselspannung, ein Rechteck-, Sägezahn- oder PWM-Signal anlegen, d.h. einlesen, messen, auswerten und programmieren!

 

Dabei darf die Eingangsspannung, d.h. die Amplitude, den Wert von UPin P0 3 VSS gegenüber der Masse Pin „GND“ () nicht überschreiten!

 

Damit sich das analoge Eingangssignal am Pin „P0“ (und dem Masse Pin „GND“ () ) später mittels Computerprogramm digital auswerten lässt, muss es zuvor von analog auf digital umgewandelt werden. Dies geschieht mit einem sogenannten A/D-Wandler, d.h. Analog-/Digital-Wandler.

 

Dabei wird ein zeitlich veränderliches Signal in Form der grauen, zeitabhängigen Schwingung von roten Rechteckimpulsen einer bestimmten zeitlichen Breite abgetastet

 

 

(Zum Vergrößern auf das Bild klicken! Quelle: Wikipedia)

 

und in digitale Werte aus dem Bereich [ 0, …, 1023 ] Bits umgewandelt:

 

 

(Zum Vergrößern auf das Bild klicken! Quelle: Wikipedia)

 

Wenn wir also z.B. ein analoges Eingangssignal von UBatt = 1,5 V an Pin „P0“ (+) und Pin „GND“ () anlegen, dann wird dieses vom A/D-Wandler in folgenden digitalen Wert umgewandelt:

 

3,3 V      1023 Bit

1,5 V            x Bit

________________

 

x = 1023 Bit / 3,3 V * 1,5 V = 465 Bit

 

Dabei gilt es zu beachten, dass sich der umgewandelte Bitwert im Bereich [ 0, …, 1023 ] Bit bewegt, sodass wir es insgesamt mit 1024 verschiedenen Bitwerten zu tun haben!

 

Dabei entsprechen dezimale 102310 Bits im Dezimalzahlensystem einem hexadezimalen Wert von

 

3FF16 = 3 * 162 + 15 * 161 + 15 * 160 = 3 * 256 + 15 * 16 + 15 * 1 = 102310

 

und

 

40016 = 4 * 162 +   0 * 161 +    0 * 160 = 4 * 256 +  0 * 16 +   0 * 1 = 102410

 

Wenn man den hexadezimalen Wert 3FF16 um hexadezimal +116 erhöht, dann gibt es einen hexadezimalen Überlauf in die nächste höhere hexadezimale Dekade!

 

Addiert man nämlich zu 0F16 den Wert +116, dann folgt auf das F16 die nächste höhere hexadezimale Zahl 016, weil nach F16 alles wieder von vorn, d.h. bei 016 anfängt, sodass wir wegen des Überlaufs von +116 „… eine Eins im Sinn!“, in die nächste höhere hexadezimale Dekade aufsteigen: 0F16 + 116 = 1016.

 

Übrigens:

 

Der hexadezimale Zahlenbereich geht in der ersten hexadezimalen Dekade von [ 0, …, 9, A, B, …, F ] mit z.B. A16 = 1010, C16 = 1210 und F16 = 1510 .

 

Der dezimale Wert 102310 selbst setzt sich dekadisch, d.h. zur Basis 10, wie folgt zusammen

 

102310 = 1 * 1000 + 0 * 100 + 2 * 10 + 3 * 1 = 1 * 103 + 0 * 102 + 2 * 101 + 3 * 100

 

und der dezimale Wert 102410

 

102410 = 1 * 1000 + 0 * 100 + 2 * 10 + 4 * 1 = 1 * 103 + 0 * 102 + 2 * 101 + 4 * 100

 

Der hexadezimale Überlauf von 3FF16 + 116 = 40016 wird binär im dualen Zahlensystem zur Basis 2 noch anschaulicher:

 

3FF16 = 11 1111 11112 + 12 = 100 0000 00002 = 40016

 

Wenn du z.B. jemanden ein Schimpfwort an den Kopf knallen willst, ohne dass man dich dafür strafrechtlich wegen Beleidigung zur Verantwortung ziehen kann, dann sag der betreffenden Person einfach „Du dummer 4505410 !“ Dabei handelt es sich um den dezimalen Wert 4505410, der sich in den hexadezimalen Wert AFFE16 umwandeln lässt!

 

Diesbezüglich muss man aber die Umrechnung von dezimal10 auf hexadezimal16 nicht zu Fuß machen!

 

Beim Windows-Betriebssystem gibt es nämlich standardmäßig einen leistungsfähigen Taschenrechner, der sich mittels der Einstellung auf „Programmierer“ umstellen lässt, sodass man dann auch in und mit verschiedenen Zahlensystemen von binär (= zur Basis 2), oktal (zur Basis 8), dezimal (zur Basis 10) bis hexadezimal (zur Basis 16) rechnen und umrechnen kann. -

 

 

Worin unterscheidet sich ein digitaler Batterietester von einem analogen?

 

Ein analoger Batterietester testet die Batterie analog, d.h. mit einem kleinen Drehspul-Messinstrument das die gemessene Spannung U in Volt [V] auf einer entsprechenden Skala anzeigt:

 

 

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

 

Da die meisten Batterietester keinen Lastwiderstand zwecks Belastung der Batterie verwenden, handelt es sich bei diesen eher um ein Spannungsmesser im Sinne eines Spannungsmessgerätes (= Voltmeter), das demzufolge eher die Leerlaufspannung der Batterie als die Dauerspannung bei entsprechender Belastung anzeigt.

 

Auch bei den meisten digitalen Batterietestern wird kein Lastwiderstand zwecks Belastung der Batterie verwendet, sodass es sich bei diesen ebenfalls um ein Spannungsmesser handelt, der die Leerlaufspannung der Batterie anzeigt und eben nicht die deutlich geringere Spannung unter entsprechender Last!

 

Im Gegensatz zum analogen Batterietester, verwendet der digitale kein Drehspulmessgerät zum Anzeigen der gemessenen Spannung, sondern eine Digitalanzeige z.B. in Form einer LED- oder LCD-Anzeige. Diesbezüglich verwenden der micro:bit“- als auch der „Calliope mini“-Rechner eine 9 x 9 LED-Matrix, wobei ein längerer Text oder ein großer, mehrstelliger Zahlenwert als Laufschrift dargestellt werden.

 

Außerdem verwenden digitale Batterietester eingangsseitig einen sogenannten A/D-Wandler, der die zu messende, analoge Spannung in einen entsprechenden Digitalwert umwandelt (siehe oben).

 

So, nun wird es aber Zeit, dass wir unseren digitalen Batterietester endlich selbst programmieren:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_01.js)

 

Wie man anhand des obenstehenden „Block“-Programms sieht, wird direkt nach dem Starten des Programms der Bildschirminhalt gelöscht und die Laufschrift „Batterie-Tester“ als Textstring im 9 x 9 großen LED-Matrix-Bildschirm angezeigt.

 

Anschließend geht das Programm sozusagen in Lauerstellung und wartet darauf, dass der Taster „A“ gedrückt wird. Ist dies irgendwann der Fall, wird nach dem Tastendruck auf den Taster „A“ die Bildschirmanzeige gelöscht und der Port vom Pin „P0“ am Rundloch „0“ abgefragt, die dort anliegende Spannung UPin 0 gemessen, in einen entsprechenden Digitalwert umgewandelt und als Laufschrift im Display angezeigt.

 

Messung einer schwachen, größtenteils verbrauchten 1,5 Volt Batterie:

 

1.    Messung: Anzeige des Binärwertes = 456 Bit      UBatt = 1,34 V im Leerlauf, d.h. ohne Last!

2.    Messung: Anzeige des Binärwertes = 371 Bit      UBatt = 1,09 V unter Last!

 

Wie man der Tabelle des Batterietesters „TAKIT Batterietester Digital entnehmen kann, sollte eine 1,5 Volt Batterie mit einer Batteriespannung von weniger als 1,15 V ausgewechselt, engl. „replace“, werden!

 

Bei der Programmierung des Batterietesters geht es eben nicht nur darum, dem Anwender, der die Batterie testet, einen Binärwert mitzuteilen, der am Port vom Pin „P0“ gemessen wurde und mit dem der Anwender zunächst nichts anfangen kann.

 

Deshalb müssen wir dem Anwender helfen und ihm eine Entscheidungshilfe an die Hand geben, indem wir nachfolgend einen Abfrage-/Grenzwert programmieren, der beim Unterschreiten dazu führt, dass eine Meldung in Form eines aussagekräftigen Symbols wie z.B. L angezeigt wird, um auf diese Weise zu signalisieren, dass die Batterie ausgewechselt werden sollte.

 

Gemäß der Tabelle des Batterietesters „TAKIT Batterietester Digital geht es darum, dass man den Abfrage-/Grenzwert von Uersetzen = 1,15 V zunächst wie folgt mittels Dreisatz in den entsprechenden Bitwert umrechnet:

 

3,3 V      1023 Bit

1,15 V           x Bit

________________

 

x = 1023 Bit / 3,3 V * 1,15 V 356 Bit

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_02.js)

 

Der obenstehende Dreisatz lässt sich natürlich auch umgekehrt anwenden, um den binären Messwert in einen Spannungswert, gemessen in [ Volt ] = [V] umzurechnen:

 

1023 Bit       3,3 V

  356 Bit         x  V

________________

 

x = ( 3,3 V / 1023 Bit ) * 356 Bit = 1,1484 V ≈ 1,15 V

 

Bei dem Messwert von 356 Bit handelt es sich bezüglich der Programmierung um den aufgenommenen Messwert Port vom Pin „P0“, den es in einen äquivalenten Dezimalwert umzurechnen gilt.

 

Zu diesem Zweck benutzen wir die temporäre (Hilfs-) Variable temp und weisen dieser den Ergebniswert

 

·       Statement temp = 3.3 / 1023 (= 0,00323 V/Bit) zu.

 

Des Weiteren multiplizieren wir den Ergebniswert mit dem aufgenommenen Messwert vom Port vom Pin „P0“: (= 356)

 

·       Statement temp = temp * 356 (= 0,00323 V/Bit * 356 Bit = 1,14988 V ≈ 1,15 V )

 

Anschließend wird der neue Ergebniswert der temporären (Hilfs-) Variable temp der Variablen „digital_pin_p0“ zugewiesen:

 

·       Statement digital_pin_p0 = temp

 

Mit dem

 

·       Statement zeige Zahl digital_pin_p0 (= 1,15 V)

 

wird dann der errechnete Spannungswert von UBatt = 1,15 V als Laufschrift im LED-Display angezeigt.

 

Da man es dem Anzeigewert „1,15“ von außen nicht ansieht, worauf sich dieser bezieht, wird mit dem

 

·       Statement zeige Text „Volt“

 

noch die Maßeinheit [ Volt ] hinzugefügt, damit der Anwender weiß, dass die gemessene Batteriespannung UBatt = 1,5 V einer 1,5 Volt Batterie angezeigt wird:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_03.js)

 

Nach der Anzeigepause von 500 ms gemäß dem

 

·       Statement pausiere (ms) 500

 

geht es weiter mit der Auswertung des Messergebnisses und zwar in Form einer sogenannten „Wenn …dann“-Abfrage, die an die Bedingung „analoge Werte von Pin P0 > 356 wie folgt geknüpft ist:

 

·       Statement wenn analoge Werte von Pin P0 > 356 dann

o      Statement zeige Symbol J

Statement ansonsten

o      Statement zeige Symbol L

 

Die im obenstehenden Programm „programm_03_03.js“ verwendete, temporäre (Hilfs-) Variable temp mag zwar im ersten Moment für den weniger erfahrenen Programmieranfänger bezüglich des Verständnisses hilfreich sein, lässt sich aber trotzdem durch die eigentliche Variable „digital_pin_p0“ mühelos ersetzen, sodass das Programm kompakter wird und professioneller aussieht:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_04.js)

 

Im obenstehenden Block“-Programm „programm_03_04.js“ gibt es noch ein interessantes Statement, das noch näher beleuchtet werden soll. Und zwar das

 

·       Statement zeige Text ( verbinde ( wandle( digital_pin_p0 ) um in Text + “ V“ ) )

 

Um das Statement besser verstehen zu können, muss man bei den vielen Klammerausdrücken in der Mitte anfangen! Und zwar bei der numerischen Variablen „digital_pin_p0“, die den z.B. inzwischen umgerechneten numerischen Messwert digital_pin_p0 = 1,15 enthält.

 

Wenn man sich in der Entwicklungsumgebung bei den Block“-Befehlen zu den Grundlagen umschaut, dann gibt es zwecks Anzeige von Inhalten, engl. „contents“, auf das LED-Display zwei Statements:

 

1.    zeige Text Hello und

2.    zeige Zahl 0

 

Dabei dient das 1. Statement zeige Text Hello dazu, um alphanumerische Inhalte, d.h. einzelne Buchstaben, einen Textstring (= Zeichenkette) oder Ziffern (= aus Zahlen abgeleitet) auf dem LED-Display in Form der Laufschrift anzuzeigen. Zur Erinnerung: mit Ziffern kann man nicht rechen, da sie keine Zahlen sind!

 

Das 2. Statement zeige Zahl 0 dient ausschließlich dazu eine ganzzahlige Zahl (vom Typ „inter“), einen Zahlenwert wie z.B. eine Dezimalzahl (vom Typ „float“) auf dem LED-Display in Form der Laufschrift anzuzeigen.

 

Da man dem in der numerischen Variablen „digital_pin_p0“ gespeicherten Dezimalzahlenwert 1,15 wegen der fehlenden Maßeinheit nicht ansieht, dass es bei diesem um eine Spannung von 1,15 Volt mit der Maßeinheit [V] handelt, müssen wir uns als Programmierer selbst darum kümmern und den Anwender entsprechend dazu informieren!

 

Programmiertechnisch bedeutet dies, dass wir den Inhalt der numerischen Variablen „digital_pin_p0“ in einen Textstring im Sinne einer Ziffernfolge wie folgt umwandeln müssen:

 

·       Statement wandle( digital_pin_p0 ) um in Text

 

Und, wenn dann der Inhalt der numerischen Variablen „digital_pin_p0“ in einen Textstring im Sinne einer Ziffernfolge umgewandelt wurde, lässt sich an den Textstring ein weiterer Textstring wie z.B. + „ V“ anfügen

 

·       Statement verbinde ( wandle( digital_pin_p0 ) um in Text + “ V“ )

 

und anschließend auch als Textstring auf dem LED-Display in Laufschrift anzeigen:

 

·       Statement zeige Text ( verbinde ( wandle( digital_pin_p0 ) um in Text + “ V“ ) )

 

Da das Ganze doch etwas sperrig aussieht und demzufolge die Syntax (= Satzbau) gewöhnungsbedürftig ist, schauen wir uns den Quellkode alternativ in der „JavaScript“-Programmierung an:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_04.js)

 

Wie man im obenstehenden Quellkode von JavaScript sieht ist das

 

·       Statement basic.showString("" + convertToText(digital_pin_p0) + " V")

 

doch deutlich kompakter als das Statement im Block“-Programm:

 

·       Statement zeige Text ( verbinde ( wandle( digital_pin_p0 ) um in Text + “ V“ ) )

 

Einen „Nachteil“ hat aber der Quellkode von JavaScript dann doch: er ist auf Englisch!

 

Schauen wir uns noch zum Vergleich noch den Quellkode der Python“-Programmierung an:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_04.py)

 

Wir entwickeln das obenstehende Python“-Programm und verbessern es dahingehend, dass wir nur noch eine einzige Abfrage am Port vom Pin „P0“ vornehmen, um die Batteriespannung zu erfassen und einzulesen:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis microbit-programm_03_05.py)

 

Wir wechseln die Hardware und benutzen den „Calliope mini“-Rechner, indem das obenstehende Python“-Programm abändern, weil sich der analoge Eingang mit dem A/D-Wandler am Port „Pin P1 befindet:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_05.py)

 

Bei den bisherigen „Block“-, „JavaScript“- oder Python“-Programmen zum Batterietester verhält es sich so, dass wir bei den Dezimalwerten der numerischen Variablen „digital_pin_p0 (beim micro:bit“-Rechner) bzw. „digital_pin_p1 (beim „Calliope mini“-Rechner) wegen des Rechnens mit Fließkommazahlen vom Typ „float“ mit bis zu neun Nachkommastellen rechnen, die ja nach dem vom Programm berechneten Ergebniswert auch tatsächlich im 9 x 9 LED-Matrix-Display als Laufschrift angezeigt wird.

 

Und zwar mit dem Nachteil, dass der Anwender, der sich auf die Laufschrift konzentriert, plötzlich in dieser mit mehr Nachkommastellen konfrontiert wird, auf die er gar nicht vorbereitet ist und mit denen er auch nicht gerechnet hat. Mit der nachteiligen Folge, dass er sich die ersten drei bis vier Ziffern nicht gemerkt hat, nicht merken konnte, sodass der Anwender die Messung der Batteriespannung wiederholen muss und dabei wieder mit x-Nachkommastellen konfrontiert wird!

 

Demzufolge müssen wir den Anwender entlasten, indem wir den Ergebniswert bis auf zwei Nachkommastellen verkürzen, d.h. abschneiden (oder später abrunden).

 

Beispiel:

 

Wenn man z.B. die Dezimal-/Fließkommazahl 1,23456789 bis auf zwei Nachkommastellen verkürzen will, dann muss man diese mit dem Faktor 100 multiplizieren:

 

Ergebniswert = Ergebniswert * 100 = 1,23456789 * 100

 

                       = 123,456789      Nachkommstellen abschneiden  

 

                       = 123456789      die Multiplikation wieder mit Division durch 100 rückgängig machen!

 

                       = 123 / 100 = 1,23      neuer Ergebniswert!

 

Demzufolge muss man also drei weitere Statements programmieren (siehe roter Kasten):

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_06.py)

 

Das obenstehende Block“-Programm des „Calliope mini“-Rechners lässt auch nach „JavaScript“ konvertieren,

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_06.js)

 

Besonders interessant am obenstehenden JavaScript“-Programm ist nun das

 

·       Statement digital_pin_p1 = Math.trunc(digital_pin_p1)

 

bei dem der trunc“-Befehl zum Abschneiden der Nachkommastellen eingesetzt wird.

 

Wenn der trunc“-Befehl wider Erwarten aber nicht Bestandteil des internen Befehlsvorrates der im „Calliope mini“-Hardware im ROM-Speicher hinterlegten Programm-Bibliothek, engl. „library“ ist, dann muss die Bibliothek Math zum Zeitpunkt des Kompilierens (= Übersetzen des Quellkodes in Maschinen-/Prozessorkode) von außen aus dem Internet nachgeladen werden. Und zwar in die Entwicklungsumgebung des Calliop mini“ von Microsoft, sodass der Anwender und Programmierer davon praktisch nichts mitbekommt bzw. sich um nichts kümmern muss.

 

Spannend wird es gleich wieder, wenn wir das JavaScript“-Programm „mini-programm_03_06.js“ per Mausklick in das Python“-Programm „mini-programm_03_06.py“ umwandeln:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_06.py)

 

Wie man im obenstehenden Screenshot sieht, wurde das

 

·       Statement digital_pin_p1 = Math.trunc(digital_pin_p1)

 

in „JavaScript“ wie folgt nach „Python“ konvertiert:

 

·       Statement digital_pin_p1 = int(digital_pin_p1)

 

So weit, so gut, könnte man sagen. Wenn es da nicht ein kleines Problem gäbe, nämlich, dass sich das Python“-Programm wider Erwarten nicht kompilieren lässt, weil es in „Python“ keinen integer“-Befehl gibt, um eine Fließkommazahl (= Dezimalzahl) in einen ganzzahligen Integer“-Wert umzuwandeln bzw. abzuschneiden. Zumindest könnte man das meinen. Der Grund dafür ist aber ein anderer, weil wir mit dem „Calliope mini“- oder dem micro:bit“-Rechner in Wirklichkeit mit der Programmiersprache „MicroPython programmieren, die speziell für Microcontroller quasi „abgespeckt“ wurde, damit der kleine ARM Cortex M0“-Prozessor nicht überlastet wird.

 

Aber wir wissen ja inzwischen, dass es in „JavaScript“ den Befehl Math.trunc() gibt, mit dem sich eine Fließkommazahl, d.h. die Nachkommastellen abschneiden lassen.

 

Und, Überraschung: in MicroPython gibt es den gleichen Befehl Math.trunc() aus der Library Math für mathematische Funktionen ebenfalls:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_07.py)

 

Dabei beherbergt die Library Math keine Datenbank mit MicroPython“-Einzelbefehlen, sondern vielmehr eine Datenbank mit mathematische Funktionen!

 

Dabei lässt sich eine Funktion durchaus als kleine schwarze Schachtel, engl. black box, vorstellen, in die man über den Funktionskopf etwas hinein gibt, in Funktionsrumpf Handlungsanweisungen ähnlich einem Rezept abarbeitet und sich die Ergebnisse im Funktionsfuß mittels des return“-Befehls wieder ausgeben lässt. Dabei arbeitet eine Funktion nach dem sogenannten EVA“-Prinzip. Dabei steht die Abkürzung „EVA“ für Eingabe, Verarbeitung, Ausgabe. Demzufolge werden Daten, z.B. in Form von Variableninhalten, über den Funktionskopf eingelesen, im Funktionsrumpf gemäß „Rezeptur“ verarbeitet und die Ergebnisse über die „return“-Ausgabe wieder an das Hauptprogramm zurückgegeben.

 

Muss ich mir das merken, das mit dem EVA-Prinzip und der Funktion?

 

Lernpsychologisch ist es ungünstig, wenn ich mir etwas merken soll, etwas merken muss, von dem ich noch gar nicht weiß, worin der Nutzen liegt, was ich davon persönlich habe, was mir das bringt.

 

Viel besser wäre es doch, wenn ich mir Dinge einfach so merke, d.h. vom Kurzzeitgedächtnis ins Langzeitgedächtnis bringe, sozusagen ohne dass ich es merke, ohne dass ich mich dabei anstrengen muss. Und, das gelingt tatsächlich! Nämlich immer dann, wenn mir Dinge Spaß machen! Und, wann machen Dinge Spaß? Ganz einfach, wenn es mit Spielen zu tun hat, wenn sich Dinge spielerisch vollziehen. Quasi so ganz nebenbei.

 

Im praktischen Leben gibt es viele Dinge, die wie selbstverständlich funktionieren. Einfach so! Einschalten, sofort loslegen und dann schauen, was passiert, oder? Und, wenn es knallt, kommt Freude auf, oder?

 

Na ja, das kann dann schon mal richtig gefährlich werden, wenn ich nicht von vorn herein weiß, was nach dem Einschalten passiert! Deshalb ist es nicht nur wichtig zu wissen, wie ich etwas einschalte, sondern eben auch zu wissen, was nach dem Einschalten passiert, wie ich die Geister, die ich rief, wieder loswerde, wieder in die Flasche zurückbringe und ausschalte!

 

Langer Rede, kurzer Sinn, lassen wir es einfach krachen, programmieren wir in Python eine kleine, einfache Funktion starte_Programm():

 

def starte_Programm():

    basic.clear_screen()

    basic.show_string("Batterie-Tester")

    pass

 

Während eine Variable (= Platzhalter, Unbekannte in der Mathematik) stets deklariert, d.h. erklärt und anschließend initialisiert werden muss, d.h. mit einem konkreten Inhalt, einem (Zahlen-) Wert versehen werden muss, muss eine Funktion (= Rezept, Handlungsanweisung) mittels def [Name_der_Funktion](): definiert werden.

 

„Alles hat ein Ende, nur die Wurst hat zwei!“ gilt auch für Funktionen. Auch sie haben ein Ende. Dies wird durch das

 

·       Statement pass

 

gekennzeichnet, d.h. programmiert:

 

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_08.py)

 

„Eine Funktion ist eine Funktion, ist eine Funktion“ bedeutet, dass es schön und gut ist, wenn es sie gibt und sich diese immer wieder benutzen, d.h. vom Hauptprogramm (oder von einem anderen Programmteil) aus starten lässt:

 

# +++ Hier beginnt das Hauptprogramm +++

 

starte_Programm()

 

Dabei stellt sich dann auch die Frage, was die beiden runden Klammern „()“ im Funktionskopf bedeuten.

 

In den beiden runden Klammern „()“ lassen sich später vom Hauptprogramm aus Daten, d.h. Variableninhalte wie z.B. der Textstring „Batterie-Tester“ oder ein (Zahlen-) Wert an die Funktion „starte_Programm() übergeben bzw. in diese einlesen, z.B. durch die input“-Funktions-Variableget_Textstring:

 

 

def starte_Programm(get_Textstring):

    basic.clear_screen()

    basic.show_string("get_Textstring ")

    pass

 

Das Interessante an der input“-Funktions-Variablenget_Textstring ist, dass sie im Funktionskopf nicht deklariert und initialisiert werden muss, da dies später automatisch mit dem Funktionsaufruf erfolgt:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_09.py)

 

Jetzt, wo wir wissen, was eine Funktion ist, wie diese in Python programmiert wird, stellt sich die Frage, wie man eine Funktion in JavaScript programmiert:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_09.js)

 

Wie man im obenstehenden JavaScript“-Quellkode sieht, werden in JavaScript sogenannte geschweifte Klammern { … } dazu verwendet, um den Programmkode z.B. einer Funktion als einen zusammenhängenden Programmblock zu kennzeichen.

 

Des Weiteren fällt auf, dass die Variable get_inputString innerhalb des Funktionskopfes explizit deklariert werden muss (siehe obenstehenden Screenshot). -

 

Wenn man beim Block“-Programmieren eine Funktion programmieren will, dann muss man vorab wissen, wo und wie man die Programmfunktion „Funktion“ aufruft und in das bestehende Programm einbaut. Aber das ist wirklich nicht schwer, weil eine Funktion ganz einfach durch Anklicken <Funktion> in die bestehende Block“-Programmierung hinzugefügt wird (siehe großer roter Kasten).

 

Damit die Funktion starte_Programm(get_inputString)“ dann später beim Starten des Programms auch ausgeführt wird, muss man diesen noch explizit mit dem

 

·       Statement Aufruf starte_Programm(“Batterie-Tester“)

 

im Programmblock „beim Start“ veranlassen (siehe kleiner roter Kasten):

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_09.hex)

 

Da wir gerade so schön im Flow sind, üben wir das Programmieren bzw. Setzen einer weiteren Funktion, indem wir den Programmteil

 

·       mit der Abfrage am Port „Pin P1,

·       das Verkürzen, engl. „trunc“, des eingelesenen Digitalwertes
der Variablen
„digital_pin_p1“ auf nur noch zwei Nachkommastellen,

·       die Umwandlung (= Konvertierung) des eingelesenen Digitalwertes
der Variablen
„digital_pin_p1“ in einen Textstring und

·       das Anfügen der Maßeinheit [V] (= der Spannung UPin_P1 am Port „Pin P1) an den Textstring
zwecks Anzeige als Laufschrift im LED-Display

 

in die weitere Funktion „anzeigen_PIN_P1“ wie folgt auslagern (siehe großer roter Kasten):

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_10.hex)

 

Wichtig bei der Funktion „anzeigen_PIN_P1“ ist noch, dass wir den eingelesenen Digitalwert der Variablen „digital_pin_p1“ abschließend wieder an die aufrufende Funktion „wenn Knopf A gedrückt“ zurückgeben, um den Variableninhalt mit dem eingelesenen Digitalwert der Variablen „digital_pin_p1“ weiter für die Smiley“-Anzeige J oder L auswerten zu können! -

Hier geht’s dann weiter!

Der zum obenstehenden Block“-Programm zugehörige JavaScript“-Programmkode sieht dann folgendermaßen aus:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_10.js)

 

Beim obenstehenden JavaScript“-Programmkode wurden die einzelnen Funktionsaufrufe und Funktionen in einer bestimmten logischen Zuordnung und Reihenfolge angeordnet:

 

1.    Wir gehen bis zur Zeile 30 nach unten zum Hauptprogramm, deklarieren die Variable „digital_pin_p1“ und initialisieren diese mit der Wert 0, um anschließend die Funktion „starte_Programm('Batterie-Tester“)“ aufzurufen und auszuführen.

2.    Wir gehen zur Zeile 25 nach oben, wo die Funktion „starte_Programm(get_inputString: string) { … }“ zwischenzeitlich gestartet wurde und der mittels der Variablen „get_inputString“ eingelesene Textstring „Batterie-Tester“ über die Laufschrift des LED-Displays angezeigt wird.

3.    Wir gehen zur Zeile 16 nach oben, wo die Funktion „input.onButtonPressed(Button.A, function () { … }) darauf wartet, dass die Taste A des linken Tasters am „Calliope mini“ gedrückt wird.

4.    Wir gehen zur Zeile 4 weiter nach oben, wo die Funktion „anzeigen_PIN_P1 () { … } inzwischen ausgeführt wird, nachdem die Taste A des linken Tasters zuvor gedrückt wurde.

In dieser Funktion wird der am Port
„Pin P1“ eingelesene Digitalwert der Variablen „digital_pin_p1“ auswertet und in die Spannung UPin_P1, gemessen in Volt [V], umgerechnet, auf zwei Nachkommastellen gerundet, d.h. abgeschnitten und mittels des return“-Befehls an die Funktion „input.onButtonPressed(Button.A, function () { … }) zurückgegeben wird.

5.    Wir gehen wieder zur Zeile 16, wo jetzt der Variableninhalt der Variablen „digital_pin_p1“ auswertet und in Form des Smiley J oder L im LED-Display des „Calliope mini“ angezeigt wird.

 

Wenn man das weiter obenstehende Block“-Programm „mini-programm_03_10.hex“ nimmt und in der Microsoft Entwicklungsumgebung des „Calliope mini“ in die Python“-Programmierung umwandelt, dann stellt man erstaunt fest, dass der Microsoft Compiler seine eigene Sichtweise und Auffassung davon hat, wie und in welcher Reihenfolge, nämlich Top-down, d.h. von oben nach unten, die einzelnen Funktionen und Funktionsaufrufe angeordnet werden.

 

Lediglich das Hauptprogramm steht ganz unten am Ende des Quellkodes:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_10.py)

 

Bei dem Batterie-Testprogramm verhielt es sich bisher so, dass nur die Spannung UPin_P1 = 1,2 V am Port „Pin P1“ als Maß der Dinge, d.h. als Kriterium für die Entscheidung, ob die 1,5 Volt Batterie leer ist und deshalb ausgewechselt werden sollte, herangezogen wurde (siehe obenstehendes Programm).

 

Da aber die Batteriehalterung [19] des Elektronik-Baukastens electronic 129“

 

 

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

 

für die Aufnahme zweier 1,5 Volt Batterien vom Typ „Mignon AA in Serie (= hintereinander) vorgesehen ist und der Analogeingang am Port „Pin P1“ mit dem A/D-Wandler (Eingangs-) Spannungen bis UPin_P1 = 3,0 V verarbeitet, bietet es sich an, dass wir unser Python“-Programm „mini_programm_03_10.py“ entsprechend erweitern, sodass sich von jetzt an auch zwei 1,5 Volt Batterien im Doppelpack testen lassen!

 

Demzufolge müssen wir nun bei der Auswertung der über den Analogeingang am Port „Pin P1“ mit dem A/D-Wandler anliegende (Eingangs-) Spannung bis zu drei unterschiedliche Spannungswerte UPin_P1 mittels „Wenn … dann“-Abfrage, engl. „ifthenund „Wenn … nicht, was dann“-Abfrage, engl. „ifthenelse“, abfragen, auswerten und entsprechend darauf reagieren.

 

1.    Zwei 1,5 V Batterien fabrikneu aufgeladen

 

Wenn zwei 1,5 V Batterien vom Typ „Mignon AAfabrikneu aufgeladen sind, dann verfügt jede einzelne Batterie über eine Leerlaufspannung von deutlich mehr als 1,5 V, nämlich von z.B. UBatt, leer ≥ 1,54 V, sodass sich die Gesamtspannung bei zwei in Serie geschalteten Batterien dann schon auf

 

UBatt, ges = 2 * UBatt, leer = 2 * 1,54 V = 3,08 V > 3,0 V þ beläuft.

 

Gemäß der nachfolgenden Tabelle unseres Batterietesters „TAKIT Batterietester Digital“ verhält es sich so, dass eine 3 V Batterie bzw. zwei in Serie geschaltete 1,5 V Batterien dann als engl. „good“, d.h. gut aufgeladen gelten, wenn die Gesamtspannung größer als 3 V ist.

 

2.    Zwei 1,5 V Batterien stark entladen, die zu ersetzen sind

 

Demzufolge gilt eine 3 V Batterie bzw. zwei in Serie geschaltete 1,5 V Batterien als engl. „replace“, d.h. ersetzen, wenn die Gesamtspannung weniger als 2,0 V beträgt:

 

 

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

 

Wenn wir also die beiden in Serie im Batteriehalter [19] eingelegten 1,5 V Batterien darauf testen wollen, ob diese wegen zu starker Entladung und „Verbrauch“ (es wird keine Energie verbraucht, sondern nur umgewandelt!) ersetzen müssen, dann müssen wir eine „Wenn … dann“-Abfrage wie folgt programmieren:

 

Statement

 

if digital_pin_p1 > 2:

        basic.show_icon(IconNames.HAPPY)      Beide Batterien sind voll geladen J !

 

Wenn die beiden in Serie im Batteriehalter [19] eingelegten 1,5 V Batterien nicht voll geladen sind mit UBatt, ges <= 2 V, dann müssen wir die „Wenn … dann“-Abfrage um die „Wenn … nicht, was dann“-Abfrage wie folgt ergänzen:

 

Statement

 

if digital_pin_p1 > 2:

        basic.show_icon(IconNames.HAPPY)      Beide Batterien sind voll geladen J !

else:

        if digital_pin_p1 <= 2:

basic.show_icon(IconNames.SAD)      Beide Batterien müssen ersetzt werden L !

 

Da sich in der Batteriehalterung [19] eine oder zwei in Serie geschaltete 1,5 V Batterien befinden können, müssen wir bei einer am Port „Pin P1“ gemessenen Spannung von weniger als 2,0 V, d.h. UBatt, ges <= 2 V eine weitere „Wenn … dann“-Abfrage programmieren.

 

Bei dieser „Wenn … dann“-Abfrage geht es dann darum, festzustellen, ob sich in der Batteriehalterung [19] eine oder zwei in Serie geschaltete leere, d.h. entladene 1,5 V Batterien befinden!

 

3.    Eine einzelne 1,5 V Batterie stark entladen, die zu ersetzen ist

 

Wenn sich in der Batteriehalterung [19] nur eine stark entladene 1,5 V Batterie befindet, dann müssen wir bei einer am Port „Pin P1“ gemessenen Spannung von weniger als 1,2 V, d.h. UBatt <= 1,2 V eine weitere „Wenn … dann“-Abfrage programmieren:

 

Statement

 

if digital_pin_p1 > 2:

        basic.show_icon(IconNames.HAPPY)      Beide Batterien sind voll geladen J !

else:

        if digital_pin_p1 <= 2:

if digital_pin_p1 <= 1.2:

                basic.show_icon(IconNames.SAD)      Eine Batterie muss ersetzt werden L !

 

4.    Eine einzelne 1,5 V Batterie fabrikneu aufgeladen

 

Wenn sich in der Batteriehalterung [19] nur eine fabrikneu aufgeladene 1,5 V Batterie befindet, dann müssen wir am Port „Pin P1“ eine Spannung von mehr als 1,2 V, d.h. UBatt > 1,2 V messen, sodass wir eine weitere „Wenn … nicht, was dann“-Abfrage (= „else“) wie folgt programmieren:

 

Statement

 

if digital_pin_p1 > 2:

        basic.show_icon(IconNames.HAPPY)      Beide Batterien sind nahezu vollständig aufgeladen J !

else:

        if digital_pin_p1 <= 2:

if digital_pin_p1 <= 1.2:

                basic.show_icon(IconNames.SAD)      Die Batterie muss ersetzt werden L !

else:

                basic.show_icon(IconNames.HAPPY)      Die Batterie ist voll aufgeladen J !

 

Wie man sieht, gibt es zu jeder „Wenn … dann“-Abfrage eine weitere „Wenn … nicht, was dann“-Abfrage (= „else“) und wegen der beiden gestaffelten Spannungsabfragen UBatt, ges <= 2 V und (eine Stufe darunter) UBatt <= 1,2 V auch noch eine weitere, gestaffelte „Wenn … dann“-Abfrage, gefolgt von einer weiteren „Wenn … nicht, was dann“-Abfrage (= „else“).

 

Insgesamt gibt es also drei gestaffelte „Wenn … dann“-Abfragen und zwei gestaffelte „Wenn … nicht, was dann“-Abfrage (= „else“).

 

Aber ich gebe zu, dass es die gestaffelten „Wenn … dann“-Abfragen, gepaart mit den ebenfalls gestaffelten „Wenn … nicht, was dann“-Abfrage (= „else“) „in sich haben“, d.h. nicht sofort auf Anhieb zu verstehen sind.

 

Zu einem besseren, anschaulichen Verständnis kommt man, wenn man die die gestaffelten „Wenn … dann“-Abfragen rückwärts, d.h. von hinten aus analysiert:

 

if digital_pin_p1 <= 1.2:

                basic.show_icon(IconNames.SAD)      Die Batterie muss ersetzt werden L !

else:

                basic.show_icon(IconNames.HAPPY)      Die Batterie ist voll aufgeladen J !

 

Wenn die am Port „Pin P1“ anliegende Batteriespannung weniger als 1,2 Volt (eigentlich 1,15 V 1,2 V) beträgt, dann kann sich in der Batteriehalterung [19] nur eine einzige 1,5 Volt Batterie befinden! Und, wenn dann die gemessene Batteriespannung kleiner als 1,2 Volt ist, dann muss die Batterie ersetzt werden, anderenfalls, wenn die Batteriespannung größer als 1,2 Volt ist, dann ist die Batterie praktisch voll aufgeladen, muss diese nicht ersetzt werden! Das lässt sich ganz gut nachvollziehen und verstehen.

 

Gehen wir einen weiteren Schritt, eine weitere Ebene zurück, d.h. nach oben:

 

if digital_pin_p1 > 2:

        basic.show_icon(IconNames.HAPPY)      Beide Batterien sind nahezu vollständig aufgeladen J !

else:

        if digital_pin_p1 <= 2:

if digital_pin_p1 <= 1.2:

               

 

Wenn die am Port „Pin P1“ anliegende Batteriespannung größer als 2 Volt ist, dann müssen sich in der Batteriehalterung [19] zwei in Serie geschaltete 1,5 Volt Batterie befinden, die zudem nahezu voll aufgeladen sind!

 

Wenn die am Port „Pin P1“ anliegende Batteriespannung kleiner als 2 Volt ist, dann kann sich in der Batteriehalterung [19] nur eine einzige 1,5 Volt Batterie befinden, die wiederum mit UBatt > 1,2 V nahezu vollständig aufgeladen sein muss oder aber (= „else“) bei einer Batteriespannung UBatt <= 1,2 V größtenteils entladen und deshalb ersetzt werden muss!

 

Schauen wir uns bei dieser Gelegenheit noch das Python“-Programm „mini-programm_03_11.py“ mit dem Quellkode und den gestaffelten if thenelse“-Abfragen an (siehe innerer roter Kasten):

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_11.py)

 

Lässt man sich das obenstehende Python“-Programm in der Microsoft Entwicklungsumgebung des „Calliope mini“ in die Block“-Programmierung „übersetzen“, d.h. konvertieren, dann sieht das Block“-Programm wie folgt aus:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_11.hex)

 

Wie man anhand des obenstehenden roten und grünen Kastens sieht, werden die gestaffelten ifthen“-Abfragen als auch die ifthenelse“-Abfragen bei der Block“-Programmierung grafisch, anschaulich z.B. durch stärkeres Einrücken wider Erwarten nicht umgesetzt, ganz im Gegensatz zu der „JavaScript“- oder Python“-Programmierung (siehe weiter oben).

 

Obwohl unser Batterietester bereits über zwei Statusanzeigen als Indikator für den (Rest-) Ladezustand der Batterien verfügen und zwar einerseits die Anzeige der Batteriespannung, gemessen und angezeigt in Volt [V] und die Smiley-Anzeige für gut J oder schlecht L.

 

Während die Anzeige der Batteriespannung in Volt [V] für einen Naturwissenschaftler oder Elektrotechniker/Elektroniker selbstverständlich und nichts ungewöhnliches ist, kann diese für einen nicht ambitionierten Benutzer, nicht technisch interessierten Laien durchaus nichtssagend und wenig hilfreich sein.

 

Deshalb erweitern wir unser Batterietester“-Programm um eine weitere Komponente und zwar mit der Anzeige eines Prozentwertes. Dabei gilt es vorab zu klären, wann bzw. bei welcher Spannung eine 1,5 Volt Batterie als voll aufgeladen, d.h. fabrikneu gilt.

 

Im Abschnitt

 

1. Zwei 1,5 V Batterien fabrikneu aufgeladen

 

Wenn zwei 1,5 V Batterien vom Typ „Mignon AAfabrikneu aufgeladen sind, dann verfügt jede einzelne Batterie über eine Leerlaufspannung von deutlich mehr als 1,5 V, nämlich von z.B. UBatt, leer ≥ 1,54 V, sodass sich die Gesamtspannung bei zwei in Serie geschalteten Batterien dann schon auf

 

UBatt, ges = 2 * UBatt, leer = 2 * 1,54 V = 3,08 V > 3,0 V þ beläuft.

 

wurde die Frage bereits geklärt (siehe weiter oben).

 

Demzufolge berechnet sich die Prozentanzeige für eine einzelne 1,5 Volt Batterie gemäß Dreisatz wie folgt:

 

1,54 V      100 %

0,93 V…       x %

 

x = ( 100 % / 1,54 V ) * 0,93 V = 60,39 %

 

Der Python“-Programmkode sieht dann folgendermaßen aus:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_12.py)

 

Das obenstehende Python“-Programm mit dem Batterie-Tester hat noch den Nachteil, dass sich der Prozentwert der Batteriespannung im Moment nur für eine einzelne 1,5 Volt Batterie richtig anzeigen lässt, nicht aber für zwei 1,5 Volt Batterien, die in der Batteriehalterung [19] in Serie geschaltet sind.

 

Deshalb müssen wir die bereits entwickelten „Wenn … dann“-Abfragen (siehe weiter oben im Abschnitt „1.  Zwei 1,5 V Batterien fabrikneu aufgeladen“) auch hier für die Prozentanzeige wie folgt programmieren:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_13.py)

 

Beim obenstehenden Python“-Programm „mini-programm_03_13.py“ gibt es in

 

·       Zeile 46, das Statement digital_pin_p1 = 0 und in

·       Zeile 20, das Statement global digital_pin_p1 = 0 .

 

Was bedeutet das und worin besteht der Unterschied?

 

In jeder höheren Programmiersprache wie z.B „JavaScript“ oder „Python“ unterscheidet man bei der Programmierung von Variablen zwischen

 

·       lokalen und globalen Variablen

 

Achtung, besonders aufpassen:

 

Obwohl es lokale und globale Variablen gibt, sich diese also voneinander unterscheiden, ist es wider Erwarten nicht verboten für beide ein- und denselben Variablennamen zu verwenden!

 

Demzufolge kann ich einer globalen Variablen im Hauptprogramm den Variablennamen „digital_pin_p1“ geben und gleichzeitig auch denselben Variablennamen „digital_pin_p1“ für eine lokale Variable z.B. in einer Funktion verwenden.

 

Dem Compiler (= Übersetzer in Maschinenkode des Prozessors) macht das nichts, der weiß sehr wohl zwischen lokalen und globalen Variablen zu unterscheiden und „merkt“ sich das quasi auch!

 

Wenn man es aber beim Programmieren eines umfangreichen Programmes an einer Stelle immer wieder mit den gleichen lokalen und globalen Variablennamen zu tun hat, dann verliert man früher oder später, je nach Konzentration, den Überblick und vermischt oder vertauscht lokale und globale Variable!

 

Demzufolge sitzt der größte Fehler beim Programmieren (aber nicht nur dort) vorm Bildschirm und vor der Tastatur: nämlich der menschliche und deshalb unberechenbare Faktor „Mensch“. -

 

 

Wenn man im Hauptprogramm eine Variable deklariert (= definiert) und auch initialisiert, d.h. mit einem Inhalt (= Zahlenwert, Textstring) versieht, dann handelt es sich bei dieser immer automatisch, um eine globale Variable, die nicht extra als solche gekennzeichnet werden muss:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_13.py)

 

Diesbezüglich stellt sich die Frage, worin das Hauptprogramm beim Block“-Programmieren besteht und welche Programmzeilen zu diesem gehören.

 

Lässt man sich das obenstehende Python“-Program „mini-programm_03_13.py“ in der Microsoft Entwicklungsumgebung vom „Calliope mini“ in die Block“-Programmierung übersetzen, d.h. konvertieren, dann sieht man sofort, dass sich das Hauptprogramm im Block „beim Start“ befindet.

 

Demzufolge ist der Programmblock „beim Start“ das Hauptprogramm:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_14.hex)

 

Als nächstes weisen wir der globalen Variablen „digital_pin_p1“ den Wert 1023 zu und lassen uns diesen in der Funktion „starte_Programm(get_inputString) wie folgt anzeigen:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_15.hex)

 

Wir wechseln wieder zur Python“-Programmierung, fügen in der Funktion „starte_Programm(get_inputString) die lokale Variable „digital_pin_p1“ hinzu und initialisieren diese, indem wir dieser den Wert 512 zuweisen:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_16.py)

 

Gemäß des roten Fragezeichens „?“ im obenstehenden Python“-Programm stellt sich die Frage, welcher Wert  - und zwar 512 oder 1023 ? -  wird ganz unten zum Schluss des Hauptprogramms im LED-Display des „Calliope mini“ angezeigt?

 

Ich weiß es, verrate es aber nicht! Noch nicht!

 

Wir erweitern das obenstehende Python“-Programm „mini-programm_03_16.py“ ab, indem wir in der Funktion „starte_Programm(get_inputString) das

 

·       Statement

 

global digital_pin_p1 wie folgt hinzufügen:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_17.py)

 

Übrigens: Bei dem obenstehenden

 

·       Statement

 

global digital_pin_p1

 

handelt es sich um eine Deklaration bei der die einst lokale Variable „digital_pin_p1“ zur globalen Variablen umdeklariert wird.

 

Bei dem nachfolgenden

 

·       Statement

 

digital_pin_p1 = 512

 

handelt es sich um eine Initialisierung der globalen Variable „digital_pin_p1“ mit der Wertzuweisung 512.

 

Gemäß des roten Fragezeichens „?“ im obenstehenden Python“-Programm stellt sich auch hier die Frage, welcher Wert  - und zwar 512 oder 1023 ? -  wird ganz unten zum Schluss des Hauptprogramms im LED-Display des „Calliope mini“ angezeigt?

 

Ich weiß es, verrate es aber nicht! Noch nicht!

 

Lässt man sich das obenstehende Python“-Program „mini-programm_03_17.py“ in der Microsoft Entwicklungsumgebung vom „Calliope mini“ in die Block“-Programmierung übersetzen, d.h. konvertieren, dann sieht man sofort, dass bei der Block“-Programmierung innerhalb der Funktion „starte_Programm(get_inputString) wider Erwarten nicht zwischen der jetzigen globalen Variable „digital_pin_p1“ und der vorherigen lokalen Variable „digital_pin_p1“ unterschieden wird:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_17.hex)

 

Wenn man sich das obenstehende Block“-Programm anschaut und analysiert, dann meint man, dass es sich bei der Variablen „digital_pin_p1“ innerhalb der Funktion „starte_Programm(get_inputString) um die gleiche globale Variable „digital_pin_p1“ wie im Hauptprogramm „beim Start“ handelt, was ja auch zutreffend ist!

 

Was der Block“-Programmierer allerdings nicht erfährt, ist, dass bei der Programmierung u.a. von Funktionen zwischen der lokalen Variablen „digital_pin_p1“ und der globalen Variablen „digital_pin_p1“ im Hauptprogramm „beim Start“ unterschieden wird!

 

Auch erfährt der Block“-Programmierer wider Erwarten nichts darüber, wie man z.B. in der Funktion „starte_Programm(get_inputString) die ehemals lokale Variable „digital_pin_p1“ als globale Variable „digital_pin_p1“ aus dem Hauptprogramm „beim Start“ in der Funktion verfügbar macht!

 

Nämlich indem man in der Funktion „starte_Programm(get_inputString) das

 

·       Statement

 

global digital_pin_p1

 

hinzufügt (siehe weiter oben im Programm „mini-programm_03_17.py“ ).

 

 

Wenn man sich allerdings das Python“-Programm „mini-programm_03_16.py“ mit den zwei namensgleichen(!) Variablen „digital_pin_p1“, wobei es sich bei der Variablen in der Funktion „starte_Programm(get_inputString) um die lokale Variable „digital_pin_p1“ und bei der Variablen im Hauptprogramm „beim Start“ um die globale Variable „digital_pin_p1“ handelt, in der Microsoft Entwicklungsumgebung des „Calliope mini“ in die Block“-Programmierung konvertieren lässt, dann wird wie aus heiterem Himmel die neue, globale Variable „digital_pin_p12“ aus dem Hut gezaubert:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_16.hex)

 

 

Batterietester mit Messwert-Speicher

 

Sobald man sich vom Batterietester zwei Messwerte wie z.B. die Batteriespannung und den zugehörigen Prozentwert anzeigen lässt, wird es wegen der LED-Laufschrift schwierig, sich diese gleichzeitig zu merken. Das liegt dann auch daran, dass Dezimalwerte mit zwei Nachkommastellen für die Batteriespannung und eine Nachkommastelle für den Prozentwert angezeigt werden.

 

Diesbezüglich wünscht man sich dann früher oder später eine sogenannte Memory-Funktion, sodass man sich die zuletzt gemessenen und berechneten Messwerte mittels des Tasters „B“ noch einmal in Ruhe anschauen und notieren kann:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_18.py)

 

Das obenstehende Python“-Programm lässt sich noch optimieren. Und zwar hinsichtlich der Smiley“-Anzeige J bzw. L im LED-Display:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_18.py)

 

Dabei verhält es sich so, dass der im roten Kasten stehende Programmkode bezüglich der Smiley“-Anzeige nicht nur in der Funktion on_button_pressed_a()“ vorkommt, sondern auch in Funktion on_button_pressed_b()“, sodass es sich anbietet, diesen in eine separate Funktion zeige_Smiliey()“ wie folgt auszulagern:

 

 

(Bild vergrößern: auf Bild klicken! Webverzeichnis mini-programm_03_19.py)

 

Den vollständigen Python“-Programmkode kann man sich hier im Browser direkt anschauen.

 

Und der entsprechende JavaScript“-Programmkode lässt natürlich ebenfalls hier im Browser anzeigen.

 

Das Interessante am JavaScript“-Programmkode ist noch, dass sich die globalen Variablen „digital_pin_p1“ und „prozent_pin_p1“ des Hauptprogramms in allen Funktionen nutzen, d.h. ansprechen, auslesen, verändern und zurück speichern lassen, ohne dass man diese explizit in allen Funktionen als global deklarieren muss, so wie das in Python der Fall war! -

 

 

 

 

[ electronic 159 ] [ Seitenanfang ] [ zurück ]