Was meinste mit Häuslebauer? :shock:
Ich finds immer gut, wenn man auch eine fertige Lösung hat.
Hier im Forum wird immer wieder betont, das man sich in der Ausbildung Befindlichen Hilfe zur Selbsthilfe und keine fertigen Lösungen (noch dazu ohne weitere Erklärungen) gibt. Das musste ich mir sogar schon trotz vorhergehenden wochenlangen Erklärungen meinerseits anhören.
Bei (vermeintlichen) Errichtern eines Eigenheims, die ihre Automatisierung selbst erstellen, liegen die Prioritäten dagegen ganz klar auf schneller Problemlösung.
Aber wenn's denn so sein soll:
Ich bin natürlich dankbar für alle Tips wie man "richtiges" schreiben von Code von Anfang an angehen sollte.
Will mir auch keinen Stil- wenns komplizierter wird wieder abgewöhnen müssen.
Mal davon abgesehen, das ein Rollladenbaustein mit Merkern immer ein schlechtes Beispiel ist.
Und auch die Siemenstimer sind m.M.n. da eher eine schlechte Wahl.
Für gewöhnlich hast Du im Haus ja nicht nur einen Rollladen sondern mehrere. Wenn Du im Rollladen-Baustein Merker verwendest, sind diese feste globale Adressen, so dass Du diesen Baustein auch nur für einen einzigen Rolladen verwenden kannst.
Verwendest Du dagegen im Baustein nur lokale Variablen, kannst Du den Inhalt der globalen Adressen, wie Ein-/Ausgänge beim Bausteinaufruf über die Schnittstelle an die lokalen Variablen übergeben und so ein und den gleichen Baustein für alle Rollläden verwenden.
Auch bei eventuellen Änderungen mußt Du dadurch nur einen Baustein bearbeiten, anstatt sie bei jedem Rollladen durch zu führen.
In diesem Rollladen-Baustein hast Du Daten, die Du vom aktuellen Zyklus zum nächsten speichern mußt und auch nur für diesen brauchst. Dazu gehören z.B. Flankenmerker und Multiinstanzen von IEC-Timern. Immer wenn Du solche Daten hast, solltest du einen FB verwenden. Dann legt jeder Aufruf des FBs seine Daten in seinem eigenen Instanzdatenbaustein ab. Bist Du Dir nicht sicher, ob Du einen FB brauchst oder auch ein FC reicht, bist Du mit dem FB auf der sicheren Seite.
Somit hast Du für jeden Rollladen zwar immer den gleichen FB, aber jeder hat seine eigenen Ein-/Ausgänge an der Schnittstelle beim Aufruf und seine eigenen zu merkenden Daten, wie Flanken und Laufzeiten, in seinem IDB.
Und deshalb ist hier ein IEC-Timer auch die bessere Wahl (mal davon abgesehen, dass die S7-1200 die S7-Timer auch gar nicht hat!), da diese als Multiinstanz angelegt ihre Daten ebenfalls im IDB des Rollladen-FBs speichern. Somit hat jeder Aufruf des FBs auch automatisch seinen eigenen Timer. Bei den S7-Timern müsste man einen Eingang an der Baustein-Schnittstelle anlegen und bei jedem Aufruf des Bausteins eine andere Timernummer übergeben. Geht zwar auch, ist aber hier umständlicher, da Du eh' noch andere Daten hast, die im IDB gespeichert werden sollten. Die Übergabe der Timernummer ist vor allem eine Möglichkeit für mehrfach nutzbare FCs mit Timern.
Dann hatte ich geschrieben, dass man überlegen muss, welche Variablen man benötigt:
1. reine Eingänge: Als Erstes steht hier natürlich der Taster zu Buche. Dessen Zustand muss man in den Baustein hinein bringen. Ausgeben muss man an den Taster nichts, daher nur IN.
Dann ist es ratsam, auch die gewünschte Laufzeit variabel in den Baustein zu geben, denn die Rollläden können ja unterschiedlich groß sein und damit verschieden lange laufen. Dabei kann man am Besten eine Standardzeit vorgeben, dann muss man dies nicht bei jedem Aufruf wiederholen, sonder nur wenn die gewünschte Laufzeit davon abweicht.
2. reine Ausgänge: Die Motorausgänge "Auf" und "Ab" sollen nur von diesem Baustein beeinflusst werden und das auch in jedem Zyklus von neuem. Daher kannst Du reine Ausgänge benutzen. Würdest Du dagegen z.B. den bisherigen Zustand in die Entscheidung für den neuen Zustand einfliessen lassen oder auch außerhalb des Bausteins auf diese Einfluss nehmen, dann sollte ein IN/OUT die Wahl sein. Das Gleiche gilt im Normalfall auch bei Verändern mit Setzen und Rücksetzen (vor allem in FCs!), da dies für gewöhnlich nicht in jedem Zyklus passiert!
3. Schließlich die Variablen, die nur innerhalb des Bausteins benötigt werden und keinen "Kontakt" zu den restlichen Bausteinen haben:
Da wären zuerst die Typen, die erst im Baustein zugewiesen/beschrieben und dann in weiteren Netzwerken lesend benutzt werden. Diese kann man temporär anlegen - das heißt, sie werden mit Beendigung des Bausteins zum Überschreiben freigegeben (das bedeutet nicht immer, das dies auch tatsächlich passiert, aber man sollte erst mal davon ausgehen!).
Zum anderen hat man Variablen, die man in einem Zyklus beschreibt und im nächsten erst wieder liest. Diese muss man als statisch anlegen.
Ein ganz typisches Beispiel dazu ist die Flankenerkennung:
Der Taster ist ein Signal von außerhalb des Bausteins, dass im Baustein verarbeitet wird, aber an das nichts außgegeben wird -> Eingang
Der Flankenmerker FM_Taster speichert den Zustand von Taster aus dem vorigen Zyklus (im ersten Zyklus schreiben, im 2. lesen) - daher unbedingt statisch!
Der Melder "Flanke" wird nur im aktuellen Zyklus benötigt (im nächsten wird ja wieder neu entschieden) - daher reicht temporär.
Wenn Du Dir nicht sicher bist - lieber auf Nummer sicher gehen und statisch speichern.
Dann wollen wir mal überlegen, was Du unbedingt von einem Zyklus zum nächsten speichern mußt:
den Zustand des Tasters (FM_Taster), den Zustand des Timerausgangs (FM_Timer) und die letzte Richtung des Rollladens.
Außerdem wird der IEC-Timer beim Anlegen als Multiinstanz automatisch ebenfalls im STAT-Bereich gespeichert. Das kann man zwar auch selbst machen, aber zu Beginn ist es besser/sicherer, das von TIA beim Ziehen des Timers ins Netzwerk automatisch übernehmen zu lassen.
Variablen, die im aktuellen Zyklus erst festgelegt und dann verwendet werden:
wurde eine Flanke des Tasters detektiert (Flanke_Taster) und soll damit der Timer gestartet (Start) oder gestoppt (Stop) werden.
Man könnte noch die detektierte negative Flanke des Timers in einer temporären Variablen speichern, doch da diese nur an einer Stelle benötigt wird, kann man das Ergebnis auch direkt weiter verarbeiten.
Somit würde ich z.B. folgende lokale Variablen (=Bausteinschnittstelle) anlegen:
Dann die einzelnen Netzwerke, wie oben beschrieben:
Da der Zustand des Timers entscheidend für die auszuführende Aktion ist, muss diese unbedingt vor dem Starten oder Stoppen des Timers festgelegt werden!
Beim Verarbeiten des Timerausgangs im Netzwerk 2 und 3 wird TIA meckern, da es den Timer vor Erstellen des Netzwerks 4 noch gar nicht gibt. Deshalb sollte man vorher den Timer erst mal im NW4 als Multiinstanz anlegen und dann erst die beiden vorigen Netzwerke fertig stellen (oder das Meckern von TIA einfach ignorieren).
So, das soll nun wahrlich erst mal genug Erklärung sein. Den Aufruf des FBs mit dem Anlegen des IDBs solltest Du allein hinbekommen.
Im nächsten Schritt kannst Du dann den FB ein weiters mal mit einem anderen Taster und anderen Ausgängen aufrufen.
PS: Die Verwendung von lokalen Variablen in FCs und FBs würde ich an Deiner Stelle von Anfang an generell praktizieren. Ich persönlich hab' ziemlich lange gebraucht, ehe ich den "Murks" mit den Merkern wieder raus hatte.
Und was ich jetzt hier schlechterweise nicht gemacht habe, Du Dir aber ebenfalls von Anfang an angewöhnen solltest - kommentieren, kommentieren und noch mal kommentieren. Wenn Du das nicht machst, wirst Du sehr oft bemerken, dass Du schon teilweise kurze Zeit später nicht mehr weißt, was Du Dir beim Coden da so gedacht hast.