TIA Bereich kopieren - verschiedene Datentypen

Snape

Level-1
Beiträge
117
Reaktionspunkte
13
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe eine 1500 und TIA V13 SP1.
Ich will ein Byte-Array von 100 Byte Länge in einen anderen Bereich kopieren. Der andere Bereich ist kein Array, sondern ein Struct mit ebenfalls insgesamt 100 Byte Länge. Der Baustein soll auf jeden Fall optimiert sein.
Wie kann ich jetzt das Byte-Array in mein Struct kopieren? Ich habe bisher nur Befehle gefunden, bei denen die beiden Bereiche den gleichen Datentyp haben müssen oder dass der Baustein nicht optimiert ist.
Das kann doch nicht sein, dass es da nix gibt...

Snape
 
Versuchs mal mit POKE_BLK

Edit: dazu müsste allerding der DB nicht Optimiert sein
 
Zuletzt bearbeitet:
Ist dein Struct aus einer UDT deklariert? Dann könnteste das in einem Unterprogramm mit Absolutadressen umschaufeln und am Ende das ganze Struct kopieren. Wenn nicht wirste wohl das Array von Hand audröseln, und einzeln in das Struct konvertieren/kopieren müssen.

Aber evtl. hat da TIA noch tolle Funktionen die ich nicht kenne.
 
Hi, ich denke das es mit dem BLK_Move Baustein von Siemens funktioniert.
Ich habe ein DB wo mehrere Datentypen sind, z.B Bool, int und real.
Diese Variablen werden in den nächsten DB geschrieben und es funktioniert.

Du musst dabei natürlich die Richtige Datenadresse mit der richtigen Datenlänge angeben.
 
Neuen Ansatz

Funktion erstellen ohne Optimierung

Input - array
Überlagerung (AT) - deine Struktur

Output - deine Struktur

Output = Input Struktur

Funktion aufrufen wenn kopiert werden soll

Hier stellt sich mir immer noch die Frage "müssen alle bausteine optimiert bleiben?"
 
Ich stecke nicht so dicke drin in TIA, aber es gäbe noch folgende Lösung.
Dein Struct als Datentyp anlegen (UDT) und in dem DB wo das struct sein soll als Variable deklarieren.
Dann eine Funtion schreiben, in der die UDT temporär mit einer AT Sicht in ein Bytearray zerlegt wird, dann dein Bytearray in das temporäre Array kopieren und dann kannst du die temporäre UDT symbolisch in das Struct in deinem optimierten DB kopieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Kunde verlangt rein optimierte Bausteine, keine Standard-Zugriffe. Also entfallen alle bisher aufgelisteten Möglichkeiten. :-(
Also imho entfallen ALLE Möglichkeiten, ein optimierter Baustein hat auch keine (nachvollziehbaren) 100 Byte Länge (auf den tatsächlichen Speicherverbrauch bezogen).
Insofern kann ein anderer, anderst struckturierter Datentyp erst recht kein "garantierten" 100 Byte Länge haben, und selbst wenn er 100 Byte enthalten würde,
dann ist die tatsächliche Reihenfolge im Speicher rein von der momentan genehmen Firmware / Compilerversion abhängig.
 
Zuletzt bearbeitet:
Die 100 Byte sind ein Sammelsorium aus Bool, Byte, Integer und UDINT. Dieses "Array" bekomme ich von einem Koppelpartner zugeschickt, welches ich dann auseinander nehmen muss. Deserialize() wäre eine prima Funktion, nur geht die auch nur mit Standard-Bausteinen.
 
Die (vermutlich? Marketing-)Entscheidung, auch vom dummen Programmierer ausdrücklich deklarierte STRUCT zu "optimieren", war Schwachsinn und fällt uns immer wieder auf die Füße... :evil:

Harald
 
Hallo,

mit Optimierten Bausteinen geht es nicht, da man die Anordnung im Ziel nicht beeinflussen kann.

Für nicht Optimierten Bausteine gibt es dafür die Funktion Deserialisieren.

Im Bild wird ein Feld von 100Byte auf eine Struktur kopiert. Geht Problemlos. Man kann nur nicht eine Konstanze an den Eingang POS anlegen.


Harald


Deserialisieren.jpg
 
Habe mich gerade an meine C64er Zeiten erinnert....

Hat du es schon mal mit PEEK und POKE versucht?
PEEK=Lesen, POKE = schreiben

sollte eigentlich mit optimierten DBs und nicht optimierten DBs und im mixed mode funzen(der compliler meckert jedenfalls nicht rum ueber irgenwelche falsche Symbolik)

machs mit SCL:

***********************CutStart**********************************

FUNCTION "CopyAll" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
QuellDB : Int;
ZielDB : Int;
Menge : Int;
END_VAR


VAR_TEMP
Temp : Byte;
i : Int;
END_VAR




BEGIN
#i:=0; //wird zum initialisieren gebraucht, sonst meckert Compiler

//byteweise Kopieren
For #i := 0 To (#Menge -1) Do //Hundert Bytes am eingang sind 100 in diesem Fall ;-)
#Temp := PEEK(area := 16#84, dbNumber := #QuellDB, byteOffset := #i);
POKE(area := 16#84, dbNumber := #ZielDB, byteOffset := #i, value := #Temp);
;
End_For;

//ohne ueberpruefung auf die tatsaechliche bausteingroessen vom Quell und Ziel DB
//da koennte man ja noch ne routine mit testDB vom Quell und Ziel DB einbinden
//die die Menge begrenzt
//eventuell mit einem output
//war ich zu faul dafuer ;)

END_FUNCTION



********************************CutEnd*******************************************
erklaert sich eigentlich von selbst

C64.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Peek und Poke gehen nicht, da sie nur für Standard-Speicherbereiche funktionieren. In optimierten Bausteinen habe ich keinen ByteOffset.

Die Daten hole ich mit TRCV in ein array im IDB, daher ist auch der optimiert und kein Standard.
 
BEGIN
#i:=0; //wird zum initialisieren gebraucht, sonst meckert Compiler

//byteweise Kopieren
For #i := 0 To (#Menge -1) Do //Hundert Bytes am eingang sind 100 in diesem Fall ;-)
Interessehalber: was hat der Compiler da zu meckern? :confused: Wie lautet der Meldungstext?



Tip: Programmcode wird besser dargestellt (z.B. mit Einrückungen), wenn man den Code zwischen [CODE]-Tags einfügt - z.B. mit dem #-Button im Beitragseditor. Das sieht dann so aus:
Code:
FUNCTION "CopyAll" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      QuellDB : Int;
      ZielDB : Int;
      Menge : Int;
   END_VAR


   VAR_TEMP 
      Temp : Byte;
      i : Int;
   END_VAR




BEGIN
	#i:=0; //wird zum initialisieren gebraucht, sonst meckert Compiler
	
	//byteweise Kopieren
	For #i := 0 To (#Menge -1) Do //Hundert Bytes am eingang sind 100 in diesem Fall ;-)
	    #Temp := PEEK(area := 16#84, dbNumber := #QuellDB, byteOffset := #i);
	    POKE(area := 16#84, dbNumber := #ZielDB, byteOffset := #i, value := #Temp);
	    ;
	End_For;
	
	//ohne ueberpruefung auf die tatsaechliche bausteingroessen vom Quell und Ziel DB
	//da koennte man ja noch ne routine mit testDB vom Quell und Ziel DB einbinden
        //die die Menge begrenzt 
        //eventuell mit einem output
        //war ich zu faul dafuer ;)
	
END_FUNCTION

Harald
 
Union

In anderen Sprachen (C, PASCAL...) gibt es das Konstrukt UNION, da kann mann den gleichen Speicherbereich beliebig interpretieren.
Man muss da nicht einmal umkopieren.

Aber bei "Optimiert" ist das wie oben schon erwähnt nicht möglich. Und die IEC Norm hat das wohl explizit verboten.
 
Zurück
Oben