Eigene Bibliothek, Zeitfunktionen u.a.

JanB1

Level-2
Beiträge
384
Reaktionspunkte
55
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute

Ich habe seit einiger Zeit mit der CoDeSys Programmierplattform zu tun und habe bemerkt dass gewisse Zeitfunktionen welche bei Siemens z.B. vorhanden sind bei CoDeSys nicht existieren.

Daher habe ich mich entschieden eine eigene Bibliothek zu erstellen mit diesen benötigten Zeitfunktionen sowie einigen weiteren Funktionen. Ich hab mich drangesetzt und schon recht viele Funktionen mit der Programmiersprache ST erstellt, jedoch bin ich jetzt bei den Zeitfunktionen steckengeblieben.

Da ich nicht in meiner Bibliothek die Bausteine aus einer Standardbibliothek (in welcher TON und TOF vorhanden sind) aufrufen will, würde ich die Funktionen gerne selbst schreiben. Doch wie macht man eine Zeitfunktion in ST? Zum Beispiel eine einfache Einschalfverzögerung?

Strukturierter Text ist zwar mit Pascalm vergleichbar, jedoch ist die sleep() funktion wie sie bei Pascal existiert hier nicht vorhanden.

Ich zerbrech mir jetzt schon ne Zeit darüber und find einfach keine Lösung. Wäre sehr froh wenn mir da jemand helfen könnt. Vielenm Dank im voraus schon mal.
 
Eine "Sleep" Funktion gibt es in der SPS darum nicht weil im Gegensatz zum PC eine zyklische Arbeitung erfolgt. Statt eines "sleep" machst du eben unter bestimmten Umständen einfach nichts. Ein Zeitglied implemetierst du grundsätzlich so dass du dir die Zykluszeit hernimmst, Durchläufe des Programms zählst und wenn x mal der Zyklus durchgelaufen ist du deinen Ausgang setzt oder rücksetzt...

Ob es jedoch Sinn macht grundlegende Funktionen wie TON und TOFF selbst zu programmieren sei mal dahingestellt
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nun, ich würde das TON und TOF ja gerne einfach so in meine Bibliothek importieren, leider ist dies aber (wenn ich nichts übersehen habe) nicht möglich. Und da die Bibliothek auch ohne die Standardbibliothek arbeiten soll brauch ich nun mal ein eigenes TON und TOF.

Ohne die grundlegenden Zeitfunktionen kann ich nun mal den Verl
ängerten Impuls, die speichernde Einschaltverzögerung und auch andere Zeitfunktionen nicht programmieren.

Das mit dem messen der Zykluszeit und dann einfach warten lassen klingt schon recht interessant. Ist ein Ansatz, werd ich mal versuchen weiter zu bearbeiten...
 
Ein Zeitglied implemetierst du grundsätzlich so dass du dir die Zykluszeit hernimmst, Durchläufe des Programms zählst und wenn x mal der Zyklus durchgelaufen ist du deinen Ausgang setzt oder rücksetzt...

grundsätzlich also?
ich halte den Ansatz, einen PLC-Takt auszuwerten, also inkrementieren und vergleichen für ebenso grundsätzlich.
Genauigkeit ist auch hier < 2 x Zykluszeit
 
Kannst du mir die Idee mit dem PLC-Takt ein wenig genauer erläutern? Klingt ebenfalls nach einem vielversprechenden Ansatz...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
grundsätzlich also?
ich halte den Ansatz, einen PLC-Takt auszuwerten, also inkrementieren und vergleichen für ebenso grundsätzlich.
Genauigkeit ist auch hier < 2 x Zykluszeit

Ich würde zwar sagen die Genauigkeit ist <1xZykluszeit aber ich lasse mich gerne eines Besseren belehren. Wie würdest du das lösen?
 
Kannst du mir die Idee mit dem PLC-Takt ein wenig genauer erläutern? Klingt ebenfalls nach einem vielversprechenden Ansatz...

Man benutze die Flanke eines sich periodisch ändernden Signals ... z.B. 1Hz.
mit jeder positiven oder negativen Flanke wird der Timerwert inkrementiert - bei 1Hz also Sekundenweise
man kann auch jede positive und negative Flanke benutzen und hat somit 2Hz ... 0,5s Zähler

Ich würde zwar sagen die Genauigkeit ist <1xZykluszeit aber ich lasse mich gerne eines Besseren belehren. Wie würdest du das lösen?

bei der Lösung mit der Auswertung der Zykluszeit? hast du min. 1xZykluszeit, kleiner ist nur schwer zu realisieren. 10s TON angenommen, die Addition der letzen gemessenen Zykluszeit ergibt 9,998s, der nächste Zyklus darf also max. 2ms dauern, hat aber 10ms in Anspruch genommen, liegt man formell schon mal 8ms daneben. dazu kommt die Laufzeit von Auswertung zu Auswertung, bei der Annahme durchschnittlicher Zyklus 10ms, hat man die Auswertungen in der Regel im Abstand von durchschnittlich 10ms ... also 1xZykluszeit ... (der Wert des vorhergehenden Zyklus steht synchron, zu Beginn des neuen Zyklusses zur Verfügung und wird nicht aktualisiert)

ansonsten gilt, dass durch "Umstände" die Auswertung eines asynchronen Signalzustandes erst im nächsten Zyklus passieren kann, wenn der Zustand keinen Interrupt auslöst. Und die Erfahrung lehrt mich, dass man mit <2xZykluszeit durchaus gut liegt und für die Mehrzahl der Anwendungen ist das auch vollkommen ausreichend.
 
Und wie generiere ich jetzt ein 1 Hz Signal? Ohne Signalgeber? Ich weiss dass ich mir das leben künstlich schwer mache, ich könnt in der Bibliothek einfach angeben dass die Standard.lib benötigt wird. Wobei die eh meistenst schon verwendet wird. :rolleyes:

Aber es muss doch zu schaffen sein ohne fremde Bibliotheken einen TON nachzubauen der auch noch sehr genau ist. Wie mach denn CoDeSys das? Wie machen die Ihre TON und TOF? :eek:
 
... naja ... die TON und TOF kommen ja schon aus dem System ... und wenn ich mir z.B. bei Siemens den Inhalt der Instanz dieser "Bausteine" so ansehe ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich arbeite an meinem Arbeitsplatz halt vor allem mit Wago, respektive CoDeSys. Dort sind auch die Standardfunktionen (TON und TOF) in einer Bibliothek abgelegt die man auch einfach deaktivieren kann. Ich hab grad nirgends n TIA Portal, kannst du mir den Inhalt dieser Bausteine mal zeigen?
 
Man benutze die Flanke eines sich periodisch ändernden Signals ... z.B. 1Hz.
mit jeder positiven oder negativen Flanke wird der Timerwert inkrementiert - bei 1Hz also Sekundenweise
man kann auch jede positive und negative Flanke benutzen und hat somit 2Hz ... 0,5s Zähler

Und wo bekommst du ohne Timer das 1Hz Signal her? EDIT: Außerdem sind die 0,5 s Genauigkeit wohl noch schlechter als die 2zykl...

bei der Lösung mit der Auswertung der Zykluszeit? hast du min. 1xZykluszeit, kleiner ist nur schwer zu realisieren. 10s TON angenommen, die Addition der letzen gemessenen Zykluszeit ergibt 9,998s, der nächste Zyklus darf also max. 2ms dauern, hat aber 10ms in Anspruch genommen, liegt man formell schon mal 8ms daneben. dazu kommt die Laufzeit von Auswertung zu Auswertung, bei der Annahme durchschnittlicher Zyklus 10ms, hat man die Auswertungen in der Regel im Abstand von durchschnittlich 10ms ... also 1xZykluszeit ... (der Wert des vorhergehenden Zyklus steht synchron, zu Beginn des neuen Zyklusses zur Verfügung und wird nicht aktualisiert)

Da war ich wohl zu ungenau, ich würde meinen Timer mit kostanter Zykluszeit aufrufen, damit kommt das im Endeffekt auf die Lösung raus die du mit dem 1HZ Takt beschrieben hast. Damit wird die Genauigkeit imho irgendwo <1 Zykluszeit sein.

Und die Erfahrung lehrt mich, dass man mit <2xZykluszeit durchaus gut liegt und für die Mehrzahl der Anwendungen ist das auch vollkommen ausreichend.
ACK
 
In CODESYS V2 sind die Funktionen der Standard.lib direkt im Laufzeitsystem implementiert. In V3 sind die Funktionen in ST implementiert.
Und den Code sollte man sich auch anschauen können.

Man kann das aber genauso auch in der 2.3 machen. Alles was man dazu braucht ist ein Timetick mit fester Auflösung.
Den liefert in CODESYS der (nicht so ganz öffentliche) TIME-Operator.

Für TON sieht das zum Beispiel folgendermassen aus.

Code:
FUNCTION_BLOCK TON
(*
    Timer on delay.
    Q is TRUE, PT milliseconds after IN had a rising edge.
*)
VAR_INPUT
    IN: BOOL;    (* starts timer with rising edge, resets timer with falling edge *)
    PT: TIME;    (* time to pass, before Q is set *)
END_VAR
VAR_OUTPUT
    Q: BOOL;    (* is TRUE, PT seconds after IN had a rising edge *)
    ET: TIME;    (* elapsed time *)
END_VAR
VAR
    M: BOOL;            (* internal variable *)
    StartTime: TIME;    (* internal variable *)
END_VAR

IF (IN) THEN
    IF (NOT M) THEN
        (* Start Timer *)
        STARTTIME := TIME();
    END_IF
    IF (NOT Q) THEN
        (* Timer is running *)
        ET := TIME() - STARTTIME;
        IF (ET >= PT) THEN
            Q := TRUE;
            ET := PT;
        END_IF
    END_IF
ELSE
    (* Reset everything *)
    Q := FALSE;
    ET := t#0s;
END_IF
M := IN;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe es jetzt sogar geschafft eine Standard-Intern.lib hochzuladen.
Die Lib im Archiv sollte sich einfach mit CODESYS öffnen lassen und enthält die gesamte Standard.lib als ST-Code enthalten.
Ich übernehme keinerlei Verantwortung für den Inhalt, das Ding wurde vor Jahren mal geschrieben und ist komplett ungetestet.
 

Anhänge

  • Standard-Intern.rar
    4,4 KB · Aufrufe: 51
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen, vielen, vielen Dank Werner. Haha, so sollte das funktionieren. Jetzt kann ich das doch noch so machen wie ich mir das vorgestellt habe. :D

Dass es eine solche time() funktion gibt wusst ich nicht. Das macht das ganze natürlich deutlich einfacher. Ich werd mich mal dran setzen und einen TON, einen TOF, einen TONOF (Ein- und Auschschaltverzögerung kombiniert), ein STON (Saving Timer - OFF Delay) sowie noch einige andere Funktionen erstellen. Wenn ihr wollt kann ich das Ergebnis dann hier hochladen, ich rechne damit dass ich das morgen Abend in etwa fertig haben sollte. ;)
 
Zuletzt bearbeitet:
Zurück
Oben