SpDrS60 Stellwerkssimulation Stellwerkssimulation zu Verwendung in bliebigen Schienensystemen
main.cpp
1/*Libary für die Steuerung eines SpDrS60 Gleisbildstellpults
2 * mit dieser Library können weichen Signale etc. gesteuert werden
3 *
4 * Implemetiert ist ein Stellwerk mit drei Weichen und entsprechenden Signalen
5 * Schema des Stellpults:
6 * /-----
7 * ------><------
8 * -----<--------
9 *
10 * Lennart Klüner 10.04.2022
11 */
12
13#include <Arduino.h>
14#include "WeichenControl.h"
15#include "ZugtastenControl.h"
16#include "BesetztmeldungControl.h"
17#include "HauptsignalControl.h"
18#include "Melder.h"
19#include "Graph.h"
20
21// Weichen
22#define anzahlWeichen 3
23
24#define w1g 24 // w=Weiche bzw. Weichenrelais g=Relais für gerade
25#define w1k 25 // g=Relais für gerade
26#define w2g 22
27#define w2k 23
28#define w3g 26
29#define w3k 27
30
31#define wt1 11 // Pinbelegung Weichentasten
32#define wt2 20
33#define wt3 2
34
35// Pinbelegung der WeichenLEDs
36#define ledw1g 109
37#define ledw1k 108
38#define ledw2g 50
39#define ledw2k 39
40#define ledw3g 106
41#define ledw3k 104
42
43#define ledw1gRot 110
44#define ledw1kRot 51
45#define ledw2gRot 101
46#define ledw2kRot 38
47#define ledw3gRot 107
48#define ledw3kRot 105
49
50#define weichentimeout 500 // dauer des Schaltvorgangs bei den Weichen
51#define wgt 18 // Weichengruppentaste
52
53#define zta1 5 // Zugstraßentaste 1 an Pin 2
54#define zta2 21 // Zugstraßentaste 2 an Pin 3
55#define zta3 12 // Zugstraßentaste 3 an Pin 4
56#define zta4 3
57#define zta5 6
58int zta6;
59#define zta7 13
60#define zta8 4
61#define zta9 7
62
63// Melder
64#define ftueMelderLed 124 // Fahrstraßentastenüberwachung
65#define ftueMelderWut 19
66#define weckerPin 28
67
68// Signale
69#define hauptsignalanzahl 4
70#define signalsperrtaste 16 // signalsperrtaste, zu testzwecken auf weichengruppentaste gestellt
71#define Signalentsperrtaste 17 // s.o
72#define shgt 15 // s.o
73
74// Signal1
75#define rot1 52 // Hp0 (rot) vom Signal 1
76#define gruen1 125 // Hp1 (grün) vom Signal 1
77int gelb1; // Hp2 (langsamfahrt) vom Signal 1
78#define sperrmelder1 126
79#define signaltaste1 zta3 // Signaltaste, zu tastzwecken weichentaste 1
80
81// Signal2
82#define rot2 123 // Hp0 (rot) vom Signal 1
83#define gruen2 46 // Hp1 (grün) vom Signal 1
84int gelb2; // Hp2 (langsamfahrt) vom Signal 1
85#define sperrmelder2 49
86#define signaltaste2 zta4 // Signaltaste, zu tastzwecken weichentaste 1
87
88// Signal3
89#define rot3 121 // Hp0 (rot) vom Signal 1
90#define gruen3 122 // Hp1 (grün) vom Signal 1
91int gelb3; // Hp2 (langsamfahrt) vom Signal 1
92#define sperrmelder3 127
93#define signaltaste3 zta7 // Signaltaste, zu tastzwecken weichentaste 1
94
95// Signal4
96#define rot4 47 // Hp0 (rot) vom Signal 1
97#define gruen4 111 // Hp1 (grün) vom Signal 1
98int gelb4; // Hp2 (langsamfahrt) vom Signal 1
99#define sperrmelder4 48
100#define signaltaste4 zta8 // Signaltaste, zu tastzwecken weichentaste 1
101
102// Pinbelegung Schieberegister
103int schieberegisterPins[4] = {4, 8, 9, 10};
104
105// Gleisbesetztmelder
106#define besetztmelderAnzahl 19
107// Melder
108Melder ftueMelder("FTÜ-Melder", ftueMelderLed, weckerPin, ftueMelderWut, schieberegisterPins); // Ausgabe von FTÜ im Seriellen Monitior funktioniert nicht
109
110// Zugtasten
111#define zugtastenanzahl 9
112int zugtastenPins[zugtastenanzahl] = {zta1, zta2, zta3, zta4, zta5, zta6, zta7, zta8, zta9};
113boolean zugtastenRichtung[zugtastenanzahl] = {1, 0, 1, 0, 1, 0, 1, 0, 1};
114ZugtastenControl zugtastenC(zugtastenanzahl, zugtastenPins, zugtastenRichtung);
115
116// Fahrstraßensteuerung
117int zugtastenspeicher[2]; // es werden die Zugtasten gespeichert, die gedrückt wurden.
118int anzahl = 0; // zählt wie viele zugtasten gedrückt wurden
119
120Graph *graph = nullptr;
121
122void setup()
123{
124 Serial.begin(9600);
125 // Initialisieren der Hauptsignale
126 int allgSignaltasten[3] = {signalsperrtaste, Signalentsperrtaste, shgt}; // Signalsperrtaste, Signalentsperrtaste, Signalhaltgruppentaste, Array speichert für jedes Signal wichtige informationen, hält den schreibaufwand geringer
127 int rot[hauptsignalanzahl] = {rot1, rot2, rot3, rot4};
128 int gelb[hauptsignalanzahl] = {gelb1, gelb2, gelb3, gelb4};
129 int gruen[hauptsignalanzahl] = {gruen1, gruen2, gruen3, gruen4};
130 int signaltasten[hauptsignalanzahl] = {signaltaste1, signaltaste2, signaltaste3, signaltaste4};
131 int sperrmelder[hauptsignalanzahl] = {sperrmelder1, sperrmelder2, sperrmelder3, sperrmelder4};
132 boolean richtung[hauptsignalanzahl] = {true, false, true, false};
133 HauptsignalControl hauptsignale(hauptsignalanzahl, rot, gelb, gruen, signaltasten, sperrmelder, allgSignaltasten, schieberegisterPins, richtung);
134 // int rotPin, int gelbPin, int gruenPin, int signaltaste, int sperrmelder, int allgSignaltasten[3], int registerPin[4]
135
136 // Gleisbesetztmelder
137 // jedes Feld muss als einzelner Gleisbesetztmelder definiert sein
138 int weichenbesetztmelder[besetztmelderAnzahl] = {0, 0,
139 0, 0, 0, 0, 1, 0, 2, 0, 0,
140 0, 0, 0, 0, 3, 0, 0, 0}; // Weichennummern werden übergeben
141 int besetztmelderEingaenge[besetztmelderAnzahl] = {69, 69, 59, 59, 63, 65, 65, 68, 68, 67, 67, 60, 60, 64, 64, 62, 62, 61, 61}; // an gnd angeschlossen
142 int besetztmelderLedsGelb[besetztmelderAnzahl] = {33, 45, 130, 116, 117, 114, 0, 102, 0, 31, 43, 121, 128, 133, 112, 0, 37, 35, 41};
143 int besetztmelderLedsRot[besetztmelderAnzahl] = {32, 44, 58, 0, 118, 115, 0, 103, 0, 30, 42, 132, 129, 120, 113, 0, 36, 34, 40};
144 BesetztmeldungControl besetztmeldung(besetztmelderEingaenge, besetztmelderLedsGelb, besetztmelderLedsRot, weichenbesetztmelder, besetztmelderAnzahl, schieberegisterPins);
145
146 // Weichen
147 int weichenPinsGerade[anzahlWeichen] = {w1g, w2g, w3g};
148 int weichenPinsKurve[anzahlWeichen] = {w1k, w2k, w3k};
149 int weichenLedPinsGerade[anzahlWeichen] = {ledw1g, ledw2g, ledw3g};
150 int weichenLedPinsGeradeRot[anzahlWeichen] = {ledw1gRot, ledw2gRot, ledw3gRot};
151 int weichenLedPinsKurve[anzahlWeichen] = {ledw1k, ledw2k, ledw3k};
152 int weichenLedPinsKurveRot[anzahlWeichen] = {ledw1kRot, ledw2kRot, ledw3kRot};
153 int adressWeichenpositionen[anzahlWeichen] = {1, 5, 9};
154 int weichentasten[anzahlWeichen] = {wt1, wt2, wt3};
155 WeichenControl weichen(anzahlWeichen, weichenPinsGerade, weichenPinsKurve, weichenLedPinsGerade, weichenLedPinsGeradeRot, weichenLedPinsKurve, weichenLedPinsKurveRot, adressWeichenpositionen, weichentimeout, weichentasten, wgt, schieberegisterPins);
156
157 int nachbarn[besetztmelderAnzahl][3] = {// Nachbarn ders einzelnen Gleisymbole. Nach nummerierung in einem 2d Array gespeichert. Leere Felder müssen mit einem Wert außerhalb der Wertebereichs gefüllt werden z.B. -1, da dies kleiner als 0 ist.
158 {1, 8, -1},
159 {0, -1, -1},
160 {3, -1, -1},
161 {2, 4, -1},
162 {3, 5, -1},
163 {4, 6, -1},
164 {5, 7, 15},
165 {6, 8, -1},
166 {7, 9, 0},
167 {8, 10, -1},
168 {9, -1, -1},
169 {12, -1, -1},
170 {11, 13, -1},
171 {12, 14, -1},
172 {13, 15, -1},
173 {16, 14, 6},
174 {15, 17, -1},
175 {16, 18, -1},
176 {17, -1, -1}};
177 char gleissymboltyp[besetztmelderAnzahl] = {'-', '+', // wird für die Zuweisung der Aktoren zu den Gleisbildsymbolen benötigt, in Kombination mit Control
178 '+', 's', '-', '-', '<', '-', '<', 's', '+',
179 '+', 's', '-', '-', '<', '-', 's', '+'}; //- normales Gleis, + Zugtaste, < weiche, s signal und zugtaste (lesart wie die besetztmelder von links oben nach rechts unten)
180
181 weichen.weichenRelaisHIGH(); // wird benötigt, da der Graph erst später erstellt wird und die Relais sonst Schalten würden.
182
183
184 // Der folgende Algorithmus fügt den Knoten Attribute, wie Besetztmelder, Weichen, Signale hinzu.
185 Gleissymbol knoten[besetztmelderAnzahl]; // Speichert die Knoten, des Graphen
186
187 int zta = 0; // zugtastenzähler
188 int signal = 0; // signalzähler
189 int weiche = 0; // weichenzähler
190 for (int i = 0; i < besetztmelderAnzahl; i++) // erstellen der Gleissymbole bezüglich des Array gleissymboltyp
191 {
192 if (gleissymboltyp[i] == '-') // wenn normales Gleis
193 knoten[i] = Gleissymbol(besetztmeldung.getBesetztmelder(i));
194 else if (gleissymboltyp[i] == '+') // zugtaste
195 {
196 knoten[i] = Gleissymbol(besetztmeldung.getBesetztmelder(i)); //
197 zugtastenC.setGleissymbol(zta, &knoten[i]); // weise Gleissymbol einer Zugtaste zu
198 zta++;
199 }
200 else if (gleissymboltyp[i] == 's') // signal und zugtaste
201 {
202 knoten[i] = Gleissymbol(besetztmeldung.getBesetztmelder(i), nullptr, hauptsignale.getHauptsignal(signal));
203 zugtastenC.setGleissymbol(zta, &knoten[i]);
204 zta++;
205 signal++;
206 }
207 else if (gleissymboltyp[i] == '<') // weiche
208 {
209 knoten[i] = Gleissymbol(besetztmeldung.getBesetztmelder(i), weichen.getWeiche(weiche));
210 weiche++;
211 }
212 }
213
214 graph->prepare(); // alle Eingaben an den Relais werden gelöscht und gespeicherte Weichenposition wird angezeigt und ausgeführt
215 graph = new Graph(besetztmelderAnzahl, knoten, nachbarn); // erstelle den Graphen
216}
217
218void loop()
219{
220 zugtastenspeicher[0] = 0;
221 zugtastenspeicher[1] = 0;
222 anzahl = 0;
223 for (int j = 0; j < zugtastenC.getZugtastenAnzahl(); j++)
224 {
225 if (zugtastenC.getZugtastenstatus(j) == false && anzahl < 2) // Wenn die Zugstrassentaste gedrückt wurde...
226 { //...und noch nicht zwei Tasten gedrückt wurden
227 zugtastenspeicher[anzahl] = j; // speichere das Feld auf dem die taste gedrückt wurde
228 anzahl++; // erhöhe die anzahl der gedrückten anzahl an tasten um 1
229 }
230 }
231 if (anzahl > 1)
232 {
233 graph->fahrstrasseEinstellen(zugtastenC.getZugtaste(zugtastenspeicher[0]), zugtastenC.getZugtaste(zugtastenspeicher[1]));
234 }
235
236 ftueMelder.tueMelder(zugtastenC);
237 graph->updateSymbole();
238}
Ist ein Knoten für den in Graph erstellten Graphen Speichert alle Objekte, die dem Entsprechenden Kno...
Definition: Gleissymbol.h:23
Definition: Graph.h:22
void updateSymbole()
Definition: Graph.cpp:28
boolean fahrstrasseEinstellen(Zugtaste *taste1, Zugtaste *taste2)
Definition: Graph.cpp:206
void prepare()
Definition: Graph.cpp:20
Definition: melder.h:21
void tueMelder(ZugtastenControl ZugtastenControl)
Definition: melder.cpp:29
void setGleissymbol(int zugtastenNr, Gleissymbol *symbol)
Zugtaste * getZugtaste(int zugtastenNr)
boolean getZugtastenstatus(int zugtastenNr)