Step 7 Bit aus WORD

schakel

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

Leider habe ich ein Problem was ganz schon nervt.
Mit dem folgende Code kann ich ein Kompletten WORD auf der Ausgang setzen. Die Ausgang wird wieder eingelesen mit ein Beckhoff EPC.

Code:
      L     P#1.0
      T     #A
 
      L     P#122.0
      T     #B
 
      OPN   "ALM"
      L     DBW [#A]
      T     QW [#B]

In die DB "ALM" sind Alarmen gespeichert. Wenn ein Fehler auftritt wird zum Beispiel 1.2 hoch.
Bei 1.2 kommt die wert 4 auf der Eingang von der EPC. Bei 1.3 die wert 8 und bei 1.4 die wert 16 und so weiter.

Aber was ich möchte ist folgendes.
Mit den Pointer möchte ich das Bit übersenden.
Also wenn das 1.2 hoch ist, ich ein 1 in der EPC lese.

Aber sobald ich die 1.0 andere nach 1.2 geht der PLC in System fault.
Habe schon probiert die QW zu anderen nach QB und so, aber ich bekomme es nicht hin.
Auch Beispielen im Netz Hilfen nicht wirklich.

Wie kann ich es so machen das es funktioniert?
Oder ist das überhaupt nicht möglich?

Freundliche grusse
 
falsche stelle, die Adressierung oben beschreibt den Bereich, nicht den Inhalt

so verändert man den Inhalt:
Code:
OPN "ALM"
SET
=  DBX1.2

OPN habe ich benutzt, da mir keine Symbole im DB ALM bekannt sind bzw. ich die DB-Nummer nicht kenne.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke, aber ich möchte kein Bit in den DB setzten.
Ich möchte die Status von ein Bit, 1 oder 0 auf die Ausgang der PLC setzen.
Und mit den Pointer mochte ich wählen welche Bit ausgelesen werden soll.

Sollte vielleicht was deutlicher formuliert haben

Grusse
 
verstehe den Sinn nicht, aber egal:

Code:
A  DBX[#A]
=  Q[#B]

damit wird ausschließlich Bit #A an den spezifizierten Ausgang #B übergeben

ODER

Code:
L  DBW[#A]
AW W#16#4
T  QW[#B]

selektiert das BIT 1.2 und ignoriert alle anderen Meldungen im Word aus "ALM"
 
"System fault": Bei indirekter Adressierung eines Bytes oder Words muß der Bit-Anteil der Pointeradresse (die Bitadresse) = 0 sein: P#xyz.0
Auf ein einzelnes Bit greift man nicht mit "L" zu sondern mit "U" (englische Mnemonic: "A")

Warum machst Du umständlich und fehlerträchtig indirekte Adressierung?
Einfacher und besser lesbar wäre:
Code:
A DB123.DBX1.0
= Q122.0

A DB123.DBX1.1
= Q122.1

A DB123.DBX1.2
= Q122.2

//oder auch

L DB123.DBW0
T QW122

Beschreibe mal genauer was Du eigentlich tun willst.
Willst Du aus einem Bit ein Word machen?
Was soll passieren, wenn in dem Alarm-DB mehrere Bits = 1 sind?

Edit: zu langsam

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke euch!

Code:
A  DBX[#A]
=  Q[#B]

Das macht genau was ich möchte!
Die DB hat zumindest 900 Alarmen.
Jetzt kann ich die Pointer mit 1 erhöhen, und so durch denn DB laufen.
In de EPC werde ich ein Datei machen mit welche Alarmen vorgekommen sind und auf welcher zeit.

Weil da mehr als 900 Alarmen sind, ist es zu viel Arbeit um 900 variablen an zu machen in TwinCAT.
Und wenn ich 7 PLC's loggen möchte, kann ich das Abhandeln mit nur 7 Variablen für die Data.

Freundliche Grusse aus Holland
 
Danke euch!

Code:
A  DBX[#A]
=  Q[#B]

Das macht genau was ich möchte!
Die DB hat zumindest 900 Alarmen.
Jetzt kann ich die Pointer mit 1 erhöhen, und so durch denn DB laufen.
In de EPC werde ich ein Datei machen mit welche Alarmen vorgekommen sind und auf welcher zeit.

Weil da mehr als 900 Alarmen sind, ist es zu viel Arbeit um 900 variablen an zu machen in TwinCAT.
Und wenn ich 7 PLC's loggen möchte, kann ich das Abhandeln mit nur 7 Variablen für die Data.

Freundliche Grusse aus Holland
Hast Du denn 900 Ausgänge??? Oder nutzt Du nur die Ausgangsbits im Prozessabbild? Sind das vielleicht Ausgangs-Adressen zu einer PROFINET- oder Profibus-Verbindung?
Oder willst Du 900 Alarmbits auf wenige Ausgangsbits multiplexen? Woran erkennt TwinCAT, welches Alarmbit gerade ausgegeben wird? Kommt die Alarm-Nummer (#A?) vielleicht von TwinCAT und Du müsstest immer auf das selbe Ausgangsbit schreiben?
Wenn Dein TwinCAT mit nur 1 Variable und "wenig" Aufwand 900 Ausgänge lesen kann, kann es denn dann nicht direkt die Alarmbits im DB lesen?
Falls die Alarmbits seriell nacheinander ausgegeben werden und Du willst in TwinCAT mitloggen, wie stellst Du sicher, daß kein kurzzeitiger Alarm übersehen wird? Gibt es noch ein Handshake zwischen TwinCAT und der PLC?

Ich verstehe leider nicht was Du machen willst, und ob Dein Weg ein guter Weg bzw. sicherer Weg ist. Vielleicht erzählst Du mal mehr über die TwinCAT-Seite.

Harald
 
Goeienavond schakel,

Altijd leuk om te zien dat er nog Meer nederlanders onderweg zijn hier..

Ich denke mal das du eine stinknormale Signalaustausch machen willst. Und dann versuchen dir die Anzahl der Signalen zu reduzieren.

Stimmt das ?

De groeten van een Nederlander in Duitsland

Bram
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Goedemorgen Bram,

Ja, dit is toch wel een forum waar je duidelijk wat aan hebt.
Ook op het gebied van TwinCAT wordt veel support geboden.


Das stimmt.
In den DB gibt es 900 Alarmen. Die müssen durch TwinCAT ausgelesen werden.
Leider ist es nicht möglich um direkt in ein Siemens DB zu lesen.
Also muss ich erst die werte von ein Alarm (1 oder 0) auf die Ausgang setzen.

In TwinCAT werde ich in ein Array die Status von die Alarmen notieren. Wenn zum Beispiel Alarm 1 in die Array 0 ist, und der Bit sagt er ist jetzt hoch.
Dann kann ich das wegschreiben in ein Datei. Danach wird Alarm1 in die Array 1's.

Mit ein Handshake möchte ich die PLC ein Alarm senden lassen. Wenn die EPC fertig ist, macht de EPC ein Variable hoch.
Die PLC sendet darauf das nächste Alarm.

Auf diese weise möchte ich die Alarmen austauschen.
Würdet ihr es auf ein andere Art und weise machen?

Freundliche Grusse aus Holland

Guido.
 
Hallo zusammen,

Bin jetzt ein bisschen weiter gekommen.
Laufe nur fast mit der Pointer.

test.JPG
Code:
      A     "TEST1"                     // IF 1 jump naar DELE
      JC    DELE                        // IF 0 alarm op 1.2 wordt op
      L     P#1.2                       // uitgang gezet
      T     #A


      L     P#200.4
      T     #B

      OPN   "ALM"
      A     DBX [#A]
      =     Q [#B]

      L     #A
      LAR1  
      JU    END1

DELE: L     P#200.4
      T     #B

      TAR1  #A
      OPN   "ALM"
      A     DBX [#A]
      =     Q [#B]

      A     "TEST3"
      JCN   END1
      L     P#0.1
      T     #A

      L     #A
      LAR1  

END1: NOP   0


Ich speichere die wert von der Pointer in AR1.
Aber wenn ich dann TEST1 hoch mache, springt er nach DELE.
Danach ist AR1 nicht mehr 1.2, aber wird er immer auf gezahlt.

Problem: In denn nächste Zyklus wird immer mein Pointer Adresse gelöscht.
Wenn ich den Pointer speichere in A, dan habe ich ein fehler. Nämlich "area length error when reading"

Wie kann ich das Speichern, so dass ich es wieder verwenden kann?
Weil wenn TEST1 hoch ist, möchte ich die pointer erhohen. Aber das geht nicht wenn die ursprüngliche pointer schon weg ist.

Grusse Guido.
 
Willst Du Dir von einem Programmdurchlauf zum nächsten Durchlauf Werte merken, dann mußt Du die in Variablen speichern.
AKKUs und AR1/AR2-Register und TEMP-Speicher kann man nicht zum merken benutzen. Es muß eine globale Variable oder eine Variable an IN_OUT oder STAT bei FB sein.

Ich sehe gerade, daß Du Dein Programm in einen FB108 gepackt hast - speichere Dir die Werte für den nächsten Programmdurchlauf in Variablen in STAT.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Oke, das habe ich soweit verstanden.

Habe jetzt das folgendes:
Code:
      A     "TEST1"                     // IF 1 jump naar DELE
      JC    DELE                        // IF 0 alarm op 0.0 wordt op
      L     P#1.2                       // uitgang gezet
      T     #A

      L     P#200.4
      T     #B

      OPN   "ALM"
      A     DBX [#A]
      =     Q [#B]

      L     #A
      T     #A_1
      JU    END1

DELE: L     P#200.4
      T     #B

      L     #A_1
      T     #A
      OPN   "ALM"
      A     DBX [#A]
      =     Q [#B]

      A     "TEST3"
      JCN   END1
      L     P#0.1
      L     #A
      +D    
      T     #A

      L     #A
      T     #A_1
END1: NOP   0

A und B sind variablen in TEMP und A_1 in STAT. Alle sind Dint.
Bekomme jetzt den Fehler: "Area length error when writing".
Instance DB, double-word acces Acces address: 0
Requested OB: Programming error OB (OB121)
Priority class: 1

Und im Netz könnte ich nicht wirklich ein Lösung finden, also habe ich das mit AR1 probiert.

Habe auch variable C gemacht. Ein Pointer (P#1.3) gespeichert in C
Dann bekomme ich: No indirect operations permitted for FB parameter C.
Also A DBX [#C] darf ich nicht machen.

***EDIT***

Es funktioniert jetzt!
Habe DB108 entfernt und neu generieren lassen.
Jetzt geht das programm mit den richtigen Pointer weiter.

Danke!


Grusse
Guido.
 
Zuletzt bearbeitet:
Zurück
Oben