Ereignisse mit einer Struktur aufzeichnen

bone666

Level-1
Beiträge
72
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Tag Zusammen,

ich versuche momentan Ereignisse mit Hilfe eines Arrays einer Struktur aufzeichnen zu lassen und diese in einer Tabelle darstellen zu lassen.
Code:
timestamp:STRING;
    inverter:STRING;
    report:STRING;
END_STRUCT
Wenn eine boolesche Variable TRUE wird, soll eben ein array[n] of struct mit den Werten gefüllt werden. Nun habe ich das Problem, wenn die Variable auf TRUE bleibt schreibt es mir alle 100ms das selbe Ereigniss in das Array. Ich möchte es jedoch nur einmal geschrieben haben, egal wie lange es andauert. Ich hoffe ihr versteht was ich möchte. Hat jemand einen Tipp für mich?

MfG

Bone
 
Hallo,

entweder du schaltest die Variable wieder auf FALSE wenn geschrieben wurde oder du verwendest einen Trigger (R_TRIG).
Der Trigger wertet sie steigende Flanke aus.

Grüße
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Hack,

die Variable kann ich nicht ausschalten, da ich sie als Input reinbekomme und solange z.b. ein Ereginis andauert, bekomme ich eben auch die Variable mit TRUE geliefert. Aber bleibt der Ausgang des Triggers nicht auch immer auf FALSE oder TRUE, solange sich der Eingang nicht ändert? Dann habe ich ja wieder das selbe Problem -.-
 
Ein Flankentrigger macht genau das, das sein Name vermuten lässt. Er zeigt dir an, ob ein Bit im vergleich zum letzten Zyklus von LOW nach HIGH bzw. von HIGH nach LOW gewechselt hat. Ändert sich das Bit nicht, bleibt der Triggerausgang auf FALSE.

Was du suchst ist der R_TRIG, also ein Trigger der nur ein TRUE ausgibt wenn das Eingangsbit von 0 auf 1 schaltet. In Hilfe (TwinCAT / Codesys) ist das auch nochmal erklärt.
 
ok, aber anscheinend bin ich zu blöd den R_TRIG zu nutzen -.-
Code:
test_rtrig:R_TRIG;
eingang:BOOL;
ausgang:BOOL;

und dann
Code:
test_rtrig(CLK:=eingang);
ausgang:=test_rtrig.Q;

nur ändert sich am Ausgang überhaupt nichts -.- wette es ist mal wieder eine Kleinigkeit, welche ich übersehe.

MfG

Bone
 
Hallo Bone,
wette es ist mal wieder eine Kleinigkeit, welche ich übersehe.
ja, Du übersiehst etwas, nämlich den Ausgang. ;)
Aber im Ernst, der Ausgang ist nur einen Zyklus auf TRUE und das bekommst Du in den seltensten Fällen wirklich mit, da die Anzeige "nur" ca. alle 200ms aktualisiert wird. Dein Code-Schnipsel ist auf jeden fall richtig. Zum Testen kannst Du ja hinter R_Trig eine IF-Abfrage machen in der Du eine Testvariable auf TRUE setzt.
 
Habe ein weiteres Problem/eine weitere Frage -.-

zunächst einmal mein Code
Code:
IF inverter1.bool_STS_error_SCU = TRUE THEN
    FB_R_TRIG(CLK:=inverter1.bool_STS_error_SCU);
    bool_report[1]:=FB_R_TRIG.Q;
        IF bool_report[1]= TRUE THEN
            report_collection[n].timestamp:=SYSTEMTIME_TO_STRING(FB_Systemtime.systemTime);//stri_timestamp;
            report_collection[n].inverter:='1';
            report_collection[n].report:='error: SCU';
            bool_report[1]:=FALSE;                    
            n:=n+1;            
        END_IF        
    END_IF
Jetzt schreibt er mir nur noch einmal dieses Ereignis in das Array. Das passt soweit, jedoch "resettet" sich der R_TRIG irgendwie nicht -.- CLK bleibt die ganze Zeit auf TRUE egal was ich mit der booleschen Eingangsvariable mache -.- Sorry falls ich mich etwas doof anstelle, aber habe bis jetzt nichts mit diesen Triggern angestellt.

Bone
 
Du musst den FB_R_TRIG vor die IF-Abfrage setzen, sonst wird er bei "inverter1.bool_STS_error_SCU = FALSE" nicht aufgerufen und kann also gar nicht mitkriegen,, dass die Variable wieder FALSE geworden ist.
 
Was auch logisch ist, schmeiß die IF-Anweisung weg und alles wird gut ;)
Noch kurz die Erklärung dazu. Dein Flankenbaustein wird nur aufgerufen wenn die besagte IF-Bedingung erfüllt ist, was bedeutet, dass er die Variable nur im TRUE Zustand sieht und somit, außer beim ersten Mal, nie eine positive Flanke hat und somit Q nie wieder TRUE wird.

Gruß

Oliver

Nachtrag: Sorry, doppelte Antwort, hatte übersehen das es schon eine zweite Seite bei diesem Thread gab.
 
Guten Morgen,

es funktioniert nun so wie ich es mir vorstelle, jedoch habe ich wahrscheinlich viel zu viel Code benutzt. Vielleicht hat ja jemand eine Idee wie ich es schlanker gestalten könnte.

Code:
FB_R_TRIG[1](CLK:=inverter1.bool_STS_error_SCU);
        IF inverter1.bool_STS_error_SCU = TRUE THEN    
        bool_report[1]:=FB_R_TRIG[1].Q;
            IF bool_report[1]= TRUE THEN
                report_collection[n].timestamp:=SYSTEMTIME_TO_STRING(FB_Systemtime.systemTime);//stri_timestamp;
                report_collection[n].inverter:='1';
                report_collection[n].report:='error: SCU';                                  
                n:=n+1;            
            END_IF        
        END_IF

Von diesen Blöcken habe ich noch 131 andere, also noch bis FB_R_TRIG[132]... ingesamt fast 1,5k Zeilen Code. Wahrscheinlich geht díes jedoch noch schmaler :D

MfG

Bone
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Soweit Du alles von FB_R_TRIG[1] bis FB_R_TRIG[132] auf einmal ausführst und das mit der Zykluszeit hinkommt, könntest Du das Ganze auch in einer FOR-Schleife ausführen, dann bräuchtest Du das Geraffel nur einmal und ersetzt die feste Zahl durch eine Variable.
Und dann kannst Du auch die Äußere IF-Anweisung weglassen, die macht, meiner Meinung nach, keinen Sinn.

Gruß

Oliver
 
Ich besetzte aber jeden FB_R_TRIG[n] mit einer anderen CLK Variablen. Also z.B. so
Code:
FB_R_TRIG[1](CLK:=inverter1.bool_STS_error_SCU);
..blabla..
FB_R_TRIG[1](CLK:=inverter1.bool_STS_error_output_overcurrent_peak);
..blabla..
FB_R_TRIG[3](CLK:=inverter1.bool_STS_error_output_overcurrent_rms);
usw.

Damit funktioniert das ja nicht. Oder? Also mit der FOR-Schleife?
 
Du könntest alle deine Fehler zu einem Fehler (z.B. ErrorGeneral) zusammenführen und diesen dann abfragen :D

Somit hast du das ganze 1x und alle Fehler werden abgefragt.

Edit: Also kurz gesagt so:

Code:
if error_1 or error_2 or error_3 ...... then 
error_general = true;
end_if

fals du die fehler nicht selber setzen und rücksetzten kannst sondern sie als Eingänge bekommst dann so und passt.

Code:
if error_1 or error_2 or error_3 ...... then 
error_general = true;
else
error_general = false;
end_if
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Eine generelle Fehlermeldung habe ich schon implementiert, ähnlich deinem Vorschlag. Ich will jedoch jeden Fehler auflisten, sodass man später gucken kann was, wann, wo aufgetreten ist.
 
Ich besetzte aber jeden FB_R_TRIG[n] mit einer anderen CLK Variablen. Also z.B. so
Code:
FB_R_TRIG[1](CLK:=inverter1.bool_STS_error_SCU);
..blabla..
FB_R_TRIG[1](CLK:=inverter1.bool_STS_error_output_overcurrent_peak);
..blabla..
FB_R_TRIG[3](CLK:=inverter1.bool_STS_error_output_overcurrent_rms);
usw.

Damit funktioniert das ja nicht. Oder? Also mit der FOR-Schleife?
Ganz so einfach sicher nicht, aber auch dafür gebe es eine Lösung. Wenn ich das richtig sehe hast Du mehrere Umrichter die jeweils mehrere Fehler schmeißen können. Soweit es pro Umrichter nicht zu viele Fehler sind und das Ganze wieder unübersichtlich wird könnte das Folgende funktionieren (Ob das jetzt schön ist mögen andere entscheiden):

1. Nicht mehr Inverter1, inverter2, usw. verwenden, sondern ein Array Inverter[1] - Inverter[n]
2. Das Trigger Array wird zweidimensional (Anzahl Umrichter, Anzahl Fehler/Umrichter)
3. Die For-Schleife läuft über die Anzahl der Umrichter und nicht die Anzahl der Fehler
4. Jeweiligen Trigger FB für jeden Fehler aufrufen mit FB_R_TRIG[FOR-Zähler, Fehlertypnummer]
5. Trigger auswerten und Fehlermeldung schreiben

Fertig!
Sollten es sehr viele Fehler pro Umrichter sein könnte man das auch noch über eine FOR-Schleife machen oder man macht wieder eine FOR-Schleife über alle Fehler und setzt in der Schleife einen Zähler.
 
Stimmt Oliver, es sind mehrere Umrichter, welche zum jetzigen Stand 33 verschiedene Fehler melden können. Ich muss gestehen, dass ich aus deinen Ausführungen noch nicht so schlau werde. Ich führe es mir jedoch mal zur Gemüte.
Sehe ich es richtig, dass meine Fehler dann im Grunde auch zu einem Array gewandelt werden müssen Fehler[1..n]?
Was meinst du mit Trigger Array?
 
Zurück
Oben