Verschiede DB-Bits nacheinader antriggern

Nico99

Level-2
Beiträge
134
Reaktionspunkte
12
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

ich habe mehrere Datenbausteine bestehend aus einzelnen Bits (DBX)
Jeder dieser Bits löst bei 1 eine Meldung am TP aus. Insgesamt sind es an 1200 meldungen, wobei je nach Anlage die Anzahl variert.

Jetzt muss ich für ein Testsystem alle Bits in allen DB's nacheinander, alle 5 Sekunden, kurz mit einer 1 ansteuern und somit die entsprechende Störmeldung antriggern.

Es ist leider so, dass die Meldungen in verschiedenen DB's liegen. Auch die Bitfolge ist nicht fortlaufend.

Jetzt habe ich mir gedacht, man könnte 3 DB's erzeugen. In einem stehen die Nummer der DB's, in anderem die dazugehörige Byteadresse und in drittem die Bitadresse.

Dann müsste man zum Beispiel den DB1.DBW1 laden, den DB2.DBW1 laden und DB3.DBW1 laden und anschliessend zum Pointer zusammensetzen und den Pointer dann eine 1 zuweisen.
Dann müsste man die Zeit, z.B. 5 sek. abwarten und das ganze wiederholen, aber mit DBW2 u.s.w. bis Baustein durch ist.

Jetzt mein Problem: kenn mich mit Pointern wenig bis gar nicht aus. Ich kann zwar den Pointer zusammensetzten, aber wie schaffe ich es den nächsten DBW mit Adressen zu laden?

Vielleicht gibt es auch einfacheren Weg?

Ich bin sehr dankbar für jegliche Art von Ideen und Vorschlägen.

mfg

Nico
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

Code von Gebs:
Code:
AUF DB [#DB_Nummer]
L #Byte_Nummer
SLD 3
L #Bit_Nummer
+D
LAR1
 U Bedingung
= DBX [AR1,P#0.0]



Soweit habe ich es auch. ich stehe irgendwie auf dem Schlauch mit dem Zugriff auf die Datenvariablen mit den Adressen und der Schleife.
Obwohl: eigentlich muss ich von aussen nur die Nummer der DB's vorgeben sowie Anzahl der Variablen.
Dann die Werte der ersten Variablen laden und zwischenspeichern (temporär). Aus diesen Werten den Pointer bilden unf 1 setzen, anschliessend wieder auf 0, zeitlang warten und dann wieder die Variablen laden, wobei dort bei der Wordadresse ein versatz sein muss.

Werde es diese Tage ausprobieren. Manchmal sieht man den Wald vor lauter Bäume nicht.

Wer die meldungen kontrolliert, weiss ich noch nicht. Ich denke mal, das wenn TP im Fehlerindikator genauso viele Meldungen anzeigt, wie im DB stehen, wird es wohl passen ;) [/QUOTE]
 
Hallo!

ich habe was gebastelt, vermutlich falsch, denn die CPU geht in STOP wegen Überschreitung der Zykluszeit. Hat jemand einen Rat?

Code:
FUNCTION FC 10 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  DBNummer_DB : BLOCK_DB ;    //DB-Nummer mit DB-Nummer-Variablen
  ByteNummer_DB : BLOCK_DB ;    //DB-Nummer mit Byte-Nummer-Variablen
  BitNummer_DB : BLOCK_DB ;    //DB-Nummer mit Bit-Nummer-Variablen
  Verz_Zeit : S5TIME ;    //Verzögerung zwischen den Meldungen
  Anzahl_Variablen : INT ;    //Anzahl der Triggervariablen
END_VAR
VAR_TEMP
  DB_Nummer : INT ;    
  Byte_Nummer : INT ;    
  Bit_Nummer : INT ;    
  temp_DBW : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Datenanfang vorbereiten

      L     #Anzahl_Variablen; 
      L     2; 
      +I    ; 
      T     #temp_DBW; 
NETWORK
TITLE =

anf:  NOP   0; 

NETWORK
TITLE =Trigger-DB-Nummer holen

      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #DB_Nummer; 
NETWORK
TITLE =Trigger-Byte-Nummer holen

      AUF   #ByteNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #Byte_Nummer; 
NETWORK
TITLE =Trigger-Bit-Nummer holen

      AUF   #BitNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #Bit_Nummer; 
NETWORK
TITLE =Pointeradresse der Triggervariable zusammensetzen

      AUF   DB [#DB_Nummer]; 
      L     #Byte_Nummer; 
      SLD   3; 
      L     #Bit_Nummer; 
      +D    ; 
      LAR1  ; 
      UN    M      1.0; 
      =     DBX [AR1,P#0.0]; 


NETWORK
TITLE =Vergleichen auf letztes DBW

      L     #temp_DBW; 
      L     0; 
      <=I   ; 
      SPB   ende; 
      SPA   anf; 

NETWORK
TITLE =

ende: NOP   0; 


END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe ich korrigiert. jetzt geht zwar die CPU nicht in Stop, aber es wird nur der letzte Eintrag im DB auf TRUE gesetzt.

Entweder funktioniert das runterzählen der #temp_DBW nicht oder der Pointer DBX [AR1,P#0.0] wird falsch zusammengesetzt. Kann man den eigentlich Online sehen?

Code:
FUNCTION FC 10 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  DBNummer_DB : BLOCK_DB ;    //DB-Nummer mit DB-Nummer-Variablen
  ByteNummer_DB : BLOCK_DB ;    //DB-Nummer mit Byte-Nummer-Variablen
  BitNummer_DB : BLOCK_DB ;    //DB-Nummer mit Bit-Nummer-Variablen
  Verz_Zeit : S5TIME ;    //Verzögerung zwischen den Meldungen
  Anzahl_Variablen : INT ;    //Anzahl der Triggervariablen
END_VAR
VAR_TEMP
  DB_Nummer : INT ;    
  Byte_Nummer : INT ;    
  Bit_Nummer : INT ;    
  temp_DBW : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Datenanfang vorbereiten

      L     #Anzahl_Variablen; 
      L     2; 
      +I    ; 
      T     #temp_DBW; 
NETWORK
TITLE =

anf:  NOP   0; 

NETWORK
TITLE =

      L     #temp_DBW; 
      L     2; 
      -I    ; 
      T     #temp_DBW; 

NETWORK
TITLE =Trigger-DB-Nummer holen

      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #DB_Nummer; 
NETWORK
TITLE =Trigger-Byte-Nummer holen

      AUF   #ByteNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #Byte_Nummer; 
NETWORK
TITLE =Trigger-Bit-Nummer holen

      AUF   #BitNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #Bit_Nummer; 
NETWORK
TITLE =Pointeradresse der Triggervariable zusammensetzen

      AUF   DB [#DB_Nummer]; 
      L     #Byte_Nummer; 
      SLD   3; 
      L     #Bit_Nummer; 
      +D    ; 
      LAR1  ; 
      UN    M      1.0; 
      S     DBX [AR1,P#0.0]; 


NETWORK
TITLE =

      L     #temp_DBW; 
      L     0; 
      ==I   ; 
      SPB   ende; 
      SPA   anf; 

NETWORK
TITLE =

ende: NOP   0; 


END_FUNCTION
 
Hallo!

Das Problem scheint in den NW 5 und 6 zu liegen. Denn ich will die #temp_DBW laden, dann denn DBW mit L DBW [AR1,P#0.0] zu laden, wobei im Pointer der Wert von #temp_DBW stehen soll.
Und das tut es nicht. Muss dort noch etwas rein?

Anhang anzeigen 17057
 
Probiere mal:
Code:
FUNCTION FC 10 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  DBNummer_DB : BLOCK_DB ;    //DB-Nummer mit DB-Nummer-Variablen
  ByteNummer_DB : BLOCK_DB ;    //DB-Nummer mit Byte-Nummer-Variablen
  BitNummer_DB : BLOCK_DB ;    //DB-Nummer mit Bit-Nummer-Variablen
  Verz_Zeit : S5TIME ;    //Verzögerung zwischen den Meldungen
  Anzahl_Variablen : INT ;    //Anzahl der Triggervariablen
END_VAR
VAR_TEMP
  DB_Nummer : INT ;    
  Byte_Nummer : INT ;    
  Bit_Nummer : INT ;    
  temp_DBW : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Datenanfang vorbereiten

      L     #Anzahl_Variablen; 
      L     2; 
      +I    ; 
      T     #temp_DBW; 
NETWORK
TITLE =

anf:  NOP   0; 

NETWORK
TITLE =Trigger-DB-Nummer holen

      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
[COLOR=#ff0000][B]     LAR1
[/B][/COLOR]     L     DBW [AR1,P#0.0]; 
      T     #DB_Nummer; 
NETWORK
TITLE =Trigger-Byte-Nummer holen

      AUF   #ByteNummer_DB; 
      L     #temp_DBW; 
[COLOR=#ff0000][B]     LAR1
[/B][/COLOR]     L     DBW [AR1,P#0.0]; 
      T     #Byte_Nummer; 
NETWORK
TITLE =Trigger-Bit-Nummer holen

      AUF   #BitNummer_DB; 
      L     #temp_DBW; 
[COLOR=#ff0000][B]     LAR1
[/B][/COLOR]     L     DBW [AR1,P#0.0]; 
      T     #Bit_Nummer; 
NETWORK
TITLE =Pointeradresse der Triggervariable zusammensetzen

      AUF   DB [#DB_Nummer]; 
      L     #Byte_Nummer; 
      SLD   3; 
      L     #Bit_Nummer; 
      +D    ; 
      LAR1  ; 
      UN    M      1.0; 
      =     DBX [AR1,P#0.0]; 


NETWORK
TITLE =Vergleichen auf letztes DBW

      L     #temp_DBW; 
      L     0; 
      <=I   ; 
      SPB   ende; 
      SPA   anf; 

NETWORK
TITLE =

ende: NOP   0; 


END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
NETWORK
TITLE =Pointeradresse der Triggervariable zusammensetzen

      AUF   DB [#DB_Nummer]; 
      L     #Byte_Nummer; 
      SLD   3; 
      L     #Bit_Nummer; 
      OD   ; 
      LAR2  ; 
      UN    M      1.0; 
      =     DBX [AR2,P#0.0];

Meiner Meinung nach sollte auch das +D durch OD ersetzt werden.
Das Adressregister kannst in AWL mit Rechtsklick auf z.B. VKE einblenden.

Ergänzung:
Lass mal die Änderung vom Paule weg und schreib vor dem Rücksprung +AR1 p#2.0

Nochmal edit
Hab noch mal drüber nachgedacht.
Ist auch Quatsch, da das AR1 ja zwei mal verwendet wird.
Sollte aber gehen, wenn zum setzen AR2 benutzt wird...
 
Zuletzt bearbeitet:
Hi!

wenn ich in den NW 4-6 die Anweisung LAR1 einfüge geht die CPU in STOP wegen "Ausrichtungsfehler beim Lesen"

Wenn ich jedoch anstatt LAR1 TAR1 in NW 5-6 (Lesen von Byte- und Bit Adressen aus den DB's schreibe, scheint es zu laufen.

EDIT: Ich nehme alle szurück: 1 Mal die PLC-Sim beendet (ich simuliere damit) und gestartet, Programm geladen: es tut wieder nicht :evil:
 
Zuletzt bearbeitet:
Lass mal die Änderung vom Paule weg und schreib vor dem Rücksprung +AR1 p#2.0
:ROFLMAO: Da magst du schon recht haben, aber:
Code:
      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #DB_Nummer;
Hier wird zwei mal geladen und nur einmal transferiert, das macht für mich so keinen Sinn auch wenn das Adressregister vom letzten Durchlauf angepasst wurde.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
du schiebst die Schleifendurchläufe auf die DB Nummer
das ist auf jeden Fall verkehrt

Code:
   L     #Anzahl_Variablen;  
      L     2;        +I    ; 
       T     #temp_DBW; 
 NETWORK TITLE =  anf:  NOP   0;   
NETWORK TITLE =Trigger-DB-Nummer holen;
        AUF   #DBNummer_DB;      
  L     #temp_DBW;  [COLOR=#ff0000][B]   
  LAR1  [/B][/COLOR] ;
   L     DBW [AR1,P#0.0];    
    T     #DB_Nummer; 
 NETWORK TITLE =Trigger-Byte-Nummer holen


gruß Thomas

p.s.: Sorry habe den Code nicht sauber posten können
 
Zuletzt bearbeitet:
Hallo!

Code:
AUF   #DBNummer_DB; 
L     #temp_DBW; 
L     DBW [AR1,P#0.0]; 
T     #DB_Nummer;

Wenn ich es nach Online-Beobachtung richtig verstehe, dann wird #temp_DBW nicht in den AR1. (dort stehr immer 0.0) geladen. Woran kann es liegen? Übersehe ich etwas? Eins weiß ich genau: wenn es irgendwan läuft dann verstehe ich endlich Pointer :D
 
weshalb nutzt du nicht weiter die
#DBNummer_DB;
im letzten Netzwerk kannst du diesen doch ganz normal öffnen
warum der Umweg über die temporären ?
Sorry habe gerade kein PLCSIM zur Hand
gruß Thomas
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

weshalb nutzt du nicht weiter die
#DBNummer_DB;
im letzten Netzwerk kannst du diesen doch ganz normal öffnen
warum der Umweg über die temporären ?

Ich habe 3 Datenbausteine. Der 1. enthält 96 Words mit jeweils einem DB-Nummer als integer. Der 2. hat die gleiche Länge, enthält jedoch die Byte-Adressen und der 3. die Bit-Adressen
Diese 3 DB's werden als

Code:
DBNummer_DB : BLOCK_DB ;    //DB-Nummer mit DB-Nummer-Variablen 
ByteNummer_DB : BLOCK_DB ;    //DB-Nummer mit Byte-Nummer-Variablen 
BitNummer_DB : BLOCK_DB ;    //DB-Nummer mit Bit-Nummer-Variablen

in den FC eingelesen.

Zusätzlich wird mit der Temp-Variable

Code:
 temp_DBW : INT ;

die letzte DBW-Adresse der 3 Bausteine gespeichert.

Weiterhin existieren im programm die DB's mit den Nummern, die der 1. DB enthält mit mehreren DBX.
Jetzt soll in einer Schleife das z.B. DBW96 (Wert 40) erst aus 1. Baustein gelsen werden, dann die DBW96 (Wert 2) aus dem 2. und auch die DBW96 (Wert 3) aus dem dritten Baustein.
Diese sollen als

Code:
DB_Nummer : INT ;     
Byte_Nummer : INT ;     
Bit_Nummer : INT ;

zwischengespeichert werden.

Aus diesen 3 Variablen soll dann eine Adresse zusammengesetzt werden (DB40 DBX2.3) und auf 1 gesetzt werden.

Code:
AUF   DB [#DB_Nummer];
L     #Byte_Nummer;
SLD   3;
L     #Bit_Nummer; 
+D    ;
LAR1  ;
UN    M      1.0;
S     DBX [AR1,P#0.0];

Die Daten in den 3 Bausteinen entsprechen auch komplett in der Folge den DB's, die angesteuert werden sollen.
Anschliessend soll

Code:
temp_DBW

um 2 verringert werden, so das beim nächsten Durchlauf die DBW 94 aus den 3 DB's gelesen wird und die nächste Variable auf 1 gesetzt wird.
Das Ganze wiederholt sich so lange, bis temp_DBW gleich 0 ist und somit all DBW's abgearbetet wurden.

Aber irgendwo stimmt was nicht. Wenn ich bei den Variablenbildung für DB_Nummer, Byte_Nummer oder Bit_Nummer LAR1 verwende, geht die CPU in STOP wegen "Ausrichtungsfehler beim Lesen"
Anhang anzeigen 17065Anhang anzeigen 17066Anhang anzeigen 17067Anhang anzeigen 17068
 
:ROFLMAO: Da magst du schon recht haben, aber:
Code:
      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
      L     DBW [AR1,P#0.0]; 
      T     #DB_Nummer;
Hier wird zwei mal geladen und nur einmal transferiert, das macht für mich so keinen Sinn auch wenn das Adressregister vom letzten Durchlauf angepasst wurde.

Ja. Der erste Ladebefehl ist völlig unnötig, schadet aber nicht.
Das tempDBW hat doch mit dem AR1 gar nix zu tun. Meines Erachtens ist das nur der Schleifenzähler.

@nico
Probier doch mal die Variante mit dem AR2 aus und erhöhe das AR1 bei jedem Durchlauf um 2. So wie ich das in meinem letzten Beitrag geschrieben habe. Das müsste doch funktionieren!
 
Hallo,
hab gerade mal den Code getestet,

Code:
FUNCTION "FC3" : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  DBNummer_DB : BLOCK_DB ; 
  ByteNummer_DB : BLOCK_DB ; 
  Bitnummer_DB : BLOCK_DB ; 
  Anzahl_Var : INT ; 
END_VAR
VAR_TEMP
  temp_DBW : INT ; 
  DB_NR : INT ; 
  Byte_Nr : INT ; 
  Bit_Nr : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =
// L     #Anzahl_Var
//   L     2
//     +I    
//  T     #temp_DBW

NETWORK
TITLE =DB Nummer holen
      AUF   #DBNummer_DB; 
      L     #temp_DBW; 
      LAR1  ; 
      L     DBW [AR1,P#0.0]; 
      T     #DB_NR; 
NETWORK
TITLE =Bytenummer holen
      AUF   #ByteNummer_DB; 
      L     #temp_DBW; 
      LAR1  ; 
      L     DBW [AR1,P#0.0]; 
      T     #Byte_Nr; 
NETWORK
TITLE =Bitnummer holen
      AUF   #Bitnummer_DB; 
      L     #temp_DBW; 
      LAR1  ; 
      L     DBW [AR1,P#0.0]; 
      T     #Bit_Nr; 
NETWORK
TITLE =Zuweisen
      AUF   DB [#DB_NR]; 
      L     #Byte_Nr; 
      SLD   3; 
      L     #Bit_Nr; 
      OD    ; 
      LAR1  ; 
      UN    M      1.0; 
      =     DBX [AR1,P#0.0]; 

NETWORK
TITLE =


in PLCsim funktioniert das ohne CPU Stop, man kann die einzelnen Positionen (DB_Nr, Byte_Nr, Bit_Nr ) vorgeben.
wenn du jetzt noch Probleme hast, kann es eigentlich nur an der Schleife liegen, bzw an dem Wert der
in #temp_DBW steht liegen, bei mir aktuell nur 0.

gruß Thomas
 

Anhänge

  • TEST.jpg
    TEST.jpg
    88,8 KB · Aufrufe: 12
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen!

@Thomas:

in PLCsim funktioniert das ohne CPU Stop, man kann die einzelnen Positionen (DB_Nr, Byte_Nr, Bit_Nr ) vorgeben.

Wie gibst Du di Werte für DB_Nr, Byte_Nr, Bit_Nr vor? Einfach L MW XY und dann T #temp_DBW ? Sobald ich etwas anderes in #temp_DBW stehen habe, geht die CPU in STOP wegen "Ausrichtungsfehler beim Lesen".
Anbei die Frage: muss ich die #temp_DBW, die ich als INT deklariert habe irgendwir AR1 oder AR2-"Fähig" machen?

Der zusammengebaute Pointer funktioniert ja einwandfrei, er liest den DBW0 aus den 3 DB's und setzt den Bit, dessen Adresse in den DBW steht. Was nicht funktioniert, ist die Übertragung von #temp_DBW in die Adressregister

Code:
AUF   #ByteNummer_DB
      L     #temp_DBW

HIER ZWISCHEN wird der Wert von dem INT #temp_DB nicht in AR1 geschrieben

      LAR1  
      L     DBW [AR1,P#0.0]
      T     #Byte_Nr

@SPSKiller

Probier doch mal die Variante mit dem AR2 aus und erhöhe das AR1 bei jedem Durchlauf um 2. So wie ich das in meinem letzten Beitrag geschrieben habe. Das müsste doch funktionieren!

Sorry, aber langsam verliere ich den Überblick! Wo soll ich es denn schreiben?
 
Zuletzt bearbeitet:
Hey,
nix für ungut, aber du kannst doch wohl selbst deinen Thread nochmal durchlesen.
Dann wird's auch klar wo was hinkommt....

Aber letztendlich wird das auch nur deine Schleife zum Laufen bringen.
Das nutzt dir aber nicht viel, da die Architektur Schrott ist.

Deine Schleife läuft zyklisch durch.
Dadurch werden - sofern sie denn funktioniert - alle Bits auf Null gesetzt, und einmal alle 5 s für einen Zyklus auf eins, usw.
Dabei gehe ich davon aus, dass dein Merker eine positive Flanke ist - alle 5s True.

Wenn du es zum Läufen bringen willst, dann geh folgendermaßen vor:

1. Nimm nen FB (kein Muss, aber einfacher und logischer)
2. Zähle die Adresse alle 5s hoch
3. Setze alle 5s das neu adressierte Bit

Das ist so ganz simpel. Am Ende ist dein Bereich voller Einser.
Man kann natürlich noch ein automatisches Rücksetzen einbauen.
Aber erst mal sollte es soweit laufen.

Für ne Kiste Bier mach ich's dir fertig :ROFLMAO:

Micha
 
Hi!

langsam überlege ich mir auch, die ganze Idee hinzuschmeißen und einen neuen Ansatz finden.

Ich danke euch vielmals für die ratschläge und Anregungen!
 
Zurück
Oben