Signal innerhalb Zeitfenster

JüKo

Level-2
Beiträge
108
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo an Alle,
Folgendes Problem:
Wenn innerhalb eines vorgegebenen Zeitfensters ein Sensor mehrmals detektiert, dann soll das Signal verarbeitet werden.
Ein Beispiel, ein Timer läüft 2 Sekunden, in dieser Zeit soll das Signal verarbeitet werden, wenn der Sensor in dieser Zeit mindestens 4x detektiert. Ist das Signal < 4, dann nicht.
Mein Problem ist nun, das ich immer die letzten 4 Signale anschauen muss und diese müssen innerhalb der 2 Sekunden sein. Wie mache ich das? Das Programm soll in ST erstellt werden.

Danke und freundliche Grüße,
Jürgen
 
Etwa so :
Du startest mit dem ersten Impuls einen Timer und gibst einen Zähler frei.
Ist der Timer abgelaufen wertest du den Zähler aus.
Hat er den gewünschten Wert dann setzt du z.B. einen Merker - sonst nicht. In jedem Fall löscht du nun den Zähler wieder ...

Anbieten würde es sich, dies in Form einer Schrittkette umzusetzen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry,
aber mit dieser Lösung würde ich bei dem ersten Impuls mit dem Timer starten und dann schauen ob der erste Impuls und die weiteren drei Impulse in meinem Zeitfenster sind oder nicht. Wenn dem nicht so ist dann starte ich neu. Ich hätte aber gerne, dass sobald die ersten 4 Signale innerhalb zwei Sekunden sind dann detektiert wird. Dazu müsste ich immer die letzten 4 Impulse betrachten.
Freundliche Grüße,
Jürgen
 
Ähm... ich will keinen Apfel sondern einen Apfel...

Ich sehe keinen Unterschied zwischen Deinen zwei Gegenüberstellungen. Du schaust beide Male auf 4 Impulse.

Grüße

Marcel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Array mit dem Zeitpunkt des Signaleintreffens füllen, bei Übertretung rausschieben und zwischendrin natürlich auswerten? Somit ist für jedes Signal die Erfassungszeit hinterlegt und durch das Schieben können immer die letzten 4 betrachtet werden.

Nur so ne Idee am Abend :D
 
Du kannst ein Array[0..3] OF TIME nehmen und umlaufend die Signal-Triggerzeiten reinschreiben. Bei jedem Trigger dann die älteste Zeit von der neuesten subtrahieren und mit der Sollzeitspanne vergleichen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
LOGO!-Variante ohne SCL, ohne TriggerZeiten, ohne Array, aber mit Ver(sch)wendung von 3 Timern:

4ImpulseIn2s.jpg

Anhang anzeigen 4ImpulseIn2s.lsc.pdf >>>===> nach dem Herunterladen '.pdf' entfernen!

PS:
Habe mir noch folgende Änderung überlegt:
An B006 die Verbindung an Eingang 3 und die Negation entfernen, dann kann T3 noch nachgetriggert werden, während er läuft.
Dadurch können keine EingangsImpulse mehr "ignoriert" werden.

Update. Vergleich der Restlaufzeiten der drei EinschaltVerzögerungen T1..T3 eingebaut, damit nur der/ein Timer mit der kürzesten Restlaufzeit (nach-)getriggert werden kann:

4ImpulseIn2s-2.jpg

Anhang anzeigen 4ImpulseIn2s-2.lsc.pdf >>>===> nach dem Herunterladen '.pdf' entfernen!
 
Zuletzt bearbeitet:
hi,
ich würde im gewünschten messtakt werte in ein array schreiben, also alle 0,5s für die 4 sekunden wären dann 8 messwerte ....
also ein array mit 8 werten anlegen, array mit einer schleife von 1-7 auf 2-8 kopieren und neuen messwert an die erste stelle schreiben ...
die messwerte im array kannst du dann recht konfortabel auswerten / bewerten ...
 
Was für Messwerte? Der TE erfasst laufend Trigger eines Binärsignals und möchte jederzeit wissen, ob die letzten 4 davon in einer Zeitspanne von 2s aufgetreten sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier einfach mal ein Beispiel, dient aber nur zur Veranschaulichung was passieren könnte, daher ausführlich statt kurz geschrieben, die Anpassung an CodeSys kann ich ned im Kopf, ist der falsche PC an ^^.

Code:
FUNCTION_BLOCK "Zeitfenster"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      Signal : Bool;
   END_VAR


   VAR_OUTPUT 
      Ausgabe : Bool;
   END_VAR


   VAR 
      Signalspeicher {InstructionName := 'DTL'; LibVersion := '1.0'} : Array[0..3] of DTL := [4(DTL#1970-01-01-00:00:00)];
      HM_FP_1 : Bool;
      retVal : Int;
      "Abstand 4 letzte Signale" : Time;
   END_VAR


   VAR CONSTANT 
      Startwert {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
   END_VAR




BEGIN
	IF #Signal AND NOT #HM_FP_1 THEN // Bei positiver Flanke
	    #Signalspeicher[0] := #Signalspeicher[1]; // Umkopieren beginnen (was normalerweise die Schleife macht)
	    #Signalspeicher[1] := #Signalspeicher[2];
	    #Signalspeicher[2] := #Signalspeicher[3]; // Umkopieren beenden
	    #retVal := RD_LOC_T(#Signalspeicher[3]); // Eintrag des aktuellen Ereignisses
	END_IF;
	#HM_FP_1 := #Signal; // Flankenmerker setzen
	
	#"Abstand 4 letzte Signale" := #Signalspeicher[3] - #Signalspeicher[0]; // Nur für Anzeige
	
	IF #Signalspeicher[0]<>#Startwert // einfache Auswertung damit sichergestellt wird das NUR eingetragene Werte zählen und kein Startwert
	    AND #Signalspeicher[1]<>#Startwert
	    AND #Signalspeicher[2]<>#Startwert
	    AND #Signalspeicher[3]<>#Startwert
	THEN
	    #Ausgabe := (#Signalspeicher[3] - #Signalspeicher[0] < T#2s); // Ausgabe
	ELSE
	    #Ausgabe := false;
	END_IF;
	
	    
END_FUNCTION_BLOCK

Im Grunde genommen wird hier pro positiver Flanke ein Array um 1 nach vorne (gen 0) verschoben, dann wird am Ende das neue Signal eingetragen. Dann wird einfach der neueste Eintrag vom ältesten abgezogen und geschaut ob er unter 2s liegt. Solange dieses Kriterium aktiv ist wird die Ausgabe auf TRUE gestellt. Damit nicht die Startwerte verglichen werden und ein TRUE ergeben ist das ganze in einer IF-Abfrage. Durch die Verschiebung werden automatisch immer die letzten 4 Signale miteinander verglichen.
 
Hier eine Umsetzung auf Codesysch.
Code:
FUNCTION_BLOCK fbl4TrigsInTimeRange
VAR_INPUT
    setTimeRange:TIME:=T#2S;    // Zeitbereich für letzte 4 Trigger 
    inpSignal:BOOL;    // Zu triggerndes Signal
    inpReset:BOOL;        // Reset
END_VAR
VAR_OUTPUT
    outTrigger:BOOL;    // Trigger Ausgang
    outInTime:BOOL;    // 4 letzte Trigger innerhalb des Zeitbereichs
END_VAR
VAR
    varTrigger:R_TRIG;    // Trigger FB
    varTimes:ARRAY[0..3] OF TIME;    // Triggerzeiten
    varIndex:USINT;    // Array Index
    var4Trigs:BOOL;    // Min. 4 Trigger erfasst 
END_VAR

IF inpReset THEN     // Reset, outInTime low bis 4 neue Trigger erfasst sind
    var4Trigs:=FALSE;   
    outInTime:=FALSE;
    varIndex:=0;
END_IF

varTrigger(                 // Eingangssignal triggern
    CLK:=inpSignal,
    Q=>outTrigger);

IF outTrigger THEN
    IF varIndex=3 THEN     // Vierter Trigger nach Start oder Reset
        var4Trigs:=TRUE;
    END_IF
    varTimes[varIndex]:=TIME();   // Zeit eintragen
    outInTime:=var4Trigs AND_THEN (varTimes[varIndex]-varTimes[(varIndex+1) AND 3])<=setTimeRange;   // Aktuelle mit ältester Zeit vergleichen
    varIndex:=(varIndex+1) AND 3;   // Nächster Index
END_IF
 
Zuletzt bearbeitet:
Zurück
Oben