Sekundenimpuls mit speziellen Anforderungen

tyftel

Level-2
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Viel habe ich schon als "Mitleser" vom Forum profitiert, nun ist jedoch der Zeitpunkt zur Anmeldung gekommen, da ich bis jetzt noch keine Lösung mit den üblichen Mitteln gefunden habe.

Folgendes soll realisiert werden:
Es soll ein Impuls erzeugt werden, der genau jede Sekunde für einen Zyklus anliegt. Verwendet werden soll er für eigene Betriebsstundenzähler, selbstgebaute Timer und andere technologische Funktionen mit Zeithintergrund.
Bevor jetzt aber die üblichen Verdächtigen wie "Taktmerker", "OB1 Zykluszeit", "Simatic Timer" ect. gepostet werden erstmal ein wenig zu Background:

Die Sekundenimpulse sollen lokal erzeugt werden (multiinstanzfähig). D.h. im Zuge der Erstellung eines bestimmten Funktionsbausteins soll der Impuls IM Baustein erzeugt werden und nicht extern dran parametriert werden. Dieses soll für eine Bausteinbibliothek dienen, welche den Parametrieraufwand SO GERING WIE MÖGLICH halten soll.
Die Restriktionen mal kurz und knapp zusammengefasst:

1.) Keine Verwendung von Taktmerkern (müssten von draußen an jeden Baustein dran parametriert werden, bzw. bei interner Nutzung projektübergreifend gleich benannt/adressiert werden)
2.) Keine Verwendung eines OB32-Impulsbit (dito)
3.) Keine anderen global erzeugten Impulse
4.) Keine Timer (ebenfalls mit zusätzlichem Aufwand / unnötigen Querverweisen / zu planendem Timer-Einsatz / unter umständen mangelnden Timer-Ressourcen verbunden)
5.) Kein TON/TOF (Bei Tests stellte ich bei der Sekundenimpuls-Erzeugung mit TOF eine Zyklusabhängigkeit und somit eine Ungenauigkeit von über 1% im zeitlichen Verlauf fest (wahrscheinlich steigend mit größer werdender Zykluszeit)
6.) Lauffähig auf S7 300/400/1200/WinAC
7.) Kein AWL (Am geeignetsten ist SCL, da die Funktionsbausteine auch weitestgehend in SCL erstellt werden)
8.) Verbratene Ressourcen sind zweitrangig, ressourcensparende Lösungsansätze sind jedoch zu bevorzugen
9.) Die kurzzeitgeitgenauigkeit ist irrelevant (ob der Impuls jetzt +- ein Zyklus ankommt...), wichtig ist, dass die Impulse nicht mit der Systemzeit auseinanderlaufen, also mindestens die Exaktheit dieser aufweisen


Aus letzgenanntem Grund denke ich, dass man um eine Nutzung und Auswertung der Systemzeit (RD_SYS_T oder TIME_TCK) nicht herum kommt. Jedoch hapert es noch ein wenig an der Realisierung.
Ein Gedanke war den TIME_TCK mit Modulo 1000 abzufragen. Bei einer Zykluszeit von 3ms z.B. wird der Impuls logischerweise aber nur alle 3 Sekunden ausgelöst.
Jetzt seid ihr gefragt. Ich erwarte Gedankenanstöße im 1-Sekunden-Takt ;)
 
S7-300
mit SFC64 den Timer auslesen Time_TCK,
dieser gibt die millisekunden aus, die 4.Stelle abfragen auf Änderung und dadurch einen Impuls bilden.
Diese Stelle merken im Stat, für die nächste erkennung der Änderung.

Durch die Abfrage der Stelle im Sekundenbereich und nicht der Differenzen, ergeben sich keine Abweichungen durch die Zykluszeit.
Die Abweichung betrifft nur den aktuellen Impuls.
Also kann ein Impuls nach z.b. 1020ms kommen, der nächste dann aber bei ca 980ms.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... und als Ergänzung zu dem Beitrag von jabba :
Das Modulo 1000 auf 0 (oder irgendetwas anderes) an dieser Stelle abzufragen wird aus den gleichen Gründen problematisch werden. Du könntest hier also tatsächlich nur auf den ermittelten Modulo-Wert (wenn er z.B. unter 100 ist) eine Flanke bilden und die dann für den Impuls nehmen. Dadurch wird der Impuls selbst aber (wie schon genannt) nicht genauer.

Gruß
Larry
 
Hallo

einfach den Taktmerker in der HW konfiguriren zb Mb1 und eine Flanke auf M1.5 "Puls 1Hz"
U M 1.5
FP M 2.0
= M 2.1

und m 2.1 kommt jede Sekunde für einen Zyklus

Grss ASAB
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

einfach den Taktmerker in der HW konfiguriren zb Mb1 und eine Flanke auf M1.5 "Puls 1Hz"
U M 1.5
FP M 2.0
= M 2.1

und m 2.1 kommt jede Sekunde für einen Zyklus

Grss ASAB

Bevor jetzt aber die üblichen Verdächtigen wie "Taktmerker", "OB1 Zykluszeit", "Simatic Timer" ect. gepostet werden erstmal ein wenig zu Background:

1.) Keine Verwendung von Taktmerkern (müssten von draußen an jeden Baustein dran parametriert werden, bzw. bei interner Nutzung projektübergreifend gleich benannt/adressiert werden)

ein bisschen lesen schadet nie :rolleyes:
 
S7-300
mit SFC64 den Timer auslesen Time_TCK,
dieser gibt die millisekunden aus, die 4.Stelle abfragen auf Änderung und dadurch einen Impuls bilden.
Diese Stelle merken im Stat, für die nächste erkennung der Änderung.

Durch die Abfrage der Stelle im Sekundenbereich und nicht der Differenzen, ergeben sich keine Abweichungen durch die Zykluszeit.
Die Abweichung betrifft nur den aktuellen Impuls.
Also kann ein Impuls nach z.b. 1020ms kommen, der nächste dann aber bei ca 980ms.

Hey danke, sowas in der Art ist schon in meinem Hinterkopf rumgeschwirrt, nur an der Realisierung hat es noch ein wenig gehapert.

Kannst du mir mal kurz auf die Sprünge helfen, wie ich Stelle X einer DINT-Zahl abfrage? Gibts da nen speziellen Baustein für oder läuft die Lösung über eine Rechenoperation?

(Was ich vergessen hatte zu sagen: Gearbeitet wird mit TIA V11, also bitte immer den Namen des SFCs mit nennen, da die Bibliotheken hier nur noch die symbolischen Namen zur Verfügung stellen).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit Rechnen.
Auf die schnelle:

TempZeit1:=Time / 1000 = Sekunden
TempZeit2:=(Time /10000)*10= Uninteressanter Bereich

TempZeit:=Tempzeit1-Tempzeit2= Sekunde aus dem Zeitbereich als Int 0-9
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es gilt hier doch ein wenig auf die Zählerwerte zu achten.
Der SFC64 ist sicherlich kein verkehrter Ansatz dafür, aber allein diese durch 1000-Teilerei führt nach (2^32)-1 Sekunde mal zu einer nur 0,647 Sekunden lange "Sekunde", da hier der Zähler überläuft. Das tritt schneller auf als man denkt, denn die (2^31)-1 Sekunde sind gerade mal knapp 25 Tage ....
 
Macht dann im Jahr 5,1538 Sekunden, ich denke mal das ist der Timer insgesamt ungenauer
Aber auch den zählerüberlauf kann man abfangen.
 
Ich denke mal diese Abweichung ist in Anbetracht der allgemeinen Uhr-Ungenauigkeit von typ. 2s pro Tag (cpu 317) vernachlässigbar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Noch mal eine kleine Rückfrage. Habe es soweit realisiert bekommen, hatte dann heute morgen nur mal festgestellt, dass mein Timer auf einmal keine Impulse mehr liefert, dann aber auf einmal wieder doch (glaub nachdem ich die CPU ma neugestartet hab). Als ich mir das TIME_TCK()/1000 signal mal angeschaut habe war es dann irgendwo bei 400s, d.h. es ist erst kürzlich übergelaufen.

Hier mal mein Code, welcher jeweils jede Sekunde einen Impuls pro Zyklus erzeugt:

Code:
IF (TIME_TCK()/1000) > #TIME.SAVE_OLD THEN
  #TIME.IMPULSE := TRUE;
  #TIME.SAVE_OLD :=(TIME_TCK()/1000); 
ELSE
  #TIME.IMPULSE:= FALSE;
END_IF;

Wie könnte man den Überlauf am geschicktesten abfangen?

Ich kanns nur schlecht testen, weil ich nicht Tage warten kann bis das Ding wieder überläuft. (Kann man den Wert vielleicht auch testweise vorgeben?)

EDIT: OK Problem gefunden. Wer lesen kann ist klar im Vorteil,...der TIME_TCK() wird bei jedem CPU-Restart genullt. Der gespeicherte Wert "#TIME.SAVE_OLD" enthällt aber immer noch den alten Wert ( >0 ), deswegen geht er nur in den ELSE-Zweig rein. Jetzt ist nur die Frage wie man das löst, ohne von außen ein "CPU wurde restartet"-Signal rein zu geben. (Das Überlauf-Problem dürfte aber glaube immer noch existent sein, vielleicht kann man die irgendwie zusammen lösen)
 
Zuletzt bearbeitet:
Nicht auf "größer" sondern auf "ungleich" vergleichen. Und TIME_TCK() besser nur einmal aufrufen.
Code:
#tempTIME_JETZT := TIME_TCK()/1000 ;
IF #tempTIME_JETZT <> #TIME.SAVE_OLD THEN
  #TIME.IMPULSE := TRUE;
  #TIME.SAVE_OLD := #tempTIME_JETZT ;
ELSE
  #TIME.IMPULSE:= FALSE;
END_IF;

Harald
 
Zurück
Oben