RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#1 von MicroBahner , 03.11.2018 18:44

Hallo liebe Stummies,
der Arduino ist eine feine kleine Plattform, mit der vielfältige Aufgaben auf unseren Mobas gesteuert werden können. Leider liegt - wie so oft - auch hier etwas Schweiß vor dem Spaß, denn das kleine Ding will ja auch programmiert werden.
Häufig gibt es da gerade mit Zeitsteuerungen - die bei unseren Anwendungen sehr oft vorkommen - bei vielen Einsteigern Probleme. Zunächst erscheint das mit dem delay() - Aufruf recht einfach, aber man merkt doch recht schnell, dass man damit in einer Sackgasse landet, aus der es keinen Ausweg gibt: mehrere Dinge gleichzeitig zu machen funktioniert so nicht.
Die Frage von Thomas (alias Reibuch) in seinem Thread zu diesem Thema, war für mich der Anstoß, eine Lösung dieses Problems in einem kleinen Tutorial vorzustellen. Wie immer gibt es viele Wege nach Rom, aber für einen Einsteiger ist es erstmal wichtig wenigstens einen (möglichst einfachen ) zu kennen.

Als Beispiele möchte ich die Anfrage von Thomas verwenden: Einen Wechselblinker (Andreaskreuz) und eine einfache Ampelsteuerung mit einem Arduino zu realisieren, so daß beides vollkommen unabhängig voneinander funktioniert. Ich werde dabei auch meine MobaTools verwenden, da die doch einiges vereinfachen.
Schritt für Schritt soll so dann das komplette Programm entstehen. Erst für den Wechselblinker, dann für die Ampel. Und zum Schluß wird sich zeigen, wie einfach man beides kombinieren kann, wenn man von Anfang an 'richtig' vorgegangen ist.

Der Schlüssel für das Ganze ist ein 'Zustandsautomat'. Mit dieser Technik lassen sich seehr viel Aufgaben auf dem Arduino erschlagen, weshalb es erstmal wichtig ist, dieses Prinzip zu verstehen.

Bevor wir mit dem Programmieren anfangen, müssen wir unser Problem dazu erstmal in kleine 'Häppchen' zerlegen. Diese 'Häppchen' sind die verschiedene Zustände, in denen sich das System befinden kann. Außerdem die Ereignisse, die - je nach Zustand - unterschiedliche Aktionen und Zustandswechsel auslösen.

Fangen wir erstmal mit dem Wechselblinker am Bü an. Rechts und links von der Straße steht jeweils ein Andreaskreuz mit einem Blinklicht. Bei Annäherung eines Zuges gehen kurz beide Lampen an, dann blinken sie im Wechseltakt. Hat der Zug den Bü überquert, gehen die Lampen wieder aus.
Welche Zustände können wir nun für dieses System identifizieren:

  1. Der Blinker ist im Ruhezustand. Alle Lampen sind aus. Das System wartet darauf, dass sich ein Zug nähert.
    >>Kommt der Zug, werden beide Lampen angeschaltet, die Stoppuhr gestartet, und wir wechseln in den 2. Zustand
  2. Der Zug hat den Kontakt ausglöst, beide Lampen sind für einen kurzen Zeitraum an. Die Stoppuhr für diese Zeit läuft.
    >>Ist die Stoppuhr abgelaufen, schalten wir die rechte Lampe aus, starten die Stoppuhr erneut mit der Blinkzeit und wir wechseln in den 3. Zustand.
  3. Jetzt ist nur noch die linke Lampe an, die rechte ist aus. Die Blinkzeit läuft.
    >>Ist die Blinkzeit abgelaufen, wird die linke Lampe aus, und die rechte Lampe eingeschaltet. Die Blinkzeit wird neu gestartet und wir wechseln in den 4. Zustand
  4. Jetzt ist nur die rechte Lampe an, die linke ist aus. Die Blinkzeit läuft.
    >>Ist die Blinkzeit abgelaufen, wird die reche Lampe aus, und die linke Lampe eingeschaltet. Die Blinkzeit wird neu gestartet und wir wechseln wieder in den 3. Zustand
    >>hat der Zug den Bü verlassen, werden beide Lampen ausgeschaltet, und wir wechseln in den 1. Zustand.

Jetzt haben wir unseren Wechselblinker also in 4 Zustände zerlegt, in denen sich das System befinden kann. In jedem Zustand wartet dieser Automat nun auf ein Ereigns ( mit '>>' markiert ). Tritt das Ereignis ein, wird eine Aktion gestartet, und dann der Zustand gewechselt. Im letzten Zustand warten wir sogar auf 2 Ereignisse. Das Ereignis, dass zuerst eintritt, bestimmt die ausgeführte Aktion und den Zustandswechsel.
Damit haben wir unser Problem in kleine Schritte zerlegt, die wir nun auch gedanklich durchgehen können, ob das auch alles so passt.
Da ist noch keine einzige Zeile Code geschrieben.

Im nächsten Post will ich dann vorstellen, wie man diesen noch theoretischen Ablauf in konkreten Code umsetzen kann.

Ihr dürft aber auch gerne schon Fragen zur Theorie stellen , wenn etwas unklar ist, oder mir bei obigem Ablauf ein Fehler unterlaufen ist .


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi, Langsamfahrer und Carstenhan haben sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#2 von Reibuch , 03.11.2018 19:32

Hallo Franz —Peter

Bin gespannt

Bisher alles verstanden

VG
Thomas


Gruß Thomas


 
Reibuch
InterRegioExpress (IRE)
Beiträge: 311
Registriert am: 27.08.2006
Ort: Hunsrück
Gleise Märklin C Gleis
Spurweite H0
Stromart AC, Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#3 von PATs in 1zu87 , 04.11.2018 08:40

Guten Morgen

Ich programmiere Zeitsteuerung schon seit vielen Jahren ohne Delay da dieser den Microcontroller blockiert.
Arduino Basis verwende ich nicht sondern die Programmiersprache C+.

Zwar ist Delay im MC eine sinnvolle Sache aber nützt ja nix wenn ich der Zeit nix anderes passieren kann.

Grüsse
Patrick


Irgendwo im Ruhrgebiet

- Moderner Hauptstreckenverkehr für Nah/Güterverkehr
- Industrieanbindung
- SpDrS60-Stellwerk

Meine HO-Anlage: https://stummiforum.de/viewtopic.php?f=64&t=179346
YouTube: https://www.youtube.com/channel/UCfgRbZ06vRHmpR5I5hvN3wQ


 
PATs in 1zu87
CityNightLine (CNL)
Beiträge: 1.586
Registriert am: 06.05.2017


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#4 von MicroBahner , 04.11.2018 22:52

@Patrick: für Leute wie dich ist dieses Tutorial ja auch nicht gedacht. Mal nebenbei bemerkt: die Basis von Arduino ist die Programmiersprache C++


Nun geht's weiter in diesem Tutorial für Einsteiger.

Die Liste im ersten Post müssen wir nun in einen Programmablauf umsetzten. Ich möchte das hier mal - die Programmierspezialisten mögen mir verzeihen - für die Einsteiger 'stummilike' an einem Gleisplan demonstrieren. Der Arduino ist der Lokführer, der mit seiner Lok (=dem Prozessor) diesen Gleisplan abfährt. Programmverzweigungen sind die Weichen und es gibt Stationen, an denen unser Lokführer etwas zu tun hat.



Am Anfang steht eine 4-Wege Weiche, die entsprechend dem aktuellen Zustand gestellt ist. Wie in einem Rangierbahnhof verzweigt es sich, und die folgenden Weichen in jedem Zweig sind je nachdem gestellt, ob ein erwartetes Ereignis eingetrofffen ist oder nicht. Am Ende kommen alle Zweige wieder zusammen, und es geht wieder von vorn los.
Ihr könnt jetzt mal in Gedanken ( oder mit dem Finger ) die 'Lok' kreisen lassen, und den Programmablauf durchspielen. In den weißen Kastchen ist was zu tun, ansonsten geht es ohne Unterbrechung immer im Kreis herum - mal hier, mal da lang

Natürlich gibt es für solche Abläufe auch informationstechnisch korrekte Symboldarstellungen - aber letztendlich zeigen die auch nichts anders .
Vielleicht macht es Euch so mehr Spaß, das ganze gedanklich durchzuspielen.
Wie immer - wenn was unklar ist, einfach fragen.

Im nächsten Schritt wirds dann wieder seriös - wir werden das Ganze dann in korrekten C++ Code umsetzen.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi und Carstenhan haben sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#5 von Donautal , 05.11.2018 09:57

Hervorragend erklärt und die „Schienendarstellung“ wunderbar.


Ich freue mich auf die Fortsetzung. Obwohl ich ja programmieren kann (weil das u.a. Teil meiner Ausbildung und Berufs ist) freue ich mich dennoch über eine „für Anfänger möglichst einfache“ Erklärung und Programmierweise.


Eine 50 Jahre alte, über 30 Jahre abgebaute (und somit nicht bespielte) Anlage wird für die nächste Generation wieder restauriert.
https://stummiforum.de/viewtopic.php?f=15&t=156146

Mein echter Name: Michael - sofern ich es unter einem Posting mal vergesse


 
Donautal
InterCity (IC)
Beiträge: 567
Registriert am: 07.01.2018
Ort: 78532 Tuttlingen
Spurweite H0
Stromart AC, Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#6 von Egon , 05.11.2018 10:17

Hallo Franz-Peter,

auch von mir ein
Bitte mach weiter, es wird bestimmt sehr interessant. Und wenn ich mir deine Videos anschaue, weiss ich dass es fundiert weiter gehen wird.
Gruß
Egon


Egon  
Egon
InterCity (IC)
Beiträge: 712
Registriert am: 14.01.2010
Ort: Ruhrgebiet
Spurweite H0
Steuerung TAMS MC
Stromart AC, Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#7 von Reibuch , 05.11.2018 10:57

Hallo Franz —Peter



Klasse ,bin gespannt

VG
Thomas


Gruß Thomas


 
Reibuch
InterRegioExpress (IRE)
Beiträge: 311
Registriert am: 27.08.2006
Ort: Hunsrück
Gleise Märklin C Gleis
Spurweite H0
Stromart AC, Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#8 von 4fangnix , 05.11.2018 13:09

Hallo Franz-Peter,

da kann ich mich nur anschließen.
Ich bin ein Arduino-Wiedereinsteiger und will die kleinen Kerlchen als zweite Zentrale, neben meiner BiDiB-Zentrale, in Rocrail zur zeitgesteuerten Lichtsteuerung (Häuser- und Straßenlicht und diverse andere Dinge) einsetzen.
Bin gerade daran die Anlage aufzubauen, so dass die Arduinos erst später zum Zuge kommen.
Aber Deine Moba-Tools und die sonstigen Beiträge verfolge ich schon jetzt mit großem Vergnügen.


Schöne Grüße
Armin


Rocrail; 1x OpenDCC GBMboost, 1x BiDiB RF-Basis (OpenCar), 5x GBM16T, 2x LightControl, 2x OneControl, 5x Mobalist, DMX-RGB-Dimmer;
MobaLedLib (kann > 48.000 LED via WS2811 oder > 16.000 WS2812-RGB-LED steuern und/oder Servos, Sounds, Stepper, DMX und Displays);
Intellibox; Märklin C- und K-Gleis, Bahn im Aufbau.


4fangnix  
4fangnix
InterRegioExpress (IRE)
Beiträge: 270
Registriert am: 18.10.2015
Ort: Weiterstadt
Gleise K-Gleis, C-Gleis
Spurweite H0
Stromart Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#9 von Jandrosch ( gelöscht ) , 05.11.2018 13:34

Hallo Franz-Peter,
vielen Dank, dass Du Dich den Sorgen und Nöten der Arduino Anfängern widmest. Kommt mir sehr gelegen, da ich vor Kurzem etwas frustriert meinem ersten Baustein gegenüber gesessen habe.
Thema ist für mich jetzt Pflichtlektüre.


Jandrosch

RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#10 von MicroBahner , 05.11.2018 14:53

Hallo liebe Stummies,
das freut mich, das mein kleiner Beitrag so viel Anklang findet. Das motiviert natürlich auch zum Weitermachen

Aber zuerst vielleicht noch eine kleine Zeitbetrachtung zu unserem Ablaufplan. Unsere Arduino-Lok ist schnell - sehr schnell sogar. Betrachten wir mal die Zeiten, um dies es da geht, wenn wird die Station 'Zeit starten' abarbeiten. Für einen schönen Wechselblinker werden wir da Zeiten so um eine 1/2 Sekunde, also 500ms verwenden. Für unseren Arduino ist das eine halbe Ewigkeit. Wenn der dann beim nächsten Durchlauf an der Weiche mit 'zeit abgelaufen?' vorbeikommt, hat sich da sicher noch nichts getan, und er flitzt einfach durch das frei Gleis durch. Bis die Weiche sich umstellt auf 'zeit abgelaufen' ist unsere Arduino-Lok schon mehrere Tausend Male im Kreis gelaufen ohne irgendetwas tun zu müssen. Ein aktueller ICE ist nix dagegen .

Vielleicht dämmert euch auch schon ein wenig, wie wir es später schaffen, dass der Arduino mehrere Dinge 'gleichzeitig' macht. Richtig, wenn wir die weitere(n) Aufgaben genauso strukturieren wie unseren Wechselblinker, können wir das im 'Gleiskreis' einfach hintereinander hängen. Jeder dieser 'Rangierbahnhöfe' stellt seine Weichen dann intern selbst - so wie unser Wechselblinker auch - und die Arduino-Lok fährt dann nacheinander durch jeden hindurch. Und je nach Weichenstellung muss der Lokführer kurz was erledigen, oder es geht ohne weitere Stationen einfach hindurch.

Diese Ablaufpläne zeigen etwas sehr schön, was man später im Code nicht mehr so einfach erkennt: Die Parallelität und damit Exklusivität der jeweiligen Pfade. In jeder Runde kann immer nur genau eins von den parallelen Gleisen (Aufgaben) befahren werden. Wie in dem Moment die Weichen in einem anderen Pfad stehen ist da dann vollkommen irrelevant.
Später im Code steht alles untereinander, da ist das nicht mehr so gut zu erkennen. Deshalb ist es immer sinnvoll, sich die Abläufe vor dem Codieren mit so einem Plan klarzumachen. Da reicht auch eine einfache Bleistiftzeichnung. Und Gleispläne zeichnen könnt ihr doch schließlich alle

Den Plan oben habe ich nochmal ein klein wenig überarbeitet. Nicht das sich an den Abläufen grundsätzlich etwas geändert hätte. Aber die 'Weichen' sind etwas anders platziert. So sieht man besser, dass zu jeder Verzweigung auch das genaue Gegenstück beim Zusammenführen gehört. Man kann jetzt um so einen Verzweigungblock quasi einen Kringel drummachen mit genau einem Eingang und einem Ausgang, und das entspricht dann auch genau einem Programmblock im Code.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi und Carstenhan haben sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#11 von MicroBahner , 05.11.2018 18:07

Hallo,
weiter geht's.
Nun wollen wir mal darangehen, unseren Ablaufplan auch in ablauffähigen Code umzusetzen. Die einfachen 'Weichen' sind sicher jedem klar: das sind einfache if-Anweisungen. Gibt es in beiden Zweigen etwas zu tun, brauchen wir auch einen else Zweig, ist ein Zweig ein 'leeres Gleis' reicht ein einfaches if.
Aber wo bekommen wir unsere 4-Wege-Weiche her?. Klar könnte man das in einzelne Verzweigungen auflösen, aber das ist nicht notwendig.
C++ bietet für sowas eine eigene Anweisung: die 'switch' Anweisung.
Die Grundstruktur sieht so aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
switch ( switchVariable ) {
case 1:
// Codeblock, der ausgeführt wird, wenn die switchVariable den Wert 1 hat
break; // Ende des Codeblocks, das Programm läuft hinter dem Switch-Block weiter
case 2:
// Codeblock, der ausgeführt wird, wenn die switchVariable den Wert 2 hat
break; // Ende des Codeblocks, das Programm läuft hinter dem Switch-Block weiter
default:
// Codeblock, der ausgeführt wird wenn die switchVariable einen Wert hat, der in
// keiner der obigen case-Zeilen vorkommt
// der 'default-Block' ist optional. Fehlt das default:, so verhält er sich genauso, als wenn
// dieser Codeblock leer ist. D.h. passt keine der obigen case-Zeilen, wird das gesamte switch
// übersprungen, und es geht danach weiter
}
 
 

In Abhängigkeit vom Wert der switchVariable wird die passende case-Zeile angesprungen. Dann werden die dortigen Anweisungen ausgeführt, und mit dem 'break;' springt das Programm zum Ende des gesamten switch-Blocks und macht dahinter weiter.
Hinter dem 'case' Schlüsselwort sind nur Konstante erlaubt, und natürlich müssen sie eindeutig sein. D.h. 2 case-Zeilen mit dem gleichen Konstantenwert sind nicht erlaubt. Wenn man das 'break;' vergisst, springt das Programm nicht ans Ende des switch-Blockes, sondern macht einfach mit dem Code hinter der nächsten case-Zeile weiter. Für die Zahl der case-Zeilen gibt es keine fest Grenze.

Diese Anweisung ist nun perfekt für unseren Zustandsautomaten geeignet. Die switch-Variable enthält immer den Wert für den aktuellen Zustand unseres Automaten und so wird bei jedem Durchlauf der entsprechende Codeblock ausgeführt. Damit werden wir nun unseren 'Rangierbahnhof' realisieren.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi hat sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#12 von MicroBahner , 05.11.2018 22:16

Edit: Objektnamen an aktuelle MobaTools angepasst

So jetzt geht's schon etwas ans Eingemachte - es wird codiert .

Wie wir gesehen haben, ist die switch-Anweisung der richtige Rahmen, um unseren Ablaufplan in Code umzusetzten. Nun müssen also die einzelnen case-Blöcke noch mit Leben gefüllt werden. Zunächst möchte ich jeden case-Block - also die Automatenzustände - einzeln aus unserem Ablaufplan ableiten.
Dann bauen wir das zu der kompletten switch Anweisung zusammen. Zum Schluß müssen wir dann sehen, was wir noch 'drumherum' brauchen, damit es ein lauffähiger Sketch wird.

Als erstes ein paar Bemerkungen zu den verwendetetn Variablen und Funktionen:
bueBelegt
Diese Variable zeigt uns an, dass ein Zug auf den Bü zufährt. Sie wird TRUE sobald sich der Zug nähert, und FALSE wenn er den Bü komplett überquert hat. Im einfachsten Fall kann das ein entsprechender Belegtabschnitt sein, dann ist es einfach ein Einganspin, den wir abfragen. Evtl. kann dies aber auch eine komplexere Logik sein. In unserem Zustandsautomaten soll uns aber erstmal noch nicht interessieren, wie diese Variable gesetzt wird.
wBlinkerZustand
Das ist unsere Zustandsvariable, die bestimmt, in welchem Zustand sich unser Automat befindet. Also sozusagen die Stellung der 4-Wege Weiche am Anfang.

LampeLinks LampeRechts
Das sind SoftLed-Objekte der MobaTools. Damit können wir ganz einfach durch die Methoden .on() und .off() unsere Led's im Andreaskreuz weich auf- und abblenden.
StoppUhr
Das ist ein MoToTimer Objekt der MobaTools. Damit können wir unsere Zeit setzen, und abfragen ob sie abgelaufen ist.

Wie wir die MobaTools Objekte einrichten und initiieren werden wir später sehen, wenn der switch-Block ( also unser Zustandsautomat ) zum kompletten Sketch erweitert wird.

Zustand 1 - Ruhezustand


1
2
3
4
5
6
7
8
9
10
11
12
13
14
 

case 1: // Grundzustand, abfragen, ob sich ein Zug nähert ( z.B. über einen Belegtmelder )
if ( bueBelegt ) {
// Der Zug ist in den Belegtabschnitt vor der Schranke eingefahren
// beide Lampen einschalten
LampeLinks.on();
LampeRechts.on();
// Stoppuhr mit der Zeit die beide Lampen an sein sollen vorbelegen
StoppUhr.setTime( STARTZEIT ); // StoppUhr 'aufziehen'
// in den 2. Zustand wechseln
wBlinkerZustand = 2; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 2 ausgeführt
}
break; // Ende der Anweisungen für den 1. Zustand
 
 



Zustand 2 - beide Lampen sind an

1
2
3
4
5
6
7
8
9
10
11
 

case 2: // beide Lampen ein, wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um
LampeRechts.off();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// in den 3. Zustand wechseln
wBlinkerZustand = 3; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 3 ausgeführt
}
break; // Ende der Anweisungen für den 2. Zustand
 
 



Zustand 3 - links an / rechts aus

1
2
3
4
5
6
7
8
9
10
11
 
      case 3: // linke Lampen ist an, rechte aus: wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um, Lampen umschalten
LampeLinks.off();
LampeRechts.on();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// in den 4. Zustand wechseln
wBlinkerZustand = 4; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 4 ausgeführt
}
break; // Ende der Anweisungen für den 3. Zustand
 
 



Zustand 4 - links aus / rechts an

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
      case 4: // linke Lampen ist aus, rechte an: wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um, Lampen umschalten
LampeLinks.on();
LampeRechts.off();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// wieder in den 3. Zustand wechseln
wBlinkerZustand = 3; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 3 ausgeführt
}
// Im 4. Zustand müssen wir auch noch abfragen, ob der Zug den Belegtabschnitt verlassen hat
if ( not bueBelegt ) {
// Der Zug ist komplett über den Bü gefahren, die Straße ist wieder frei
// Beide Lampen ausschalten
LampeLinks.off();
LampeRechts.off();
// wieder in den 1. Zustand wechseln. Eine Zeitüberwachung wird nicht gebraucht
wBlinkerZustand = 1; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 1 ausgeführt
}
break; // Ende der Anweisungen für den 4. Zustand
 
 



Einer der 4 Zustände ist übrigens nicht exakt so codiert wie es dem Ablaufplan entspricht. Erkennt ihr welcher? Und wo ist der Unterschied?


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi hat sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#13 von MicroBahner , 06.11.2018 11:33

Edit: Objektnamen an aktuelle MobaTools angepasst

Hallo liebe Stummis und Arduino-Interessierte :D
nach den theoretischen Vorüberlegungen wollen wir uns jetzt daranmachen und das Ganze zu einem lauffähigen Sketch zusammenbauen. Dann bleibt das nicht so theoretisch, und es tut sich schon was, bevor wir das Ganze um eine unabhängige Ampelsteuerung erweitern (Multitasking 8) ).

Da rufen wir uns in Erinnerung, wie so ein Sketch aufgebaut ist. So ein Sketch besteht zumindest aus 3 Abschnitten:

  1. Im ersten Block sagen wir dem Arduino, was wir alles benutzen wollen. Wir binden Bibliotheken ein, definieren die globalen Variablen und Libraryobjekte, die wir verwenden und ordnen gegebenenfalls konstanten Zahlen auch einen Namen zu, damit man sie im Bedarfsfall einfacher ändern kann (z.B. die Pin-Nummern).
  2. der setup-Block. In der setup-Funktion werden alle die Dinge erledigt, die beim Starten des Sketches einmalig gemacht werden müssen. Dazu gehört die Festlegung ob die verwendeten Pins Ein- oder Ausgänge sind und das Initiieren der verwendeten Library-Objekte
  3. der loop-Block. Das eigentliche 'Herzstück' des Sketches. Hier dreht unsere 'Arduino-Lok' dann endlos ihre Runden :D :D


Was gehört bei unserem Sketch nun alles in den ersten Block?
Da wir die MobaTools Lib verwenden wollen, muss die als erstes mal eingebunden werden:

1
 
#include <MobaTools.h>
 

Wer sie noch nicht auf seinem Rechner hat, kann sie hier herunterladen. Die zip-Datei an einem beliebigen Ort speichern. Dann in der Arduino IDE unter 'Sketch'->'Bibliothek einbinden'->'.ZIP-Bibliothek hinzufügen...' zu der heruntergeladenen Datei navigieren und OK drücken. Den Rest macht die IDE, und nun kann die Lib verwendet werden.

Dann müssen wir festlegen, welche Pins wir verwenden wollen:

1
2
3
4
5
 
// Festlegen der Anschlüsse (Pinnummer) für Ein- und Ausgänge
const byte linksPin = 4; // linke Lampe
const byte rechtsPin = 5; // rechte Lampe
const byte belegtPin = 8; // Eingang 'Zug kommt'
 
 

Die könnt ihr gegebenenfalls anpassen. Der 'belegtPin' Eingang schaltet in unserer ersten Version den Warnblinker einfach an bzw. aus. Die Schaltung dazu ist recht simpel ( auf dem UNO funktioniert es mit den gleichen Pinnr. natürlich genauso ):


Von den MobaTools verwenden wir den MoToTimer für die Zeitmessung, und SoftLed für die 'weiche' Ansteuerung der Leds. Timer brauchen wir nur einen, Softleds aber 2 ( für rechts und links )

1
2
3
4
5
6
7
8
9
10
 
// Benötigte MobaTools Objekte:
MoToTimer StoppUhr; // Zum Messen von Zeiten
MoToSoftLed LampeLinks;
MoToSoftLed LampeRechts;
 
// Zeiten für den Blinkrhythmus ( in ms )
const int STARTZEIT = 500;
const int BLINKZEIT = 600;
const int FADEZEIT = 200;
 
 

Für die Lampen des Wechselblinkers habe ich da auch gleich noch die Zeiten festgelegt: wie lange sind beim Start beide gleichzeitig an, und in welchem Rhythmus blinken sie danach. Mit den Zeiten kann man dann auch ein wenig experimentieren. FADEZEIT gibt an, wie lange das auf/Abblenden dauert.

Ja, und dann brauchen wir noch 2 Variable, die wir oben im Code für unseren Zustandsautomaten schon verwendet haben:

1
2
3
4
 
// Variable
boolean bueBelegt; // = TRUE, wenn sich ein Zug im Bereich des Bue befindet
byte wBlinkerZustand; // aktueller Zustand unseres Blinkerautomaten
 
 


Damit ist unser erster Block komplett.

Im Setup
müssen wir den Eingangspin als 'Eingang' definieren, und unsere 'SoftLed Objekte initiieren. Das Schalten der Pins auf 'Ausgang' macht die MobaTools Lib. Als letztes setzen wir dann noch den Startzustand unseres Blinkautomaten:

1
2
3
4
5
6
7
8
9
10
11
12
 
void setup() {
 
// Pins einrichten
pinMode( belegtPin, INPUT_PULLUP ); // Mit einem Schalter nach GND wird Blinker eingeschaltet
LampeLinks.attach( linksPin ); // Zuordnung der Softleds zu den Ausgangspins
LampeRechts.attach( rechtsPin );
LampeLinks.riseTime( FADEZEIT ); // Überblendzeit einstellen
LampeRechts.riseTime( FADEZEIT );
 
wBlinkerZustand = 1; // Startzustand des Blinkautomaten.
}
 
 



Nun noch zum loop()

Der besteht im Wesentlichen ja nur aus der switch-Anweisung mit den case-Blöcken aus dem vorigen Post. Ganz am Anfang muss unser Lokführer aber noch kurz Station machen, unseren Eingangspin abfragen und den gelesenen Wert in der Variablen 'bueBelegt' ablegen:

1
2
 
    bueBelegt = not digitalRead( belegtPin ); // ein LOW-Level am Eingangspin schaltet den Blinker ein
 
 



Der fertige Sketch
Damit haben wir jetzt den ganzen Sketch zusammem, den wir so in der IDE übersetzen und auf den Arduino laden können:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
 
/* Tutorial 'Zeitabläufe ohne delay() '
* Einfacher Wechselblinker ( unbeschrankter Bahnübergang )
*/
 
#include <MobaTools.h>
 
// Festlegen der Anschlüsse (Pinnummer) für Ein- und Ausgänge
const byte linksPin = 4; // linke Lampe
const byte rechtsPin = 5; // rechte Lampe
const byte belegtPin = 8; // Eingang 'Zug kommt'
 
// Benötigte MobaTools Objekte:
MoToTimer StoppUhr; // Zum Messen von Zeiten
MoToSoftLed LampeLinks;
MoToSoftLed LampeRechts;
 
// Zeiten für den Blinkrhythmus ( in ms )
const int STARTZEIT = 500;
const int BLINKZEIT = 600;
const int FADEZEIT = 200;
 
// Variable
boolean bueBelegt; // = TRUE, wenn sich ein Zug im Bereich des Bue befindet
byte wBlinkerZustand; // aktueller Zustand unseres Blinkerautomaten
 

void setup() {
 
// Pins einrichten
pinMode( belegtPin, INPUT_PULLUP ); // Mit einem Schalter nach GND wird Blinker eingeschaltet
LampeLinks.attach( linksPin ); // Zuordnung der Softleds zu den Ausgangspins
LampeRechts.attach( rechtsPin );
LampeLinks.riseTime( FADEZEIT ); // Überblendzeit einstellen
LampeRechts.riseTime( FADEZEIT );
 
wBlinkerZustand = 1; // Startzustand des Blinkautomaten.
}
 
void loop() {
 
// Belegtzusatnd abfragen. Das machen wir hier jetzterstmal ganz einfach: Letztendlich
// schalten wir mit dem Eingang einfach den Wechselblinker ein und aus.
// Im realen Praxisfall könnte hier gegebenenfalls auch ein komplexere Logik stehen, um zu
// erkennen, ob ein Zug sich nähert oder den Bü wieder verlassen hat.
bueBelegt = not digitalRead( belegtPin ); // ein LOW-Level am Eingangspin schaltet den Blinker ein

switch ( wBlinkerZustand ) {
// je nach Wert der Variable wBlinkerZustand, wird die entsprechende 'case' Zeile angesprungen
case 1: // Grundzustand, abfragen, ob sich ein Zug nähert ( z.B. über einen Belegtmelder )
if ( bueBelegt ) {
// Der Zug ist in den Belegtabschnitt vor der Schranke eingefahren
// beide Lampen einschalten
LampeLinks.on();
LampeRechts.on();
// Stoppuhr mit der Zeit die beide Lampen an sein sollen vorbelegen
StoppUhr.setTime( STARTZEIT ); // StoppUhr 'aufziehen'
// in den 2. Zustand wechseln
wBlinkerZustand = 2; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 2 ausgeführt
}
break; // Ende der Anweisungen für den 1. Zustand
//-------------------------------------------------------------------------
case 2: // beide Lampen ein, wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um
LampeRechts.off();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// in den 3. Zustand wechseln
wBlinkerZustand = 3; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 3 ausgeführt
}
break; // Ende der Anweisungen für den 2. Zustand
//-------------------------------------------------------------------------
case 3: // linke Lampen ist an, rechte aus: wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um, Lampen umschalten
LampeLinks.off();
LampeRechts.on();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// in den 4. Zustand wechseln
wBlinkerZustand = 4; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 4 ausgeführt
}
break; // Ende der Anweisungen für den 3. Zustand
//-------------------------------------------------------------------------
case 4: // linke Lampen ist aus, rechte an: wir fragen ab, ob die Stoppuhr abgelaufen ist.
if ( not StoppUhr.running() ) {
// Die Stoppuhr läuft nicht mehr, die Zeit ist um, Lampen umschalten
LampeLinks.on();
LampeRechts.off();
StoppUhr.setTime( BLINKZEIT ); // Stoppuhr 'aufziehen'
// wieder in den 3. Zustand wechseln
wBlinkerZustand = 3; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 3 ausgeführt
}
// Im 4. Zustand müssen wir auch noch abfragen, ob der Zug den Belegtabschnitt verlassen hat
if ( not bueBelegt ) {
// Der Zug ist komplett über den Bü gefahren, die Straße ist wieder frei
// Beide Lampen ausschalten
LampeLinks.off();
LampeRechts.off();
// wieder in den 1. Zustand wechseln. Eine Zeitüberwachung wird nicht gebraucht
wBlinkerZustand = 1; // Ab dem nächsten loop-Durchlauf werden nur die Anweisungen des case 1 ausgeführt
}
break; // Ende der Anweisungen für den 4. Zustand
} // Ende des switch-Blockes
}

 



Bevor es weitergeht, sollte das bei Euch so funktionieren. Deshalb mache ich hier jetzt erstmal etwas Pause. Über Rückmeldungen würde ich mich natürlich freuen. Ich habe versucht den Sketch möglichst ausführlich zu kommentieren, damit man - zusammen mit diesem Tutorial - auch versteht was da abläuft.
Wenn noch etwas unklar ist - einfach fragen. Ich weis, am Anfang klemmt es oft an Stellen, die einem später ganz selbstverständlich erscheinen.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi und MobaPro59 haben sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog

zuletzt bearbeitet 09.08.2021 | Top

RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#14 von Erich Müller , 06.11.2018 19:13

Hallo Franz-Peter,

Die "Stoppuhr" ist eine Countdown-Funktion, richtig?

Zitat

Einer der 4 Zustände ist übrigens nicht exakt so codiert wie es dem Ablaufplan entspricht. Erkennt ihr welcher? Und wo ist der Unterschied?



Ich denke schon: der vierte. Hier wird in jedem Durchlauf abgefragt., ob der Zug noch da ist. Im Ablaufdiagramm entfällt die Abfrage, wenn der Timer abgelaufen ist und die Lampen umschalten.
Gewissermaßen besteht im Code Case 4 nicht aus drei parallelen Gleisen, sondern aus zwei aufeinander folgenden jeweils zweigleisigen Abschnitten, zwischen denen auf dasselbe Hauptgleis zurückgeführt wird.
In Turbo-Pascal, das ich vor ca. 30 Jahren mal kennenlernen durfte, wäre das mit einem "else" vor der zweiten If-Abfrage gemacht worden. Der Code ist natürlich sinnvoller ohne Else.


Freundliche Grüße
Erich

„Es hat nie einen Mann gegeben, der für die Behandlung von Einzelheiten so begabt gewesen wäre. Wenn er sich mit den kleinsten Dingen abgab, so tat er das in der Überzeugung, daß ihre Vielheit die großen zuwege bringt.“
Friedrich II. über Fr. Wilhelm I.


Erich Müller  
Erich Müller
ICE-Sprinter
Beiträge: 6.319
Registriert am: 03.12.2015


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#15 von MicroBahner , 06.11.2018 21:12

Hallo Erich,
dem ist nichts hinzuzufügen . Alles ist so wie Du es schreibst.
[quote="Erich Müller" post_id=1892086 time=1541528017 user_id=26147]
In Turbo-Pascal, das ich vor ca. 30 Jahren mal kennenlernen durfte, wäre das mit einem "else" vor der zweiten If-Abfrage gemacht worden.
[/quote]bei C++ auch . Bei der 'dreigleisigen Variante' ( mit else ) wäre es sinnvoller erst nach dem Zug zu schauen, und dann nach dem Timer. Allerdings macht es nur einen Unterschied, wenn die Ereignisse 'kein Zug mehr' und 'Timer abgelaufen' exakt beim gleichen Schleifendurchlauf auftreten, was recht unwahrscheinlich ist.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#16 von Reibuch , 07.11.2018 11:51

Hallo Franz Peter,

Schaltung habe ich nachgebaut , und funktioniert

klasse

VG
Thomas

PS.Ob ich das alles verstanden habe wie der Sketch sich Aufbaut ich glaube ich muss es noch ein paar mal lesen bis ich das Verstanden habe


Gruß Thomas


 
Reibuch
InterRegioExpress (IRE)
Beiträge: 311
Registriert am: 27.08.2006
Ort: Hunsrück
Gleise Märklin C Gleis
Spurweite H0
Stromart AC, Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#17 von MicroBahner , 08.11.2018 11:00

Hallo Thomas,
ja, anfangs ist das Eindenken in diese Zustandsautomaten nicht ganz einfach, erfordert es doch ein ziemliches Umdenken. Aber es lohnt sich. Wenn Du das einmal verinnerlicht hast, tuen sich mit dem Arduino ganz neue Welten auf. Wenn Du mein 'elektromechanisches Stellwerk' ( s.u.) mal betrachtest: Da werkelt auch nur genauso ein Prozessor drin wie im Arduino. Liegt - was Speicher und Anschlüsse angeht so zwischen UNO und Mega. Und der managed das ganze Stellwerk mit Fahrstraßen und Zugüberwachung. Das ist weitgehend mit genau dieser Technik realisiert. Da werkeln ein paar Dutzend solcher Automaten drin .

Die Analogie mit der Arduino-Lok und dem Gleiskreis passt schon recht gut. Daran kann man sich das klarmachen. Man muss sich eben wirklich in Gedanken neben den Lokführer stellen und die Gleise abfahren.

Wenn Du irgendwo noch ein spezielles Problem hast und etwas unklar ist - frag einfach.
Gilt natürlich genauso für alle anderen Mitleser. Den bisherigen Code solltet ihr schon verstanden haben, bevor es weitergeht.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#18 von sebi0410 , 11.11.2018 15:46

Halo Franz-Peter,

sehr cool gemacht ich habe den Thread mal in die Abo's genommen Bisher fehlt mir allerdings der Arduino.

Bitte mach weiter so, ist total interessant was das kleine Teil alles kann.


Gruß
Sebastian


 
sebi0410
InterCity (IC)
Beiträge: 613
Registriert am: 12.08.2005
Ort: Howi
Gleise K-Gleise
Spurweite H0
Steuerung MSII
Stromart Digital


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#19 von MicroBahner , 12.11.2018 17:23

Hallo Sebastian,

Zitat
Bisher fehlt mir allerdings der Arduino.

Dann ist das aber ziemlich trockener Stoff . Aber was nicht ist, kann ja noch werden.
Wobei sich das Tutorial sicher nicht an den absoluten Erstanwender richtet. Zumindest ein paar grundlegende Beispiele aus der IDE oder einem Einsteiger-Kit sollte man schon zum Laufen gebracht haben. Diese Beispiele verwenden ja auch meistens das delay() und hier geht es dann darum. wie man das wieder los wird .


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#20 von TecnoWorld , 12.11.2018 18:23

Nur mal so am Rande:
Schön, das mal jemand so ein Tutorial macht, um "sauberer" programmieren zu können und nix mit Schleifen und delay().

Aber sollte man dann nicht gleich "unten" anfangen und erst mal die Hardware erklären? Also, Event-System, DMA, Interrupts. Damit erschlägt man nämlich schon sehr viele Dinge und braucht bei den meisten Aktionen noch nicht mal den Prozessor dazu (Weil DMA und Events alleine laufen).

Aber sorry - ich wollte nicht stören - nur eine Anregung.


__________________________
LG aus Andalusien.
RailSolution - das Lichtprojekt von Modellbahnern für die Modellbahn


TecnoWorld  
TecnoWorld
InterRegioExpress (IRE)
Beiträge: 270
Registriert am: 11.03.2015


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#21 von Gelöschtes Mitglied , 12.11.2018 21:18

Zitat

Dann ist das aber ziemlich trockener Stoff . Aber was nicht ist, kann ja noch werden.



Dem kann man abhelfen, nicht nur die Modellbahn laesst sich auf dem PC simulieren
https://www.smashingrobotics.com/arduino...out-real-board/

Wenn ich es recht sehe, hast Du vor, die State-Machine nur in einer Schleife laufen zu lassen. Mit Timer-Interrupts koennte man das noch eleganter loesen, aber fuer den Anfaenger ist das schon ok und die Erklaerung finde ich super!

Gruss,
Tom



RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#22 von Gelöschtes Mitglied , 12.11.2018 21:21

Zitat

Weil DMA und Events alleine laufen



Auf einem 8-Bit ATMega? Da muesste man schon einen anderen Controller waehlen.

Gruss
Tom



RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#23 von ThKaS , 13.11.2018 07:29

Moin moin Franz-Petrr,

danke für das Tutorial. Super! Sehr verständlich.

Habe es mal „nachgebaut“ mit einem Nano. Hat geklappt.
Habs dann mal erweitert auf mehrere Ausgänge und Zeit- und Variablenvariationen. Hat auch geklappt.
(obwohl ich bisher das Programmieren immer gescheut habe)

Nun aber doch noch eine Frage dazu.
Wieviele Schleifendurchläufe pro Zeiteinheit macht denn der Nano da? Kann man das errechnen?


lieben Gruss von südlich des Weisswurst-Äquators
Thomas

guckst: runderneuerte https://www.thkas-moba.de ‹(•¿•)› www.mucis.de

‹(•¿•)›

Mä-K-Gleis, Tams MC, Multi-Kulti Decoder, WDP


 
ThKaS
InterCityExpress (ICE)
Beiträge: 2.199
Registriert am: 28.04.2005
Homepage: Link


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#24 von MicroBahner , 13.11.2018 09:07

Hallo Thomas,
super, das freut mich. So ist es gedacht, und wenn es für dich verständlich ist, habe ich ja nicht alles falsch gemacht .

Was die Schleifendurchläufe angeht: Berechnen ist da kaum möglich, aber man kann es mit ein paar zusätzlichen Programmzeilen messen. Klar verfälschen die das Ergebnis etwas. Aber so genau muss es ja gar nicht sein, es geht eher um die Größenordnung. Ich habe das mal eben gemacht, und das Ergebnis:
im Ruhezustand( warten auf Zug ) : ca 107000 Durchläufe/Sek.
Während des Blinkens : ca. 80000 Durchläufe / Sek.

So ein Blinker ist für den Arduino also keine echte Herausforderung. Da dreht er hauptsächlich Däumchen - und das ziemlich flott


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino: Zeitsteuerungen ohne Delay - ein kleines Tutorial

#25 von MicroBahner , 17.11.2018 18:22

Hallo liebe Freunde der Kombination Arduino+Moba ,
ich hoffe, der eine oder andere hat es inzwischen doch geschafft, den bisherigen Sketch in der Praxis umzusetzen und auch nachzuvollziehen, was da passiert. Wenn nicht - bitte melden

Nichts desto trotz mach ich jetzt mal einfach weiter. Wir wollten ja auch noch ein Ampelschaltung einbauen. Also werden wir jetzt in gleicher Art und Weise einen Ampelsketch realisieren, und dann beide kombinieren.
Ich weis jetzt nicht genau, was Thomas da als Ampelschaltung im Sinn hatte. Im einfachsten Fall haben wir nur eine Kreuzung, und da sehen unsere Ampelbilder dann so aus:

In der Reihenfolge müssen die Ampeln geschaltet werden ( wobei die 'Übergangsphasen' mit dem gelben Licht natürlich kürzer zu sehen sind, als die reinen Rot/Grün Phasen 1+5 ).
Die 8 Signalbilder sind nun auch unsere Automatenzustände. Auf irgendwelche Eingänge brauchen wir erstmal nicht zu reagieren. Die Zustände werden einfach von 1 bis 8 und wieder bei 1 beginnend zeitgesteuert im Kreis herum geschaltet.
Damit wir mit dem Wechselblinker nicht in Konflikt kommen, müssen wir natürlich unsere Pins entsprechend verteilen. Die jeweils gegenüberliegenden Ampeln einer Straße können parallel geschaltet werden, so dass wir insgesamt 6 Ausgänge benötigen:


So das wäre nun die Basis für unseren Ampel-Sketch. Wenn das zu einfach ist - ihr könnt noch Ideen einbringen
Ich hatte da schonmal an eine per Schalter aktivierbare Nachtschaltung gedacht ( gelbes Blinklicht auf der Nebenstraße )


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


hubedi hat sich bedankt!
 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


   

passende Stecker / Buchsen zum Arduino Nano
Märklin Sounddecoder defekt

  • Ähnliche Themen
    Antworten
    Zugriffe
    Letzter Beitrag
Xobor Einfach ein eigenes Forum erstellen
Datenschutz