TIA DB Werte komplett in einen gleichen DB Kopieren Optimierter Baustein

Zuviel Werbung?
-> Hier kostenlos registrieren
Nur Kleinigkeiten.

Ich finde es lesbarer wenn die Schleifenzähler anstatt ein Variabel ist ("Rezept_Werkseinstellung".zaehler), eine einfachen TEMP #i ist.
Wenn man mehrere Array Dimensionen hat, ist es üblich die Namen i, j, k, l, m... usw. dafür zu verwenden.

Und wie Windoze es bemerkt, wenn du ein kompletten identischen Array für die Werkseinstellungen verwendet, brauchst du kein Schleife.
Einfach
"Rezept".Nr := "Rezept_Werkseinstellung".Nr ;
 
Hallo Chris80

Ich habe gerade mein erstes TIA Projekt mit V16 beendet. Dabei aber im Prinzip nur mein altes S7 Projekt migriert ...die Anlage läuft.
Den Code möchte ich jetzt auf eine neue Anlage adaptieren und auch SCL zu verwenden - so wie Du es hier gezeigt hast.

Ich habe in meinem Projekt mehrere gleiche Reglungs-Systeme, welche jeweils einen eignen Daten DB besitzen. Wir haben dazu aus einem zentralen Rezeptur DB alle notwendigen Daten zusammengefügt und als neue Rezept-Struktur innerhalb der System-DB´s ablegt. Bei der Migration wurde wild "Peek" und "Poke" verwendet:
// copy data from source DB to destination DB
// copy data from ParDB(HMI) to CtrlDB
For #j := 0 To (#GrpNum-1) By 1 Do
For #i := 0 To (#DataNum-1) By 1 Do
(* classic code: #TargDB.DD(#TargDB_StartAddr + #TargDB_AddrOfs*#DataNum*#j + #TargDB_AddrOfs*#i)
:= #SourDB.DD(#SourDB_StartAddr + #SourDB_AddrOfs*#i + #j*4);*)
POKE( area:=16#84,dbNumber:=#TargDB,byteOffset:=#TargDB_StartAddr + #TargDB_AddrOfs*#DataNum*#j + #TargDB_AddrOfs*#i,
value := PEEK_DWORD(area:=16#84,dbNumber:=#SourDB,byteOffset:=#SourDB_StartAddr + #SourDB_AddrOfs*#i + #j*4));
End_For;
End_For;


Es muss doch möglich sein eine indirekte Adressierung mit einem lesbaren Code aus dem 21. Jahrundert hinzubekommen, so wie Du es oben gemacht hast?
Meine DB´s heißen z.B.:
RegSysDB1
RegSysDB2
RegSysDB3
...
Je nach Anlage zwischen 10 und 40 Systeme.

Bei denen ist jeweils der gleiche Rezeptur UDT abgelegt. Die Zuordnung der Rezeptwerte aus dem Source-DB in den UDT habe ich geschafft ....aber leider nur in einem übergeordnetem RegSysDB mit sequentiell abgelegten UDT´s:
For #i := 1 To "Ps_Init_DB".SysTotal Do
"RegSysDB"."THIS"[#i].Rcp.Single.DstSpm := "RcpInpDB".Rcp.DstSet.Sys[#i];

...
"RegSysDB"."THIS"[#i].Rcp.Single.MaxPrsSpm := "RcpInpDB".Rcp.PrsMaxSet.Sys[#i];
"RegSysDB"."THIS"[#i].Rcp.Single.MinPrsSpm := "RcpInpDB".Rcp.PrsMinSet.Sys[#i];
End_For;


Wie kann ich aber symbolisch die Daten in die verschiedenen RegSys[X]-DB´s ablegen?

Also ungefähr so:
For #i := 1 To "Ps_Init_DB".SysTotal Do
"RegSysDB"[#i].Rcp.Single.DstSpm := "RcpInpDB".Rcp.DstSet.Sys[#i];
...


Kannst Du mir da auch weiter helfen ...oder jemand anderes evtl.?

Danke
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich finde es lesbarer wenn die Schleifenzähler anstatt ein Variabel ist ("Rezept_Werkseinstellung".zaehler), eine einfachen TEMP #i ist.
Wenn man mehrere Array Dimensionen hat, ist es üblich die Namen i, j, k, l, m... usw. dafür zu verwenden.
(y)
hier sieht man, wo diese "Üblichkeit" herkommt:
FROTRAMimplizit.jpg
... und dass man bei dieser Festlegung an all diejenigen gedacht hat, die eine GedächtnisStütze brauchen: i bis n, also die beiden ersten Buchstaben des Wortes integer. Das konnte sogar ich mir merken. Bisher immerhin 53 Jahre lang. ;)
Ja, Jesper, als SchleifenZähler kann man sehr gut bis viel besser möglichst kurze VariablenNamen verwenden.
Es bleiben dann immer noch genügend eloquente VariablenNamen übrig, um den Code ziemlich unübersichtlich zu machen ...
Die "Sparsamkeit" bei den SchleifenZählern hilft auf jeden Fall, den Überblick nicht ganz zu verlieren.
 
Es ist ein einziges Rätselraten was genau Du bewerkstelligen willst. 😐
Möchtest Du die Aktualwerte als Startwerte übernehmen, dann kannst Du Dir das nämlich alles sparen, denn das kannst Du bequem mit zwei Klicks im DB selbst machen. Bei jedem Reinitsialisieren oder neustarten der CPU werden dann die Startwerte geladen, sofern sie nicht remanent sind.
Möchtest Du kontrolliert die „alten“ Daten abspeichern und ggf. wieder neu laden, dann genügt Dir eine einfache IF-Anweisung, welche die Daten entsprechend in die Eine oder andere Richtung zuweist.
 
Ich vermute er meint das so

Wobei hier i ein Platzhalter für den DB wäre. Also RegSysDB1, RegSysDB2, usw

FOR #i := 1 TO 10 DO
RegSysDB[#i] := "RegSysDefault";
END_FOR;
Das geht nicht. Zumindest ist mir nicht bekannt wie

Das ginge. Dann ist aber alles in 1 DB. Wobei RegSys.DB dann Array[1..10] of "Anwenderdatentyp_1" ist
FOR #i := 1 TO 10 DO
"RegSys".DB[#i] := "RegSysDefault".DB;
END_FOR;

Wenn die DB's nicht optimiert wären und und in der DB-Nummer aufsteigend wären könnte man über indirekte Adressierung was zaubern
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke Volker
genau darum ging es ... die Daten aus einem zentralen Rezeptur DB an unterschiedliche Regler mit jeweils eigenem Daten-DB zu übergeben. Aktuell liegen diese Regler noch auf der gleichen CPU. Da die Anlagen immer größer werden (und mit jedem zusätzlichen Regler auch die Zykluszeiten auf der CPU), muss ich irgendwann Regler auf separate CPU´s auslagern. Spätestens dann muss ich die Sollwerte auf verschiedene DB´s verteilen. Also versuche ich dass jetzt bereits strukturiert, nachvollziehbar und möglichst symbolisch zu integrieren.
z. Z. läuft das nach der Migration von S7 noch absolut adressiert mittels Peek und Poke (das gabs zuletzt beim Commodore 64🙄).
Anderswo hatte ich gesehen, das man dazu eine CASE Schleife verwendete und dort die Daten-Strukturen symbolisch zuweist:

CASE #i OF
1: "RegSysDB1".Rcp := "RegDB"."THIS"[#i].Rcp
2: "RegSysDB2".Rcp := "RegDB"."THIS"[#i].Rcp
3: "RegSysDB3".Rcp := "RegDB"."THIS"[#i].Rcp
...
END_CASE;

Aber das sieht ebenfalls unflexibel aus? Das muss doch auch in einer variablen Schleife über indirekte Adressierung möglich sein, oder?
Ich kann kaum glauben das dieses "Rad" in TIA noch keiner erfunden hat???
 
Danke Volker
genau darum ging es ... die Daten aus einem zentralen Rezeptur DB an unterschiedliche Regler mit jeweils eigenem Daten-DB zu übergeben. Aktuell liegen diese Regler noch auf der gleichen CPU. Da die Anlagen immer größer werden (und mit jedem zusätzlichen Regler auch die Zykluszeiten auf der CPU), muss ich irgendwann Regler auf separate CPU´s auslagern. Spätestens dann muss ich die Sollwerte auf verschiedene DB´s verteilen. Also versuche ich dass jetzt bereits strukturiert, nachvollziehbar und möglichst symbolisch zu integrieren.
z. Z. läuft das nach der Migration von S7 noch absolut adressiert mittels Peek und Poke (das gabs zuletzt beim Commodore 64🙄).
Anderswo hatte ich gesehen, das man dazu eine CASE Schleife verwendete und dort die Daten-Strukturen symbolisch zuweist:

CASE #i OF
1: "RegSysDB1".Rcp := "RegDB"."THIS"[#i].Rcp
2: "RegSysDB2".Rcp := "RegDB"."THIS"[#i].Rcp
3: "RegSysDB3".Rcp := "RegDB"."THIS"[#i].Rcp
...
END_CASE;

Aber das sieht ebenfalls unflexibel aus? Das muss doch auch in einer variablen Schleife über indirekte Adressierung möglich sein, oder?
Ich kann kaum glauben das dieses "Rad" in TIA noch keiner erfunden hat???
Na, das CASE könnte man auch weglassen und statt #i im Index einfach den absoluten Index eintragen. Nebenbei: eine CASE-Anweisung ist keine Schleife.

Also, Dein Haken ist der indizierte Zugriff auf einzelne DBs. I.M. fällt mir tatsächlich nur Peek/Poke ein. Da muss man noch einmal einen Möment drüber nachdenken. Aber, wenn Du sowieso die Einzel-DBs anlegst, wäre der Aufwand zu groß, das Kopieren eines Datensatzes in einen bestimmten DB entsprechend oft zu programmieren? Es werden ja wohl nicht 100erte DBs sein, oder?

VG

MFreiberger
 
Ein alte S7-300 oder S7-400 wird in eine S7-1500 migriert, und jetzt muss du das Programm auf mehrere CPUs 'auslagern' weil die Zykluszeit zu gross wird (!).
Da ist etwas ganz schief gelaufen.

Die Lösung ist, pack das alles in 1 (ein) DB, nicht mehrere DBs. Optimierte DBs kann in S7-1500 MB grösse haben.
Dann kannst du alles ganz schön symbolisch programmieren ohne Peek und Poke, und wenn das Hauptprogramm mit optimierte DBs erstellt ist läuft die Code mehrfach schneller als mit nicht-optimierte DBs.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
1: "RegSysDB1".Rcp := "RegDB"."THIS"[#i].Rcp
das ist aber andersrum als wie du das haben möchtest. oder verstehe ich dich falsch?
also ich denke das ..."THIS"[#i]... ein array [1..x] ist
also so
1659526879512.png

Die Lösung ist, pack das alles in 1 (ein) DB, nicht mehrere DBs. Optimierte DBs kann in S7-1500 MB grösse haben.
sag ich ja auch
 
Zurück
Oben