TIA Absolute Adresse einer DB-Variable ermitteln (kein AWL)

Beiträge
63
Reaktionspunkte
24
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Gemeinde,
gibt es eine Möglichkeit die absolute Adresse einer DB-Variable in TIA ohne AWL zu ermitteln? In AWL ist mir die Lösung über ANY-Pointer bekannt. Die DB-Nummer kann man in SCL mit VARIANT_TO_DB_ANY ermitteln.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es handelt sich hierbei um nicht optimierte DBs. Der Variablenname ist bekannt. Ich brauche die DB-Nummer (bspw. 14) und die Adresse der Variable (DBD, DBX, DBB, ...) bzw. eigentlich nur die Startadresse des Bytes. Die SPS muss die Adresse für POKE_BLK wissen. Ich möchte AWL vermeiden, da dies so langsam seitens Siemens ausstirbt und nicht mehr überall unterstütz wird.


In einem Sammel-DB sind verschiedene Strukturen vorhanden die ich mit POKE_BLK in andere Sende-DBs kopieren möchte. Diese DBs werden dann per BSEND/BRECIVE zu einem Partner geschickt/empfangen. Die Übertragungs-DBs sind als Array of Byte angelegt. Um im laufenden Betrieb Erweiterungen bzw. Änderungen der Variablennamen des Sammel-DBs vorzunehmen sind im Übertragungs-DB Reserven vorgesehen. Die Startadresse ändert sich beim Kopierbereich nicht.
Ich hatte mir den POKE_BLK für meine Lösung rausgesucht, da nach meinem Verständnis dieser die moderne Art der BLKMOV ist (intern wird dieser wahrscheinlich auf BLKMOV aufsetzen). Für POKE_BLK benötige ich die Adresse der DBs und die Startadressen des zu kopierenden Bereichs. Ich könnte natürlich jede Startadresse und DB-Nummern händisch ermitteln/eintragen, aber aufgrund der Fehleranfälligkeit beim Tippen möchte ich dies vermeiden. Über AWL kann man über den ANY-Pointer der an SRCBLK bzw. DSTBLK vom BLKMOV geschrieben wird händisch zusammensetzen
 
Warum überhaupt in ein Byte-Array umwandeln ?
Einfach die Datenstruktur als Datentyp in beide Projekte teilen. Dann kannst du die Daten für die BSEND/BRECV Bausteine Vollsymbolisch addressieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, jetzt noch mal ein klein wenig verständlicher, sonst wird mein unscheinbarer Hinweis wieder ignoriert :) .

Code:
    #ADR := 0;     // Hilfsvariable , DInt, TEMP
    #RET := (Serialize(SRC_VARIABLE := #STRUCT1, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));
    #RET := (Serialize(SRC_VARIABLE := #STRUCT2, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));
    #RET := (Serialize(SRC_VARIABLE := #STRUCT3, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));

Einfacher geht es nicht! Das kannst du beliebig erweitern. Serialize schreibt deine Strukturen fein säuberlich nach einander in den Sendepuffer. Über Adressen musst du dir überhaupt keine Gedanken machen. Der Sendepuffer (Array of Byte) muss nur groß genug sein, aber da geht was. Auf der Empfangsseite kannst du ggf. den dortigen Empfangspuffer mit Deserialze auf die selbe Art und Weise wieder zerlegen.
 
wenn es sich hier jeweils um Strukturen handelt so kann man diese auch direkt in SCL einem ANY-Pointer zuuweisen ...
Code:
myAnyPointer := derNameDerStruktur ;
 
Warum überhaupt in ein Byte-Array umwandeln ?
Einfach die Datenstruktur als Datentyp in beide Projekte teilen. Dann kannst du die Daten für die BSEND/BRECV Bausteine Vollsymbolisch addressieren.
Es geht darum, dass sich die Schnittstelle zum Partner beim Ändern nicht reinitialisiert. Wenn ich bspw. eine Variablenname änder ist nicht das Problem, es geht eher darum, dass wenn bspw. eine Eingangskarte gesteckt wird der Partner dann zeitgleich die Erweiterung mitbekommen muss, da sonst der Übertragungs-DB zu kurz wäre.

So, jetzt noch mal ein klein wenig verständlicher, sonst wird mein unscheinbarer Hinweis wieder ignoriert :) .

Code:
    #ADR := 0;     // Hilfsvariable , DInt, TEMP
    #RET := (Serialize(SRC_VARIABLE := #STRUCT1, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));
    #RET := (Serialize(SRC_VARIABLE := #STRUCT2, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));
    #RET := (Serialize(SRC_VARIABLE := #STRUCT3, DEST_ARRAY => #SENDEPUFFER, POS := #ADR));

Einfacher geht es nicht! Das kannst du beliebig erweitern. Serialize schreibt deine Strukturen fein säuberlich nach einander in den Sendepuffer. Über Adressen musst du dir überhaupt keine Gedanken machen. Der Sendepuffer (Array of Byte) muss nur groß genug sein, aber da geht was. Auf der Empfangsseite kannst du ggf. den dortigen Empfangspuffer mit Deserialze auf die selbe Art und Weise wieder zerlegen.
Das ist eine sehr charmante Art mein Problem zu lösen. Ich hatte mich irgendwie in meinem Problem verrant und auf die altbewährte Methode mit neuen Lösungsansätzen zu lösen. Serialize klingt sehr vielversprechend, das werde ich gleich mal ausprobieren.


Vielen Dank an alle Beteiligten!! 😁
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es geht darum, dass sich die Schnittstelle zum Partner beim Ändern nicht reinitialisiert. Wenn ich bspw. eine Variablenname änder ist nicht das Problem, es geht eher darum, dass wenn bspw. eine Eingangskarte gesteckt wird der Partner dann zeitgleich die Erweiterung mitbekommen muss, da sonst der Übertragungs-DB zu kurz wäre.
Dann wurde ich auch nach serialize/deserialize tendieren.
 
Freundchen, bist du jetzt wieder stiller Beobachter, oder beantwortest du auch mal unsere bescheidenen Fragen? Oder ist das vielleicht zu viel verlangt? Wir lernen nämlich auch gerne dazu. Eine Rückmeldung, ob es geklappt hat, wäre auch charmant :).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Entschuldigung für die späte Antwort. Ich bin dabei ein Konzept zu entwickeln, welches die Nachteile des Reinitailisierens, welche durch Änderung der Variablennamens, hervorgerufen wird zu kompensieren. Durch das aufteilen der Übertragungs-DB in nicht symbolisch abgeleitet bleibt der Zustand gleich und wird nicht einen Zyklus lang 0 geschrieben. Wenn Signale auf der Gegenseite zum Teil eine 0 beinhaltet kann dies zu Abschaltungen beim Partner führen. Ich hab mich jetzt auf eine Kombination serialize/deserialize entschieden, wenn die symbolik entfernt ist nutze ich einfache Zuweisungen. Die entsprechenden Arrays habe ich über Konstanten abgeleitet um halt bei Vergrößerung der Anlage bzw. neue Anlagen eine Anpassung des Programms zu realsieren. Um nicht einen DB mit Nullwerte auf den Übertragungs-DB zu übertragen frage ich ab, ob ein "Beschrieben Bit" 1 ist. Alles etwas umständlich, aber nach dem Motto "die alten Steuerungen können das doch ja und die neuen müssen das ja auch können". Man darf sich halt nicht verschlechtern.
 
Anmerkung: ein anderer Lösungweg über POKE_BLK ist auch zum symbolischen Kopieren auf absolute Adressen interessant. Hierzu muss man sich über AWL die Start-Adressen der DBs, Eingänge etc. zusammenbauen. Über SCL habe ich es nicht hinbekommen mir die Zeiger zu ermitteln. Wenn man diese weis kann man mit POKE_BLK die Anzahl an Bytes die kopiert werden sollen übergeben und man hat eine nach gefühl kleinere Zykluszeit, da dieser Befehl auf MOVE_BLK aufsetzt.
 
Nochmal meine Frage:
Wann genau meinst Du mit "zeitgleich"?
Verstehe ich Dich richtig, daß Du zur Programmlaufzeit (im RUN der SPS) "zeitgleich" in 2 SPS die Datentypen, Struktur und Länge von übertragenen Daten ändern können willst? Da wirst Du dem Empfänger eine Beschreibung der Struktur mitschicken müssen.

PS: für welche SPS willst Du den Code entwickeln?
 
Zurück
Oben