# Alarmliste programmieren



## Flo (4 Dezember 2009)

Servus,
habe zur zeit ein projekt, bei dem ich in der visu die Alarmliste/Alarmanzeige (wie man es aus WinCCFlex kennt) selbst in der SPS programmieren muss. Die Anzeige in der Visu erfolgt über eine Tabelle (sprich in der SPS muss ein Array gefüllt werden).
Ich habe die Liste bereits programmiert, Problem ist gelöst, dennoch würde es mich interessieren wie ihr das lösen würdet
Das Programm habe ich in ST auf Codesys geschrieben, werde es natürlich auch posten.

MfG,
Flo


----------



## Flo (9 Dezember 2009)

also, die Fehlerliste die ich programmiert habe sieht folgendermaßen aus:

```
PROGRAM Alarmliste
VAR
 i,j,k,l,m:INT;
 x_init: BOOL;
 FM:ARRAY[0..num_of_Fehler] OF FB_Fehler;
 Fehler_Hilfsarray:ARRAY[0..num_of_Fehler] OF INT;(*Platzierungsliste*)
 Fehlerliste:ARRAY[0..num_of_Fehler] OF sAlarmliste;
   (*TYPE sAlarmliste :
      STRUCT
       alarmzeit:STRING;
       fehlernummer:STRING;
       fehlertext:STRING[100];
      END_STRUCT
      END_TYPE
   *)
END_VAR
 
(*
VAR_GLOBAL CONSTANT
 num_of_Fehler:INT:=512;
END_VAR
*)
```
 

```
IF NOT x_init THEN (* Initialisieren*)
x_init:=TRUE;
k:=0;
END_IF
 
FOR i:=0 TO num_of_Fehler DO   (* Durchlaufe Initialisiereungen der Fehlerbausteine *)
 IF FM[i].Fehler_Aktiv THEN
  Fehler_Hilfsarray[k]:=i;      (*Schreibe den aufgetretenen Fehler in eine Hilfsliste, um die Reihenfolge der Fehler zu platzieren*)
  k:=k+1;
 END_IF
END_FOR
j:=0;
FOR i:=0 TO k-1 DO  (* Für alle Elemente in der Fehlerliste *)
 IF NOT FM[Fehler_Hilfsarray[i]].Fehler_Aktiv THEN   (*nicht mehr enabled oder aktiv*)
  Fehler_Hilfsarray[i]:=0;
  j:=j+1; (*Counter für gelöschte Einträge, um Liste wieder nach oben hin auf zu füllen*)
 ELSE
 IF j>0 THEN
 Fehler_Hilfsarray[i-j]:=Fehler_Hilfsarray[i]; (*verschieben der Elemente um j*)
 Fehler_Hilfsarray[i]:=0;
 END_IF
 END_IF
END_FOR
k:=k-j;  (* neuen index auf letztes Element berechnen*)
l:=0;
FOR i:=(k-1) TO 0 BY -1 DO (* Fehlerliste befüllen*)
 Fehlerliste[l].fehlertext:=FM[Fehler_Hilfsarray[i]].text;
 Fehlerliste[l].alarmzeit:=FM[Fehler_Hilfsarray[i]].string_DT;
 Fehlerliste[l].fehlernummer:=INT_TO_STRING(FM[Fehler_Hilfsarray[i]].Fehlernummer);
 l:=l+1;
END_FOR
FOR m:=l TO 200 DO (* restliche Einträge nullsetzen*)
 Fehlerliste[m].fehlertext:='';
 Fehlerliste[m].alarmzeit:='';
 Fehlerliste[m].fehlernummer:='';
END_FOR
```
 
das ist jetzt meines erachtens recht umfangreich, daher stellt sich mir die Frage ob es auch noch andere (kompaktere) Lösungsansätze dafür gibt.
Verbesserungsvorschläge sind auch gerne erwünscht.
mfG,
Flo


----------



## apalm (8 Januar 2010)

Hey!
Und wie füllst du deine Liste?
Mfg


----------



## Chräshe (9 Januar 2010)

Hallo Flo,

ich hatte das selbe Problem mit der Alarmanzeige, weil die TwinCAT Target VISU CE die Funktion leider nicht unterstützt. 






Sieh mal hier...
http://www.sps-forum.de/showthread.php?t=25726&page=2#14
Aber Vorsicht! Wenn du die Struktur zu groß wählst kommt die Steuerung mächtig in schwitzen 





Alternativ wollte ich mal dein Entwurf ausprobieren, aber der „FB_Fehler“ fehlt.
Kannst du den FB, oder besser noch das Projekt hier reinstellen?  

Gruß
Chräshe


----------



## apalm (11 Januar 2010)

Hey!
Das gleiche Problem mit der PLC HMI CE hatte ich auch, ich frage ständig wann die Alarmtabelle unter CE integriert wird und jedesmal heißt es demnächste bzw. dann wenn CE 6.0 auf die Panels kommt.
Ich wollte das Beispiel auch mal ausprobieren nur leider fehlt der FB_Fehler!
Vielleicht könntest du den ja auch noch reinstellen?!
Danke im Voraus


----------



## Flo (11 Januar 2010)

```
FUNCTION_BLOCK FB_Fehler
VAR_INPUT
 Fehlernummer:INT;
 Enable:BOOL;
 In:BOOL;
 EV:TIME;
 AV:TIME;
 Reset:BOOL;
 Reaktion_Fehler:INT;
 Text:STRING(100);
END_VAR
VAR_OUTPUT
 Aktiv:BOOL;
 Reset_moeglich:BOOL;
 Fehler_Log:STRING(35);
END_VAR
VAR
 TON_In:TON;
 TOF_In:TOF;
 AV_In:BOOL;
 R_TRIG_Aktiv:R_TRIG;
 string_DT:STRING(25);
 Fehler_num:STRING(8);
 Fehler_Log_tmp:STRING(35);
END_VAR
```
 

```
TON_In(IN:=In , PT:=EV );
TOF_In(IN:=In , PT:=AV,Q=>AV_In );
IF AV = t#0ms
THEN
 AV_In:=FALSE;
END_IF
IF Reset
THEN
 Aktiv:=FALSE;
END_IF
 IF Enable AND (TON_In.Q OR (NOT In AND AV_In))
 THEN
  Aktiv:=TRUE;
 END_IF
Reset_moeglich:= NOT TON_In.Q AND NOT TOF_In.Q AND aktiv;
R_TRIG_Aktiv(CLK:= Aktiv );
IF R_TRIG_Aktiv.Q
THEN
string_DT:=LEFT(systemTime, LEN(systemTime) -4);
Fehler_num:=INT_TO_STRING(Fehlernummer);
Fehler_Log_tmp:=CONCAT(string_DT,' FM:');
Fehler_Log:=CONCAT(Fehler_Log_tmp,Fehler_num);
END_IF
(*Info!!*)
Reaktion_Fehler;
(*Eingang Input Bedeutung:
0: Meldung, nur Anzeige;
1: Störung Gesamtanlage; Stopp nach Takt;
2: Störung Gesamtanlage; Sofortstopp;
3: Störung Gesamtanlage; Einschaltsperre;*)
```
 
Hier der FB_fehler.


> ich hatte das selbe Problem mit der Alarmanzeige, weil die TwinCAT Target VISU CE die Funktion leider nicht unterstützt.


Genau deshalb ist der Code dafür entstanden
Das Problem mit der Systemleistung hatte ich auch, allerdings lag das bei mir (in diesem Fall wars ein CX9010) nicht an den großen Strukturen, sondern vielmehr an den beiden VisuTasks.

Edit: Die Variable "systemTime" ist Global, muss also zusätzlich angelegt werden:

```
systemTime   : STRING;
 fbGetSystemTime  : GETSYSTEMTIME;
 fileTime  : T_FILETIME;
```


```
fbGetSystemTime(timeLoDW=>fileTime.dwLowDateTime, timeHiDW=>fileTime.dwHighDateTime );
systemTime :=SYSTEMTIME_TO_STRING( FILETIME_TO_SYSTEMTIME( fileTime ) );
```


----------



## apalm (11 Januar 2010)

Trotzdem verstehe ich jetzt noch nicht ganz wie du das Array gefüllt kriegst sprich deine einzelnen Alarme in das Array schreibst bzw. die einzelnen Alarme auflistest!
Mfg


----------



## Chräshe (11 Januar 2010)

Hallo Flo,

im 2. Anlauf hat es leider auch nicht geklappt, deine Pusselteile zusammenzusetzen.


```
FOR i:=0 TO num_of_Fehler DO    
[COLOR=Red]IF FM[i].Fehler_Aktiv THEN[/COLOR]
Fehler_Hilfsarray[k]:=i;      
k:=k+1;
END_IF
END_FOR
```
Jetzt schimpft der Compiler „Fehler_Aktiv“ ist keine Komponente von „FB_Fehler“...
Da muss ich ihm recht geben – das ist so.

Kann es sein dass die Codeschnipsel aus unterschiedlichen Versionsständen stammen?

Gib mir ein Tipp – einen Versuch starte ich noch..
 … aber langsam bin ich zu alt zum pusseln... 

Gruß
Chräshe


----------



## apalm (11 Januar 2010)

Ich denke man braucht nur das Fehler vor aktiv wegzunehmen dann müsste es gehen.
Aber ich frage mich ob es noch einen Baustein gibt wo man seine Alarme eingibt?!


----------



## Flo (12 Januar 2010)

ja stimmt, habe falscherweise den FB_Fehler aus nem älteren Projekt genommen.
Wenn du das "Fehler_" weg machst müsste es funktionieren.


----------



## Flo (12 Januar 2010)

apalm schrieb:


> Aber ich frage mich ob es noch einen Baustein gibt wo man seine Alarme eingibt?!


Nein gibt es nicht, der FB_Fehler hat als eingang eine Stringvariable "Text".
Der hier eingetragene Text wird dann im Baustein mit der Fehlernummer und der Zeit, an der der Fehler aufgetreten ist, verknüpft und dann in die Tabelle eingetragen.
mfg,


----------

