FUNCTION_BLOCK "ZweiSpurZaehler"
TITLE =
VERSION : 0.1
VAR_INPUT
IN_Spur_A : BOOL ; //Phasenversatz 0°, sozusagen Referenzspur
IN_Spur_B : BOOL ; //Phasenversatz 90°, bei Rechtsdrehung nacheilendes Signal
END_VAR
VAR_OUTPUT
OUT_Zaehler : INT ; //laeuft bei 32767 auf -32768 über (und umgekehrt)
OUT_dreht_rechts : BOOL ; //zeigt die aktuelle bzw. letzte Drehrichtung an
OUT_Bewegung_vorhanden : BOOL ; //zeigt an, dass aktuell eine Änderung an den Spureingängen vorlag
OUT_Doppelzaehlung : BOOL ; //Änderung an beiden Spureingängen, Zählung anhand der letzten Drehrichtung
OUT_Spurverlust : BOOL ; //wenn mehrere Signalwechsel an nur einem Spureingang vorliegen
OUT_UEberlauf : BOOL ; //wenn die Drehrichtung ohne Stillstand wechselt
END_VAR
VAR
f_IN_Spur_A : BOOL ;
f_IN_Spur_B : BOOL ;
UEberwachungszaehlerA : BYTE ;
UEberwachungszaehlerB : BYTE ;
END_VAR
BEGIN
NETWORK
TITLE =
// Version 020315 2002041216Co auf 315-2DP: 0,15..0,31 Millisekunden
// **********************************
// ***** Zähler mit zwei Spuren *****
// **********************************
// Code zeitoptimiert für 312/313/314/315/316-CPU (8-Bit-Zugriffe).
// Bei Power-Up können Fehlermeldungen generiert werden, weil die remanenten
// Daten dieses Bausteins dann eventuell inkonsistent zum Prozess sind.
// Fehlermeldungen treten nur temporär auf und quittieren sich selbstätig.
// Der Zähler ist nicht null-stellbar. Da dies häufig mit Randbedingungen
// verknüpft ist, wird eine Nullstellung durch das aufrufende Programm
// empfohlen:
// wenn Referenz, dann aktueller Zählerstand --> Nullstand (oder Referenzstand).
// Anwenderzähler = aktueller Stand minus Nullstand (Integersubtraktion!).
// So können mehrere Zähler aus diesem einen abgeleitet werden und auch
// Varianten wie z.B. Nullung nur bei Rechtsdrehung o.ä. realisiert werden.
// Soll durch das aufrufende Programm die Drehrichtung überprüft werden,
// so empfiehlt sich die Verknüpfung mit dem Signal Bewegung (ggf zeitverzögert).
// Für das Signal Spurverlust ist e i n e Drehrichtungsumkehr berücksichtigt,
// jedoch müssen danach wenigstens zwei Zählungen in die andere Richtung erfolgen.
// Wenn dies nicht grundsätzlich gewährleistet ist, sollte Spurverlust erst
// zeitverzögert nach Anlauf des Antriebs ausgewertet werden. Die Auswertung
// des Ausgangs Bewegung erfolgt zweckmäßigerweise:
// und "Bewegung_vorhanden"
// starte auschaltverzögert die Zeit "verlaengert_Bewegung_vorhanden"
// und "verlaengert_Bewegung_vorhanden"
// starte einschaltverzögert die Zeit "zuegige_Bewegung_vorhanden"
// Ggf. kann bzw. sollte der Steuerzustand des Antriebs (mit) ausgewertet werden.
// Das Signal Doppelzählung kann zum Auslösen einer Störung verwendet werden,
// normalerweise hat es nur informativen Charakter, um zu beurteilen, inwieweit
// Reserven bei der SPS-Zykluszeit vorhanden sind. Bei Doppelzählung wird anhand
// der letzten Drehrichtung weitergezählt, da die Ermittlung der Drehrichtung
// dann aktuell nicht möglich ist. Das Signal Doppelzählung wird bei Vorliegen einer
// solchen gesetzt und bei Stillstand rückgesetzt.
// Das Signal Überlauf zeigt an, dass ein Drehrichtungswechsel vorlag, ohne dass
// dazwischen ein Stillstand auftrat. Dies tritt ein, wenn die Zykluszeit zu gross
// ist in Relation zum Spursignal. Warnung: einzelne zu lange SPS-Zyklen führen
// nicht zwangsläufig zur Auslösung dieser Fehlermeldung (z.B. PG-Zugriff Baustein
// übertragen). Ggf. ist es empfehlenswert, neben der Auswertung der Fehlermeldungen
// des Zählbausteins zusätzlich die Zykluszeit der SPS zu überwachen.
// Ein Standartmotor mit 1500U/min, ausgerüstet mit einem Zweipuls-Zählrad
// (Flanken im 90°-Winkel, Initiatoren im 45°-Winkel angeordnet) generiert bei einer
// Motorfrequenz von 100Hz alle 2,5 Millisekunden einen Flankenwechsel. Wird
// Doppelzählung zugelassen, so kann dieses Signal mit einer Zykluszeit von
// 5 Millisekunden eingelesen werden. Beschränkt man sich auf ein Einpuls-Zählrad
// und eine Motorfrequenz von 50Hz, so ist eine Zykluszeit von weniger als 20ms
// ausreichend. Sollte die damit erzielbare Auflösung zu gering sein, kann durch
// eine Zeitsteuerung das Positionsergebnis optimiert werden.
UN #IN_Spur_A;
X #f_IN_Spur_A;
SPB m050; // wenn kein Wechsel auf Spur A --> weiter Spur B
U #IN_Spur_B;
X #f_IN_Spur_B;
SPB ctdd; // wenn auch Wechsel auf Spur B --> Doppelzaehlung
L #UEberwachungszaehlerA; // Überwachung Spurverlust
+ 1;
T #UEberwachungszaehlerA;
L 2;
>I ;
= #OUT_Spurverlust;
L 0;
T #UEberwachungszaehlerB;
U #IN_Spur_A;
X #IN_Spur_B;
SPB ctup; // hochzaehlen
SPA ctdn; // bzw. herabzaehlen
m050: UN #IN_Spur_B;
X #f_IN_Spur_B;
SPB ctnt; // keine Änderung Spur B --> keine Zählung
L #UEberwachungszaehlerB; // Überwachung Spurverlust
+ 1;
T #UEberwachungszaehlerB;
L 2;
>I ;
= #OUT_Spurverlust;
L 0;
T #UEberwachungszaehlerA;
UN #IN_Spur_A;
X #IN_Spur_B;
SPB ctup; // hochzaehlen
SPA ctdn; // bzw. herabzaehlen
ctdd: = #OUT_Doppelzaehlung; // Doppelzählung
= #OUT_Bewegung_vorhanden;
L 1;
T #UEberwachungszaehlerA;
T #UEberwachungszaehlerB;
L #OUT_Zaehler;
+ -2;
UN #OUT_dreht_rechts;
SPB m005;
+ 4;
m005: T #OUT_Zaehler;
SPA ende;
ctup: U #OUT_Bewegung_vorhanden; // Einfachzählung aufwärts
UN #OUT_dreht_rechts;
= #OUT_UEberlauf;
SET ;
= #OUT_Bewegung_vorhanden;
= #OUT_dreht_rechts;
L #OUT_Zaehler;
+ 1;
T #OUT_Zaehler;
SPA ende;
ctdn: U #OUT_Bewegung_vorhanden; // Einfachzählung abwärts
U #OUT_dreht_rechts;
= #OUT_UEberlauf;
SET ;
= #OUT_Bewegung_vorhanden;
CLR ;
= #OUT_dreht_rechts;
L #OUT_Zaehler;
+ -1;
T #OUT_Zaehler;
SPA ende;
ctnt: CLR ; // keine Zählung, Quittungsfunktion
= #OUT_Spurverlust;
= #OUT_UEberlauf;
= #OUT_Doppelzaehlung;
= #OUT_Bewegung_vorhanden;
ende: U #IN_Spur_A; // Flankenerkennung
= #f_IN_Spur_A;
U #IN_Spur_B;
= #f_IN_Spur_B;
END_FUNCTION_BLOCK