Kleines Programm für eine S7-200 CPU 212

Zuviel Werbung?
-> Hier kostenlos registrieren
...
In der 1-Stundenfibel. die bei der SPS dabei war, steht drin, dass man eine Programmendanweisung braucht. Und in AWL heißt die "MEND"! Daher schreib ich die. Brauche ich die nicht?
Hab' ich noch bei keinem meiner Programme gesehen und mein MicroWin kennt den Befehl auch nicht und meckert, wenn ich das eingebe.
Kannst Du Dir also komplett sparen.


Jetzt kommt das 1. Feintuning:
Du wolltest die Ausgänge A0.0 bis A0.2 in den ersten 40 Sekunden und A0.3 bis A0.5 in den folgenden 15s!
 
Habs mir anders überlegt. Bringt ja nicht viel, wenn die alle gleichzeitig rumschalten.
Daher Hab ich mir überlegt, sie jeweils mit einem Eingang zu koppeln. Klappt das so wie ich mir das vorstelle? Wenn ich den E0.0 auf EIN setze, dann schalten nur die beiden 1. Ausgänge?

Code:
//

NETWORK 1
LD     SM0.5                //Taktmerker für 1s
LD     Z0                //Rücksetzen, wenn 55 erreicht ist
ZV     Z0, +55

NETWORK 2
LDW<=  Z0, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.1

NETWORK 3
LD     M10.1                //Ausgang 1 für 40s gesetzt
U E0.0
=      A0.0

NETWORK 4
LDN    M10.1                //Ausgang 1 für 15s gesetzt
U E0.0
=      A0.1

NETWORK 5
LD     SM0.5                //Taktmerker für 1s
LD     Z1                //Rücksetzen, wenn 55 erreicht ist
ZV     Z1, +55

NETWORK 6
LDW<=  Z1, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.2

NETWORK 7
LD     M10.2                //Ausgang 1 für 40s gesetzt
U E0.1
=      A0.2

NETWORK 8
LDN    M10.2                //Ausgang 1 für 15s gesetzt
U E0.1
=      A0.3

NETWORK 9
LD     SM0.5                //Taktmerker für 1s
LD     Z2                //Rücksetzen, wenn 55 erreicht ist
ZV     Z3, +55

NETWORK 10
LDW<=  Z3, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.3

NETWORK 11
LD     M10.3                //Ausgang 1 für 40s gesetzt
U E0.2
=      A0.4

NETWORK 12
LDN    M10.3                //Ausgang 1 für 15s gesetzt
U E0.2
=      A0.5
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im Netzwerk 9/10 kommt irgendwie Dein Zähler durcheinander. ;)

Frage: Warum benutzt Du für die eigentlich gleiche Zeit-/Zählerfunktion getrennte Zähler, anstatt immer Z0 abzufragen?


Außerdem hätte ich noch etwas Feintuning, bevor Du die Ausgänge erweiterst, können wir aber auch danach machen.
 
Stimmt habe ich auch gesehen, das ich da Z3 verwendet habe. Das ich immer den gleichen Zähler nehmen kann, war mir nicht so klar. Jetzt aber schon.

Wenn ich also das Programm einfach auf die CPU übertrage, läuft das. Sonst muss ich da nichts machen.

Code:
//
//KOMMENTARE ZUM PROGRAMMTITEL
//
//Mit F1 rufen Sie die Hilfe und ein Beispielprogramm auf.
//

NETWORK 1
LD     SM0.5                //Taktmerker für 1s
LD     Z0                //Rücksetzen, wenn 55 erreicht ist
ZV     Z0, +55

NETWORK 2
LDW<=  Z0, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.1

NETWORK 3
LD     M10.1                //Ausgang 1 für 40s gesetzt
U      E0.0
=      A0.0

NETWORK 4
LDN    M10.1                //Ausgang 1 für 15s gesetzt
U      E0.0
=      A0.1

NETWORK 5
LD     SM0.5                //Taktmerker für 1s
LD     Z0                //Rücksetzen, wenn 55 erreicht ist
ZV     Z0, +55

NETWORK 6
LDW<=  Z0, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.2

NETWORK 7
LD     M10.2                //Ausgang 1 für 40s gesetzt
U      E0.1
=      A0.2

NETWORK 8
LDN    M10.2                //Ausgang 1 für 15s gesetzt
U      E0.1
=      A0.3

NETWORK 9
LD     SM0.5                //Taktmerker für 1s
LD     Z0                //Rücksetzen, wenn 55 erreicht ist
ZV     Z0, +55

NETWORK 10
LDW<=  Z0, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.3

NETWORK 11
LD     M10.3                //Ausgang 1 für 40s gesetzt
U      E0.2
=      A0.4

NETWORK 12
LDN    M10.3                //Ausgang 1 für 15s gesetzt
U      E0.2
=      A0.5
 
Das mit den Zählern funktioniert so nicht.
Versuche noch einmal nachzuvollziehen, was die SPS macht. Die arbeitet den Code "von oben nach unten" durch. Jetzt steht dort in NW1 + NW4, dass der Zähler hochgezählt werden soll wenn SM0.5 kommt. Was wird also passieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jetzt läßt Du im Netzwerk 1, 5 und 9 dreimal den gleichen Zähler zählen und rücksetzen!
Entweder Du nimmst in 5 und 9 separate Zähler, weil Du vlt. zu anderen Werten zählen willst, oder Du verzichtst auf die beiden Netzwerke, denn Z0 zählt doch schon im Netzwerk 1, oder?
 
Dann kommen wir gleich mal noch zum nächsten Feintuning:

Du hast Deine Vorgaben 40s und 15s. Die verwendest Du mehrfach im Programm, zum Teil auch nur indirekt als 55. Wenn Du diese Werte ändern willst, mußt Du dein gesamtes Programm durchsuchen!

Also würde ich im ersten Netzwerk (vor Deinem jetzigen Programm einfügen) die 40 und 15 mit dem MOVW-Befehl z.B. an die Variablen VW0 und VW2 übertragen. MOVW brauchst Du, weil es sich beim Vorgabe- und Zählerwert jeweils um einen INTegerwert handelt.
Dabei mußt Du festlegen, wann diese Übertragung stattfinden soll. Normalerweise reicht das im ersten Zyklus, den man durch den gesetzten Sondermerker SM0.1 ermitteln kann.

Die beiden so angelegten Variablen (VW0 & 2) sollten dann im nächsten Netzwerk addiert werden (zb. ins VW4), um so den Vorgabewert für den Zähler zu ermitteln. Auch dies reicht im ersten Zyklus aus.

Die Vorgaben bzw. Vergleiche führst Du dann nicht mit den konkreten Zahlen sondern mit den Variablen durch.
 
Zuletzt bearbeitet:
Also kann ich die NW 5 und 6 und 9 10 einfach löschen und frage im NW 7 und 8 und 11 und 12 immer nur den Merker 10.1 ab, oder?
 
Richtig!


Hast Du das nächste Feintuning gesehen?
Dann kommen wir gleich mal noch zum nächsten Feintuning:

Du hast Deine Vorgaben 40s und 15s. Die verwendest Du mehrfach im Programm, zum Teil auch nur indirekt als 55. Wenn Du diese Werte ändern willst, mußt Du dein gesamtes Programm durchsuchen!

Also würde ich im ersten Netzwerk (vor Deinem jetzigen Programm einfügen) die 40 und 15 mit dem MOVW-Befehl z.B. an die Variablen VW0 und VW2 übertragen. MOVW brauchst Du, weil es sich beim Vorgabe- und Zählerwert jeweils um einen INTegerwert handelt.
Dabei mußt Du festlegen, wann diese Übertragung stattfinden soll. Normalerweise reicht das im ersten Zyklus, den man durch den gesetzten Sondermerker SM0.1 ermitteln kann.

Die beiden so angelegten Variablen (VW0 & 2) sollten dann im nächsten Netzwerk addiert werden (zb. ins VW4), um so den Vorgabewert für den Zähler zu ermitteln. Auch dies reicht im ersten Zyklus aus.

Die Vorgaben bzw. Vergleiche führst Du dann nicht mit den konkreten Zahlen sondern mit den Variablen durch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja habe ich, aber da die Werte nur noch einmal abgefragt werden, macht es das in diesem Fall nur komplizierter. Ist mir klar, wenn ich ein langes Programm habe, an bei dem die Werte an mehreren Stellen abgefragt werden, das so Sinnvoll ist. Aber hier....

Code:
NETWORK 1
LD     SM0.5                //Taktmerker für 1s
LD     Z0                //Rücksetzen, wenn 55 erreicht ist
ZV     Z0, +55

NETWORK 2
LDW<=  Z0, +40            //wenn der Zählerwert größer als 40s ist, wird der Merker gesetzt
=      M10.1

NETWORK 3
LD     M10.1                //Ausgang 1 für 40s gesetzt
U      E0.0
=      A0.0

NETWORK 4
LDN    M10.1                //Ausgang 1 für 15s gesetzt
U      E0.0
=      A0.1

NETWORK 5
LD     M10.1                //Ausgang 1 für 40s gesetzt
U      E0.1
=      A0.2
NETWORK 6
LDN    M10.1                //Ausgang 1 für 15s gesetzt
U      E0.1
=      A0.3

NETWORK 7
LD     M10.1                //Ausgang 1 für 40s gesetzt
U      E0.2
=      A0.4

NETWORK 8
LDN    M10.1                //Ausgang 1 für 15s gesetzt
U      E0.2
=      A0.5
 
Ok, lassen wir mal so gelten, da der Grund verstanden wurde.

Dann das nächste:
Du willst 40s und 15s. Der Zähler beginnt bei Null. Im Netzwerk 2 wird auf kleiner gleich 40 verglichen.
M10.1 ist also von 0 bis 40 gesetzt, aber nur von 41 bis 54 nicht, dennn bei 55 wird sofort auf Null zurückgestellt.
 
OK, dann setze ich den Vergleicher auf 39. Allerdings ist eine Sekunde mehr oder weniger laut "meiner Auftraggeberin" nicht so wichtig. Aber da es ja kein Aufwand ist, mache ich das so.

Vielen Dank schon mal. Fahre dann jetzt zu meinem Spetzl und spiele das Programm ein. Bin mal gespannt.:)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In diesem Fall ist das so OK.

Beim Einsatz von Variablen müsstest Du auf kleiner 40 vergleichen. Das steht Dir aber nicht zur Verfügung.
Eine Lösung wäre z.B. das "kleiner als" "NICHT größer gleich" entspricht.

Viel Erfolg!
 
Also das Programm läuft. Allerdings ist der SM0.5 nicht eine Sekunden lang. Also zumindest nicht genau. Nicht das das sehr wichtig wäre, aber interessieren würde mich das schon. Wir reden hier von einer Abweichung von ca. 2s auf eine Minute. Wie geht das????? :confused:

Kann es sein, dass wegen der kürze des Zykluses das Programm mehrmals pro Sekunde durchlaufen wird und so er ein wenig schneller ist?

Kann ich irgendwie nur die Flanke abfragen?
 
Zuletzt bearbeitet:
Würde folgendes klappen?


Code:
NETWORK 1 
LD     SM0.5                //Taktmerker für 1s 
EU
LD     Z0                //Rücksetzen, wenn 55 erreicht ist ZV     
Z0, +55
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jein,
funktionieren 'tutet' es zwar. Aber wahrscheinlich nicht besser als vorher, denn die Flankenabfrage macht der Zähler intern sowieso.
MicroWin-Hilfe: Vorwärtszähler schrieb:
Die Operation Vorwärtszählen (CTU/ZV) zählt bei steigender Flanke am Vorwärtszähleingang CU vom aktuellen Wert des Zählers an vorwärts.
...

2 Sekunden Taktabweichung pro Minute ist schon stark heftig. Woran das liegt kann ich Dir leider nicht beantworten, aber ich würde auf die CPU selber als Ursache tippen.


Versuch Dir mal einen eigenen Takt zu programmieren.
Nimm dazu einen Timer als Einschaltverzögerung mit einer Auflösung von 1000ms, um eine hohe Genauigkeit zu erreichen. Die soll dann starten, wenn der eigene Timer (noch) aus ist. Den Vorgabewert stellst Du dann so ein, dass dieser Timer nach einer Sekunde auf 1 geht.
Und diesen Timer verwendest Du dann auch zum Zählen anstelle des Systemtaktes.
Den Vorgabewert kannst Du dann bei Deinen Tests entsprechend erhöhen/oder verringern, um Systemungenaugigkeiten auszugleichen.


PS: Die Zykluszeit des letzten Zyklus in Millisekunden kannst Du übrigens mit dem Sondermerker SMW22 auslesen. Diese Adresse in eine Zeile der Statustabelle eingeben und in der Symbolleiste bei angeschlossener CPU auf das Symbol "Tabellenstatus" klicken.
 
Warum so kompliziert?

Hallo Leute, warum so kompliziert?

Man braucht doch nur 2 Timer und ein paar Setz/Rücksetzbefehle. Das folgende Progrämmchen sollte funktionieren: (Nicht getestet, weil ich gerade zu Hause bin und keine Steuerung hier herumliegt...)


Network 1 // Schalte mit dem Anlaufmerker die ersten 3 Ausgänge ein und die letzen 3 aus
LD SM0.1
S A0.0, 3
R A0.3, 3
Network 2 // Wenn A0.0 eingeschaltet ist, starte die Einschaltverzögerung T40
LD A0.0
TON T40, 400
Network 3 // Nach Ablauf der Zeit (40s) schalte die letzten 3 Ausgänge ein und die ersten 3 aus
LD T40
S A0.3, 3
R A0.0, 3
Network 4 // Wenn A0.3 eingeschaltet ist, starte die Einschaltverzögerung T41
LD A0.3
TON T41, 150
Network 5 // Nach Ablauf der Zeit (15s) schalte wieder die ersten 3 Ausgänge ein und die letzten 3 aus. Da jetzt wieder die Bedingung von Network 5 erfüllt ist, sollte es dort weitergehen...
LD T41
S A0.0, 3
R A0.3, 3


Das war's
 
Hallo Horkatz,

danke für dein Programm, aber die SPS läuft schon seit Januar mit dem anderen Porgramm.

Grüße
Tompson
 
Zurück
Oben