Beckhoff Zusammenhang ADR BITADR Pointer etc

pezi179

Level-2
Beiträge
27
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!
Gibt es irgendwo eine sinnvolle/verständliche Beschreibung über Pointer/Adressierungen etc. Also die Zusammenhänge zwischen ADR, BITADR, Pointer - bei %I, %Q und %M

ich hab zwar hier im Forum schon einige Beiträge gefunden, die davon handelten aber eine komplette Beschreibung/Doku wäre toll, damit ich's auch check ;)

mein ziel wäre eigentlich nicht sooo schwierig aber es will nicht (immer). ich habe eine Variable 'var' AT%MX20.0: BOOL; an einer anderen Stelle möchte ich dann ein Pointer 'pt' welcher auf 'var' zeigt um dann zu sagen pt^:= true

kann es sein, dass hier Merker wieder speziell zu behandeln sind - in den Beispielen die ich bisher gefunden habe wurden nirgends Merker verwendet !?!

by the way: das ganze ist ein Teil für meine Lichtszenen - habt ihr solche schon wo gemacht/verwendet - wenn ja, bin für jeden Tipp dankbar

danke schon mal
 
Wie hast du es denn programmiert?

Code:
pt: Pointer to bool;
var AT%MX20.0:bool;

pt := ADR(var);
pt^:=true;

?
Kann es leider nicht zu Hause testen. Wüsste aber nicht warum Merker da stressen sollten. Kann aber sein, ich nutze halt nur nie Merker.
Hast du es mal mit einer normalen Variable versucht, also einer die nicht im Merkerbereich liegt? Da sollte es auf jeden Fall klappen. Warum muss 'var' bei dir unbedingt ein Merker sein?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein, du kannst keine Zeiger auf "echte" Bit-Variablen wie Merker, Ein- oder Ausgangsbits bilden. Aus dem gleichen Grund kannst du auch an einen IN_OUT Parameter eines FC keine dieser Variablen übergeben, weil diese auch über einen Zeiger an die Funktion übergeben werden.
Hintergrund ist, dass alle 8 Bits eines Merkerworts auf der gleichen Adresse liegen. Und da eine Adresse ein Ganzzahliger Wert ist, kann man dort keine Bit-Adressen unterbringen.

Beispiel:
MB0 liegt im Speicher an Adresse 1000
MB1 liegt im Speicher an Adresse 1001

Die Informationen für einen Zugriff auf MX0.3 könnte man also in der reinen Adresse nicht ablegen (bei der Siemens S7 geht das, dort sind bei einem Zeiger für die Bitnummer zusätzliche 3 Bit reserviert).

Etwas offizielles habe ich dazu auch noch in keiner Doku gefunden - leider. Ich habe es auch durch Versuch und Fragen hier im Forum rausgefunden.
 
Stimmt, das Ganze ist etwas schwammig. Mir wäre es auch lieber, wenn "echte" Bitmerker nicht den Typ "BOOL", sondern meinetwegen "BIT" hätten.
Wenn Du unbedingt dieses Konstrukt brauchst, musst Du ein wenig tricksen:
Code:
VAR
   varAbsoluteBit AT %MX20.0:BOOL;   (* Der Bitmerker *)
   varAbsoluteByte AT %MB20:BYTE;   (* Eine Bytevariable auf der gleichen Adresse *)
   varPtrToBool:POINTER TO BOOL;   (* Der Bool-Zeiger *)
END_VAR

varPtrToBool:=ADR(varAbsoluteByte);   (* Das geht, weil es ja eine Byteadresse ist *)
varPtrToBool^:=TRUE;
Die Merkerbits MX20.1 bis MX20.7 darfst Du dann natürlich nicht verwenden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
hm...das ist schlecht, möchte ungern mein ganzes bestehendes Programm verändern

hat von euch jemand Erfahrung mit Lichtszenen? Vielleicht könnte ich mir die ganzen Pointer ja sparen, wenn ich die Lichtszenen anders hinbekomme. Bin gerade auf FB_ScenesLighting aus der BABasic gestoßen - ist die brauchbar? sprich: lohnt es sich die BABasic zu besorgen?
 
Ich kenne Dein Programm nicht, befürchte aber, dass diese beiden Dinge
möchte ungern mein ganzes bestehendes Programm verändern
und
Vielleicht könnte ich mir die ganzen Pointer ja sparen
nicht unter einen Hut zu bringen sind.
Was Du da vorhast, ist eine ziemlich exotische Sache, die bei einer einigermassen durchdachten Daten- und Programmstruktur nicht notwendig sein sollte.
Warum muss der Bitmerker unbedingt absolut adressiert sein, und warum musst Du anschliessend mit einem Pointer darauf zugreifen?
 
bin gerade dabei Lichtszenen in ein bestehendes Programm zu integrieren. Diese Lichtszenen sollten in der Visu jederzeit änderbar sein. --> wahrscheinlich stehe ich nur grad auf dem Schlauch und es ist gar nicht so kompliziert dies umzusetzen.

eine andere Frage: über ADS ist es ja möglich entweder über Indexgruppe+Offset bzw über den Variablennamen auf eine Variable zuzugreifen
geht das direkt im PLC auch irgendwie? dass ich nur einen String mit dem (dynamischen) Variablennamen übergebe und dann diese Variable lesen/schreiben kann (falls sie exisitert natürlich)

werde in der Zwischenzeit mein ganzes Konzept nochmal überdenken - vielleicht komm ich ja vom Schlauch runter ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich es richtig verstehe, willst Du auf die absolut adressierte Bitvariable AT %MX20.0 mit einer Schaltfläche der integrierten Visu zugreifen.
Auch dazu kannst Du eine absolut adressierte Bytevariable auf der gleichen Adresse (AT %MB20) nutzen. In dem Visu-Objekt trägst Du dann bei "Eingabe/Variable toggeln" oder "Variable tasten" das gewünschte Bit der Bytevariablen ein, z. B. für Bit 0 "ByteVar.0".
 
Hallo pezi179,

habe jetzt eingige Stunden mit dem Thema Pointer auf Eingangs- und Ausgangsbits (echte Bit-Variablen) verwendet. Ich wollte einfach einem FB die lokalen Ein- und Ausgänge der Steuerung, auf die er arbeitet als Zeiger übergeben. Auf direktem Weg ist das (aus den genannten Gründen) ja offensichtlich nicht möglich.
Habe mir jedoch einen Workaround geschaffen, den ich hier teilen möchte. Vielleicht ist er ja dem ein oder anderen hilfreich:
Code:
VAR
    pBool: POINTER TO BOOL;
    qxTest  AT%QX0.5: BOOL;

    pByte: POINTER TO BYTE;
    bDataBit: BOOL; 
END_VAR 



    pBool := BITADR(qxTest); (* pass a bitpointer to the FB as argument *)

    bDataBit := TRUE; (* the value, the FB will set to qxTest *)


    (* the following is to be implemented in the FB *)
    dwByteAdr := pBool / 8; (* calculate the byte portion of the bitpointer *)
    dwBitOfByte := pBool MOD 8; (* calculate the bit´s position of the bitpointer *)
     pByte := ADR(%QB0) + dwByteAdr; (* calculate the pointer by getting  the memory offset to the IO output image and adding the bitpointer´s  byte portion *)

    CASE wBitOfByte OF (* this is neccessary because the bit-address operator '.' only accepts constants *)
        0: pByte^.0 := bDataBit;
        1: pByte^.1 := bDataBit;
        2: pByte^.2 := bDataBit;
        3: pByte^.3 := bDataBit;
        4: pByte^.4 := bDataBit;
        5: pByte^.5 := bDataBit;
        6: pByte^.6 := bDataBit;
        7: pByte^.7 := bDataBit;
    END_CASE;

Das Beispile zeigt, wie ein Ausgangsbit an einen FB übergeben wird und dieses dort aus den Wert bDataBit gesetzt wird. Gleiches kann natürlich auch für das Lesen des Zusands von Eingangsbit, Ausgangsbit oder Merkerbits oder das Schreiben von Merkerbits realisiert werden.

Die einzige Einschränkung bei der Sache ist, dass man an pBool nicht erkennt, ob BITADR aus einem Merker, Input oder Output kommt. Ob pBool im Merker-, Eingangs- oder Ausgangsabbild verwendet wird, hält alleine davon ab, welche deren Basisadressen mit "pByte := ADR(%QB0) ..." ermittlet wird!


Grüße
Swampler
 
Guten abend,

Ich habe mich auch einige Zeit mit der Szenenproblematik da mir auch widersprochen hat, alles hart programmieren zu müssen. Ich habe es mittlerweile so gelöst, dass ich mir einen FB geschrieben habe, der mir 8 digitale sowie 8 analoge Signale abspeichern kann. Zusätzlich habe ich alle Aktoren, auf die eine Szene wirken soll in eine Struktur gepackt. Daraus habe ich mir eine aktuelleSzene variable erzeugt, die direkt an den Ausgängen hängt. Zum neu anlegen habe ich eine SaveSzene angelegt die ich als Eingang an meinen FB anlege. Diese Variablen kann ich aus meiner Visu bearbeiten, eine Nummer vorgeben und auf speichern drücken. Bisher hab ich noch keine Nachteile gefunden. Und das Pointer Problem habe ich so auch umgangen
 
Zurück
Oben