twincat 3: betriebsstundenzaehler programmieren.

Beiträge
69
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo sps-welt,

ich soll einen betriebstundenzaehler (HH-MM) programmieren. beim Druecken von S0 (start) sollte der BS-zaehler starten. bei stoerungen und beim Druecken von S1(stop) soll der BS-zaehler stoppen und beim wieder druecken von S0 weiter zaehlen.

und bei hochfahren der Maschine soll die BS-zaehler weiterlaufen , wo er gestern aufgehoert hat. und Nach eine Anzahl von Stunden (HH) kann der User mit R (Reset1) zuruecksetzen.

ich konnte bei der suche nicht findig sein.
koennte jemand mir mit dem code helfen. es waere mir sehr hilfreich.
 
Zuletzt bearbeitet:
Die einfachste Variante in meinen Augen wäre es mit zwei Einschaltverzögerungen, woraus du dir einen Sekundentakt generierst, da es glaub ich keinen Taktmerker bei TC3 gibt?

Mit dem sekündlichem Impuls zählst du eine Variable hoch, welche ebenfalls Remanent deklariert ist. Dann benötigst du lediglich noch die Umrechnung von den Sekunden in Minuten und Stunden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Betriebsstundenzähler soll die Betriebsstunden von genau was zählen? Solange ein Antrieb läuft, oder solange Automatik-Mode aktiv ist, oder ...? Die Frage läßt sich bestimmt einfacher beantworten (und dann das Programm einfacher realisieren) als eine Menge besondere Bedingungen und bestimmte Tastendrücke aufzuzählen.

Den Zeittakt würde ich nicht mit Timern (z.B. Einschaltverzögerungen) bilden, weil das wird ungenau/zählt generell zu wenig.

Besser: in einer zyklischen Task (z.B. alle 50 ms) in jedem Durchlauf die Zykluszeit (ms) in einer remanenten Variable addieren, wenn die Zählbedingung zutrifft. Immer wenn die ms-Summe 1000 ms überschreitet, dann einen Übertrag zu einer remanenten Sekunden-zähl-Variable bilden (SekundenZähler+=1 und MillisekundenZähler-=1000). Auf die gleiche Art kannst Du noch MinutenZähler und Stundenzähler kaskadieren. Oder nur für die Anzeige den Sekunden-Wert in HH:MM umrechnen.

Oder: einen Sekundenpuls aus der Uhrzeit bilden - immer wenn sich der Sekunden-Wert ändert (größer wird oder von 59 zu 0 springt).

Harald
 
da hat doch TC schon einen fertigen FB


FB_HVACWork

Der kostet aber extra. Die HVAC-Lib kostet für Rechner mit geringer bis mittlerer Leistung zwischen 25 und 60 Euro. Dafür kann man einen Betriebsstundenzähler auch einmal selbst programmieren.
Ein Zykluszähler bietet sich bei Beckhoff zunächst an, weil man ja auf jeden Fall mindestens eine Task mit fester Zykluszeit hat. Wenn man den FB aber in unterschiedlichen Anwendungen einsetzen will, kann man die Taskzykluszeit nicht als Konstante annehmen, sondern der FB muss sie auslesen. Ausserdem kann es auch mal Zykluszeitüberschreitungen geben, die den Zähler verfälschen. Alternativ kann man die TIME()-Funktion verwenden, um in jedem Zyklus die seit dem letzten Zyklus vergangene Zeit zu bestimmen und zu dem ms-Zähler zu addieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der kostet aber extra. Die HVAC-Lib kostet für Rechner mit geringer bis mittlerer Leistung zwischen 25 und 60 Euro. Dafür kann man einen Betriebsstundenzähler auch einmal selbst programmieren.
Ein Zykluszähler bietet sich bei Beckhoff zunächst an, weil man ja auf jeden Fall mindestens eine Task mit fester Zykluszeit hat. Wenn man den FB aber in unterschiedlichen Anwendungen einsetzen will, kann man die Taskzykluszeit nicht als Konstante annehmen, sondern der FB muss sie auslesen. Ausserdem kann es auch mal Zykluszeitüberschreitungen geben, die den Zähler verfälschen. Alternativ kann man die TIME()-Funktion verwenden, um in jedem Zyklus die seit dem letzten Zyklus vergangene Zeit zu bestimmen und zu dem ms-Zähler zu addieren.

koenntest du mir mit dem code helfen? waere nett
 
Erstmal persistente Variablen für den Betriebszeit-Zähler:
Code:
VAR_GLOBAL PERSISTENT
   WorkTime_ms:UDINT;   // Betriebs-Millisekunden
   WorkTime_s:UDINT;   // Betriebs-Sekunden
END_VAR

Variablen im MAIN:
Code:
VAR
   InitCycle:BOOL:=TRUE;   // Erster SPS-Zyklus
   LastTime:TIME;   // Systemzeit im vorangegangenen SPS-Zyklus
   Irgendwas:BOOL;  // Von Irgendwas = TRUE soll die Betriebszeit gezählt werden
END_VAR

Und der Code:
Code:
IF InitCycle THEN
   LastTime:=TIME();   // Letzte Zeit mit aktueller Zeit initialisieren
   InitCycle:=FALSE;   // Init-Zyklus beenden
END_IF

IF Irgendwas THEN
   WorkTime_ms:=WorkTime_ms+(TIME()-LastTime);   // Zeit seit letztem Zyklus zum ms-Zähler addieren
   IF WorkTime_ms>=1000 THEN                // Wenn ms-Zähler > 1000 ms
      WorkTime_s:=WorkTime_s+1;             // 1 Sekunde zum s-Zähler addieren
      WorkTime_ms:=WorkTime_ms-1000;  // und 1000 ms vom ms-Zähler subtrahieren
   END_IF
END_IF
LastTime:=TIME();   // Aktuelle Zeit wieder als letzte Zeit merken, für den nächsten Zyklus

Kann sein, dass Du hier und da Typumwandlungen zwischen TIME und UDINT machen musst. Das sagt Dir dann schon der Compiler.
 
Erstmal persistente Variablen für den Betriebszeit-Zähler:
Code:
VAR_GLOBAL PERSISTENT
   WorkTime_ms:UDINT;   // Betriebs-Millisekunden
   WorkTime_s:UDINT;   // Betriebs-Sekunden
END_VAR

Variablen im MAIN:
Code:
VAR
   InitCycle:BOOL:=TRUE;   // Erster SPS-Zyklus
   LastTime:TIME;   // Systemzeit im vorangegangenen SPS-Zyklus
   Irgendwas:BOOL;  // Von Irgendwas = TRUE soll die Betriebszeit gezählt werden
END_VAR

Und der Code:
Code:
IF InitCycle THEN
   LastTime:=TIME();   // Letzte Zeit mit aktueller Zeit initialisieren
   InitCycle:=FALSE;   // Init-Zyklus beenden
END_IF

IF Irgendwas THEN
   WorkTime_ms:=WorkTime_ms+(TIME()-LastTime);   // Zeit seit letztem Zyklus zum ms-Zähler addieren
   IF WorkTime_ms>=1000 THEN                // Wenn ms-Zähler > 1000 ms
      WorkTime_s:=WorkTime_s+1;             // 1 Sekunde zum s-Zähler addieren
      WorkTime_ms:=WorkTime_ms-1000;  // und 1000 ms vom ms-Zähler subtrahieren
   END_IF
END_IF
LastTime:=TIME();   // Aktuelle Zeit wieder als letzte Zeit merken, für den nächsten Zyklus

Kann sein, dass Du hier und da Typumwandlungen zwischen TIME und UDINT machen musst. Das sagt Dir dann schon der Compiler.
koenntest du explixit sein ? ich sehe gerade nicht den unterschied zwischen Die variablen Initcycle (????) und Irgendwas (bei mir wäre der Start-taster ?) trotz der Kommentare.

danke im voraus.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
InitCycle markiert den ersten Programmzyklus beim Start der SPS und hat mit dem Zustand, dessen Zeit Du erfsassen willst, nicht zu tun.
Du wirst doch mit dem Start-Taster irgendwas einschalten und mit dem Stop-Taster oder bei einer Störung wieder ausschalten, und genau für dieses "irgendwas" steht die gleichnamige Variable.
 
Die einfachste Variante in meinen Augen wäre es mit zwei Einschaltverzögerungen, woraus du dir einen Sekundentakt generierst, da es glaub ich keinen Taktmerker bei TC3 gibt?

Mit dem sekündlichem Impuls zählst du eine Variable hoch, welche ebenfalls Remanent deklariert ist. Dann benötigst du lediglich noch die Umrechnung von den Sekunden in Minuten und Stunden.
koenntest du das im code umsetzen bitte?
 
Der Betriebsstundenzähler soll die Betriebsstunden von genau was zählen? Solange ein Antrieb läuft, oder solange Automatik-Mode aktiv ist, oder ...? Die Frage läßt sich bestimmt einfacher beantworten (und dann das Programm einfacher realisieren) als eine Menge besondere Bedingungen und bestimmte Tastendrücke aufzuzählen.

Den Zeittakt würde ich nicht mit Timern (z.B. Einschaltverzögerungen) bilden, weil das wird ungenau/zählt generell zu wenig.

Besser: in einer zyklischen Task (z.B. alle 50 ms) in jedem Durchlauf die Zykluszeit (ms) in einer remanenten Variable addieren, wenn die Zählbedingung zutrifft. Immer wenn die ms-Summe 1000 ms überschreitet, dann einen Übertrag zu einer remanenten Sekunden-zähl-Variable bilden (SekundenZähler+=1 und MillisekundenZähler-=1000). Auf die gleiche Art kannst Du noch MinutenZähler und Stundenzähler kaskadieren. Oder nur für die Anzeige den Sekunden-Wert in HH:MM umrechnen.

Oder: einen Sekundenpuls aus der Uhrzeit bilden - immer wenn sich der Sekunden-Wert ändert (größer wird oder von 59 zu 0 springt).

Harald

die maschine soll solange automatik oder halbautomatik mode aktiv ist.

einen Sekundenpuls aus der Uhrzeit bilden - immer wenn sich der Sekunden-Wert ändert (größer wird oder von 59 zu 0 springt)
wie koennte es aussehen?

Besser: in einer zyklischen Task (z.B. alle 50 ms) in jedem Durchlauf die Zykluszeit (ms) in einer remanenten Variable addieren, wenn die Zählbedingung zutrifft
ich konnte diesen teil nicht realisieren
 
Zurück
Oben