TIA Meldung mit Date and Time in DB schreiben

Byte0815

Level-2
Beiträge
151
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich arbeite seit kurzem mit dem TIA Portal V15.1.
Derzeit versuche ich mich an der Analogwertverarbeitung/skallierung.
Ich habe mir bereits meinen Wert 4-20mA (0-30m3/h) skaliert, nun wollte ich gern wenn es zum Max wert also 30m3/h kommt. Das mir dies mit Datum und Uhrzeit in einem DB geschrieben wird.
Leider klappt dies nicht.


Danke schon mal im Voraus
 
Leider klappt dies nicht.
Aha, meine Glaskugel sagt, Du weißt nicht wie man den Wert auf 30m³/h vergleicht? ;)

Oder wie man Datum + Uhrzeit kopiert?
Soll in dem DB nur Datum + Uhrzeit des letzten Ereignisses stehen oder soll das eine Art Logbuch sein? Mit mehreren Einträgen wie in einem Meldearchiv?
Was genau ist Dein Problem?
Welche CPU hast Du?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich arbeite mit einer 1212 DC/DC/DC

Denn Baustein zum Vergleichen habe ich denke ich gefunden :D

Genau mein Problem ist das ich nicht weiß wie ich das jetzt in ein Meldearchiv oder Logbuch einfügen soll. Damit mir Zeit und Datum angezeigt werden wenn es zur Überschreitung kommt.
Ich will Quasi irgendwo sehen wann mein Wert „Max“ erreicht wurde
 
Moin Byte0815,

Genau mein Problem ist das ich nicht weiß wie ich das jetzt in ein Meldearchiv oder Logbuch einfügen soll. Damit mir Zeit und Datum angezeigt werden wenn es zur Überschreitung kommt.
Ich will Quasi irgendwo sehen wann mein Wert „Max“ erreicht wurde

was jetzt? Meldearchiv oder DB? Oder beides?

VG

MFreiberger
 
Ob Meldearchiv oder Datenbaustein wäre mir egal.
Wenn ich beides hinbekommen würde wäre das auch super. Aber die Hauptsache wäre wenn eins von beiden realisiert würde
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Byte0815,

vielleicht erst einmal in einen DB.

Soll immer nur ein Ereignis eingetragen werden oder willst eine Anzahl an Ereignissen (z.B. in einem Ringpuffer) speichern?

VG

MFreiberger
 
Theoretisch würde ein Eintrag reichen. Aber ich denke das ganze gleich als Ringpuffer anzulegen wäre wohl am besten.
Bräuchte immer wenn mein Grenzwert Überschritten wird einen Eintrag mit Datum und Uhrzeit
 
Moin Byte0815,

eigentlich brauchst Du ja nur Datum/Uhrzeit. Das die Eintragung von der Grenzwertüberschreitung herrührt ist ja klar.
Du könntest den DB entsprechend benennen (z.B. "Limit_OF" (Limit Overflow).

Ließt Du irgendwo schon Datum und Uhrzeit aus? Es gibt die Systemzeit der CPU (bezieht sich auf die UTC) und die Lokalzeit (UTC+1 (für Deutschland (Berlin, etc.)) und Sommer-/Winterzeitumstellung). Zur Sommer-/Winterzeitumstellung gibt es einen entsprechenden Baustein (SET_TIMEZONE) in der CPU.
Ansonsten für das Auslesen der Uhrzeiten:
RD_LOC_T für die Lokalzeit (also mit UTC+1 und Sommer-/Winterzeit)
RD_SYS_T für Systemzeit (also UTC)

für weitere Anwendungen usw. würde ich die Uhrzeiten immer zyklisch lesen und in einem DB (den Du z.B. "CLOCK" nennst ablegen).
Uhrzeit dann mit dem Datentyp DT (Date_and_Time) deklarieren.

So. Jetzt immer wenn Dein Grenzwert überschritten wurde eine positive Flanke erzeugen. Damit kannst Du dann die Eintragung in Deinem Ringpuffer vornehmen.

Empfehlung: mache Dir eine Anwenderkonstante (z.B. LimitCnt). Die kannst Du dann sinnvoll so einsetzen:

DB "Limit:OF":

Lfd_Nr int
TimeStamp Array[0.."LimitCnt"] of DT


Programm:

if "Triggerflanke" then
TimeStamp[Lfd_Nr] := "CLOCK".LocalTime;
Lfd_Nr := Lfd_Nr + 1;
Lfd_Nr := Lfd_Nr MOD (LimitCnt + 1);
end_if;


Dann enthält der Ringpuffer so viel Einträge wie LimitCnt + 1. Damit hast Du ja auch dein Array deklariert, also musst Du nichts weiter beachten, wenn Du die Ringpuffergröße änderst (das geht NICHT zur Laufzeit. UND: wenn du die Ringpuffergröße änderst, muss der DB neu initialisiert werden!).

Zu MOD (Modulo):
Das ist ja die Restdivision. Also bei 5 Einträgen:

5 MOD 0 = 0
5 MOD 1 = 1
5 MOD 2 = 2
5 MOD 3 = 3
5 MOD 4 = 4
5 MOD 5 = 0 > hier geht es also wieder (automatisch) von vorne los

Deshalb auch LimitCnt +1, da das Array bei 0 anfängt bzw. anfangen muss.


VG

MFreiberger
 
Du kannst z. B. mit RD_LOC_T die CPU-Uhr auslesen, diesen Wert (DTL) anschliessend mit T_CONV DTL TO Date und T_CONV DTL TO Time_Of_Date in Datum und Uhrzeit wandeln. Zum Speichern in einen DB erstellst du einen UDT aus Arrays [0...x Einträge] der entsprechenden Datentypen (Date; Time_of_day; Int, Real oder was auch immer für deinen Wert).

Zum Eintragen eines Wertes schiebst du zuerst per MOVE_BLK alle Einträge in den UDT-Arrays um 1 Position weiter und überträgst anschliessend die neuen Daten in die jeweiligen Arrays an die Stelle 0.

Edit: Das geht auch in FUP
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Byte0815,

Ok das Auslesen von Datum und Zeit hat geklappt.

Jetzt scheitert es daran die Daten in einen DB zu bekommen....

WIE scheiterst Du denn? Wie ist Dein DB aufgebaut? Wie kopierst Du die Daten?
Vielleicht kannst Du Deinen Code mal posten.

VG

MFreiberger
 
Moin Byte0815,

vgl. Beitrag #8.

Du brauchst eine Variable als Index für Deinen Eintrag im DB.
Du musst den Kopiervorgang mit einer Flanke anstoßen.
Du musst den Index "im Ring" inkrementieren (z.B. mit einer Moduloberechnung).

Am MOVE-Baustein (nicht MOVE_BLK) brauchst zum Übertragen des Zeitstempels nur einen Eingang:


Ausgang: DB.Element[Index]
Eingang: aktuelle Zeit

TIPP: Du kannst auch ein SCL-Netzwerk einfügen...


Eines hatte ich übersehen. Du kannst natürlich nicht einen Zeitstempel in Deine Structur reindrücken.
Dazu würde ich einen eigenen Datentyp erstelllen:

myStruct
- Datum Date
- Tageszeit TOD
- Bit Bool (aber das wäre bei Dir ja sowieso immer TRUE)

Dann im DB ein "ARRAY[0..n] of myStruct
und irgendwo einen Speicherbereich für die aktuellen Daten auch mit dem Datentyp myStruct

Da kannst Du z.B. auch so drafu zugreifen: "DB".Element[INDEX].Datum






VG

MFreiberger
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
So jetzt klappt es die Zeit und das Datum in meinen DB zu schreiben.

Letztes Problem wie kann ich dem Move Baustein zuweisen das er mein Array von 0-100 beschreiben soll.
Aktuell beschreibt er nur die 0 und überschreibt es dann immer wieder.
 
Na, Du musst jedesmal, wenn Du einen Wert schreibst oder geschrieben hast auch den Index der Array-Variablen inkriminierten (Index + 1)


Gesendet von iPhone mit Tapatalk
 
Moin Byte0815,

kein Problem.


Also:
mit der Triggerflanke, mit der Du den Wert in den DB schreibst kannst Du direkt den INDEX inkrementieren. Du kannst direkt hinter dem MOVE (Ausgang ENO) weitere Bausteine anschalten (z.B. ADD und MOD...)
D.h. noch #8 in SCL kann man das auch in KOP machen.

ADD
IN1 := INDEX
IN2 := 1
OUT => INDEX

ADD
IN1 := INDEXCNT
IN1 := 1
OUT => TEMP

MOD
IN1 := INDEX
IN2 := TEMP
OUT => INDEX

...immer noch die Empfehlung ein SCL-Netzwerk einzufügen :)


In SCL ist es halt sehr übersichtlich:

IF Triggerflanke THEN
"DB".Element[INDEX] := Daten; // Sinnvoll für eine Struktur wäre hier einen Datentypen anzulegen, der Datum, Zeit und Bit enthält...
INDEX := INDEX + 1;
INDEX := INDEX MOD INDEXCNT + 1;
END_IF;


VG

MFreiberger
 
Zuletzt bearbeitet:
Okay vielen Dank für die Hilfe.
Am besten ich fang da am Montag nochmal von vorn an.
Ich werde es auch mal mit SCL versuchen auch wenn mir da bis jetzt die Erfahrung fehlt.


Gesendet von iPhone mit Tapatalk
 
Zurück
Oben