# Ausreisser erkennen.



## McNugget (6 November 2009)

Moin allerseits.

Wie würdet Ihr es machen?

Es kommen kontinuierlich Pulse über einen digitalen Einagang in gleichem zeitlichen Abstand.

Ab und an kommt ein Puls genau dazwischen.

Wie finde ich dieses Ereignis, so dass nur bei diesem Puls mit sozusagen halber Pausenweite ein Zähler angesprochen werden kann?


Grus

McNugget


----------



## witkatz (6 November 2009)

Hi McNugget,

z.B. so

```
VAR
	bInTrig: BOOL;
	flTrig: R_TRIG;
	tpCountEnable: TP;
	Counter: CTU;
END_VAR
tpCountEnable(
	IN:= flTrig.Q,
	PT:= t#900ms); (* period time - tolerance *)
flTrig(CLK:= bInTrig);
Counter(CU:= tpCountEnable.Q AND  flTrig.Q);
```
Gruß,
witkatz


----------



## Mobi (6 November 2009)

Könnte es passieren, dass der Zähler schon bei einem regulären Puls hochzählt. Da ja bei der Flankenerkennung einer steigenden Flanke der TP schon gestartet wird und das Signal von der Flankenerkennung auch ansteht. Eventuell müsste man den R_TRIG durch einen F_TRIG ersetzen und die Zeit dann anpassen auf die Pausendauer. Oder irre ich mich da?


----------



## witkatz (7 November 2009)

Hallo Mobi,

der Flankentrigger wird nach dem Timer aufgerufen, also kommt der Timer erst einen Zyklus später, da ist die erste Flanke schon weg. Erst folgende Flanken triggern den Counter, solange der Timer aktiv ist. Aber du hast recht es - ist zwar kurz und tricky aber nicht selbsterklärend. 
Mein nächster Lösungsansatz ist hoffentlich lesbarer und verständlicher:



```
VAR
    tpCountEnable1: TP;
    tonCountEnable2: TON;
    Counter: CTU;
    flTrig: R_TRIG;
END_VAR
VAR_INPUT
    bInTrig: BOOL;
    tPeriod: TIME:= t#1s;
END_VAR

flTrig(CLK:= bInTrig);
tpCountEnable1(
    IN:= flTrig.Q,
    PT:= tPeriod*2/3);
tonCountEnable2(
    IN:=  tpCountEnable1.Q,
    PT:= tPeriod/3);
Counter(
    CU:= flTrig.Q
    AND tpCountEnable1.Q
    AND tonCountEnable2.Q);
```
@McNugget: ist das für dich brauchbar?

Gruß
witkatz


----------



## Mobi (7 November 2009)

Das müsste eigentlich klappen, aber es reicht doch wenn du bei dem AND, nur den Ausgang vom TON nimmst, das müsste doch reichen.

Also wird der Puls detektiert, wenn er im mittleren Drittel der Pause kommt.


----------



## McNugget (8 November 2009)

@Witkatz: Ich werde es morgen mal in meine Steuerung spielen und schauen, ob es das tut, was ich davon erwarte.

Vielen Dank für den Code.

Der erste Code war echt tricky, aber wer kann, der kann...

Bin leider bisher noch nicht in Ruhe dazu gekommen, das zu testen..


Eine Frage noch: ist der Code fehlertolerant gegenüber Geschwindigkeitsschwankungen (wenn z. B. die Geschwindigkeit über Rampe hoch oder heruntergeregelt wird)?

Nochmals vielen lieben Dank

McNugget


----------



## Mobi (8 November 2009)

Du meinst tolerant wenn sich die Periodendauer ändert? Ja, aber nur solange sich der Puls der unregelmäßig kommt, sich in dem vorgegebenen Zeitfenster hält.


----------



## McNugget (9 November 2009)

Super. Das scheint so zu klappen.

Klasse.. Vielen Dank.

Ich rufe diesen Baustein nun mehrfach auf und er scheint so weit ganz sauber durchzuzählen.


Noch eine weiterführende Frage:

Ich habe zwei Signale die sich etwas zeitverzögert überlappen. 

Siehe Anhang.
Pulse.jpg


Wie kann ich kontrollieren, ob die vier Stati A, B, C, D in richtiger Reihenfolge eingehen?

Im Normallfall müsste ich ja immer ABCDABCDABCD usw. erhalten,


Aber wenn z. B. Sensor S1 verschmutzt ist und daher Dauersignal gibt, müsste die Folge ja BCBCBCBCBCBCB werden.


Es kann im Prinzip ja nur folgende abweichenden Fälle geben: 
S1 immer High-Signal, owohl S2 einen Puls gibt, 
S1 immer Low-Signal, owohl S2 einen Puls gibt, 
S2 immer High-Signal, owohl S1 einen Puls gibt, 
S1 immer Low-Signal, owohl S2 einen Puls gibt, 
Reihenfolge DCBA (Anlage läuft rückwärts),
dauerhaftes Low-Signal von beiden Sensoren, obwohl die Anlage (durch einen weiteren Eingang) als laufend gilt,
dauerhaftes High-Signal von beiden Sensoren, obwohl die Anlage (durch einen weiteren Eingang) als laufend gilt.



Wie könnte man die verschiedenen Fehlermöglichkeiten (also alles was von der Folge ABCD abweicht) auswerten und pro möglichem Fehler Zähler hochzählen lassen?



Gruss

McNugget


----------



## witkatz (9 November 2009)

Das ist im Prinzip ein Quadratur Encoder. Dafür gibt es in der Oscat den Baustein INC_DEC, nur ohne explizite Fehlerdiagnose. Man kann über die DIR und CNT die Richtung und Geschwindigkeit überwachen.

Gruß,
witkatz


----------



## McNugget (9 November 2009)

Danke. Den schaue ich mir mal an.

McNugget


----------



## McNugget (9 November 2009)

Hallo Witkatz. Ich habe ihn mir angeschaut.

Wie müsste ich den modifizieren um die möglichen Fehler gemeldet zu bekommen?

Wie kann ich die Folgerichtigkeit der Phasen abfragen?

Setzt man da in den Phasen Flags, die man später wieder als String rausgibt?


Zudem hat dieser Baustein doch das Problem, dass wenn ich das Programm starte und gerade die Phasen B, C oder D anstehen, ich keinen sauberen Wert erhalte, der durch 4 teilbar wäre, oder?

Zudem wertet der Baustein Flanken aus und nicht die Zustände der beiden Eingangssignale.

In meinem Fall /bei meiner Problemstellung müsste ich doch eine Art "Schrittabfrage" haben, oder?

Bin da etwas planlos..

McNugget


----------



## witkatz (10 November 2009)

Hallo McNugget,

INC_DEC erkennt die Richtung. Wenn die Reihenfolge der Signale umkehrt - toggelt der Ausgang DIR und man könnte einen Fehler signalisieren.

Deine komplexe Fehlererkennung läuft nach meiner Meinung auf Mustererkennung hinaus. Der Ansatz mit den Buchstaben ist nicht schlecht, aber String-Bearbeitung ist langsam. Ich würde es auf binär-Ebene lösen, ansatzweise so:

```
FUNCTION_BLOCK FB_EncoderWatchdog
VAR
    Status: BYTE;
    Status_1: BYTE;
    Status_Muster: BYTE;
END_VAR
VAR_INPUT
    bAnlageInRun: BOOL;
    bReset: BOOL;
    S1: BOOL;
    S2: BOOL;
END_VAR
VAR_OUTPUT
    bErr: BOOL;
END_VAR

Status.0:= S1;
Status.1:= S2;
IF Status <> Status_1 THEN
    Status_1:= Status;
    Status_Muster:= SHL(Status_Muster, 2) OR Status;
END_IF
CASE Status_Muster OF
2#01_11_10_00, 2#11_10_00_01, 2#10_00_01_11, 2#00_01_11_10:
    IF bReset THEN bErr:= FALSE; END_IF
ELSE
    IF bAnlageInRun THEN bErr:= TRUE; END_IF
END_CASE
```
Gruß,
witkatz


----------



## McNugget (10 November 2009)

Hallo Witkatz.

Vielen Dank, dass Du es aufgegriffen hast. Kann es heute leider nicht mehr in die Steuerung spielen um zu testen, aber werde morgen mal sehen, was es tut.

So weit ich es jetzt sehe, gibt der code aber lediglich aus, dass ein Fehler vorliegt, nicht welcher.

Für meine Zwecke wäre es sinnvoll, für jeden Fehler einen dedizierten Boolschen Ausgang zu schalten, um
a) einen Zähler pro Fehler anzusprechen
b) genau herauszufinden beim wievielen Puls der Fehler aufgetreten ist.

Bei einem "Endlos-System" kann man auf diese Weise feststellen, ob etwas das den Puls auslöst in irgendeiner weise anders beschaffen ist.

Ich werde das morgen mal so weit testen.

Die Binär Lösung finde ich schon jetzt super, allein schon aus Performancegründen.

Schönen abend noch

McNugget


----------



## McNugget (24 November 2009)

@Witkatz: Der Code, um Ausreisser zu erkennen läuft super!

Habe ich nun ausgiebig getestet.

Vielen Dank noch mal dafür.


Zu dem Encoder_Watchdog:

Aktuell kommen für die 4 Phasen, vier Dezimalzahlen. 
Aber wie überprüfe ich den korrekten Ablauf / die korrekte Abfolge?

Und wie kann ich für jeden möglichen abweichenden Abfolgentyp einen Counter zählen lassen?

Gruss

McNugget


----------



## McNugget (25 November 2009)

Hat hierzu noch jemand eine Idee?


Gruss

McNugget


----------



## Cerberus (25 November 2009)

Nur mal zum Verständnis:

Du bekommst nacheinander 4 verschiedene Phasen. Und diese müssen einer genauen Reihenfolge entsprechen (z.B. Phase1 Phase4 Phase2 Phase3). Sobald aber eine andere Reihenfolge auftritt willst du einen entsprechenden boolschen Ausgang schalten?


----------



## McNugget (25 November 2009)

Genau. 

Allerdings Phase1, Phase2, Phase3, Phase4.
Dazu habe ich auf der ersten Seite dieses Threads eine Zeichung angehängt, die es erklären soll.

Ich möchte wissen, ob Sensor 1 Verschmutzt ist, oder ausgefallen.
das gleiche möchte ich zu Sensor 2 wissen.

Ausserdem möchte ich, wenn eines der möglichen Fehlerevents nur ein mal eintritt, wissen, bei dem wievielten Puls das passiert ist.

Es handelt sich dabei um eine Art Endloskette mit Mitnehmern. 

Diese werden immer wieder von Null hochgezählt. Der Nullpuls ist der in diesem Thread bezeichnete "Ausreisser". Da ich diesen nun finde, kann ich die Runden hochzählen.

Nun möchte ich noch bestimmen können, welcher Sensor eine Macke hat, oder welcher Mitnehmer von den Sensoren nicht korrekt gesehen wird (z.B. durch Verschleiss, oder abgerisse, oder verbogen etc.). Dann könnte ich für den Techniker eine Meldung ausgeben: "Mitnehmer 20 fehlt, bitte kontrollieren."




Gruss

McNugget


----------



## Larry Laffer (25 November 2009)

Hallo,
du beschreibst es doch schon ... dein Ablauf ist der eines Inkrementalgebers und dieser spiegelt sich in einem festen Ablauf (Schrittkette) wieder. Ich würde es also im Programm genauso abbilden : in der Schrittfolge muß nach Zustand "A" dann "B" kommen. Ist das nicht so und du erhälst irgendetwas anderes, dann ist der fehlende deine Ereignis ...

Gruß
LL


----------



## McNugget (25 November 2009)

Hallo Larry,

leider habe ich noch nicht den Fatz einer Ahnung, wie und in welcher Sprache ich eine Schrittkette definieren kann/muss, um mein Ziel zu erreichen.

Gruss


McNugget


----------



## Larry Laffer (25 November 2009)

... das könnte vielleich Q & D ungefähr so aussehen :
	
	



```
if Schritt = 0 and S1 then
   Schritt := 1 ;
elsif Schritt = 0 and S2 then
   Fehler := 1 ;
end_if ;
 
if Schritt = 1 and S2 then
   Schritt := 2 ;
elsif Schritt = 1 and not S1 then
   Fehler := 2 ;
end_if ;
 
if Schritt = 2 and not S1 then
   Schritt := 3 ;
elsif Schritt = 2 and not S2 then
   Fehler := 3 ;
end_if ;
 
if Schritt = 3 and not S2 then
   Schritt := 0 ;
elsif Schritt = 3 and S1 then
   Fehler := 4 ;
end_if ;
```
... da läßt sich aber bestimmt auch noch etwas mehr draus machen ... 

Gruß
LL


----------



## McNugget (26 November 2009)

Hallo Larry,

aus irgendwelchen Gründen kommt die Schrittkette nicht über die 2. Phase hinaus.

Der Code von Witkatz zeigt ja schon mal die vier Phasen an. Ich brächte jetzt ja nur noch eine Reihenfolgenüberwachung...

Bitte seht mir nach, wenn ich mich etwas "hakelig" ausdrücke. Habe das noch nie machen müssen und will lernen.. ;-)


Gruss

McNugget


----------



## Larry Laffer (26 November 2009)

... ist denn sicher gestellt, dass deine Steuerung immer alle Impulse sauber mitbekommt ? Hast du mal irgend etwas über Signalzeiten geschrieben ? 
Gruß
LL


----------



## McNugget (26 November 2009)

Hallo Larry, 

die High-Zeit der Pulse liegt zwischen 50 und 50 ms, die LOW-Zeit zwischen 100 und 200ms.

Der Task, in dem das bearbeitet wird, hat eine feste Zykluszeit von 5ms.

Maximal läuft der Task ca 3-4 Skeunden.

Normalerweise nur eine halbe ms.

Gruss

McNugget


----------



## Larry Laffer (26 November 2009)

OK ... 
bekommst du denn den Fehler gesetzt ?
An der Stelle bliebe zur Zeit meine "Schrittkette" stehen ...

Gruß
LL


----------



## McNugget (27 November 2009)

Hallo Larry,

sorry, das sich erst jetzt antworten, die Anlage läuft nicht immer. Insofern muss ich immer warten, bis ich wieder schauen kann.

An dem Baustein sind die Fehler 1, 2 und 3 aktiv.

Wenn ich in den Baustein schaue, kann ich die Phasen von 0-3 erkennen.



Gruss

McNugget


----------



## Larry Laffer (27 November 2009)

Hallo,
das heißt dann für mich, dass deine Signalfolge wohl anscheinend nicht immer so ist, wie du es in dem Diagramm dargestellt hast.
In "meiner Schrittkette" frage ich für den Fehler ja immer das übernächste folgende Ereignis als Fehler-Bedingung ab. Im Augenblick weiß ich jetzt nicht so recht, wie ich dir da weiterhelfen kann ...

Gruß
LL


----------



## McNugget (27 November 2009)

Hmm.. Ich wunere mich nur, dass die alte Steuerung das kann.

Was haben die da bloss reinprogrammiert. Die kochen doch auch nur mit Wasser...

Zu Illustration habe ich mal einen Trace von vier verschiedenen Sensorbrücken reingesetzt.

Zwei Signale sind immer eine Messbrücke.

Die ersten beiden Signale sind noch die besten, da habe ich die Lichtschranken bereits optimiert.



Gruss

McNugget


----------



## Larry Laffer (27 November 2009)

... ich kann dir nicht so ganz folgen ... aber was ist denn mit Brücke 4 (Spur 7 + 8 ) - da fehlt doch schon mal einer ... und bei Brücke 3 (Spur 5 + 6) - die ist doch auch nicht wirklich Klasse ...

Gruß
LL


----------



## McNugget (27 November 2009)

Genau.

Das hast Du richtig erkannt.#

Ich habe bisher nur auf Sensorbrücke 1 (also Spur 1 und 2) getestet.

Es geht genau darum, die anderen Spuren so zu detektieren, dass ich genau die Aussagen treffen kann, wie Du sie mit dem Auge treffen konntest.

Ich möchte, dass die Steuerung mir etwas über die Qualität der Sensoren und der Signale gibt.

Anhand des Traces kann ich sehen, was mit den Sensoren los ist, aber ich kann ja nicht jedem User das komplette Codesys auf den Rechner installieren.

Für so etwas muss ich doch Warnungen und Meldungen generieren können.

Im Prinzip ist es immer so, dass die eine Spur (z.B. 2) die andere (z.B. 1) verifiziert.

Das alte System (das ich ablösen möchte) gibt bereits zu der vierten und dritten Brücke Meldungen aus. Und eben das möchte ich auch können.

Da die alte Steuerung noch läuft (aber wer weiss noch wie lange?), möchte ich die Funktionen so lange nachbilden, bis beide Steuerungen in etwa das gleiche tun, und dann möchte ich umstellen.

Angeblich ist es so gebaut, da die Anlage beim Stop noch mal etwas zurückdrehen könnte. So etwas habe ich ehrlich gesagt, in Jahren noch nie gesehen.

Zusätzlich ist auch noch eine Lochscheibe montiert, die zwischen zwei Pulsen einer Spur exakt 10 Pulse über einen Sensor geben soll.


Gruss

McNugget


----------



## McNugget (1 Dezember 2009)

@Larry: Hmmm, Nun habe ich Dich vollends "konfusioniert", wie??


Welche Ansätze gäbe es denn noch, mein Problem anzugehen? 



Gruss

McNugget


----------



## Larry Laffer (1 Dezember 2009)

"konfusiert ..." ?
Nein ... ich wußte nur auf deinen letzten Beitrag nichts sinnvolles zu erwidern. Ein weiterer (als der schon dargestellte) Ansatz fällt mir nicht ein. Möglicherweise möchtest du das Ganze ja etwas erweitern / modifizieren - also die Schrittkette läuft weiter und zählt nur die Fehler. Wie wäre das ...?

Gruß
LL


----------



## McNugget (1 Dezember 2009)

Hallo Larry, vielen Dank, dass Du noch mal antwortest.


Genau das wäre gut, weil dem alten System ähnlich.

Jetzt, wo Du so fragst, muss ich auch zugeben, dass ich Dich falsch verstanden habe.

Die Schrittkette soll im Prinzip nie stoppen, so lange die Anlage läuft, sondern bei Fehler einfach wieder im richtigen Moment einspringen.

Es muss fehlertolerant sein, da es ja im besten Falle als "Frühwarnsystem laufen soll.

Im alten System laufen vier Zähler pro Messbrücke.

Wenn dazu noch eine Info abgelegt wird, bei welchen Mitnehmernummern Fehler aufgetreten sind, lässt sich auch z. B. eine Häufung bei einem bestimmten Mitnehmer feststellen, so dass auch dieser als defekt festgestellt werden kann.

Wie könnte man diese Anforderungen un abdecken?

Gruss

McNugget


----------



## witkatz (3 Dezember 2009)

Hallo McNugget,

hast du meinen Ansatz mit Mustererkennung nicht weiterverfolgt?
Hier ein verfeinerter Algorithmus:

```
FUNCTION_BLOCK FB_EncoderWatchdog
VAR
    State: BYTE;
    State_1: BYTE;
    State_Pattern: BYTE;
    State_Pattern_ROL: BYTE;
    loop: INT;
    tonSignalsLow: TON;
    tonSignalsHigh: TON;
    tonTimeOut: TON;
END_VAR
VAR_INPUT
    bMachineInRun: BOOL;
    S1: BOOL;
    S2: BOOL;
END_VAR
VAR_OUTPUT
    bDirR: BOOL;
    bDirL: BOOL;
    bErrS1High: BOOL;
    bErrS1Low: BOOL;
    bErrS2High: BOOL;
    bErrS2Low: BOOL;
    bErrSignalsLow: BOOL;
    bErrSignalsHigh: BOOL;
    bErrTimeOut: BOOL;
    bPhaseError: BOOL;
END_VAR
VAR CONSTANT
    Pattern_DirR: BYTE:= 2#01_11_10_00;
    Pattern_DirL: BYTE:= 2#10_11_01_00;
    Pattern_ErrS1High: BYTE:= 2#01_11_01_11;
    Pattern_ErrS1Low: BYTE:= 2#10_00_10_00;
    Pattern_ErrS2High: BYTE:= 2#11_10_11_10;
    Pattern_ErrS2Low: BYTE:= 2#01_00_01_00;
END_VAR

State:= 0;
State.0:= S1;
State.1:= S2;
IF State <> State_1 THEN
    State_1:= State;
    State_Pattern:= SHL(State_Pattern, 2) OR State;
    tonTimeOut(IN:= FALSE);
END_IF
tonSignalsLow(IN:= bMachineInRun AND S1=FALSE AND S2=FALSE, PT:= t#1s, Q=> bErrSignalsLow);
tonSignalsHigh(IN:= bMachineInRun AND S1=TRUE AND S2=TRUE, PT:= t#1s, Q=> bErrSignalsHigh);
tonTimeOut(IN:= bMachineInRun, PT:= t#1s, Q=> bErrTimeOut);

bDirR:= FALSE; bDirL:= FALSE;bErrS1High:= FALSE;bErrS1Low:= FALSE;
bErrS2High:= FALSE;bErrS2Low:= FALSE;bPhaseError:= FALSE;
FOR loop:= 0 TO 6 BY 2 DO
    State_Pattern_ROL:= ROL(State_Pattern, loop);
    IF State_Pattern_ROL = Pattern_DirR THEN (*clockwise rotation*)
        bDirR:= bMachineInRun;
    ELSIF State_Pattern_ROL = Pattern_DirL THEN (*counterclockwise rotation*)
        bDirL:= bMachineInRun;
    ELSIF (State_Pattern_ROL AND 2#00111111) = (Pattern_ErrS1High AND 2#00111111)
        OR (State_Pattern_ROL AND 2#11111100) = (Pattern_ErrS1High AND 2#11111100)
    THEN
        bErrS1High:= bMachineInRun;
    ELSIF (State_Pattern_ROL AND 2#00111111) = (Pattern_ErrS1Low AND 2#00111111)
        OR (State_Pattern_ROL AND 2#11111100) = (Pattern_ErrS1Low AND 2#11111100)
    THEN
        bErrS1Low:= bMachineInRun;
    ELSIF (State_Pattern_ROL AND 2#00111111) = (Pattern_ErrS2High AND 2#00111111)
        OR (State_Pattern_ROL AND 2#11111100) = (Pattern_ErrS2High AND 2#11111100)
    THEN
        bErrS2High:= bMachineInRun;
    ELSIF (State_Pattern_ROL AND 2#00111111) = (Pattern_ErrS2Low AND 2#00111111)
        OR (State_Pattern_ROL AND 2#11111100) = (Pattern_ErrS2Low AND 2#11111100)
    THEN
        bErrS2Low:= bMachineInRun;
    END_IF
END_FOR
IF NOT bDirR AND NOT bDirL AND NOT bErrS1High AND NOT bErrS1Low AND NOT bErrS2High AND NOT bErrS2Low THEN
    bPhaseError:= bMachineInRun;
END_IF
```
Wie gefällt dir das?

Gruß,
witkatz


----------



## Larry Laffer (3 Dezember 2009)

McNugget schrieb:


> Wenn dazu noch eine Info abgelegt wird, bei welchen Mitnehmernummern Fehler aufgetreten sind, lässt sich auch z. B. eine Häufung bei einem bestimmten Mitnehmer feststellen, so dass auch dieser als defekt festgestellt werden kann.
> 
> Wie könnte man diese Anforderungen un abdecken?


 
Vielleicht dann in etwa so :
	
	



```
if Schritt = 0 and S1 then
   Schritt := 1 ;
elsif Schritt = 0 and S2 then
   Fehler_1 := Fehler_1 + 1 ;
   Schritt := 1 ;
end_if ;
 
if Schritt = 1 and S2 then
   Schritt := 2 ;
elsif Schritt = 1 and not S1 then
   Fehler_2 := Fehler_2 + 1 ;
   Schritt := 2 ;
end_if ;
 
if Schritt = 2 and not S1 then
   Schritt := 3 ;
elsif Schritt = 2 and not S2 then
   Fehler_3 := Fehler_3 + 1 ;
   Schritt := 3 ;
end_if ;
 
if Schritt = 3 and not S2 then
   Schritt := 0 ;
elsif Schritt = 3 and S1 then
   Fehler_4 := Fehler_4 + 1 ;
   Schritt := 0 ;
end_if ;
```


----------



## McNugget (3 Dezember 2009)

Puh.

Gleich zwei aufwendige Codeansätze in 5 Minuten. Bin platt..

Ich muss das erst mal testen. (bin echt baff....)

Tausend Dank.

Das ist soo cool.

Ich wäre echt froh, wenn ich mal Euch mal mit irgend was helfen könnte.


----------



## McNugget (7 Dezember 2009)

So, einige Tage sind vergangen, ich hatte ein wenig Zeit zu testen und da ich morgen in Urlaub fahre, möchte ich zumindest noch ein paar Rückmeldungen verteilen.

Letztendlich habe ich den Code von Witkatz verwendet, da er sehr schöne Diagnose- und Erweiterungsmöglichkeiten für mich bietet.

@Larry: Vielen Dank für den Code und die Mühen. Ich hoffe, ich schaffe es mal irgendwann zu einem Forentreffen zum persönlich Danke sagen. (auch für die anderen Threads in denen Du antwortest.) Dein Code ist für mich zum Erlernen von ST sehr wertvoll. Da kann ich jetzt immer mal wieder nachschlagen, wie man es machen könnte (speziell die Zähler).

@Witkatz: Vielen Dank für den extrem ausgefeilten Code.  Ich verstehe zwar bei weitem noch nicht alles, was Du dort mit den Bitpatterns machst, aber es funzt! Ich habe den Code mal um einige Zähler erweitert, um meine Bedingungen besser zu erfüllen.



Nun gibt es noch weitere Fragen (wahrscheinlich kann ich die Antworten darauf aber wegen meines Urlaubs erst Mitte nächster Woche umsetzen):

Wie kann ich Signalspitzen kleiner 15 ms rausfiltern?



Ich habe versucht, den Code von Witkatz aus Antwort #4 in diesem Thread in den Encoder-Code zu integrieren, da die beiden Bausteine ja mit den gleichen EIngangssignalen arbeiten. Leider mit mässigem Erfolg.

Der Mitnehmerzähler läuft nicht mehr komplett hoch sondern resettet sich immer wieder zwischendurch. 

Wie müsste der Code erweitert werden, um auch die in Beitrag #4 gelösten Bedingungen zu erfüllen?

Sollte ich heute oder Morgen vormittag nichts lesen, kann ich erst nach meinem Urlaub (Mitte nächster Woche) testen und reagieren. Also bitte keinen Stress.. ;-)

Zur Demonstration (der kläglichen Versuche) habe ich mal als Textdateien den Code angefügt, der gut läuft, und den, der mistig ist.

Sollten wir uns nicht mehr lesen wünsche ich Euch Mentoren einen schönen Urlaub von mir.. ;-)


----------



## Larry Laffer (7 Dezember 2009)

^Hallo,
egal, wann du es liest ... ob ich nächste Woche noch daran denke hier etwas zu schreiben will ich mal dahin gestellt sein lassen ... 
Also gleich erledigen ...

Wenn du deine Signal-Eingänge entsprellen willst, so geht das mit TON's (du hast so welche schon eingesetzt). Diese legst du von der Ansprechzeit auf den von dir gewünschten Wert (also >= 15 ms) und du wertest dann nicht mehr die Eingänge direkt aus sondern die Ausgänge der TON's.

Zu der Code-Kombination halte ich mich mal heraus (mir ist der Ciode für die Aufgabe ein bißchen zu kompliziert). Da wird dir aber Witkatz sicherlich weiter helfen.

Also dann ...
Gruß
LL


----------



## McNugget (7 Dezember 2009)

@Larry: Mann, da war ich mal wieder blind. Klar: TON. Die baue ich gleich heute noch mal ein.

Danke schön.


----------



## witkatz (14 Dezember 2009)

McNugget schrieb:


> Der Mitnehmerzähler läuft nicht mehr komplett hoch sondern resettet sich immer wieder zwischendurch.



Der Mitnehmerzähler resettet sich nicht selbst, sondern von der globalen Variablen reset, oder? Kann es sein, dass reset zwischendurch gesetzt wird?

Gruß,
witkatz


----------



## McNugget (14 Dezember 2009)

Hallo Witkatz,

bin gerade seit 6 Stunden vom Ski fahren zurück... War COOL! 

Nein, der reset wird nicht von aussen betätigt. Diesen nutze ich nur, um per Hand ans der Visu die Counter resetten zu können.

Irgend eine Bedingung wird im "erweiterten" Code nicht sauber umgesetzt, und so kommt es zu "ausserplanmässigen" Resets.


----------



## witkatz (16 Dezember 2009)

Wenn ich mir dein Code so anschaue:

```
VAR_INPUT
    reset:BOOL;
END_VAR
Counter(Reset:=reset, CU:=Rd_Puls);
```
dann kann der Counter nur durch die Input-Variable reset zurückgesetzt werden. Sonst zählt er nur hoch. Woher sollen die ausserplanmässigen Resets kommen? 

Ich vermute, dass du an die Bausteininstanz irgendein globales reset übergeben hast, das zwischendurch TRUE ist. Um sicher zu sein würde ich den lokalen reset in der Instanz tracen oder fangen, z.B.: IF reset THEN s_reset:= true; END_IF

Gruß,
witkatz


----------

