Step 7 Überwachung von Digital Eingängen mit Uhrzeit

Wolfgang14

Level-1
Beiträge
175
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Grüße
Ich hoffe die Frage existiert noch nicht zu mindest konnte ich nichts finden.

Mein Problem ist ich habe eine CPU314 v1.2.0 (314-1AE04-0AB0) ja ich weiß ist nicht gerade die neueste :).
Mit dieser wollte ich nun gern zu Kabel/Signal Testzwecken Digitaleingänge "Überwachen" also Quasi wenn ein Eingang schaltet soll dies mit Zeit und Datum irgendwo auftauchen und wenn das Signal abbrechen würde auch . Sodass ich nach 24 Stunden dies mithilfe eines Laptops das kurz auslesen und nachvollziehen kann. Ich hoffe dies ist irgendwie möglich .

Danke schon einmal im vorraus :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für die schnelle Antwort. Ich habe nur leider das Problem das ich nicjt so recht weiß wie ich das auf anhieb machen soll da ich mit FiFo noch nicht gearbeitet habe. Könntest du mir da mal einen Lösungsansatz zeigen ?

Danke schonmal im vorraus
 
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
 
Einfache Logbuch-Funktion mit Ringpuffer

1) lege die Struktur eines "Logbucheintrag" fest: Zeitstempel + Infofeld(er)
2) erstelle ein Array [0..x] of "Logbucheintrag" für einen Ringpuffer
Code:
TYPE "Logbucheintrag"
  STRUCT
   TimeStamp : DATE_AND_TIME ;
   EventID   : BYTE ;
   ExtraInfo : BYTE ;
  END_STRUCT ;
END_TYPE

DATA_BLOCK "Logbuch"
  STRUCT
   LastIndex : INT  := -1;     //Schreibzeiger: Index des zuletzt beschriebenen Arrayplatzes
   LBA : ARRAY  [0 .. 99 ] OF  //Logbuch-Array (als Ringpuffer genutzt)
   "Logbucheintrag";
  END_STRUCT ;
BEGIN
   LastIndex := -1; 
   LBA[0].TimeStamp := DT#90-1-1-0:0:0.000;
   LBA[0].EventID := B#16#0;
   LBA[0].ExtraInfo := B#16#0;
...
   LBA[99].ExtraInfo := B#16#0;
END_DATA_BLOCK

4) programmiere das Eintragen eines Ereignisses ins Logbuch als FC "AddLog", der mehrfach aufgerufen werden kann (für jedes Ereignis ein Aufruf)
Für variabel indiziertes Schreiben in ein Array ist indirekte Adressierung nötig. Das ist in FUP/KOP nicht möglich, nur in AWL oder SCL. (in FUP/KOP könnte man lediglich einen ANY-Pointer für BLKMOV basteln)
Code:
FUNCTION "AddLog" : VOID
TITLE =Logbucheintrag zu Logbuch hinzufügen
//Logbuch als Ringpuffer mit 100 Einträgen
VERSION : 0.1

VAR_INPUT
  EnableLog : BOOL ;
  EventID   : BYTE ;
  ExtraInfo : BYTE ;
END_VAR
VAR_TEMP
  tmpLogEintrag : "Logbucheintrag";
  tmpInt : INT ;
END_VAR

BEGIN
NETWORK
TITLE =Logging aktiv?

      UN    #EnableLog;              //wenn Logging nicht aktiv ist
      BEB   ;                        //dann abbrechen (keinen Eintrag hinzufügen)

NETWORK
TITLE =Logbucheintrag erstellen/ausfüllen

      CALL "BLKMOV" (
           SRCBLK  := "DB1".OB1_DATE_TIME,
           RET_VAL := #tmpInt,
           DSTBLK  := #tmpLogEintrag.TimeStamp);

      L     #EventID;
      T     #tmpLogEintrag.EventID;

      L     #ExtraInfo;
      T     #tmpLogEintrag.ExtraInfo;

NETWORK
TITLE =Logbucheintrag in Logbuch kopieren

//Schreibzeiger auf nächsten Eintrag im Logbuch-Array stellen
      L     "Logbuch".LastIndex;     //Index des zuletzt geschriebenen Eintrags
      +     1;                       //nächster Eintrag
      L     100;                     //Anzahl Einträge im Logbuch-Array
      MOD   ;                        //Ringpuffer: Array-Ende mit Array-Anfang verbinden
      T     "Logbuch".LastIndex;     //neuer Wert des Schreibzeigers merken (0..99)

//Zielpointer: Anfangsadresse des Logbuch-Eintrags "Logbuch".LBA[Index]
      L     "Logbuch".LastIndex;     //Schreibzeiger jetzt (0..99)
      L     10;                      //Größe eines Logbucheintrags in Bytes
      *I    ;                        //--> Anzahl Bytes vom Anfang des Arrays
      SLD   3;                       //wandeln in Bitadresse --> P#x.0
      L     P#DBX 2.0;               //Anfangsadresse des Logbuch-Arrays im DB (+2.0 LBA)
      +D    ;                        //dazu --> Anfangsadresse des Eintrags im DB
      LAR2  ;                        //in AR2 (als Zielpointer) laden
      AUF   "Logbuch";               //und Logbuch-DB öffnen

//Quellpointer: tmpLogEintrag
      LAR1  P##tmpLogEintrag;

//tmpLogEintrag in Logbuch kopieren (10 Bytes) von Adresse in AR1 nach Adresse in DBNO+AR2
//(bereichsinterne registerindirekte Adressierung benutzen, weil alte CPU 314)
//(kann evtl. noch keine bereichsübergreifende registerindirekte Adressierung)
      L     LD [AR1,P#0.0];          //von tmpLogEintrag Bytes 1..4
      T     DBD [AR2,P#0.0];         //in Logbuch-Array
      L     LD [AR1,P#4.0];          //von tmpLogEintrag Bytes 5..8
      T     DBD [AR2,P#4.0];         //in Logbuch-Array
      L     LW [AR1,P#8.0];          //von tmpLogEintrag Bytes 9..10
      T     DBW [AR2,P#8.0];         //in Logbuch-Array

END_FUNCTION

3) im OB1 kopiere die aktuelle Datum+Uhrzeit auf eine globale Variable
...
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
Code:
Netzwerk: Datum+Uhrzeit OB1_DATE_TIME global verfügbar machen
               +---------------+
               |     SFC20     |
               |   "BLKMOV"    |
           ...-|EN      RET_VAL|-#tmpInt
               |               |
#OB1_DATE_TIME-|SRCBLK   DSTBLK|-"DB1".OB1_DATE_TIME
               |               |
               |            ENO|-
               +---------------+

Netzwerk: Logbuch Eintrag bei steigender Flanke E0.0
//EventID  : 1 = Änderung E0.0
//ExtraInfo: 1 = kommen / steigende Flanke

      M10.1    +---------------+
     +-----+   |   "AddLog"    |
E0.0-|  P  |---|EN             |
     +-----+   |               |
         M10.0-|EnableLog      |
               |               |
        B#16#1-|EventID        |
               |               |
        B#16#1-|ExtraInfo   ENO|-
               +---------------+

Netzwerk: Logbuch Eintrag bei fallender Flanke E0.0
//EventID  : 1 = Änderung E0.0
//ExtraInfo: 2 = gehen / fallende Flanke

      M10.2    +---------------+
     +-----+   |   "AddLog"    |
E0.0-|  N  |---|EN             |
     +-----+   |               |
         M10.0-|EnableLog      |
               |               |
        B#16#1-|EventID        |
               |               |
        B#16#2-|ExtraInfo   ENO|-
               +---------------+

Im Anhang das Programm als AWL-Quelle. Damit die AWL-Quelle übersetzt werden kann brauchst Du noch ein paar Einträge in der Symboltabelle:
Code:
Logbucheintrag  UDT10
Logbuch         DB10
AddLog          FC10
DB1             DB1
BLKMOV          SFC20

Zum Lesen des Logbuchs aus der CPU am einfachsten
- den Logbuch-DB online öffnen
- Ansicht Datensicht
- erste bis letzte Zeile des DB markieren ("Alles markieren" gibt es nicht im DB-Editor)
- "Kopieren" und in ein Arbeitsblatt in Excel "Einfügen"

Schicker/bequemer könntest Du auch z.B. mit Libnodave das Logbuch aus der CPU in Excel einlesen.
FAQ: LibNoDave + EXCEL

Harald
 

Anhänge

  • Logbuch.AWL.txt
    14,1 KB · Aufrufe: 64
Wolfgang14 schrieb:
Noch eine Frage aus Interesse wäre es ein größerer aufwand wenn ich Beispielsweise 5 Eingänge überwachen will ? Weil aktuell würde ich ja im Logbuch nicht sehen welche eingang "ausgelöst" hat
Ganz einfach: Du schreibst bei jedem Eingang eine andere EventID ins Logbuch (also an den FC10-Aufruf), z.B.
EventID = 1 : Änderung "Eingang_1"
EventID = 2 : Änderung "Eingang_2"
EventID = 3 : Änderung "Eingang_3"
EventID = 4 : Änderung "Eingang_4"
EventID = 5 : Änderung "Eingang_5"

Ob Du das "Kommen" und "Gehen" eines Eingangs als selbe EventID mit unterschiedlicher ExtraInfo oder als unterschiedliche EventID loggst ist ganz Dir überlassen. Es richtet sich ein bisschen danach, wie Du das Logbuch später mal auswerten willst.

Harald
 
Damit das Beispielprogramm Beitrag #5 auch loggt, muß der Logging-Enable-Merker M10.0 auf 1 gesetzt werden (fest 1 zuweisen oder von einer Bedingung abhängig)
oder eine "Immer1"-Variable an den FC10-Aufruf anschalten
oder im FC10 das erste Netzwerk "Logging aktiv?" löschen (und den Input "EnableLog" im FC10 ganz entfernen, oder drin lassen ohne Funktion)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe heute alles überspielt läuft in der Praxis wunderbar ! .

Jedoch habe ich versucht auch noch einen Analog Eingang zu benutzen ob 4-20mA oder 0-10V oder sogar 80mV wäre erstmal egal jedoch wollte er meine Eingangsadresse PEW288 nicht annehmen muss ich den Wert vorher noch skallieren ? Oder geht es generell nicht ?

Mit freundlichen Grüßen
 
Ja was willst du denn Triggern? Willst du jede Wertänderung deines 4-20ma Signals aufzeichnen? Wenn ja musst du daraus irgendeine Triggervariable basteln die dann den Fifo anstösst und den gemessenen Wert da reinschreibt.
Das ist was ganz anderes als Digitaleingänge überwachen. Das wäre mehr so Trending.
 
Grüße
Also will da erstmal keine Trenddarstellung sondern nur ob am Analogeingang überhaupt etwas ankommt. Wie gesagt ob das nun 4,5,6 oder 20mA sind wäre mir erstmal egal

Mit freundlichen Grüßen
 
Danke nochmal für den Tipp mit dem Logbuch alles funktioniert einwandfrei !!

Nun wollte ich mich mit dem angesprochenem Thema auslesen per Libnodave und Ereignisse in eine Excel Tabelle exportieren beschäftigen. Jedoch weiß ich nicht so recht wie ich das auf das bezogene Projekt "Logbuch" anstellen soll.

Danke schon mal im voraus :)
 
Zurück
Oben