Abfangen von falscher Eingabe

Beckx-net

Level-1
Beiträge
132
Reaktionspunkte
18
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe gerade eine kleine S7 Blockade.
Ich habe einen FB mit 10 Boolsche IN-Variablen. Von diesen Inputs darf jeweils nur einer aktiv sein. Sobald mehr als zwei "1" sind, soll ein Error_bit gesetzt werden.
Nun will mir nix richtiges einfallen, wie ich dies mit wenig code effizient hinbekommen soll. Meine erste Idee, das mit einem XOR mit 10 Eingängen zu lösen, brachte leider keinen Erfolg ( Ausgang ist bei einer ungeraden Anzahl an geschalteten Eingängen leider auch immer "1")
Vielleicht weiß einer von euch ja weiter?

Danke
 
Hallo Beckx-net!

Mach Dir aus den 10Bit ein Word,

dann mit Sprungliste verteilen und alles was nicht passt -> letzter Eintrag -> Errorbit setzen BausteinEnde-

Es gibt sicher elegantere Lösungen, aber so kannst Du u.U gleich zwei Fliegen mit einer Klappe schlagen.

Gruß Thomas
 
Also wenn die Eingangsdatenbits im Wort vorliegen:

Code:
      L     #IN_WORD
      DTR   
      L     DW#16#7FFFFF
      UD    
      L     L#0
      <>D   
      =     #Fehler
Das Bit #Fehler ist immer dann gesetzt wenn mehr als ein Bit im Wort gesetzt ist.

Das wär doch mal eine schöne Prüfungsfrage. Wie und wieso funktioniert das? :rolleyes:
 
Zuletzt bearbeitet:
Also wenn die Eingangsdatenbits im Wort vorliegen:

Code:
      L     #IN_WORD
      DTR   
      L     DW#16#7FFFFF
      UD    
      L     L#0
      <>D   
      =     #Fehler
Das Bit #Fehler ist immer dann gesetzt wenn mehr als ein Bit im Wort gesetzt ist.

Das wär doch mal eine schöne Prüfungsfrage. Wie und wieso funktioniert das? :rolleyes:

Da wär ich von alleine auch nicht drauf gekommen, aber man kann das schon rausbekommen.

Die Auflösung gehört auch irgendwann mal dazu, also bring ich das mal, hoffentlich ein wenig verständlich.

Ansatz:
Eine 32Bit-Gleitpunktzahl nach IEEE754 besteht aus 1Bit Vorzeichen + 8Bit Exponent + 23 Bit Mantisse.

Formel: x = s*m*b^e

Vorzeichen s (fast ausnahmslos 1 Bit)
Basis b (bei normalisierten Gleitkommazahlen nach IEEE 754 ist b = 2)
Exponent e (r Bits), nicht zu verwechseln mit dem „biased exponent“ bzw. der Charakteristik
Mantisse m (p Bits), manchmal als Signifikant bezeichnet

23 Bit Mantisse => 2#0000_0000_0111_1111_1111_1111_1111_1111 oder DW#16#007FFFFF

Alle Zahlen, bei denen nur ein Bit gesetzt ist (1,2,4,8,16,32,...) haben eine "leere" Mantisse, denn diese Zahlen "stecken" sozusagen komplett im Exponenten, da b=2.

Schöne Übersicht zum Thema: http://de.wikipedia.org/wiki/IEEE_754
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe zuerst über den Zweierlogarithmus nachgedacht, und dabei kommt, wenn ein Bit gesetzt ist, immer eine ganze Zahl raus.
Um zu überprüfen ob hinter dem Komma eine null steht bin ich dann darauf gekommen, dass beim Real-Format ja der Exponent die Basis 2 hat, und man somit nur die letzten Bits abfragen muss.

Mit der Lösung lassen sich aber nur 23 Bits überprüfen, weil ab dann der Rundungsfehler auftritt.
Z.B. haben 16777216 (2^24) und 16777217 ((2^24) + 1) beide 23 Nullbits in der Mantisse.
 
Hier mal eine Variante ohne Umweg über Gleitpunktzahl:
Code:
      L     #IN_WORD
      PUSH
      +     -1
      UW
      U     <>0
      =     #Fehler   //true wenn mehr als 1 Bit gesetzt ist

... die auch für 32 Bit DWORD funktioniert:
Code:
      L     #IN_DWORD
      PUSH
      +     L#-1
      UD
      U     <>0
      =     #Fehler   //true wenn mehr als 1 Bit gesetzt ist

... und wenn man auf "genau 1 Bit gesetzt" abfragen will:
Code:
      L     #IN_DWORD
      PUSH
      UD
      U     ==0
      SPB   MNOT
      +     L#-1
      UD
      U     <>0
MNOT: NOT
      =     #Genau1   //true wenn genau 1 Bit gesetzt ist

Die Varianten beruhen zugegebenerweise auf einem schönen uralten Algorithmus, den nicht ich erfunden habe. ;)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und bei solch extremen Konstrukten bitte nen eindeutigen Kommentar dazu schreiben
Hmm, ausgerechnet bei DEM Beispiel wird ein einfacher Zeilenkommentar wohl nicht reichen - siehe #10.
Sowas packt man am besten in einen Baustein, betrachtet es als Black Box und vertraut darauf, daß es funktioniert.
Sicherheitshalber noch KNOW_HOW_PROTECT wie bei den Siemens-Bausteinen, dann glaubt das auch (fast) jeder.

Harald
 
Hmm, ausgerechnet bei DEM Beispiel wird ein einfacher Zeilenkommentar wohl nicht reichen - siehe #10.
Sowas packt man am besten in einen Baustein, betrachtet es als Black Box und vertraut darauf, daß es funktioniert.
Sicherheitshalber noch KNOW_HOW_PROTECT wie bei den Siemens-Bausteinen, dann glaubt das auch (fast) jeder.

Harald

Wobei es doch einer gewissen künstlerischen Kreativität bedarf, sich solch eine Lösung auszudenken. :rolleyes:


bike
 
Was sind das für Eingaben?
Warum ein Fehlerbit erzeugen?
Kannst Du bei der Eingabe nicht den Fehler vermeiden -> Tip: Umschalter!

Entweder über klassische SETZ / RÜCKSETZ-Bedingung oder über ein Wort. Jede Taste erhällt einen Wert, der einer 2'er Potenz entspricht:

Bei drücken der
Taste 1 = 2 hoch 0 = Bit 0 = Wert 1
Taste 2 = 2 hoch 1 = Bit 1 = Wert 2
Taste 3 = 2 hoch 3 = Bit 2 = Wert 4
...
(Nur Achtung Bit 0-7 sind bei einem Wort im 2. Byte, Bit 8-15 im 1.)

Jetzt können niemels 2 Werte aktiv sein und Du könntest mit dem angewählten Bit im Wort weiterarbeiten. Kleiner check des Wortes auf Wert 0 und Du weißt, ob überhaupt eine Taste angewählt wurde.

Diese Variante kann auch sehr gut in WinCCflex genutzt werden!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Was sind das für Eingaben?
Warum ein Fehlerbit erzeugen?
Kannst Du bei der Eingabe nicht den Fehler vermeiden -> Tip: Umschalter!
...
Hi MCerv,
eventuell ist Dir entgangen, daß die Treaderöffnung vor 2 Jahren war. Ich glaub' nicht, daß der TE noch nach 'ner Lösung sucht.

PN/DP hat heut' Nacht nur für Suchende mal eine andere Lösungsvariante mit ebensowenig notwendigem Code wie bei der Realzahlvariante hinzugefügt.
 
Zurück
Oben