TIA SCL - ganzes Array wird überschrieben obwohl nur eine Stelle verwendet wird

Schornsteiner

Level-1
Beiträge
6
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo erstmal,

nun muss ich nach 3 Jahren stillen mitlesen doch einmal einen Beitrag verfassen.

Ich hab folgendes Problem ich versuche in SCL einen Alarmbaustein zu schreiben, und der funktioniert auch einwandfrei solange ich ihn nur einmal aufrufe.
Nur sobald ich ihn öfter verwende scheint es als würde er jedes mal wenn er aufgerufen wird jeden anderen Alarm in meinem Melde-DB rücksetzen wobei ich mir nicht erklären kann warum.


Meinem Baustein übergebe ich natürlich den Störeingang (+ Zustand separat), ein Array für die Meldetrigger (DB101.DBX0.0), ein Array für die Quittiervariablen der PLC (DB101.DBX250.0) und ein Array mit dem ich auch den Zustand der Quittiervariable der HMI sehen kann (DB101.DBX500.0). Zusätzlich eine Melde-ID (mitdessen Hilfe ich den jeweiligen Alarm in meinem Array anspreche) und einen externen Quittiereingang.


IF #Zustand THEN //Nur für Anzeige​
#Daten.Status.EIN := True;​
#Daten.Status.AUS := False;​
ELSE​
#Daten.Status.EIN := FALSE;​
#Daten.Status.AUS := true;​
END_IF;​


#pf := #Taktmerker AND NOT #fm; //für Verzögerung​
#fm := #Taktmerker;​

IF #Stoereingang AND NOT #Daten.Status.Stoerung THEN //neuer Alarm​
IF #pf THEN​
#i := #i + 1;​
END_IF;​
IF #i >= #Daten.Verz THEN​
#Quitt_PLC[#"Melde-ID" - 1] := FALSE;​
#StoerDB[#"Melde-ID" - 1] := True;​
#Daten.Status.Stoerung := True;​
#Daten.Status.Stoerung_unquittiert := True;​
END_IF;​
ELSE​
#i := 0;​
END_IF;​

IF NOT #Stoereingang AND (NOT #Daten.Status.Stoerung_unquittiert OR NOT #Quitt_HMI_Array[#"Melde-ID"-1]) THEN​
#StoerDB[#"Melde-ID" - 1] := false;​
#Daten.Status.Stoerung := false;
#Daten.Status.Stoerung_unquittiert := false;​
END_IF;​



IF #Quitt_Ext THEN​
IF NOT #Stoereingang THEN​
#Daten.Status.Stoerung := false;
END_IF;​
#Daten.Status.Stoerung_unquittiert := false;​
#Quitt_PLC[#"Melde-ID" - 1] := True;​
END_IF;​

Kann mir jemand sagen wo da mein großer Denkfehler ist? :confused:

Wenn ich den Baustein nur einmal verwende arbeitet er genauso wie er soll (zumindest wirkt es so).

Sobald ich ihn aber öfter verwende (ja unterschiedliche Melde-ID's, unterschiedliche Instanzen, alles 3-mal kontrolliert von der Beschaltung) wechseln sich die Alarme in meiner Meldeanzeige ab.
Das heißt ein Alarm kommt, geht, ein neuer kommt, der neue geht,...usw... und auch in meinem DB sehe ich eigentlich nur den Zustand des Alarms an der Stelle der letzten Melde-ID die ich verwende.

Beste Grüße Schornie
 
Zuletzt bearbeitet:
Für mich liegt das an dem Flankenmerker.
Der wird wahrscheinlich nicht STAT sein und nach meinem Dafürhalten wirst du für jeden neuen Aufruf einen neuen FM benötigen.
Rufst du den Baustein immer mit dem gleichen I-DB auf ? Wahrscheinlich ja ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bausteinaufruf.JPG

Multiinstanz, jeder Alarm neue Instanz -> für Visualisierung.

Der "fm" (Flankenmerker) ist statisch und die Variable "pf" (positive Flanke) ist Temporär, gehört die auch statisch?

Gruß Schornie
 
Für bessere Lesbarkeit von Code mit Erhalt der Einrückungen bitte [CODE]-Tags verwenden (der #-Button im Beitragseditor):
Code:
IF #Zustand THEN     //Nur für Anzeige
    #Daten.Status.EIN := True;
    #Daten.Status.AUS := False;
ELSE
    #Daten.Status.EIN := FALSE;
    #Daten.Status.AUS := true;
END_IF;

#pf := #Taktmerker AND NOT #fm; //für Verzögerung
#fm := #Taktmerker;

IF #Stoereingang AND NOT #Daten.Status.Stoerung THEN //neuer Alarm
    IF #pf THEN
        #i := #i + 1;
    END_IF;
    IF #i >= #Daten.Verz THEN
        #Quitt_PLC[#"Melde-ID" - 1] := FALSE;
        #StoerDB[#"Melde-ID" - 1] := True;
        #Daten.Status.Stoerung := True;
        #Daten.Status.Stoerung_unquittiert := True;
    END_IF;
ELSE
    #i := 0;
END_IF;

IF NOT #Stoereingang AND (NOT #Daten.Status.Stoerung_unquittiert OR NOT #Quitt_HMI_Array[#"Melde-ID"-1]) THEN
    #StoerDB[#"Melde-ID" - 1] := false;
    #Daten.Status.Stoerung := false;
    #Daten.Status.Stoerung_unquittiert := false;
END_IF;

IF  #Quitt_Ext THEN
    IF NOT #Stoereingang THEN
        #Daten.Status.Stoerung := false;
    END_IF;
    #Daten.Status.Stoerung_unquittiert := false;
    #Quitt_PLC[#"Melde-ID" - 1] := True;
END_IF;

Ist Dein Baustein ein FC oder FB, wie sind die Variablen und Übergabeparameter deklariert?

Harald
 
Kurz überflogen:
Wofür ist die Verarbeitung des Taktmerkers? Wofür ist das i?

PS: Warum schreibst Du diese logischen Verknüpfungen in SCL? KOP/FUP wäre viel weniger anfällig für logische Fehler und jeder könnte Deinen Code viel leichter verstehen ...

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
EinAusgaenge.JPG

Hier sieht man die Beschaltung des Bausteins.

der Baustein ist ein FB (sonst könnte er sich ja statisch gar nichts "merken").

Variablen sind einmal ein großer Melde DB der aus drei Array of Bool (0...1999) besteht (Trigger, PLC-Quitt, HMI-Quitt).

ein Taktmerker (CPU-Intern) ein Merker für externe Quittierung und halt 2 Eingänge.

Außerdem übergebe ich die Daten innerhalb meines FB's auf einen UDT den ich in der HMI auswerte.

Es wirkt halt so als würde er immer alle Stellen des Array's auf false setzen bei Bausteinaufruf oder einfach überschreiben wenn ich eine andere Stelle beschreibe.

Vielen Dank für die schnellen Antworten übrigens! :D

Grüße Schornie
 
Die Verarbeitung des Taktmerkers ist nur um ohne einen IEC-Timer zu verwenden eine Verzögerung zu realisieren das i sind quasi die Sekunden die ablaufen (bei Clock_1Hz).

Ich soll alle Standard-Bausteine in SCL halten, laut Kunde wäre zwar KOP/FUP in Ordnung aber Firmenintern haben wir uns auf SCL geeinigt, deswegen wär ich schon erpicht eine Lösung in SCL zu finden
kann doch nicht so schwer sein.

Ich bin kurz davor das ansprechen über die Melde-ID rauszunehmen und jedes mal den jeweiligen Platz im Array an den Baustein zu verschalten.
 
Moin,


Meinem Baustein Übergebe ich natürlich den Störeingang (+ Zustand separat), ein Array für die Meldetrigger (DB101.DBX0.0), ein Array für die Quittiervariablen der PLC (DB101.DBX250.0) und ein Array mit dem ich auch den Zustand der Quittiervariable der HMI sehen kann (DB101.DBX500.0). Zusätzlich eine Melde-ID (mitdessen Hilfe ich den jeweiligen Alarm in meinem Array anspreche) und einen externen Quittiereingang.
also ehrlich gesagt sehe ich in deinen Bildern nicht, dass du auch nur ein einziges Array übergibst. :confused:
Du übergibst laut Schnittstelle lediglich Bool-Variablen. Und die Variable Melde_DB.Trigger am Output ist bei beiden Calls die selbe?!:confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
aber gut...
wenn es sich um die Variable Melde_DB.Trigger handelt von der du glaubst das sie überschrieben wird und die eigentlich ein Array wäre, dann darf sie nicht als Output deklariert sein.
Um die gesetzten Bits der vorherigen Aufrufe zu erhalten, müsste die Variable Melde_DB.Trigger als In/Out übergeben werden -> die bereits gesetzten Bits gehen quasi in deinen Baustein rein (In), und werden um ggf. weitere Störungen ergänzt (Out).
 
Schnittstelle.JPGMelde DB.JPGAufruf.JPG

Hab im Eifer des Gefechts wohl die Schnittstelle meiner Alternative geschickt bei der ich die einzelnen Bits des Arrays verschalte (anders wärs schon angenehmer).
Hier nochmal die Schnittstelle des Bausteins an dem ich die Arrays übergebe.

Ich hab jetzt die Alternative auch ausprobiert -> funktioniert einwandfrei, also wenn ich die Trigger und die Quittierbits direkt übergebe und nicht die ganzen Arrays übergebe wird auch nichts überschrieben.

Aber ich verstehe einfach nicht was da falsch ist, sollte doch im Endeffekt genau das gleiche sein ob ich an der Schnittstelle z.B.: Melde_DB.HMI_Quitt[0] übergebe oder das ganze Array und dafür dann im Baustein auf das jeweilige Bit mit Quitt_HMI_Array[0] zugreife oder etwa nicht?!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab jetzt die Alternative auch ausprobiert -> funktioniert einwandfrei, also wenn ich die Trigger und die Quittierbits direkt übergebe und nicht die ganzen Arrays übergebe wird auch nichts überschrieben.

Aber ich verstehe einfach nicht was da falsch ist, sollte doch im Endeffekt genau das gleiche sein ob ich an der Schnittstelle z.B.: Melde_DB.HMI_Quitt[0] übergebe oder das ganze Array und dafür dann im Baustein auf das jeweilige Bit mit Quitt_HMI_Array[0] zugreife oder etwa nicht?!

Vielleicht würde es auch schon helfen, wenn du ALLE Array's via IN_OUT an den Baustein gekoppelt hättest ... versuch das doch noch mal ...

Gruß
Larry
 
Zurück
Oben