# Statusbits auswerten?



## McNugget (6 Oktober 2008)

Hallo allerseits.

Ich setze an einem Wago 750-841 Controller analoge Eingangsklemmen 4-20 mA (750-455)ein.

Zu diesen Klemmen heisst es in der DOKU:

Prozessabbild 
Die analoge Eingangsklemme 750-455 liefert je Kanal 16 Bit Messwerte und 
8 Statusbits.  
Der digitalisierte Messwert wird in einem Datenwort (16 Bit) als 
Eingangsbyte 0 (low) und Eingangsbyte 1 (high) in das Prozessabbild des 
Kopplers / Controllers ¸bertragen. 
Dieser Wert ist mit einer Auflˆsung von 12 Bit auf Bit B3 ... B14 abgebildet. 
In den zwei niederwertigen Bits (B0 und B1) sind Statusinformationen 
enthalten, die im Fehlerfall ausgewertet werden kˆnnen. Dabei sind im Falle 
eines Leitungsbruchs, einer Messbereichsunter- oder -¸berschreitung Bit B0 
und B1 = 1 gesetzt. 
Bit B2 ist nicht definiert und wird nicht ausgewertet. In der Tabelle ist dieses 
deshalb mit ëXë dargestellt. 



Nun möchte ich  Bit B0 und B1 auswerten um einen Fühlerbruch zu erkennen. Da das Signal ständig (wie bereits bei meinem Thema mit dem Glätten eines Signals) "pendelt" erscheinen ab und an beide Bits als TRUE.

Hierdurch kommt es zu Fehlalarmen.

Wie löse ich dieses Problem?

Sollte ich hier ein TON mit 1 Minute statt nur 1 Sekunde hinterschalten, um Fehlalarme zu vermeiden? Oder gibt es einen eleganteren/besseren Weg?



Folgendes habe ich bereits erstellt:

Deklaration:
FUNCTION_BLOCK S_Fehler
    VAR_IN_OUT
    IN: WORD;                (* input value*)

END_VAR
VAR_OUTPUT
    Error_S: BOOL; (*Sensorstoerung*)
END_VAR
VAR
    Verz:TON;
END_VAR


Anweisungsteil:

IF IN.00
AND IN.01
(*
AND IN1.13
AND IN1.12
AND IN1.11
AND IN1.10
AND IN1.09
AND IN1.08
AND IN1.07
AND IN1.06
AND IN1.05
AND IN1.04
AND IN1.03
AND IN1.02
AND IN1.01
AND IN1.00
*)
THEN

Verz(IN:=TRUE,PT:=t#1s);

Error_S :=Verz.Q;


END_IF






Vielen Dank schon mal jetzt.

McNugget


----------



## Eliza (6 Oktober 2008)

*sieht nicht gut aus*

Korrigiert mich wenn ich mich täusche, aber der 841 wertet die statusbits nicht aus. ich fürchte das wird nichts! hatte so ein ähnliches problem auch schon mal und kam nicht an die statusbits ran.
(siehe handbuch 750-841, S. 223 und S. 243)


----------



## McNugget (6 Oktober 2008)

Hallo Eliza,

hmm... Ich weiss nicht, welche Infos Du auf diesen Seiten meinst.

Im Handbuch auf Seite 259 wird lediglich davon gesprochen, dass es 4 mal 2 Bytes gibt. Dem steht doch nicht entgegen, dass ich einzelne Bits "von Hand" auswerten kann.. Oder??

McNugget


----------



## Eliza (6 Oktober 2008)

*Sorry!*

Fehler vom Amt. Erst richtig lesen, dann schreiben. 
Ich dachte du wolltest die Status- bzw Steuerbits auswerten.


----------



## McNugget (6 Oktober 2008)

Hmmm.. 

Vielleicht habe ich das falsch ausgedrückt:

Das möchte ich ja auch.

Aber eben nicht die Statusbits vom Controller zur Klemme (interne Buskommunikation), sondern die Statusbits des Datenbytes.

Gruss

McNugget


----------



## Eliza (6 Oktober 2008)

also meiner meinung nach müsste das so gehen.
eine minute kommt mir etwas lang vor.


----------



## McNugget (6 Oktober 2008)

OK, 
aber eine Sekunde ist definitiv zu kurz.

Die Frage ist ja, ob es normal ist, von AE-Klemmen so schwankende Werte zu erhalten. Im Feld sind Temperaturtransmitter mit geschirmten Leitungen (Schirm natürlich einseitig im Schaltschrnk aufgelegt) verbaut.

Die Minute mehr oder weniger wäre für eine Alarmierung nicht "kriegsentscheidend".

Gruss McNugget


P.S.: @Eliza:Wo in Delmenhorst bist Du eigentlich am werkeln?


----------



## M_o_t (8 Oktober 2008)

Hallo,

im Strukturierten Text die Timer nicht in einer If Bedingung laufen lassen.
Den Timer ausserhalb der if Bedingung schreiben oder

Verz(IN:=(in00 And In01),PT:=t#1s);

dann sollt 1s ausreichen

Gruß
Silke


----------



## McNugget (8 Oktober 2008)

@M_o_t: Danke, kannst Du mir erklären, warum? Ich bin im ST noch nicht besonders mit Basics beschlagen. Was ändert es, wenn ich den Timer aus der Schleife nehme?

Wie würde die Anweisung dann aussehen?

Wobei natürlich Deine Anweisung auch elegant ist. Wusste noch gar nicht, dass ich auch beim Belegen von bausteineingängen logische Verküfungen integrieren kann.

Gruss

McNugget


----------



## Cerberus (8 Oktober 2008)

Wenn du deinen Timer aus der Schleife raus nimmst, kannst du dir die Schleife sparen. Gleichzeitig kannst du die Q-Zuweisung auch im Timer machen. Du hast dann einfach nur noch folgende Anweisung:

```
Verz(IN:= (IN.00 and IN.01), PT:= t#1s, Q=> Error_S);
```
 
Allerdings musst du hierbei beachten, dass während der kompletten Sekunde die Eingänge IN.00 und IN.01 TRUE sein. Ansonsten fängt der Timer wieder bei 0 an zu zählen.

Wenn die zwei Eingänge nur kurz TRUE sein sollen und der Timer trotzdem bis zu Sekunde zählen soll, dann probiers doch wie folgt:

```
VAR
hilf: BOOL := FALSE;
END_VAR
 
 
if IN.00 and IN.01 then
     hilf := TRUE;
END_IF
 
if hilf then
     Verz(IN:= TRUE, PT:= t#1s, Q=> Error_S);
END_IF
 
if Verz.Q then
     Verz(IN:= FALSE, PT:= t#1s, Q=> Error_S);
     hilf := FALSE;
END_IF
```


----------



## McNugget (8 Oktober 2008)

Danke Cerberus. 

Die erste Anweisung passt schon sehr gut auf meine Anforderung. Aber auch 

Dein Ansatz ist interessant, dass man also quasi für 1s eine Meldung bekommt, dass was mit den Sensoren ist/war.

Aber wie habe ich das zu verstehen:

"im Strukturierten Text die Timer nicht in einer If Bedingung laufen lassen."

Warum darf man das nicht? (geht nur um mein Verständnis)

Gruss

McNugget


----------



## Cerberus (8 Oktober 2008)

Grundsätzlich kannst du deine Timer schon in einer If-Schleife ablaufen lassen. Habe ich in der zweiten Variante ja auch getan. Aber dann musst du sicherstellen, dass auch in die If-Schleife verzweigt wird solange der Timer läuft.
Gerade wenn du irgendwelche Eingänge als Bedingung der If-Schleife hast, besteht die Gefahr, dass dein Timer zum Beispiel bereits eine halbe Sekunde läuft und sich dann plötzlich die Eingänge ändern. Dann wird nicht mehr die If-Schleife durchlaufen und dein Timer bleibt stehen. Du wunderst dich wieso und kannst evtl. keinen Fehler erkennen. Blöder Fehler. Einer der Sorte, nach dem man tagelang ohne Erfolg sucht.


----------



## McNugget (8 Oktober 2008)

Aber das wäre doch das, was ich will. Nur wenn der Fehler länger als 1s ansteht, will ich auch die Meldung erhalten.
Ansonsten soll der Timer sich wieder löschen.

Das Problem, das hierbei besteht, ist natürlich, dass ich, wenn der Senseor in der Nähe des Fehlerbereiches "pendelt" keine Meldung bekomme.

Andererseits bekomme ich nicht mit, wenn der Sensor lamngsam "stirbt".

Die zweite Variante von Dir (Cerberus) könnte ich also in Verbindung mit einem Zähler verwenden, um zu überprüfen, ob der Sensor mehr als x-mal in einer Minute "Ausreisser" hatte.

Damit liesse sich eine Warnmeldung: "Sensor überprüfen" auslösen, oder?

Zur vorbeugenden Wartung quasi?

Gruss

McNugget


----------



## Cerberus (8 Oktober 2008)

McNugget schrieb:


> Aber das wäre doch das, was ich will. Nur wenn der Fehler länger als 1s ansteht, will ich auch die Meldung erhalten.
> Ansonsten soll der Timer sich wieder löschen.


 
Genau den Fall deckt die erste Variante ab, richtig!




McNugget schrieb:


> Die zweite Variante von Dir (Cerberus) könnte ich also in Verbindung mit einem Zähler verwenden, um zu überprüfen, ob der Sensor mehr als x-mal in einer Minute "Ausreisser" hatte.
> 
> Damit liesse sich eine Warnmeldung: "Sensor überprüfen" auslösen, oder?


 
Ja könntest du! Dazu müsstest du nur in der letzten If-Schleife (mit der Bedingung "Verz.Q") deine Zählvariable hochzählen und in einer neuen Schleife abfragen, ob deine Zählvariable schon den Wert x hat. In dieser könntest du dann deine Warnung ausgeben.


----------



## drfunfrock (8 Oktober 2008)

McNugget schrieb:


> "im Strukturierten Text die Timer nicht in einer If Bedingung laufen lassen."
> 
> Warum darf man das nicht? (geht nur um mein Verständnis)
> 
> ...



Weil der Timer nur dann auswertet, wenn der FB ausgeführt wird. Das bedeutet, dass du eine Änderung des Ausgangsignals bekommst, wenn der FB so betrieben wird: 


```
timer(<evtl. parameter>);
```

Wenn du den hingegen so ansprichst


```
timer.IN := TRUE;
```

wird der Code im FB nicht ausgeführt. Ich ziehe es der Übersichtlichkeit wegen vor, solche FBs immer auszuführen, daher nicht in einer IF-Anweisung zu verstecken. Du brauchst natürlich auch ein paar CPU-Zyklen mehr, aber auf einem PC fällt das kaum auf. Beispiel: 


```
VAR
  timer : TON;
EN_VAR

timer(PT:=T#1s);

IF <Bedingung> THEN
 timer.IN := TRUE; 
ELSE 
 timer.IN := ,,,,
END_IF;
```


----------



## M_o_t (8 Oktober 2008)

Hallo,

ich hatte eben auch mal einen Timer in der If Bedingung drin. Hat das erste mal auch super funktioniert. Aber wenn ich zum zweiten mal in die If Bedingung gekommen bin war der Timer schon abgelaufen (Keine Änderung am Timer Eingang). 


Also entweder Timer wieder sauber löschen oder eben erst gar nicht in der If Bedingung laufen lassen, sonder einfach nur die Startbedingung für den Timer schreiben.

Gruß
Silke


----------



## Cerberus (9 Oktober 2008)

M_o_t schrieb:


> Hallo,
> 
> ich hatte eben auch mal einen Timer in der If Bedingung drin. Hat das erste mal auch super funktioniert. Aber wenn ich zum zweiten mal in die If Bedingung gekommen bin war der Timer schon abgelaufen (Keine Änderung am Timer Eingang).


 
Lag wahrscheinlich daran, dass der Timer nicht zurückgesetzt wurde.


----------



## Andy :-) (26 Oktober 2008)

McNugget schrieb:


> Hallo allerseits.
> 
> Ich setze an einem Wago 750-841 Controller analoge Eingangsklemmen 4-20 mA (750-455)ein.
> 
> McNugget




Hi,

ich verwende zwar meist die 750-492, die Auswertung ist aber gleich...

Meine Lösung:

FUNCTION Skaliere_492_INT2 :INT
VAR_INPUT
    wEingang :WORD;
    iMin        :INT ;
    iMax       :INT ;
END_VAR
VAR_IN_OUT
    xKurzschluss    :BOOL;    
    xDrahtbruch    :BOOL;
END_VAR

CODE>>
xKurzschluss    := wEingang.0 AND NOT wEingang.1;
xDrahtbruch     := wEingang.0 AND wEingang.1;

Wert      := WORD_TO_REAL ( SHR(wEingang , 2) );
Weite     := iMax - iMin ;

Skaliere_492_INT2 := REAL_TO_INT(iMin + (Wert * Weite / REAL#8192));


Auch ich habe/hatte extreme Probleme mit springenden Werten aus der Busklemme. Bei mir lag es am Schaltnetzteil - nur mit massig Ferrigringen um die Ausgangsleitungen und X-Kondensator zwischen 0Volt und Erde ist der Wert stabil gewesen... 
War das erste Mal, seit ich mit CoDeSys und Wago zutun hatte, das ich mir meine S7-Baugruppen zurück gewünscht hatte  
	

	
	
		
		

		
			






mfg
Andy


----------



## McNugget (27 Oktober 2008)

Vielen Dank, Andy.




Andy :-) schrieb:


> Auch ich habe/hatte extreme Probleme mit springenden Werten aus der Busklemme. Bei mir lag es am Schaltnetzteil - nur mit massig Ferrigringen um die Ausgangsleitungen und X-Kondensator zwischen 0Volt und Erde ist der Wert stabil gewesen...




Bedeutet das, dass wenn ich ein besseres Netzteil einsetze, diese "Schwingerei" aufhört/weniger wird???

Aktuell setze ich das WAGO-Hutschienen-Netzteil (aus dem Starter-Set) ein. 

Welches Netztwil würde sich denn empfehlen?? Murrelektronik??

Du meinst Ferritringe um die Netzteil-Ausgangsleitungen, oder?
Was für Kondensatoren hast Du konkret eingesetzt?

Meine Messleitungen sind geschirmt.

Gruss

McNugget


----------



## Andy :-) (28 Oktober 2008)

Hallo Mc Nugget,

das Wago-Netzteil soll die Schwinger (wie meines auch >> Meanwell) nur unter geringer Belastung (<30%) haben. naja - konnte ich bis jetzt noch nicht testen. 
Im Akku-Betrieb (unsere Anlagen haben eine Notstromversorgung) sind die Messwerte über die Klemmen sauber...

Die Ferritringe habe ich Ausgangsseitig 2x durchgezogen. X-Kondensatoren 470 mF von Conrad zwischen 0 und Erde kurz vor der Steuerung...
Meine Leitungen sind auch alle einseitig geschirmt. Ich vermute eher, das die Eingangsfilter an den Stromklemmen von Wago zu klein oder falsch dimensioniert sind.

Bin noch an einer abschliessenden Lösung dran, zumal eine für uns wichtige ISO für Spannungsversorgungen ende des Jahres ausläuft und dann härtere Anforderungen an die Quallität des Netzteiles gestellt werden.


mfg
Andy


----------

