Betriebsstundenzähler über Zykluszeit erstellen

nikkemil

Level-1
Beiträge
27
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe Gemeinde,

als erstes, ich habe die Such-Funktion benutzt und nichts passendes gefunden;)

Nun zum mein Problem. Ich programmiere mit CoDeSys IFM-Steuerungen. Dafür möchte ich gerne für diverse Anlagen einen Betriebsstundenzähler mit Wartungsfunktion programmieren.
Momentan löse ich das ganz einfach über Timer die die Sekunden,Minuten und Stunden zählen.
Das ist ziemlich ungenau, und zwar so ungenau das es sogar unsere Kunden aufgefallen ist(mit der Stoppuhr nachgemessen). Ich möchte das ganze gerne über die Zykluszeit com Controller realisieren.
Mir fehlt leider dazu der Ansatz, sprich ich komme nicht weiter bzw. weiß gar nicht so richtig wie ich anfangen soll.
Es ist keine Hausaufgabe oder ähnliches und ich brauche erstmal ein Ansatz. mir soll keiner diesen Baustein programmieren, aber ein bischen Hilfe wäre schön.

Ich danke schon mal alle im vorraus

Gruss
nikkemil
 
ich hab hier mal was um dir die CPU zeit zu holen und in ms auszugeben.
Ist allerdings für Beckhoff und braucht SYSTEMTASKINFOTYPE aus der TcSystem.lib
Aber ich denke was ähnliches sollte IFM auch bereitstellen um die Zykluszeit herauszufinden.

Hier mal die Funktion:
Code:
FUNCTION fc_GetCycleTime : UDINT
VAR_INPUT
END_VAR
VAR
         udiTaskId        : UDINT;
         FB_GetCurrTaskIndex    : GETCURTASKINDEX;
END_VAR

FB_GetCurrTaskIndex();
udiTaskId := BYTE_TO_UDINT(FB_GetCurrTaskIndex.index);
(* cycle time comes in ns --> output in ms*)
fc_GetCycleTime := SystemTaskInfoArr[udiTaskId].cycleTime / 10000;



Und so könntest du dann die Zeiten z.B. in einem Array aufsummieren aufsummieren:
Code:
    audiWriteCounter[uiLogCounter] := audiWriteCounter[uiLogCounter] +fc_GetCycleTime();


So hast du schon mal die ms addiert, daraus musst du nur noch stunden:minuten:sekunden machen und fertig.

Code:
        udiOperatingHours        := udiOpSeconds / 3600;
        udiTmp                            := udiOpSeconds MOD 3600;
        udiOperatingMinutes := udiTmp / 60;
        udiOperatingSeconds := udiTmp MOD 60;

Hoffe das hilft erstmal :grin:
Code:
[CODE]
[/CODE]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was ich nicht verstehe ist, warum die Messung mit Timern ungenau ist ... wie ist das realisiert? Die Zeitgeber sind ja nicht dermaßen unpräzise das man es mit einer Stoppuhr nachweisen könnte.
 
@DaHauer
Danke schonmal. Also den ersten Teil brauch ich nicht, die Zykluszeit kann ich auslesen(DWord=z.B. 25430mü). Muss ich dann ein Array deklarieren und ein Array mit der Zykluszeit addieren. Warum ein Array??
Die Umrechnung in Sek,Min, und Stunden krieg ich dann wohl schon hin.

@altelutex
Istzustand: Ich generie ein Blinktakt 1sek. Den Blinktakt+Startbefehl zähle ich eine Counter für die Sekunden, Minuten etc hoch. Ich habs nochmal nachgemessen, auf 1min. --> 4-8sek Abweichung. Auf 1Std. sind das dann 4-8Minuten, auf ein 8Std.Tag sind das dan schon 32-64Minuten. Und das ist zuviel.
Vielleicht ist die Wahl mit Countern nicht gerade die Beste, deshalb wollte ich das über die Zykluszeit machen, da ich da genauer werde.

Danke für eure Hilfe.

nikkemil
 
Jo Blinktakte zählen ist tatsächlich keine elegante Lösung. Ich würde vorschlagen mit dem Startbefehl einen Timer zu starten und selbigen mit Stopbefehl zu stopen. Die abgelaufene Zeit dann verwerten und speichern. Da alle Timer einen Zykluszeit-unabhängigen Takt haben sind sie präzise genug für diese Aufgabe und man muss nicht umständlich die CPU-zeit dazu benutzen.
 
Das sind alles Codeschnipsel die ich einfach mal so reinkopiert habe, den array verwende ich einfach weil ich mehrere Zeiten verwendet habe.

Es sind einfach 2 wege um ans ziel zu kommen, entweder mit BLINK oder mit der Zykluszeit und aufaddieren, beides ist machbar.
Bei den Blinkbausteinen hab ich manchmal bei Veränderung der Zykluszeit wieder rumfummeln müssen, deswegen bevorzuge ich einen Counter mit der Zykluszeit, ist aber Geschmakssache :-)
 
Ähm nein ohne counter sondern etwa wie folgt:

Code:
var
Betrieb : Bool;
Start : Bool;
Stop : Bool;
timer1 : TON;
Betriebszeit : time;
Addiert : bool;
end_var

if Start = true then 
  Betrieb := true;
  Addiert := false;
elsif Stop = true then 
  Betrieb := false; 
end_if

timer1(in := Betrieb, pt := t#1000s);

if Betrieb = false and addiert = false then
  Betriebszeit := Betriebszeit + timer1.et;
  addiert := true;
end_if

Wichtig ist das pt größer ist als die maximale zu erwartende Einzellaufzeit des Motors. Sollte das nicht gehen muss eine Zwischensumme eingebaut werden für den Fall das ET gleich PT ist, inklusive eines Timer-Neustarts.

Ich hoffe das ist nicht allzu schwer und hilfreich.
 
Zurück
Oben