TIA TIA V17 Date and Time auf einzelne Bytes zugereifen?

Moin MrNiceGuy,

zum Beispiel so:
Code:
// Jahr
"MAIN_CLOCK_DB".LokalzeitDateChar.YYYY[0] := BYTE_TO_CHAR(INT_TO_BYTE(UINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.YEAR) / 1000 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitDateChar.YYYY[1] := BYTE_TO_CHAR(INT_TO_BYTE(UINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.YEAR) / 100 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitDateChar.YYYY[2] := BYTE_TO_CHAR(INT_TO_BYTE(UINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.YEAR) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitDateChar.YYYY[3] := BYTE_TO_CHAR(INT_TO_BYTE(UINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.YEAR) MOD 10) + 16#30);
// Monat
"MAIN_CLOCK_DB".LokalzeitDateChar.MM[0] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.MONTH) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitDateChar.MM[1] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.MONTH) MOD 10) + 16#30);
// Tag
"MAIN_CLOCK_DB".LokalzeitDateChar.DD[0] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.DAY) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitDateChar.DD[1] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.DAY) MOD 10) + 16#30);

// Stunde
"MAIN_CLOCK_DB".LokalzeitTimeChar.hh[0] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.HOUR) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.hh[1] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.HOUR) MOD 10) + 16#30);
// Minute
"MAIN_CLOCK_DB".LokalzeitTimeChar.mm[0] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.MINUTE) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.mm[1] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.MINUTE) MOD 10) + 16#30);
// Sekunde
"MAIN_CLOCK_DB".LokalzeitTimeChar.ss[0] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.SECOND) / 10 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.ss[1] := BYTE_TO_CHAR(INT_TO_BYTE(USINT_TO_INT("MAIN_CLOCK_DB".Lokalzeit.SECOND) MOD 10) + 16#30);
// Millisekunde
"MAIN_CLOCK_DB".LokalzeitTimeChar.msmsmsms[0] := BYTE_TO_CHAR(DINT_TO_BYTE(UDINT_TO_DINT("MAIN_CLOCK_DB".Lokalzeit.NANOSECOND) / l#100_000_000 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.msmsmsms[1] := BYTE_TO_CHAR(DINT_TO_BYTE(UDINT_TO_DINT("MAIN_CLOCK_DB".Lokalzeit.NANOSECOND) / l#10_000_000 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.msmsmsms[2] := BYTE_TO_CHAR(DINT_TO_BYTE(UDINT_TO_DINT("MAIN_CLOCK_DB".Lokalzeit.NANOSECOND) / l#1_000_000 MOD 10) + 16#30);
"MAIN_CLOCK_DB".LokalzeitTimeChar.msmsmsms[3] := BYTE_TO_CHAR(DINT_TO_BYTE(UDINT_TO_DINT("MAIN_CLOCK_DB".Lokalzeit.NANOSECOND) / l#100_000 MOD 10) + 16#30);

Das ist zwar für den Datentypen DTL, aber sinngemäß sollte es genauso funktionieren.

VG
MFreiberger
 
Moin MrNiceGuy,

genau das, was @DCDCDC gerade gefragt hat, wollte ich auch gerade fragen.

Mein Code macht aus den einzelnen Stellen eines Numerischen Datentyps CHAR.
Das macht er, indem er die zu überführende Stelle auf die Einer-Stelle schiebt (Division) und dann vereinzelt (Restberechnung mit 10). Daraus ergibt sich ein Zahlenwert von 0-9. Durch das Addieren von 16#30 wird der CHAR-Wert nach der ASCII-Tabelle erzeugt. Der wird jetzt noch in CHAR gewandelt und als CHAR gespeichert.

VG
MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe eine 1511er CPU FW V2.9. Es soll ein Baustein entstehen, der bei einem Startsignal eine Messung im Sekundentakt aufzeichnet. Als Eingang kommt ein Analog Input der uns den durchfluss in einer Leitung misst. Ich will dass bei einer positiven Flanke der Bausten aufzeichnet, und sobald eine neue (volle) Stunde beginnt, der Baustein seine bisher alten Werte in ein anderes Array umschreibt und von vorne beginnt die Messungen aufzuzeichnen.

Ich benutze die Funktion ReadSysTime und würde am liebstendie Stunden im Byte auslesen und schauen ob die nue stunde angeborchen ist
 
Ich habe eine 1511er CPU FW V2.9. Es soll ein Baustein entstehen, der bei einem Startsignal eine Messung im Sekundentakt aufzeichnet. Als Eingang kommt ein Analog Input der uns den durchfluss in einer Leitung misst. Ich will dass bei einer positiven Flanke der Bausten aufzeichnet, und sobald eine neue (volle) Stunde beginnt, der Baustein seine bisher alten Werte in ein anderes Array umschreibt und von vorne beginnt die Messungen aufzuzeichnen.

Ich benutze die Funktion ReadSysTime und würde am liebstendie Stunden im Byte auslesen und schauen ob die nue stunde angeborchen ist
Dafür kannst du auch einfach zB die Taktmerker aus dem Systembyte nehmen, musst du nur in der CPU aktivieren in der Hardwarekonfiguration
Screenshot 2024-02-29 154924.png

Eventuell noch eine TON Funktion dazu, welche auf eine Stunde eingestellt ist.

Messung aktiv > TON starten mit Flanke > Stunde rum > TON wird ausgeführt + Messung Stop + Werte schieben > Werte geschoben > Messung aktiv > TON starten mit Flanke..
 
Zuviel Werbung?
-> Hier kostenlos registrieren
War mein erster Ansatz. Vorgabe ist aber sein die CPU Uhr zu nutzen. Es kann wohl sein dass später auch eine Uhrzeit als Startparameter hinzukommen soll dass zur bestimmten Uhrzeit die Aufzeichnung startet. Oder mitten drin eben, und dann zur voll nStunde immer neu aufgezeichnet wird
 
Zuletzt bearbeitet:
Dann könntest Du mit TIME_TCK die Systemzeit als TIME auslesen. TIME ist ja auch nichts anderes als ein 32-BitWert, dessen Inhalt als Millisekunden gewertet wird. Wenn man TIME in DINT überführt, kann man auch wunderbar damit rechnen.
 
Also die Systemzeit auslesen und speichern. Dann zyklisch gucken, ob die Differenz von aktuell gelesener Systemzeit und gespeicherter Zeit eine Dauer von 3_600_000 (ms) überschreitet.
 
Ich habe eine Lösung in der ich beim Start meine Uhrzeit "speichere" wenn eine positiven flanke am Start-Input kommt. und arbeite dann mit der differenz und würde prinzipiell so funktionieren.....Aber es kam dann die vorgabe ich soll das einzelne Byte (Date and Time besteht aus 8bytes) auslesen...und finde um verrecken keine Lösung dafür
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum du einzelne Bytes vergleichen sollst, ist für mich nicht ersichtlich.. es gibt ja nicht ohne Grund die Datum und Uhrzeit Datentypen innerhalb der Projektierung. Die kann man auch super miteinander in KOP vergleichen.
 
Das ist zwar für den Datentypen DTL, aber sinngemäß sollte es genauso funktionieren.
Achtung! Das mag zwar für DTL passen, für DT muss man aber u.A. noch die Kleinigkeit beachten, dass da die einzelnen Zahlen BCD-codiert sind.

Wenn ich einen Datentyp in einzelne Bytes zerlegen will, dann schau ich mir zuerst in der Hilfe oder Dokumentation den Aufbau des Datentyps an. Dann bastele ich mir dazu passend eine Struktur (wenn möglich und sinnvoll), und versuche dann mit "AT" zu arbeiten. Wenn ich mal gar keine Phantasie habe, dann kann ich auch in der Hilfe suchen, ob es da nicht vielleicht schon eine fertige Funktion/Anweisung dafür gibt, oder für das, was ich eigentlich tun will.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe eine 1511er CPU FW V2.9. Es soll ein Baustein entstehen, der bei einem Startsignal eine Messung im Sekundentakt aufzeichnet. ... Ich will dass bei einer positiven Flanke der Bausten aufzeichnet, und sobald eine neue (volle) Stunde beginnt, der Baustein seine bisher alten Werte in ein anderes Array umschreibt und von vorne beginnt die Messungen aufzuzeichnen.

Ich benutze die Funktion ReadSysTime und würde am liebstendie Stunden im Byte auslesen und schauen ob die nue stunde angeborchen ist
:unsure:
Warum liest Du die SysTime dann statt in DateAndTime nicht einfach als DTL?
Für Deine Suppe nimmst Du doch vermutlich auch nicht die Gabel sondern den Löffel, oder?

Mit DTL hast Du die einzelnen Bestandteile der (System-) Zeit als Struct vorliegen und kannst somit auch vollsymbolisch darauf zugreifen:
1709222289369.png
 
Zuletzt bearbeitet:
Unterm Bild steht auch noch Text. Zudem ist das Thema ja auch schon weiter fortgeschritten und es gibt auch mehr Informationen und dazu passendere Lösungswege.
 
Zurück
Oben