Twincat 3 Steigung berechnen

flo_ffb

Level-1
Beiträge
10
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe eine Frage bezüglich der Verarbeitung eines Messwerts.
Ich messe eine Te,mperatur, diese steigt an.

Nun möchte ich gerne die Steigung der Kurve berechnen (zB Sekundenweise) und auf eine Minute hochrechnen und den Wert speichern.

Wie geht das? Wie kann ich zeitlich versetzte Werte verrechnen? Habe das bis jetzt immer erst in der Auswertung danach gemacht.

Danke

Gruß
Florian
 
Wie geht das? Wie kann ich zeitlich versetzte Werte verrechnen? Habe das bis jetzt immer erst in der Auswertung danach gemacht.
Wo siehst Du den Unterschied zwischen "Auswertung danach" und "Auswertung sofort"?
Die "Auswertung sofort" kann natürlich keine Voraussage sein und ist letzlich ebenfalls eine "Auswertung danach", nur eben viel "zeitnäher".
Du brauchst den aktuellen MessWert und den (oder die) letzten der vorausgegangenen MessWerte und musst diese natürlich vorübergehend gespeichert haben (z.B. in einem Array, das als FiFo fungiert).
Gruss, Heinileini
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Formel für die Steigung lautet :
y = m * x
umgestellt zur Steigung und unter Berücksichtigung deiner Messungen :
m = (y2 - y1) / (x2 - x1)

Damit hättest du dann für jedes Paar Messwerte (also aktueller Wert und letzter Wert davor) den Steigungswert in (je nach verwendeten Masseinheiten) z.B. Grad/Sekunde

Gruß
Larry
 
Wie grundsätzlich die Steigung berechnet wird ist mir geläufig.
Bei der bisherigen Berechnung kann ich auf Werte mit Zeitstempel zugreifen, da ist es kein Problem.
Die Steigung soll aber nun neben der Temperaturkurve mit angezeigt werden um den Anstieg direkt bewerten zu können.

natürlich vorübergehend gespeichert haben (z.B. in einem Array, das als FiFo fungiert).

Ja das ist mein Problem. Die Kenntnisse dazu besitze ich nicht.Es liest sich so einfach, ich weiß aber nicht wie.
 
Du möchtest nur wissen, ob die Temperatur steigt oder fällt? Dann dämpfe den Messwert und vergleiche ihn mit dem aktuellen Wert. Der Gedämpfte Wert eilt dem aktuellen Wert nach. Natürlich kannst du auch einen stärker gedämpften Wert und einen leicht gedämpften Wert zum Vergleich verwenden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Task ein richten, die in SekundenAbständen aufgerufen wird.
Darin neuen TemperaturWert einlesen, ggfs normieren, skalieren.

AnstiegProSek := NeueTemperatur - AlteTemperatur
AnstiegProMin := AnstiegProSek * 60
AlteTemperatur := NeueTemperatur (* Der Wert in "AlteTemperatur" muss bis zum nächsten Aufruf unverändert erhalten bleiben! *)
 
Wenn ja eine Temperaturänderung von einer Sekunde auf die andere messbar ist, dann ist das ok, anderenfalls ist es reine Theorie. Und wenn man einen DB mit aktuellen Werten, einen DB mit leicht gedämpften Werten, so wie einen DB mit stärker gedämpften Werten zu seinem Standard zählt, dann ist es keine Frage ;) .
 
Zuletzt bearbeitet:
Sicher, Onkel Dagobert. Ich dachte, wir fangen erstmal ganz einfach und unbedarft an, zumal wir noch nicht wissen, wo die Reise hingeht.
Wenn Florian über Probleme stolpert, werden wir die hier erfahren (?) und können dann weiterhelfen.
Es geht doch zunächst mal darum, das Prinzip zu verstehen. Erweiterungen und Verfeinerungen wird sich Florian dann vielleicht bis hoffentlich sogar selbst ausdenken können. Von Dir liegen ja nun schon StichWorte vor, die ihn dazu inspirieren könnten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
oh, ich seh schon, ich muß präzieser werden.
Es interessiert nicht nur ob die Temperatur steigt oder fällt, sondern wie stark.
Die Temperatur wird immer steigen. Wenn die Steigung zu gering ist wird nachgeheizt, wenn zu stark, wird die Temperaturzufuhr gedrosselt.
Ein Sekundentakt ist vermutlich zu gering, es können 3,5, oder 10 werden, die dann auf °C/min hochgerechnet werden. Wie das funktioniert weiß ich auch. Welche Abtastrate für die Steigungsberechnung hergenommen wird, zeigt dann der Versuch.
Mein Problem ist die praktische Umsetzung, da hängts bei mir. Ich kann eine einfache Ablaufsteuerung erstellen, überwachen,... und das wars das. Ich arbeite mich gerade noch ein.
Wenn ich schreibe, dass ich es vorher hinterher ausgewertt habe, dann habe ich dies mit einem in Diadem (NI) erstellten Script gemacht. Ein Script für sowas in Diadem erstellen kann ich, da die Werte aller einer Zeit zugeordnet sind.

Hier weiß ich es nicht. Ich kann zwar aktuelle Werte skalieren, verrechnen,... aber eben keinen vergangenen.
"AnstiegProSek := NeueTemperatur - AlteTemperatur" woher kriege ich die Werte?

Danke

Gruß
Florian
 
ich kenne Codesys jetz nicht, aber vom Prinzip sollte das so aufgebaut sein:

Du programmierst eine Funktion die du all x Sekunden für einen Zyklus aufrufst.
Darin dann folgendes:
Aktuelle Temperatur - alte Temperatur (Global siehe weiter unten) -> deine Differenz für die Berechnung der Steigung
hier dann deine Berechnung, Wert ausgeben aus der Funktion -> aktuelle Steigung
dann schreibst du auf einen Merker außerhalb deiner Funktion (Global) den aktuellen Temperaurwert, diesen Wert nennst du "alte Temperatur"

somit steht beim nächsten Aufruf dieser Funktion dann der Wert vom letzten Aufruf in alter Temperatur.
 
"AnstiegProSek := NeueTemperatur - AlteTemperatur" woher kriege ich die Werte?
Neue (= aktuelle) Temperatur: vom AnalogEingang einlesen, nach Bedarf normieren/skalieren.
Differenz neu - alt (= Anstieg) bilden.
Den Wert neue Temperatur speicherst Du dann "zu guter letzt" als alte Temperatur ab, um beim nächsten Durchlaufen Deiner Befehle damit die Differenz neu - alt bilden zu können.
Beim ersten Durchlaufen der Befehle ist der Inhalt von "alte Temperatur" (noch) nicht sinnvoll.
Wenn Du damit leben kannst OK, ansonsten im 1. PLC-Zyklus die neue Temperatur einlesen etc. und als alte Temperatur abspeichern, aber die Differenz noch nicht auswerten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier weiß ich es nicht. Ich kann zwar aktuelle Werte skalieren, verrechnen,... aber eben keinen vergangenen.
"AnstiegProSek := NeueTemperatur - AlteTemperatur" woher kriege ich die Werte?
Du brauchst Dir doch nur den älteren Wert (oder mehrere) merken: bei einem FB in der Instanz (Static), bei einem FC in einer externen Variable an einem IN_OUT. Oder notfalls direkt in einer globalen Variable. Beim ersten Programm-Durchlauf oder bei CPU-Neustart Wert_vorher mit Wert_jetzt initialisieren.
Prinzip:
Code:
IF NOT init_done THEN //erster Durchlauf? init_done nicht remanent --> FALSE beim ersten Durchlauf
  init_done := TRUE;
  Wert_vorher := Wert_jetzt;
END_IF;

Anstieg := Wert_jetzt - Wert_vorher;
Wert_vorher := Wert_jetzt; //Wert für nächsten Durchlauf merken
In welchem Intervall Du den Code aufrufst ist Dir überlassen.

PS: zu langsam getippselt ...

Harald
 
Ja, hab ich probiert.

bei einem FB in der Instanz (Static), bei einem FC in einer externen Variable an einem IN_OUT. Oder notfalls direkt in einer globalen Variable.

Daran muß ich jetzt arbeiten und mich einlesen wie ich es umsetzte und aufrufen kann. Ich lese mich gerade in einem Tutorial ein, hoffe ich steige durch.
 
zu Hilfe! Verzweiflung macht sich breit.
Hab ein eigenes kleines POU geschrieben. Dieses war dem normalen Task zugeordnet. Es läuft, soll aber ja nicht mit 10ms laufen.
Also habe ich ein neues Task eingerichtet mit 5000ms. Hab das Programm dem zugeordnet. --> Fehler. Ich weiß nicht warum, Twincat Systembeim Senden an AMS...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das liegt an der Zahl der Zyklusticks. Bei einer Basiszeit von 1ms kommt diese Fehlermeldung bei einer Zahl ab 4295, bei einer Basiszeit von 500µs kommt die Meldung bei Werten ab 8590 usw., warum das so ist weiß ich aber leider auch nicht.
Übrigens um etwas langsamer laufen zu lassen brauchst Du keine zweite Task, das geht mit TON z.B. auch.
 
Zuletzt bearbeitet:
Ah ok, Danke. Mit 1000ms gings auch. Es gibt ein paar so Eigenarten, die einen wahnsinnig machen können.

Ein Problem hab ich gerade noch mit eingelesenen Werten aus Klemmen.
Ich lese aus einer EL3312über ein TypK Element eine Temperatur ein. Ein Onlinewert wird angezeigt-->21,9° passt
Ich deklariere eine Variable und lese den Wert ein. Jetzt beginnt das Problem. Als real- Variable kommt ein ..e-44 Wert raus, wenn ich die Variable als INT einlese kommt der Klemmenwert um Faktor 10 verschoben rasu (aus 21,9 wir 219).
Ok, hab mir gedacht ich Teil den Wert durch 10 und mach eine Real- Variable draus, 219/10 =21,9, macht es aber nicht, sondern macht eine ganze Zahl draus.

Ich vermute mal, die Lösung ist lächerlich einfach, ich komme aber nicht drauf. Auch der Umweg hat diesmal nicht funktioniert.
 
Erst in Gleitpunktzahl umwandeln, dann dividieren - so geht die Nachkommastelle nicht verloren.
Code:
MyRealTemperature := INT_TO_REAL(Klemmenwert) / 10.0;

Harald
 
:roll: ...ich schäme mich schon fast ein bischen, die Lösung ist so trivial.
Freu mich aber über die schnelle Hilfe und das es nun geht.
Danke und bis zur nächsten Kleinigkeit
 
Danke und bis zur nächsten Kleinigkeit
Gerne und immer wieder gerne. Bitte wähle doch noch einen der Beiträge als hilfreichste Antwort aus, damit der Thread als "Gelöst" markiert ist und Heinileini, Harald und die Anderen würden sich auch noch über einen Klick auf den Danke Button freuen.
@Alle Experten: Weiß einer woher die Beschränkung bei den Zyklusticks kommt? Bei Tante Google bin ich nicht wirklich fündig geworden.
 
Zurück
Oben