Massig Eingänge gleichzeitig abfragen - wie?

sk1rie

Level-1
Beiträge
108
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen!

Ich suche nach einer guten Strategie/Lösung, ca. 256 digitale Eingänge gleichzeitig abzufragen und darauf hin zu überprüfen, ob das 0-1-Muster dem entspricht, wie es sein soll.
Hinzu kommt, dass das Ganze für 200-500 verschiedene Zustände getan werden soll.

Hat sowas schonmal jemand gemacht und kann mir nen guten Tipp dazu geben, den Aufwand dafür möglichst gering zu halten?
 
ich vermute mal, dass das 0-1-Muster einer Information entspricht die einer Zahl oder einer Zeichenkette oder sonst irgendetwas entspricht, daher würde ich diese Innformation in einem Datenbaustein mit 200-500 Datenfächern ablegen und dann über einen Pointer aufrufen und mit den Eingängen vergleichen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Abfragen ist ja kein Problem. Das macht jede SPS mit (manche schaffen über 32 000 Eingänge). Vergleichen kannst du aber immer nur 32 auf einmal. Evtl mit Schleife arbeiten. Kommt natürlich auch drauf an, wie dein Vergleichsmuster aussieht
 
Dem Muster können eigentlich keine weiteren Informationen entnommen werden. Es kommt also später kein Wort oder Text raus, sondern tatsächlich nur der Zustand der Eingänge.
Alle erlaubten Zustände in einem DB abzulegen war eigentlich auch mein Gedanke, aber das Problem daran ist, dass jeder Zustand nur mit 256 Bit beschrieben werden kann.
Letztlich interessiert auch tatsächlich das Bitmuster. Wenn also auch nur ein einziger Eingang abweicht, so gilt es, herauszufinden, welcher es ist um dann weitere Schritte einzuleiten.
 
@Dr.M:
sehe ich aus so. Die Abfrage selbst stellt natürlich keine Herausforderung dar, sondern das möglichst effiziente Auswerten der ganzen Sache, um den Arbeitsaufwand zu minimieren.
Wie das Vergleichsmuster aussieht, ist derzeit leider noch nicht bekannt. Ich gehe davon aus, dass es chaotisch sein wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
FC...

INPUT:
xCompare : BOOL
iSourceStart : INT
iSourceLength : INT
iDBNumber : INT

OUTPUT:
xEqual : BOOL
iDeviation : DINT //ausgabe der ersten Abweichung im Pointerformat

FUNCTION
adressen vorbereiten
schleife über iSourceLength
DW-weise vergleichen
bei unterschied schleifenzähler speichern und schleife verlassen​
/schleife

unterschied:
entsprechend schleifenzähler DW laden und bitweise untersuchen
im pointer-format ausgeben


...so könnte ich mir das vorstellen...
 
Dem Muster können eigentlich keine weiteren Informationen entnommen werden. Es kommt also später kein Wort oder Text raus, sondern tatsächlich nur der Zustand der Eingänge.
Alle erlaubten Zustände in einem DB abzulegen war eigentlich auch mein Gedanke, aber das Problem daran ist, dass jeder Zustand nur mit 256 Bit beschrieben werden kann.
Letztlich interessiert auch tatsächlich das Bitmuster. Wenn also auch nur ein einziger Eingang abweicht, so gilt es, herauszufinden, welcher es ist um dann weitere Schritte einzuleiten.

Aber wenn du 200 - 500 "gute" Zustände hast, wie willst du Abweichungen feststellen. Wenn du nun annimmst das aktuelle Muster stimmt mit keinem der erlaubten Muster überein. Zu welchem Muster musst du die Differenz prüfen und die weiteren Schritte einleiten ?

Jedenfalls bietet sich für sowas immer XOR an, da genau die Bits welche unterschiedlich sind schon eine "1" ergeben...

bg
bb
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für Eure kreativen Hinweise :)
Die Bitmuster folgen einer festen Reihenfolge. Soll bedeuten, dass zu jeder Zeit klar ist, wie die Eingänge tatsächlich stehen sollten.
Theoretisch wird sich Soll und Ist auch nicht groß unterscheiden. Es werden maximal 1-2 Bit abweichen. Welche das sind, ist dabei jedoch völlig offen.
Ich werd mich dann gleich mal dran machen, die Sache zu programmieren, mal sehen, wie es läuft.

Eigentlich ist das ja auch nicht besonders schwer, jedoch ist hier die Masse an Eingängen und Bitmustern das, was das Handling schwierig macht.

@vierlagig:
was sagt denn Deine Variable iDBNumber?
 
die nummer der DB in dem das Vergleichsmuster abgelegt ist
zu benutzen mit AUF DB[#iDBNumber]

Kann es sein, dass ich für diese Aktion keine Eingangsvariablen verwenden kann?
Der Syntax AUF DB[#iDBNumber] wird als falsch markiert.
Wenn ich ihn vorher in eine temporäre Variable transferiere funktioniert es aber.
 
Kann man eine Variable, die das Byte als Zahl bereits enthält, auch in einer Bitabfrage verwenden?

Sinngemäß:
U DBX[#iDBB].0

Wie oben geschrieben funktioniert es leider nicht.

Oder muss ich dann mit echten Adressen wie L10.0 arbeiten?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hab da grad ne Idee:

Würde es funktionieren, wenn ich das Komma der Bytenummer um 3 Stellen nach Rechts schiebe, die Zahlen 0-7 dazu addiere und das Ergebnis jeweils als Bitadresse nutze?
 
da ich mit deinem pdf wenig anfangen kann, da sich der code darin schwer debuggen lässt habe ich mir mal 10minuten zeit genommen, den groben entwurf von gestern in einen baustein zu pressen

Code:
*
FUNCTION "InputDB_Compare" : VOID
TITLE =Input-DB-Compare
//compares a input range defined by start and length (DWORD) with a DB-range 
//starting at 0.0
//
//DATE:    02.12.2011
//VERSION: 0.1
//AUTHOR:  4L
AUTHOR : '4L'
VERSION : 0.1




VAR_INPUT
  xCompare : BOOL ;    
  iSourceStart : INT ;    
  iSourceLength : INT ;    
  iDBNumber : INT ;    
END_VAR
VAR_OUTPUT
  xEqual : BOOL ;    
  xError : BOOL ;    
  dDeviation : DWORD ;    
END_VAR
VAR_TEMP
  iDBNumberTemp : INT ;    
  dAR1Temp : DINT ;    
  dAR2Temp : DINT ;    
  iLoopCounter : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =


      U     #xCompare; 
      SPBN  end; //start
      L     #iDBNumber; 
      T     #iDBNumberTemp; 
      AUF   DB [#iDBNumberTemp]; //open DB
      L     DBLG; 
      L     #iSourceLength; 
      <I    ; //get save, the DB is long enough
      =     #xError; 
      R     #xEqual; 
      SPB   end; 


      TAR1  #dAR1Temp; //save adress registers
      TAR2  #dAR2Temp; 


      L     #iSourceStart; //set adresses
      SLD   3; 
      LAR1  ; 
      L     L#0; 
      LAR2  ; 


      L     #iSourceLength; 
next: T     #iLoopCounter; //compare DWs
      L     ED [AR1,P#0.0]; 
      L     DBD [AR2,P#0.0]; 
      ==D   ; 
      SPBN  notE; 
      +AR1  P#4.0; 
      +AR2  P#4.0; 
      L     #iLoopCounter; 
      LOOP  next; 
      SET   ; 
      =     #xEqual; 
      L     L#0; 
      T     #dDeviation; 
      SPA   end; 
notE: CLR   ; 
      =     #xEqual; 


      L     32; 
nex2: T     #iLoopCounter; //compare BITs
      U     E [AR1,P#0.0]; 
      X     DBX [AR2,P#0.0]; 
      SPB   dev; 
      +AR1  P#0.1; 
      +AR2  P#0.1; 
      L     #iLoopCounter; 
      LOOP  nex2; 
dev:  TAR1  ; 
      T     #dDeviation; 
      LAR1  #dAR1Temp; 
      LAR2  #dAR2Temp; 


end:  SET   ; 
      SAVE  ; 


END_FUNCTION
 
Zuletzt bearbeitet:
Danke. Leider bin ich nun etwas im Stress.
Schau mir das Montag mal genau an.
Auf den ersten Blick hab ich aber schon gesehen, dass Du das genau so machst, wie ich mir das jetzt auch schon überlegt hatte.

Schönes Wochenende
 
Zurück
Oben