Das Foto zeigt den Betrieb ohne TPS und
ohne OLED. Der Draht oben linhs verbindet D12 mit GND, und A3 wird hier
mit einem Widersatnd an +5V gezogen.
Mit der Anweisung „gosub L247“ ( bzw. call L247) wird ein spezielles
Unterprogramm aufgerufen, mit dem man die Länge positiver Impulse am
Arduino Pin D2 (nanoBasic D0) messen kann. Das Ergebnis ist in A.
1. Arduino wartet, bis das Signal an Pin 2 LOW ist.
2. Dann wartet er, bis das Signal HIGH wird (Beginn des Pulses).
3. Jetzt startet die Messung.
4. Er misst, wie lange das Signal HIGH bleibt.
5. Sobald das Signal wieder LOW wird, ist die gemessene Zeit in Millisekunden in Speicher A.
6. Wenn innerhalb von TIMEOUT kein Puls erkannt wird, gibt die Funktion A = 0 zurück.
Im Simulator wird das auch nachgebildet, selbstverständlich nicht in
Echtzeit. Wenn das Programm an die Anweisung „Gosub L 247“ kommt,
stoppt es. Wenn man die CheckBox D0 auf TRUE stellt, läuft in der
unteren Zeile „A =“. Wenn man die CheckBox dann auf FALSE stellt, wird
der nächste Programmschritt ausgeführt.
Ein Beispiel für die Verwendung der
Impulslängenmessung findet man unten in der Funkuhr-Anwendung.
Betrieb mit OLED
Mit der erweiterten Firmware kann ein OLED-Display SSD1306
128x64 mit TLScript / picoBasic / nanoBasic angesprochen werden. Der
Bildschirm ist in 9 Felder aufgeteilt, in die Zahlen mit der Anweisung
„Pulldown =“ geschrieben werden können. Pulldown = x bezeichnet das
Feld. Der Button „Pulldown =“ wurde gewählt, weil dieser beim Arduino
keine Funktion hat. Auf der nanoBasic-Bedienungsoberfläche heißt der
Button „display A Pos x“. Nach dem Einschalten bleibt das Display
zunächst dunkel, es muss erst aktiviert werden. Der Arduino kann auch
ohne das Display betrieben werden. In jedem Fall muss aber der Pin D12
an GND gelegt werden, damit das Programm nicht in den Programmiermodus
geht.
Anschluss des Displays an den Arduino. In Feld 5 wird „102“ angezeigt.
Wichtig ist, dass D12 an GND gelegt wird, sonst geht das Programm
unkontrolliert in den Programmiermodus.
Beispiel für ein OLED-Programm in nanoBasic:
(In picoBasic und TLScript heißt es pulldown = x statt display A, aber der Code ist der gleiche).
Die am Anschluss A0 anliegende Spannung wird fortlaufend im Sekundentakt angezeigt (0…255 entspricht 0…5 V).
0x0B00 display A, Pos: 0 Rem: Display starten und löschen
L1:
0x3C00 A = AD0
0x0B05 display A, Pos: 5
0x1A01 Delay s = 1
0x2001 Goto L1:
0x4900 End
Wenn man ein offenes Leitungsstück an A0 anschließt, wird der
elektrische Störnebel in unserem Haus angezeigt und führt zu
wechselnden Anzeigen. Die Zahlen werden normalerweise im Dezimalcode
angezeigt. Man kann sie aber auch im Hexadezimalcode anzeigen lassen,
wenn man an die Feldkennziffer eine „1“ anhängt, also z. B. „51“ statt
„5“ . Kommazahlen erhält man, wenn man an die Feldkennziffer eine „2“
anhängt, also z. B. „52“ statt „5“. Es werden dann Spannungen von 0.00
bis 5.00 V angezeigt.
Anwendung: nanoBasic-Programm >>Funkuhr<<
Das folgende Programm ist ein Anwendungsbeispiel für nanoBasic. Es
handelt sich um eine Funkuhr, die Stunden, Minuten und Sekunden auf dem
OLED-Display anzeigt. Die genaue Uhrzeit wird von dem Langwellensender
DCF77 ausgestrahlt (siehe Wikipedia, Stichwort DCF77). Der Sender
sendet ein Dauersignal, das zu Beginn einer jeden Sekunde für 0,1
Sekunden oder 0,2 Sekunden abgesenkt wird. Eine Absenkung von 0,1 s
entspricht einer logischen 0, eine Absenkung von 0,2 Sekunden
entspricht einer logischen 1. Auf diese Weise werden in einer Minute 58
Bits übertragen, die im BCD-Code Datum und Uhrzeit codieren. Die 59.
Sekundenabsenkung fehlt, sodass die nachfolgende Absenkung den Beginn
einer neuen Minute markiert. Details siehe Wikipedia.
Zum Empfang des Signals verwendet man am besten ein fertiges
Empfangsmodul. Das Modul liefert bereits saubere positive Impulse der
entsprechenden Dauer. Die Dekodierung erfolgt durch das Programm. Kern
des Programms ist die Impulslängen-Messfunktion, die mit Gosub L247
aufgerufen wird. Die gemessenen Zeiten werden in „0“ und „1“
klassifiziert. Diese Bitfolge wird in Bn+ fortlaufend gespeichert. Die
time out-Zeit wurde in der Arduino-Firmware auf 1,5 Sekunden gestellt
sodass nach dieser Zeit zur Dekodierung gesprungen wird (also wenn der
Sekundenimpuls länger als 1,5 Sekunden ausbleibt). Das Signal kann
zeitweise gestört sein, sodass es zu Falschanzeigen kommt.
Der Empfänger wird bei mir über Pin D7 mit „+ 5 V“ versorgt. Nach dem
Anlegen der Betriebsspannung braucht der Empfänger etwa 20 Sekunden,
bis er sich auf das Signal abgestimmt hat. Das Programm nutzt in seiner
Länge fast den gesamten Speicherplatz von 128 Zeilen aus. Die im
Prinzip mögliche Datumsanzeige hätte keinen Platz mehr. Wenn man hinter
Gosub L247 „Print A“ einfügt, werden die gemessenen Zeiten auf dem
Bildschirm angezeigt. Sie liegen nicht exakt bei 100 ms bzw. 200 ms.
Wenn man das Programm im EEPROM speichern möchte, zuerst STOP drücken. Ebenso vor RUN immer STOP drücken.
Programm Funkuhr:
0x09FE Pdir = 254
0x0880 Pout = 128
0x0B00 display A, Pos: 0
0x5800 n = 0
0x5003 m = 3
0x018C A = 140
0x5600 Bm = A
L1:
Rem Sekunden
0x5001 m = 1
0x5500 A = Bm
0x2800 A = A + 1
0x5600 Bm = A
0x0B06 display A, Pos: 6
0x21F7 Gosub L247:
0x0200 B0 = 0
0x5000 m = 0
0x2218 If A=Bm Goto L2:
0x5003 m = 3
0x2415 If A<Bm Goto L3:
0x0101 A = 1
0x3B00 [Bn+] = A
0x2007 Goto L1:
L3:
0x0100 A = 0
0x3B00 [Bn+] = A
0x2007 Goto L1:
Rem Min-Einer
L2:
0x5815 n = 21
0x5000 m = 0
0x3A00 A = [B+]
0x5600 Bm = A
0x3A00 A = [B+]
0x3100 A = A Shl 1
0x2A00 A = A + Bm
0x5600 Bm = A
0x3A00 A = [B+]
0x5B02 A = A shl 2
0x2A00 A = A + Bm
0x5600 Bm = A
0x3A00 A = [B+]
0x5B03 A = A shl 3
0x2A00 A = A + Bm
0x5600 Bm = A
Rem Min-Zehner
0x5001 m = 1
0x5819 n = 25
0x3A00 A = [Bn+]
0x5600 Bm = A
0x3A00 A = [Bn+]
0x3100 A = A Shl 1
0x2A00 A = A + Bm
0x5600 Bm = A
0x3A00 A = [Bn+]
0x5B02 A = A shl 2
0x2A00 A = A + Bm
0x5600 Bm = A
0x5002 m = 2
0x010A A = 10
0x5600 Bm = A
0x5001 m = 1
0x5500 A = Bm
0x5002 m = 2
0x2C00 A = A * Bm
0x5000 m = 0
0x2A00 A = A + Bm
0x0B05 display A, Pos: 5
Rem Std-Einer
0x581D n = 29
0x5000 m = 0
0x3A00 A = [B+]
0x5600 Bm = A
0x3A00 A = [B+]
0x3100 A = A Shl 1
0x2A00 A = A + Bm
0x5600 Bm = A
0x3A00 A = [B+]
0x5B02 A = A shl 2
0x2A00 A = A + Bm
0x5600 Bm = A
0x3A00 A = [B+]
0x5B03 A = A shl 3
0x2A00 A = A + Bm
0x5600 Bm = A
Rem Std-Zehner
0x5001 m = 1
0x5821 n = 33
0x3A00 A = [Bn+]
0x5600 Bm = A
0x3A00 A = [Bn+]
0x3100 A = A Shl 1
0x2A00 A = A + Bm
0x5600 Bm = A
0x5002 m = 2
0x010A A = 10
0x5600 Bm = A
0x5001 m = 1
0x5500 A = Bm
0x5002 m = 2
0x2C00 A = A * Bm
0x5000 m = 0
0x2A00 A = A + Bm
0x0B04 display A, Pos: 4
0x5800 n = 0
0x0100 A = 0
0x5001 m = 1
0x5600 Bm = A
0x2007 Goto L1:
0x4900 End
Programmieren ohne PC
Wer dieses Feature nicht nutzen möchte, muss den Digitalanschluss D12
an GND legen, wie im Schaltplan oben gezeigt, damit das Programm nicht
ungewollt in den Programmiermodus geht. Auch wenn die Programmierung
abgeschlossen ist, empfiehlt es sich, D12 an GND zu legen, also den
100k-Widerstand zu überbrücken. Die Software sortiert zwar Spikes
normalerweise aus, aber das benötigt Zeit und stört den Programmablauf.
Damit man Daten eingeben kann, ist etwas Peripherie nötig. Schaltplan:
Der Code von TLScript: Zur Vorbereitung muss man das Script von Hand in
den Programmcode umschlüsseln. Der Programmcode ist eine vierstellige
Hexadezimalzahl. Die vorderen zwei Ziffern codieren den Befehl, die
hinteren beiden den Wert.
Beispiel: 09 FF Pdir = 255
Manche Befehle haben keinen Wert, dann sind die beiden hinteren Ziffern 00.
Beispiel: 28 00 A = A + 1
Der Programmcode kann hier heruntergeladen werden:
Zettel-IDE.pdf
Programmieren:
Die Eingabe des Codes erfolgt über analoge Spannungen, die von einer
Widerstandskette abgenommen werden. Fehlerquellen sind hier schlechte
Kontaktgabe oder zu kurzes Antippen der Kontaktpunkte. Man verwendet am
besten eine Tastspitze und drückt diese solange auf den Kontakt, bis am
Display der gewünschte Wert angezeigt wird, was etwas verzögert
geschieht. Wenn es nicht geklappt hat, kann man die Eingabe
wiederholen. Erst wenn man den Kontakt „S“ mit der Tastspitze berührt,
wird das, was angezeigt wird, übernommen. Zum Start der Programmierung
berührt man den Kontakt „S“ mit der Tastspitze. Das Display startet mit
einer kurzen Verzögerung und zeigt die erste Programmzeile an, also
Adresse 00. Bei der nächsten Berührung von „S“ wird zusätzlich COM
(Befehl) angezeigt und bei der nächsten Berührung DAT (Wert), dann
folgt die nächste Adresse usw. Die Zahl, neben der der Text neu
erscheint, kann geändert werden, indem man die entsprechenden
Kontaktpunkte berührt. Bestätigung jeweils mit „S“:
Verlassen des Programmiermodus:
Man drückt solange auf „S“, bis „main“ angezeigt wird. Das dauert
einige Sekunden. Das Programm befindet sich dann in der main-Schleife
und läuft ab. Die maximale Anzahl von Zeilen ist 128. Wird eine Adresse
über 127 erreicht, wird „adr overflow“ angezeigt. In diesem Fall
erfolgt am besten ein Neustart.

Vorschlag für ein Eingabegerät. Die Widerstände sind auf der Rückseite verlötet.
Dauerhaftes Speichern des Programms:
Das Programm ist zunächst nur im flüchtigen Speicher abgelegt und kann
getestet werden. Um es dauerhaft im EEPROM zu speichern, während des
Programmlaufs, also wenn „main“ angezeigt wird, die „0“ der
Widerstandskette berühren. Am Display wird „stored“ angezeigt.
Das Programm ermittelt während des Laufs die letzte Programmzeile.
Gespeichert werden also die Zeilen 0 bis max. Damit das Programm
vollständig gespeichert wird, muss man sicherstellen, dass die letzte
Zeile auch tatsächlich erreicht wird. Danach kann man den Arduino
ausschalten. Beim Wiedereinschalten startet das Programm automatisch.
Zusätzliche Möglichkeiten:
Neben den beschriebenen Grundfunktionen gibt es zusätzliche Möglichkeiten.
Zeile Anspringen:
Wenn ADR angezeigt wird, gibt man die Zeilennummer an, zu der gesprungen werden soll.
Zeile löschen:
Die angezeigte Adresse auf „DD“ (wie delete) ändern. Da Adressen im
Zehnersystem angezeigt werden, wird 1313 angezeigt. Dann „S“ berühren.
Die Zeile wird nicht gelöscht, sondern durch den Code 4A 00 Nop (nichts
machen) ersetzt, das Programm muss also nicht neu durchnummeriert
werden.
Zeile einfügen:
Man scrollt bis zu der Zeile, vor der eine Zeile eingefügt werden soll
und gibt als Adresse „EE“ (wie Einfügen) an, es wird 1414 angezeigt.
Dann kann man COM und DAT wie gewohnt eingeben Nach Bestätigung mit „S“
ist die Zeile eingefügt und die Sprungbefehle sind korrigiert. Im
Script muss man jetzt die Zeilennummern korrigieren. Wenn der
gewünschte Einfügeort nicht durch Scrollen, sondern Springen erreicht
wird, muss man auf eine Zeile vorher springen und dann zur nächsten
Zeile scrollen. Wenn beispielsweise zwischen Zeile 3 und Zeile 4 eine
Zeile eingefügt werden soll, auf Zeile 3 springen und auf Zeile 4
scrollen.