Fehlernummer aus mehreren Bytes erstellen

Freki

Level-1
Beiträge
29
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Morgen,
hocke nun schon seit letzter Woche vor einem recht simpel klingendem Problem das ich trotzdem nicht richtig gelöst bekomme.

Also: Bei uns gibt es einen Baustein der 8 externe Störungen überwacht und verwaltet. Diese werden als Byte in einem DB abgespeichert. Nun haben wir ein System das kein Panel hat, sondern nur 2 7-Segment Anzeigen. Somit muss aus mehreren Bytes die Fehlernummer erzeugt werden. Klingt ja soweit recht einfach.......

Ansätze bisher: ein FC mit 8 Byte an Eingängen, der jedes Bit mit einer Schleife überwacht und wenn True und am Schluss alle Zählerstände mit einem Offset zusammenzählt und aufaddiert. Also bei Byte 2 Zähler +8+alter Zählstand, usw.

Bin beim indirekten Programmieren leider kein Käpsele, da ich seit nem Lehrgang von über einem Jahr nichts mehr gemacht habe. Zu kompliziert sollte das alles natürlich auch nicht werden, da die Kollegen das auch noch verstehen können sollten.

Code für Schleife 1:

L #Error_Byte_1
T #Error_Byte
L P#0.0
T #Zeiger

L 0
T #Adresse

L 8
FLT1: T #Loop

L 1
L #Zaehler
+I
L #Zeiger
SRD 1

U >0
SPBN Bit1
L #Zeiger
L 1
+I

L #Loop
LOOP FLT1

Bit1: L #Zaehler
T #Error_Nr_BCD

Wenn ich das jedoch in PLC-Sim zum laufen bringen will geht das nicht.....

Hoffe mal dass mir da jemand weiterhelfen kann.

MfG
 
Also keine Ahnung was Du da machen willst, die Beschreibung ist nicht durchschaubar.
Welche Zählerstände? Welche "8"?

Na egal:
es gibt ein paar Dinge an Deinem Programm:
#Zaehler in einem FC wird irgendeinen Wert haben wenn Du den FC aufrufst.
#Zaehler wird nie beschrieben.
Was bringt das?
L 1
L #Zaehler
+I L
L #Zeiger
SRD 1

Fehlt da vielleicht ein
T #Zaehler nach "+I"?

Was ist #Zeiger für eine Variable?
L #Zeiger
L 1
+I
macht auch nicht viel.....

Also alles in allem glaube ich, dass das so nicht funktionieren kann. Bedenke, dass ein "+I" nur im Akku was addiert, aber nirgends speichert....

Gruß
Karl
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dass das nicht funktioniert habe ich auch bemerkt. Wenn dem nicht so wäre hätte ich keinen Grund meinen Code der Welt zu präsentieren wie toll der ist.

Nochmal zur Erklärung was das machen soll: Ein FB/ FC soll 8 Bytes als Eingänge haben, dass ich einfach die Fehler-Bytes die in einem anderen FB erzeugt werden da drauf legen kann. und aus denen 64Bits soll er entsprechende Fehlernummer erzeugen. Bit 1 = Fehlernummer 1, Bit 2 = Fehlernummer 2, usw.
Ist das klarer soweit?

Das mit dem fehlenden transfer habe ich auch bemerkt. Habe schon lange kein AWL gemacht, da bisher nur Sicherheits-SPS anstanden, und man da auch grundlegendes und FUP angewiesen ist.

Hab enun aber auch einen anderen lösungsansatz, der jedoch auch nicht zufriedenstellend funktionier.


L 0
T #Zaehler

L 10
T #adresse

L 4
FLT2: T #Loop2

L 16
FLT1: T #Loop
L DIW [#adresse]
UW W#16#1
T #Fehler
L #Fehler
U ==0
SPBN Bit0
L 1
L #Zaehler
+I
T #Zaehler

L DIW [#adresse]
SRW 1
T DIW [#adresse]

L #Loop
LOOP FLT1

L 2
L #adresse
+I
T #adresse

L #Loop2
LOOP FLT2


L 0
T #Zaehler

Bit0: L #Zaehler
T #Fehlernummer
 
Zuletzt bearbeitet:
Nein, ist nicht klar.
Die 64 Bits entsprechen also 64 Alarmen.
Gut.
Bit1= Nummer1
Bit2= Nummer2
.
.
.
Bit 64= Nummer64

Was soll ausgegeben werden wenn mehrere Bits "1" sind?
 
Ok, dann sind ja jetzt die Grundlagen geklärt.

Was ausgegeben werden woll ist eine gute Frage. Da ja in der Fehlerbildung eigentlich schon Folgefehler abgefangen sein sollten DÜRFTE (So die Theorie) eigentlich nur immer ein Fehler gleichzeitig auftreten, bzw wenn mehrere Fehler dann unabhängig voneinander. Dann muss man eben Problem 1 beheben und sich dann an Problem 2 machen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also, nun bin ich soweit: die erste Schleife funktioniert, bei der zweiten meldet PLCSim jedoch einen Systemfehler. Vielleicht weiß ja jemand warum.
L 0
T #Zaehler

L 10
T #adresse

L 4
FLT2: T #Loop2

L 15
FLT1: T #Loop
L DIW [#adresse]
UW W#16#1
T #Fehler
L #Fehler
U ==0
SPBN Bit0
L 1
L #Zaehler
+I
T #Zaehler

L DIW [#adresse]
SRW 1
T DIW [#adresse]

L #Loop
LOOP FLT1

L 2
L #adresse
+I
T #adresse

L #Loop2
LOOP FLT2

L 0
T #Zaehler

Bit0: L #Zaehler
T #Fehlernummer
 
Wenn nur 1 Bit eins sein kann, bietet sich da nicht Doppelwortweise ein logarithmus an?
LN (Doppelwort) / LN (2)

zB
L LDx //1024= Bit 11 (bei 1 beginnend)
DTR
LN
L 0,693147 //das ist der LN(2)
/R
RND
L 1 //wegen Bitbeginn bei 1
+I
T #Fehler

Vorher muss aber auf ungleich 0 abgefragt werden weil es einen LN (0) nicht gibt.
Wenn Du das 2x machst, also für jedes Doppelwort einmal und beim zweiten einfach 32 dazuzählst sollte das im großen und ganzen schon fertig sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn nur 1 Bit eins sein kann, bietet sich da nicht Doppelwortweise ein logarithmus an?
LN (Doppelwort) / LN (2)

Deswegen lese ich hier so gerne mit. Abundzu kommt ausser dem mitlerweile nervigen "Für/Wider TIA" ein wirklich interessanter Beitrag zustande...

Gruß.
 
Ok, das funktioniert soweit, aber bei 2 Fehlern hat er dann ndoch seine Probleme.
Werde es nach der anderen vorgeschlagenen Lösungen probieren. Trotzdem schon mal danke für die Hilfe, auf sowas wäre (und werde) ich nie (ge)kommen.
 
Zuletzt bearbeitet:
Ja weil Du vor DTR
L 0
schreibst
Dann steht genau das drinnen was Du nicht möchtest nämlich "0".
Drehs um:
L 0
L LD0
==I
SPB FLTE
DTR

abgesehen davon:
==D
muss es heissen!!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok, das funktioniert soweit, aber bei 2 Fehlern hat er dann ndoch seine Probleme.
Werde es nach der anderen vorgeschlagenen Lösungen probieren. Trotzdem schon mal danke für die Hilfe, auf sowas wäre (und werde) ich nie (ge)kommen.
OK meine Antwort #11 bezog sich auf Dein Originalposting.

Gut, wenn nun mehrere Bits "1" sein können, was soll denn dann ausgegeben werden?
Das ist ja eine andere Aufgabe.

Anleitung: Schleife von 1 bis 32 wo Du vor Beginn der Schleife eine 1 (DINT) in eine Variable lädst und das Fehlerdoppelwort mit UD #Variable ausmaskierst.
In der Schleife dann SLD 1 #Variable das MaskierBit weiterschieben.
Du müsstest am Baustein aber dann dementsprechend 32 Ausgangsbytes haben für jeden Fehlerkanal eines.
 
Aus Spass an der Freud mal ein Baustein:

Code:
FUNCTION_BLOCK FB 2
TITLE =
VERSION : 0.1

VAR_INPUT
  Fehlerbyte1 : BYTE ; 
  Fehlerbyte2 : BYTE ; 
  Fehlerbyte3 : BYTE ; 
  Fehlerbyte4 : BYTE ; 
  Zeit : TIMER ; 
END_VAR
VAR_OUTPUT
  Err_1 : INT ; 
  Err_2 : INT ; 
  Err_3 : INT ; 
  Err_4 : INT ; 
  Err_5 : INT ; 
  Err_6 : INT ; 
  Err_7 : INT ; 
  Err_8 : INT ; 
  Err_9 : INT ; 
  Err_10 : INT ; 
  Err_11 : INT ; 
  Err_12 : INT ; 
  Err_13 : INT ; 
  Err_14 : INT ; 
  Err_15 : INT ; 
  Err_16 : INT ; 
  Err_17 : INT ; 
  Err_18 : INT ; 
  Err_19 : INT ; 
  Err_20 : INT ; 
  Err_21 : INT ; 
  Err_22 : INT ; 
  Err_23 : INT ; 
  Err_24 : INT ; 
  Err_25 : INT ; 
  Err_26 : INT ; 
  Err_27 : INT ; 
  Err_28 : INT ; 
  Err_29 : INT ; 
  Err_30 : INT ; 
  Err_31 : INT ; 
  Err_32 : INT ; 
  Err_Akt : INT ; 
END_VAR
VAR
  Schleife : INT ; 
  FehlerDW : DINT ; 
  Fla1 : BOOL ; 
  NeueAnzeige : BOOL ; 
  Fehleranzahl : INT ; 
  AktAnzeige : INT ; 
END_VAR
VAR_TEMP
  Maskier : DWORD ; 
  ERG : DWORD ; 
  Null : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =Maskierbit
      L     1; 
      T     #Maskier; 

NETWORK
TITLE =Fehleranzahl reseten
//
//
      L     0; 
      T     #Fehleranzahl; 
NETWORK
TITLE =FehlerDoppelwort einlesen
      L     P##Fehlerbyte1; 
      LAR1  ; 
      L     B [AR1,P#3.0]; 
      SLD   24; 
      L     B [AR1,P#2.0]; 
      SLD   16; 
      OD    ; 
      L     B [AR1,P#1.0]; 
      SLD   8; 
      OD    ; 
      L     B [AR1,P#0.0]; 
      OD    ; 
      T     #FehlerDW; 
NETWORK
TITLE =Ausgänge ablöschen
      L     P##Err_1; 
      LAR1  ; 
      L     1; 
      T     #Schleife; 
ABL:  L     0; 
      T     W [AR1,P#0.0]; 
      +AR1  P#2.0; 
      L     #Schleife; 
      INC   1; 
      T     #Schleife; 
      L     33; 
      <>I   ; 
      SPB   ABL; 
 
NETWORK
TITLE =Fehlercode generieren
      L     P##Err_1; 
      LAR1  ; 
      L     1; 
      T     #Schleife; 
NEXT: L     #FehlerDW; 
      L     #Maskier; 
      UD    ; 
      T     #ERG; 
      L     0; 
      ==D   ; 
      =     #Null; 
      L     0; 
      U     #Null; 
      SPB   M1; 
      L     #Schleife; 
M1:   T     W [AR1,P#0.0]; 
      U     #Null; 
      SPB   M2; 
      +AR1  P#2.0; 
      L     #Fehleranzahl; 
      INC   1; 
      T     #Fehleranzahl; 
M2:   L     #Maskier; 
      SLD   1; 
      T     #Maskier; 
      L     #Schleife; 
      INC   1; 
      T     #Schleife; 
      L     33; 
      <>I   ; 
      SPB   NEXT; 
 
NETWORK
TITLE =Fehlerwert Anzeige umschalten
      L     P##Err_1; 
      LAR1  ; 
      U     #Zeit; 
      FP    #Fla1; 
      =     #NeueAnzeige; 
      L     S5T#3S; 
      UN    #Zeit; 
      SE    #Zeit; 
      UN    #NeueAnzeige; 
      SPB   M3; 
      L     #AktAnzeige; 
      INC   1; 
      T     #AktAnzeige; 
      L     #Fehleranzahl; 
      <I    ; 
      SPB   M3; 
      L     0; 
      T     #AktAnzeige; 
M3:   L     #AktAnzeige; 
      SLD   4; 
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      T     #Err_Akt; 
 
END_FUNCTION_BLOCK

Der gibt in Abhängigkeit der Eingangsbytes 1 bis 4 an den Ausgängen Err_1 bis Err_32 die Fehlercodes der Reihenfolge nach aus.
Zusätzlich gibt es einen Ausgang Err_Akt der alle anstehenden Alarme alle 3 Sekunden umschaltet.

Wenn man mehr als 32 Alarme hat könnte man den Baustein noch um einen Offseteingang erweitern.....
Viel Spass.
 
Danke schon mal für den Baustein!!! Ist gut gemacht. Will den nur noch anpassen dass der baustein die Fehler auf einen Trigger Impuls nacheinander ausgibt, so dass man zB das ankündigen einer neuen Fehlerschleife über 5 Blinkimpule zb anzeigen kann. Also 5 Impulse, dann der Fehlerdurchlauf 1x, dann wieder 5 Impulse, Fehler wieder 1x, usw. Wobei der Impuls zum triggern, sowie die anzeige der zahl 88 (= alle 7 Segmente) extern gebildet wird.

Code:
      L     P##Err_1
      LAR1  
      U     #Anzeigen
      FP    #Fla1
      S     #NeueAnzeige

      UN    #NeueAnzeige
      BEB   

      L     #Zaehler
      INC   1
      T     #Zaehler
      L     100
      L     #Zaehler
      >I    
      SPB   M3                          //M4
      L     0
      T     #Zaehler
      L     #AktAnzeige
      INC   1
      T     #AktAnzeige
      L     #Fehleranzahl
      <I    
      SPB   M3
      L     #AktAnzeige
      L     #Fehleranzahl
      ==I   
      R     #NeueAnzeige
      L     0
      T     #AktAnzeige
M3:   L     #AktAnzeige
      SLD   4
      +AR1  
      L     W [AR1,P#0.0]
      T     #Err_Akt

So habe ich das umgesetzt. Geht bestimmt auch schöner, aber hat so schon ne Weile gedauert.................
 
Zuletzt bearbeitet:
Zurück
Oben