Konzept Logbuch Ringpuffer
Was schätzt Du wie viele Log-Ereignisse in 24 Stunden etwa auftreten? Danach richtet sich, wie groß Dein Logbuch sein muß, und ob es denn überhaupt in die CPU passt oder ob/welche Klimmzüge nötig/möglich sind.
6ES7 314-1AE04-0AB0 CPU314, Arbeitsspeicher 24 KByte
Realisierung des Logbuchs:
1) lege die Struktur eines "Logbucheintrag" fest: Zeitstempel + Infofeld(er)
2) erstelle ein Array [0..x] of "Logbucheintrag" für einen Ringpuffer
3) im OB1 kopiere die aktuelle Datum+Uhrzeit auf eine globale Variable (in einen DB, von #OB1_DATE_TIME oder die Uhr abfragen mit SFC1)
4) programmiere das Eintragen eines Ereignisses ins Logbuch als FC "AddLog", der mehrfach aufgerufen werden kann (für jedes Ereignis ein Aufruf)
5) programmiere die Ereignisse, z.B. steigende oder fallende Flanke eines Eingangs, und rufe beim Ereignis den "AddLog"-FC mit der Ereignis-ID (und ggf. Zusatzinfos) auf, eventuell noch Ausschaltverzögerungen dazu, damit unerwartet schnell "flackernde" Ereignisse nicht das Logbuch vollschmieren
zu 1)
Die Struktur am besten als UDT deklarieren, weil sie mehrfach verwendet wird.
Eine normale DATE_AND_TIME-Variable belegt 8 Byte. Sollte der Pufferspeicher nicht reichen, dann eventuell nur die Uhrzeit (TIME_OF_DAY) speichern (braucht nur 4 Byte) und das Datum (2 Byte) nur bei Datumswechsel als spezieller Log-Eintrag speichern. Das Infofeld speichert eine Kennung und eventuell Zusatzinformationen, was für ein Ereignis da im Logbuch steht. Das Infofeld kann 2 Byte oder Vielfache davon sein, weil Structs in Arrays auf gerade Wordgrenzen ausgerichtet werden.
Beispiel-Struct "Logbucheintrag":
+ Zeitstempel (DATE_AND_TIME, 8 Byte)
+ Ereignis-ID (1 Byte)
+ Zusatzinfo (1 Byte)
= 10 Byte
zu 2)
Sollen 100 Ereignisse in 24 Stunden speicherbar sein (etwa 4 Ereignisse pro Stunde), dann wird ein Array [0..99] of "Logbucheintrag" = 100 x 10 Byte = 1000 Byte (ca. 1 kByte) gebraucht.
Das Logbuch sollte ein
Ringpuffer sein, wo ein neuer Eintrag den ältesten Eintrag überschreibt, so daß immer die letzten 100 Einträge im Logbuch enthalten sind.
zu 4)
In TEMP (oder in einem DB) einen "Logbucheintrag" ausfüllen:
- die global gemerkte Datum+Uhrzeit in den Zeitstempel kopieren (oder nur den TIME_OF_DAY)
- die Ereignis-ID
- die Zusatzinfo(s)
Das Logbuch braucht eine Verwaltungsvariable, wo sich gemerkt wird, welcher Arrayplatz zuletzt geschrieben wurde (oder welcher Arrayplatz der nächste freie Platz ist). Als Initialwert der Verwaltungsvariable würde ich -1 festlegen, dann startet das Logbuch beim ersten Arrayplatz.
Beim Eintragen eines Ereignisses den Verwaltungszeiger auf den nächsten Arrayplatz setzen (Index um 1 erhöhen), dann prüfen, ob der Verwaltungszeiger auf ein Element innerhalb des Logbuch-Arrays zeigt und falls nicht dann den Verwaltungszeiger auf den ersten Eintrag setzen. (Der Verwaltungszeiger muß sich den hier verwendeten Wert merken.)
Nun noch den "Logbucheintrag" aus TEMP in den durch den Verwaltungszeiger adressierten Arrayplatz kopieren: speicherindirekte oder registerindirekte Adressierung verwenden oder einen ANY-Zeiger basteln und SFC20 BLKMOV verwenden.
Harald