|
Programmierung
|
16.01.2002 |
|
|
Die Programmierung der EPIC-Card
Die Programmierung der EPIC ist - sofern man das Prinzip verstanden hat - keine allzu
große Sache mehr. Aber wie so oft liegt hier die Tücke im Detail und umfangreiche
Programmierberspiele sucht man leider in der Dokumentation vergebens. Daher möchte ich
hier in einer etwas ungeordneten Reihenfolge ein paar kleine Programmierbeispiele für einige
alltägliche Problemstellungen geben. Viel Spaß damit.
Anschluss von Kippschaltern an die EPIC-Card |
|
Zuerst einmal müssen wir den Kippschalter an die EPIC-Card anschliessen. Hierfür
benötigen wir natürlich neben der Basic Card mit ihrem First Expansion Modul ein ABA-Modul
und mindestens ein 64BTN-Modul. An einem 64BTN-Modul befinden sich - wie der Name schon
vermuten läßt - 64 Schraubklemmen zum bequemen Anschluß von Schaltern, Buttons
etc. sowie 2 Klemmen zum Anschluß der Masseleitungen. Der eine Pol unseres Kippschalters
wird nun an irgend einer der 64 Klemmen angeschraubt. Den zweiten Pol schrauben wir an eine der
beiden Masseklemmen. Das war's schon.
Wenn wir mehr als einen Kippschalter o.ä. anschliessen wollen, müssen wir wie im
unten angezeigtem Schaltbild den einen Pol des zusätzlichen Schalters an eine freie Klemme
am 64BTN-Modul anschrauben. Den anderen Pol dieses Schalters "kaskadieren" wir, indem wir ihn an
den Pol des bereits angeschlossenen Kippschalters schrauben, welcher weiter zur Masseklemme des
64BTN-Moduls weitergeführt wurde.
Anschluss eines Kippschalters an die EPIC-Card
|
|
Grundsätzliches zu einem EPIC-Programm |
|
Ein EPIC-Programm bzw. besser der EPIC-Quelltext kann mit jedem handeslüblichen ASCII-Editor
erstellt und bearbeitet werden. Nach der Erstellung wird dieser Quelltext mit Hilfe des mitgelieferten
Programmes EPL.EXE auf Fehler überprüft und anschliessend kompiliert. Das
kompilierte EPIC-Programm kann nun mit dem Programm LOADEPIC.EXE an die EPIC-Card
"upgeloadet" werden und ist anschliessend dort aktiv.
Leider dürfen EPIC-Quelltexte inklusive Kommentare nicht grösser sein als 64 KByte, da
sonst EPL.EXE mit einer Fehlermeldung abbricht. Bei mir zumindest ist mein Quelltext
gut dokumentiert und damit wesentlich grösser als die 64 KByte. Daher habe ich ein kleines
Hilfsprogramm mit Namen XEPL.EXE geschrieben, welches meinen Quelltext automatisch
komprimiert, indem es alle Kommentare sowie überflüssige Leerstellen und Tabulatoren
temporär entfernt und anschliessend den EPIC-Compiler EPL.EXE aufruft.
Ein EPIC-Quelltext sollte immer aus folgenden Programmzeilen bestehen:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset }
Dieses Programm macht erst einmal nicht besonders viel, sondern initialisiert nach seinem Laden
nur die EPIC-Card. Ebenfalls wird hier angegeben, dass das sogenannte Modul 0 sehr häufig
(Angabe "FASTSCAN") sowie die weiteren Module 1 und 2 nur mit normaler Geschwindigkeit auf
Veränderungen gescannt werden soll. EPIC kann maximal 16 Rows schnell scannen.
Ansteuerung eines ON/OFF-Kippschalters |
|
Zuerst müssen wir mit dem mitgelieferten Programm
TEST128.EXE feststellen, auf
welcher Nummer der angeschlossene Kippschalter reagiert. Hierfür müssen wir als
erstes das obige
Kernprogramm kompilieren und an die EPIC-Card updoaden.
Danach starten wir das Programm
TEST128.EXE und betätigen den angeschlossenen
Kippschalter. Wenn auf dem Bildschirm keine Taste von Modul 0 aufleuchtet, wählen wir
in Programm Modul 1 aus und betätigen den Kippschalter erneut. Wird hier die Taste noch
immer nicht erkannt, wählen wir Modus 2 aus und wiederholen den Vorgang. Jetzt spätestens
muss eine Taste erkannt werden. Eine Nummer müsste bei Aktivierung des Schalters in
Grün angezeigt werden und beim Deaktivieren müsste die gleiche Nummer Rot aufleuchten.
Diese Nummer merken wir uns, da sie in Zukunft für diesen Schalter steht. Wir gehen
für unser Beispiel nehmen wir an, dass die Nummer "192" ist. Jetzt gehen wir davon aus,
dass wir mit diesem Kippschalter das
ECM aktivieren
wollen. Hierzu müssen wir die Taste "j" an den Flugsimulator Falcon senden. Hier nun das
dazugehörige Programm:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset }
:ECMToggle { KeyHit(j) } ; ECM togglen
DefineButton(192, ON, ECMToggle)
DefineButton(192, OFF, ECMToggle)
Ist doch gar nicht so schwer, oder?
Ansteuerung eines ON/OFF/ON-Kippschalters |
|
Ein sogenannter ON/OFF/ON-Kippschalter ist genauso einfach in EPIC zu programmieren. Bei einem
ON/OFF/ON-Kippschalter haben wir es - wie der Name bereits andeutet - mit einem Schalter zu tun,
welcher zwei! ON-Stellungen besitzt. Somit müssen bei einem korrekten Anschluss an die
EPIC auch zwei Nummern mit dem Programm
TEST128.EXE geliefert bekommen und zwar für
jede ON-Stellung eine. Gehen wir einmal davon aus, dass wir die Nummern "73" und "74" geliefert
bekommen haben und mit dem Kippschalter den
Master Arm Schalter
simulieren wollen. Dann sieht das Programm so aus:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset }
:MasterArm { ShiftHit(m) } ; Master Arm auf Arm
:MasterOff { CtrlHit(m) } ; Master Arm auf Off
:MasterSim { AltHit(m) } ; Master Arm auf Simulate
DefineButton(73, ON, MasterArm)
DefineButton(73, OFF, MasterOff)
DefineButton(74, ON, MasterSim)
DefineButton(74, OFF, MasterOff)
Ansteuerung eines Rotary-Elementes |
|
Der Anschluss eines sogenannten Incrementalgebers - ich möchte es einfacher Rotary-Element
nennen - kann einen schon graue Haare kosten, wenn man nicht genau versteht, was da passiert
und wenn man keine Hilfen hat. Da gibt es zum einen schon einmal zwei verschiedene Typen von
Rotary-Elemente, welche unterschiedlich programmiert werden. Und da man den Rotary-Elementen
so leicht nicht ansehen kann, zu welchem Typ sie gehören, hilft hier nur ausprobieren.
Doch zuerst einmal, was ist ein Rotary-Element und für was kann es in der F-16 verwendet
werden? Ein Rotary-Element ist ein in beiden Richtungen endlos drehbarer Knopf, welcher beim
Drehen in die ein- oder andere Richtung Impulse ausgiebt. In der F-16 befinden sich z.B. zwei
Rotary-Elemente auf dem
HSI zum Einstellen von "Course"
und "Heading".
Um überhaupt ein Rotary-Element am Rotary-Modul zum Laufen bringen zu wollen, muß die
Datei
MAKEBTN.DAT angepasst werden. Dort müssen folgende Zeilen angehängt werden:
700 BUTTON700 0 1 7
701 BUTTON701 0 2 7
702 BUTTON702 0 4 7
703 BUTTON703 0 8 7
704 BUTTON704 0 16 7
705 BUTTON705 0 32 7
706 BUTTON706 0 64 7
707 BUTTON707 0 128 7
708 BUTTON708 1 1 7
709 BUTTON709 1 2 7
710 BUTTON710 1 4 7
711 BUTTON711 1 8 7
712 BUTTON712 1 16 7
713 BUTTON713 1 32 7
714 BUTTON714 1 64 7
715 BUTTON715 1 128 7
716 BUTTON716 2 1 7
717 BUTTON717 2 2 7
718 BUTTON718 2 4 7
719 BUTTON719 2 8 7
720 BUTTON720 2 16 7
721 BUTTON721 2 32 7
722 BUTTON722 2 64 7
723 BUTTON723 2 128 7
724 BUTTON724 3 1 7
725 BUTTON725 3 2 7
726 BUTTON726 3 4 7
727 BUTTON727 3 8 7
728 BUTTON728 3 16 7
729 BUTTON729 3 32 7
730 BUTTON730 3 64 7
731 BUTTON731 3 128 7
Anschliessend müssen diese Änderungen mit dem Programm
MAKEBTN.EXE aktiviert
werden. Der Anschluss des Rotary-Elementes an das Rotary-Moodul von EPIC ist gemäß
der zum Rotary-Modul mitgelieferten Handzettel relativ einfach zu erledigen. Nun müssen
wir nur noch mit
TEST128.EXE in Modul 7! (Rotaries liegen hier) die Nummern des
angeschlossenen Rotary-Elementes herausginden. Auch hier bekommen wir für jede
Drehrichtung des Rotary-Elementes eine Nummer geliefert. In unserem Beispiel gehen wir davon
aus, dass wir die Nummern "700" für Linksdrehen und "701" für Rechtsdrehen bekommen.
In unserem Beispiel wollen wir mit diesem Rotary-Element den "Heading"-Knopf am
HSI programmieren.
Gut, jetzt sind wir Startbereit für die Programmierung des 1. Typen. Diese sieht wie folgt
aus:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 8)
DefineModule(0, LOWSCAN, 8, 8)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
DefineModule(7, FASTSCAN, 0, 8)
:INIT { Reset SendData(7, 0, 1) }
:HSIHeadingInc { KeyPress(CTRL) AltHit(m) KeyRelease(CTRL) }
:HSIHeadingDec { KeyPress(CTRL) AltHit(n) KeyRelease(CTRL) }
DefineButton(700, ON, HSIHeadingDec)
DefineButton(700, OFF, HSIHeadingDec)
DefineButton(701, ON, HSIHeadingInc)
DefineButton(701, OFF, HSIHeadingInc)
Mit dem Befehl "SendData(7, 0, 1)" wird das 1. Rotary-Element auf den Typ 1 gesetzt. Zu beachten
ist hierbei, dass das Rotary-Modul (7) besser mit hoher Priorität von EPIC gescannt wird,
daher habe ich hier die ersten 8 Rows des 7. Modules mit "DefineModule(7, FASTSCAN, 0, 8)" auf
schnelles Scannen gesetzt.
Und hier nun das gleiche Beispiel mit dem zweiten möglichen Typen eines Rotary-Elementes:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 8)
DefineModule(0, LOWSCAN, 8, 8)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
DefineModule(7, FASTSCAN, 0, 8)
:INIT { Reset SetPoint(7,0,0b00000001) }
:HSIHeadingInc { KeyPress(CTRL) AltHit(m) KeyRelease(CTRL) }
:HSIHeadingDec { KeyPress(CTRL) AltHit(n) KeyRelease(CTRL) }
:HSIHeading { ifactive(701) jump HSIHeadingDec else jump HSIHeadingInc }
DefineButton(700, ON, HSIHeading)
DefineButton(700, OFF, HSIHeading)
Ansteuerung einer LED per Kippschalter |
|
Ein LED über die EPIC anzusteuern ist mit Hilfe des Output-Modules von EPIC eine
Kleinigkeit. Über ein Output-Modul können biz zu 32 Schaltkreise über ein EPIC-
Programm geschlossen und wieder geöffnet werden. Was man hinter diese Schaltkreise
hängt, bleibt jedem selbst überlassen. Es könnten LEDs sein,
Lüftungsmotoren, Scheinwerfer und vieles mehr sein. Der Anschluß einer LED an ein
Output-Modul ist relativ einfach. Die Spannungsversorgung eines Output-Modules beträgt 12
Volt. Wenn mann will, kann man diese 12 Volt auch als Spannungsversorgung für an das
Output-Modul angeschlossene Lampen etc. verwenden. Bei einer LED müssen wir hier aber noch
ein paar Widerstände dazwischen löten. LEDs eignen sich besser als Leuchtmittel in
einem F-16 Simulator, da hier auch bei mehreren brennenden LEDs der Stromverbrauch noch sehr
gering ist.
Ein wenig aufwendiger wird es, die Nummer des an das Output-Modul angeschlossenen LED zu
ermitteln. Leider geht dies nicht mit dem Programm TEST128.EXE, sodass wir uns hier
mit Hilfsprogrammen zum Ermitteln der Nummern herumärgern müssen. Gehen wir für
unser Beispiel mal davon aus, dass die angeschlossene LED das ECM-Light räpresentieren soll
und die Nummer "2" des 5. Output-Rows ist. Nummern von Output-Kanälen werden in EPIC binär
codiert, sodass die Nummer unserer LED wie folgt geschrieben wird: 0,5,0b00000010. Diese
Nummer ist nicht ganz leicht zu verstehen, deshalb werden wir sie per DEFINE-Befehl einem
sprechenden Namen zuordnen:
#define LED_ECM 0,5,0b00000010
In unserem Beispiel werden wir diese LED bei Aktivierung des ECM per Kippschalter ein- und
bei Deaktivierung wieder ausschalten. Das sieht wie folgt aus:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
#define LED_ECM 0,5,0b00000010
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset }
:ECMOn { KeyHit(j) SetPoint(LED_ECM) }
:ECMOff { KeyHit(j) ClearPoint(LED_ECM) }
DefineButton(192, ON, ECMOn)
DefineButton(192, OFF, ECMOff)
Wie man sieht, kann man mit "SetPoint()" die LED zum Leuchten bringen und mit "ClearPoint()"
wieder löschen. Nun hat unser Programm noch eine kleine Schwäche. Wenn der Kippschalter
auf "On" steht, wenn wir das Programm zur EPIC-Card uploaden, so bleibt die LED aus. Wenn wir
es schöner finden, die LED in diesem Falle gleich einzuschalten, so sieht unser Programm
so aus:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
#define LED_ECM 0,5,0b00000010
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset ifactive(192) Call LED_ECMOn }
:LED_ECMOn { SetPoint(LED_ECM) }
:LED_ECMOff { ClearPoint(LED_ECM) }
:ECMOn { KeyHit(j) Call(LED_ECMOn) }
:ECMOff { KeyHit(j) Call(LED_ECMOff) }
DefineButton(192, ON, ECMOn)
DefineButton(192, OFF, ECMOff)
Hier habe ich nun zwei Functionen mit Namen "LED_ECMOn" und "LED_ECMOff" hinzugefügt, die
jetzt das Ein- und Ausschalten der ECM LED übernehmen. In der INIT-Function, welche beim
ersten Upload zur EPIC-Card ausgeführt wird, wird nun überprüft, ob der
ECM-Kippschalter auf ON steht (Nummer "192"). Ist dies der Fall, so wird die Function zum
Einschalten der dazugehörigen LED aufgerufen. Thats all.
Ansteuerung einer LED über QProcs |
|
Im obigen
Beispiel haben wir eine LED direkt bei Betätigen des
dazugehörigen Kippschalters aktiviert. Ein anderer und wesentlich eleganterer Weg ist das
Ein- und Ausschalten einer LED über eine direkte Schnittstelle zwischen der EPIC-Card und
dem verwendeten Flugsimulatorprogramm. Hierzu benötigen wir jedoch ein spezielles
Schnittstellenprogramm, welches Daten von dem Flugsimulator auslesen und weitergeben kann.
Für Falcon habe ich das Programm
F4-Reader geschrieben,
welches auch kostenlos zum Download zur Verfügung steht.
Im Programm
F4-Reader gibt es nun zwei Möglichkeiten,
Daten von LEDs u.ä. an die EPIC-Card zu senden. Die erste und etwas einfachere Art wollen
wir hier behandeln. Es ist die Kommunikation über sogenannte QProcs. Hierbei wird eine
Kanalnummer definiert, die für das Ein- oder Ausschalten einer LED genutzt werden soll. In
unserem Beispiel gehen wir davon aus, das die Kanalnummer "20" zum Einschalten und die
Kanalnummer "21" zum Ausschalten der ECM-LED genutzt wird. Welche Kanalnummern für
welche LED verwendet wird, kann beliebig im
F4-Reader
definiert werden.
Und hier nun das dazugehörige Programm:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
#define LED_ECM 0,5,0b00000010
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
:INIT { Reset }
:LED_ECMOn { SetPoint(LED_ECM) }
:LED_ECMOff { ClearPoint(LED_ECM) }
DefineQProc(20, LED_ECMOn)
DefineQProc(21, LED_ECMOff)
Mit dem Befehl "DefineQProc()" wird hierbei die Funktion angegeben, welche bei Aktivieren des
entsprechenden QProcs angesprungen werden soll.
Ansteuerung von LEDs über Pigeon-Holes |
|
Wie wir in dem obigen
Beispiel gesehen haben, ist die Ansteuerung von
LEDs über QProcs kein allzu grosses Problem. Wenn wir aber eine Reihe von Zuständen
von LEDs über das Schnittstellenprogramm
F4-Reader an die
EPIC-Card senden wollen, so wird das Programm schon etwas umfangreicher. Ebenfalls haben QProcs
den Nachteil, dass - wenn viele Zustandsänderungen von LEDs gleichzeitig zusammentreffen,
EPIC sich hierbei verschluckt und eine Reihe von QProcs nicht bearbeitet werden. Abhilfe
schafft hier die Verwendung von sogenannten Pigeon-Holes. Leider ist dieser Begriff in der
EPIC-Dokumentation nicht beschrieben und auch Beispiele sucht man vergebens. Daher hier ein
kleiner Ausflug in die Programmierung mit Pigeon-Holes.
Mit einem QProc kann nur eine digitale Information übertragen werden. Wenn man nun aber
einen analogen Wert per Schnittstelle übertragen will (z.B. Geschwindigkeit, Höhe
etc.), so kann man dies über Pigeon-Holes tun. Über ein Pigeon-Hole können
gleichzeitig vier analoge Werte von 0 bis 255 an die EPIC-Card übertragen werden. Wir
können uns dies zunutze machen, um z.B. über ein Pigeon-Hole gleichzeitig 32 LED
Zustände übertragen zu können (4 x 8Bit = 32).
Wir wollen in unserem Beispiel einmal davon ausgehen, dass wir alle LED-Zustände des
Caution Panels gleichzeitig per Pigeon-Holes
übertragen wollen. Wir haben zuvor alle 32 Caution Lights des Caution Paneles an ein
Output-Modul angeschlossen. Nun müssen wir im Programm
F4-Reader
alle Caution Lights den entsprechenden Bits eines Pigeon-Holes zuordnen. Wir wählen
hierzu das Pigeon-Hole mit der Nummer "10". Die binäre Zuordnung auf die einzelnen
Rows bzw. PH-Indexe im
F4-Reader erfolgt analog zur Zuordnung
auf dem Output-Modul. Das z.B. 12. LED auf dem Output-Modul würde ja das Bit 3 auf dem 1.
Output-Row sein (=0,1,0b00001000). Somit wäre diese LED Bit 3 des 1. PH-Indexes. Zu
kompliziert? Ich glaube ja, daher hier einmal das ganze 1. Output-Modul mit der entsprechenden
Zuordnung im
F4-Reader:
LED-# |
Row-# |
Bit-# |
EPIC-Call |
PH-Index |
Bit(s)s to send |
1 |
0 |
0 |
0,0,0b00000001 |
0 |
00000001 |
2 |
0 |
1 |
0,0,0b00000010 |
0 |
00000010 |
3 |
0 |
2 |
0,0,0b00000100 |
0 |
00000100 |
4 |
0 |
3 |
0,0,0b00001000 |
0 |
00001000 |
5 |
0 |
4 |
0,0,0b00010000 |
0 |
00010000 |
6 |
0 |
5 |
0,0,0b00100000 |
0 |
00100000 |
7 |
0 |
6 |
0,0,0b01000000 |
0 |
01000000 |
8 |
0 |
7 |
0,0,0b10000000 |
0 |
10000000 |
9 |
1 |
0 |
0,1,0b00000001 |
1 |
00000001 |
10 |
1 |
1 |
0,1,0b00000010 |
1 |
00000010 |
11 |
1 |
2 |
0,1,0b00000100 |
1 |
00000100 |
12 |
1 |
3 |
0,1,0b00001000 |
1 |
00001000 |
13 |
1 |
4 |
0,1,0b00010000 |
1 |
00010000 |
14 |
1 |
5 |
0,1,0b00100000 |
1 |
00100000 |
15 |
1 |
6 |
0,1,0b01000000 |
1 |
01000000 |
16 |
1 |
7 |
0,1,0b10000000 |
1 |
10000000 |
17 |
2 |
0 |
0,2,0b00000001 |
2 |
00000001 |
18 |
2 |
1 |
0,2,0b00000010 |
2 |
00000010 |
19 |
2 |
2 |
0,2,0b00000100 |
2 |
00000100 |
20 |
2 |
3 |
0,2,0b00001000 |
2 |
00001000 |
21 |
2 |
4 |
0,2,0b00010000 |
2 |
00010000 |
22 |
2 |
5 |
0,2,0b00100000 |
2 |
00100000 |
23 |
2 |
6 |
0,2,0b01000000 |
2 |
01000000 |
24 |
2 |
7 |
0,2,0b10000000 |
2 |
10000000 |
25 |
3 |
0 |
0,3,0b00000001 |
3 |
00000001 |
26 |
3 |
1 |
0,3,0b00000010 |
3 |
00000010 |
27 |
3 |
2 |
0,3,0b00000100 |
3 |
00000100 |
28 |
3 |
3 |
0,3,0b00001000 |
3 |
00001000 |
29 |
3 |
4 |
0,3,0b00010000 |
3 |
00010000 |
30 |
3 |
5 |
0,3,0b00100000 |
3 |
00100000 |
31 |
3 |
6 |
0,3,0b01000000 |
3 |
01000000 |
32 |
3 |
7 |
0,3,0b10000000 |
3 |
10000000 |
So, wenn wir jetzt einmalig die Zuordnung im Programm
F4-Reader
vorgenommen haben, können wir an das eigendliche EPIC-Programm gehen. Dieses sieht so
aus:
#define FASTSCAN 0
#define LOWSCAN 1
#define OUTPUT 2
DefineModule(0, FASTSCAN, 0, 16)
DefineModule(1, LOWSCAN, 0, 16)
DefineModule(2, LOWSCAN, 0, 16)
#macro GetPH8(bytev, phnum)
pushc(phnum)
exec(67)
popv8(bytev)
#endmac
VAR(Var_PHoles) ; 8-Bit Hilfs-Variable deklarieren
:INIT { Reset }
:PH_OutputM0 {
#expand getPH8(Var_PHoles, 0x000A)
ClearPoint(0, 0, 0b11111111)
SetPoint(0, 0, Var_PHoles)
#expand getPH8(Var_PHoles, 0x010A)
ClearPoint(0, 1, 0b11111111)
SetPoint(0, 1, Var_PHoles)
#expand getPH8(Var_PHoles, 0x020A)
ClearPoint(0, 2, 0b11111111)
SetPoint(0, 2, Var_PHoles)
#expand getPH8(Var_PHoles, 0x030A)
ClearPoint(0, 3, 0b11111111)
SetPoint(0, 3, Var_PHoles)
}
DefinePH(10, PH_OutputM0, 0, 0, 0, 0)
Das ist alles. Was auffällt, ist das definierte Macro "GetPH8", welches einen 8 Bit-Wert
aus dem Pigeon-Hole Speicher liest. Dieses Macro ist normalerweise in der mitgelieferten
Include-Datei EpicVXD.inc enthalten. Ich habe es jedoch zur besseren Übersicht
mit in das obige Programm aufgenommen.
Als nächstes erfolgt die Deklaration einer Hilfsvariablen mit Namen "Var_PHoles", über
die wir später die Werte aus dem Pigeon-Hole auslesen werden.
Dann folgt eine Function für die Abarbeitung des kompletten 1. Output-Modules (Nr. 0).
Dort wird für jedes Output-Row der dazugehörige Pigeon-Hole Wert gelesen. Dann
werden mit einem Schlag alle LEDs des entsprechenden Rows gelöscht und anschliessend
gemäss der Übergabe neu gesetzt. Das komplette Löschen und anschliessende
Aktualisieren eines Output-Rows geht dermaßen schnell, dass man es mit dem Auge nicht
mitbekommt, zumal diese Function nur dann angesprochen wird, wenn es tatsächlich eine
Veränderung in einem der 4 Pigeon-Hole Werte gegeben hat.
Mit "DefinePH" wird wie oben gewünscht das 10. Pigeon-Hole der Function "PH_OutputM0"
zugewiesen. Das war's schon ;-)