TIA kWh Zähler

xxxxxxx

Level-2
Beiträge
7
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Aus einem Analogsignal wird eine Leistung ausgelesen (0–1500 kW). Ich habe einen Zähler erstellt, der die Kilowattstunden misst. Allerdings wollte ich wissen, ob die Lösung, die ich umgesetzt habe, gut ist. Verliert der Zähler über die Jahre an Genauigkeit?

Ein Stillstand des Zählers kann ich mir kaum vorstellen, da die Maschine nicht ständig in Betrieb ist.

Der aktuelle Ansatz: Jede Sekunde (über einen Taktmerker) wird der Wert eingelesen und addiert. Wenn die Summe 1000 kW überschreitet, wird der Zähler auf 0 gesetzt und der MWh-Zähler um 1 erhöht.


Hat jemand eine bessere Lösung?
 

Anhänge

... Aus einem Analogsignal wird eine Leistung ausgelesen (0–1500 kW). Ich habe einen Zähler erstellt, der die Kilowattstunden misst. Allerdings wollte ich wissen, ob die Lösung, die ich umgesetzt habe, gut ist. Verliert der Zähler über die Jahre an Genauigkeit?
Die Kilowattstunden werden gezählt und nicht gemessen, aber das hast du ja auch getan. Natürlich wird der Zählerstand im Laufe der Zeit, auf Grund des mehr oder weniger großen Messfehlers des Analogwerts immer weiter davon laufen. Eine Möglichkeit zur Korrektur des Zählerstandes sollte man daher vorsehen. Ebenso könnte man das Analogsignal durch ein Offset abgleichen, falls eine deutliche Abweichung erkennbar ist. Das kann natürlich auch im Laufe der Zeit erfolgen. Ich würde den Analogwert eventuell auch etwas Dämpfen. Bei einem Analogsignal könnte man auch eine Schleichmengenunterdrückung vorsehen. Ansonsten kannst du aus einem Analogwert viel mehr nicht heraus holen. Ein S0-Signal bzw. Zähler-Impuls steht nicht zur Verfügung?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
    // Wenn die Kilowattstunden 1 Milion erreichen, werden sie zürücksetzt und 1 Megawatt hochgezählt
    IF #kWH > 1000 THEN
        #kWH := 0;  // Kilowattstunden reset
        #MWH := #MWH + 1;   // Megawattstunden Count Up
    END_IF;
Wenn es die CPU hergibt, würde ich für #kWH ein LReal verwenden, höhere Genauigkeit kann ja nicht schaden, besonders wenn addiert oder subtrahiert. Dann sollte man beim Übertrag diesen Real-Zähler nicht zurücksetzen, sondern den Übertragswert (hier 1000.0) von diesen abziehen. Dadurch bleiben restliche Kommastellen erhalten.

Dann könnte man sich noch überlegen, für so eine Funktion einen bibliotheksfähigen Baustein zu schreiben, also ohne globale Variablen.

Der Aufwand mit den Strings ist notwendig?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe den unten aufgeführten Baustein mal genutzt, um Ah zu zählen, bei eine Ampere-Messung an einer KTL-Beschichtungsanlage.
Ich weiß leider nicht mehr genau wo der Baustein her ist. Der Autor hat sich leider auch nicht verewigt.

Code:
FUNCTION_BLOCK "Integrator"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
  enable : Bool := FALSE;
  cycle1 : Bool := TRUE;   // TRUE im 1.Zyklus CPU STOP/RUN
  reset : Bool := FALSE;   // Reset Y:=0.0
  X : Real;   // Eingangswert
END_VAR
VAR_IN_OUT
  Y : LReal;   // Integral
END_VAR
VAR
  X_last : LReal;
  t_last : LReal;
  init_done : Bool := FALSE;   // möglichst nicht remanent, oder im 1.Zyklus CPU STOP/RUN auf 0, oder cycle1 benutzen
  Runtime_overflow : UInt;     // Test: Zähler RUNTIME()-Überläufe
  t_max : LReal;               // Test: höchste erreichte RUNTIME()-Startzeit
END_VAR
VAR_TEMP
  dt_s_r : LReal;   // Delta t (s) zu letztem Durchlauf
END_VAR


BEGIN
    // INTEGRATE für S7-1200/S7-1500, getestet mit PLCSIM V13 SP1 als CPU 1215C Firmware V4.1
    
    (* Zeit (s) seit letztem Aufruf *)
    #dt_s_r := RUNTIME(#t_last);
    
    IF #t_last > #t_max THEN
      #t_max := #t_last;
    END_IF; //Testcode: ca. Überlaufzeitpunkt ermitteln und merken
    
    IF #dt_s_r < 0.0 THEN  //hat RUNTIME() einen Überlauf? kommt alle ca. 1696.725 s ~ 28 Minuten vor (PLCSIM V13 SP1)
      #dt_s_r := #dt_s_r + 1696.726;  //empirisch ermittelter Korrekturwert 1696.725 s + 1 ms vorsichtshalber
     #Runtime_overflow := #Runtime_overflow + 1
      ;  //Testcode: RUNTIME()-Überlaufzähler
    END_IF;
    
    IF #reset THEN //Nullen des Integrals
      #Y := 0.0;
    END_IF;
    
    (* im 1. Zyklus CPU STOP/RUN oder neu laden des IDB: nur t_last und X_last merken *)
    IF NOT (#init_done) OR #cycle1 OR #reset THEN
      #init_done := TRUE;
      //    Y := 0.0;    //bei Laden des IDB lieber kein Reset
      //    X_last := X; //wird sowieso immer gemacht; t_last ebenso
    ELSIF #enable THEN
      (* Integrieren mit Trapezregel *)
      #Y := (#X + #X_last) * 0.5 * #dt_s_r + #Y;
    END_IF;
    #X_last := #X;
    
    
    // cycle1 mit Systemmerker "FirstScan" beschalten
    // RUNTIME() hat irgendwann Überlauf (liefert dann <0.0)! System Time für RUNTIME() läuft weiter während CPU STOP!
    // TIA V15 SP1 Hilfe sagt schwammig: Die Anweisung "Laufzeitmessung" verwendet einen internen hochfrequenten Zähler
    // um die Zeit zu berechnen. Wenn der Zähler überläuft, gibt die Anweisung Werte <= 0.0 zurück. Dies kann für
    // S7-1200-CPUs mit Firmware Stand <V4.2 bis zu einmal pro Minute vorkommen. Diese Runtimewerte sind zu ignorieren. (!)
    // Mit TIA PLCSIM V13 SP1 empirisch ermittelter Überlaufzeitpunkt (siehe t_max): ca. 1696.725 s
END_FUNCTION_BLOCK
 
Zurück
Oben