TIA Parameterspeicher im Ladespeicher mit variablem Zugriff - Variant READ_DBL / WRIT_DBL

flater

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen zusammen,

ich kämpfe aktuell mit einer S7 1200 an einem Parameterspeicher für eine Anlage und komme hier nicht wirklich weiter :confused:.

Im Folgenden kurz die Beschreibung wie das Ganze ablaufen soll:
Der Kunde kann an der Anlage verschiedene Produkte fertigen und jedes Produkt hat 103 Parameter.
Gesamt sollen über 1.000 Produkte gespeichert werden, sodass der Remanenzspeicher nicht ausreicht und ich somit die Programme im Ladespeicher ablege und lade.
Wird im HMI der Programmspeicher geöffnet, werden die ersten 10 Programme als Block in den Arbeitsspeicher geladen, sodass ich die Programmnamen und die Programmnummern im
Display anzeigen kann. Über Buttons mit +-10 / +-20 / +-50 / +-100 kann der Kunde den nächsten Block laden. (Bsp. Programme 140 - 149)
Wird ein Programm gewählt, wird dieses einzeln Kopiert und weiterverarbeitet.


HMI.PNGLoad_Save.jpgSpeicher.jpg


Aktuell läuft das Ganze mit 180 Programmen soweit.
Zum Lesen und Schreiben aus dem Ladespeicher verwende ich aktuell den Befehl "READ_DBL" sowie "WRIT_DBL" sodass ich immer Blockweise verschieben kann.
Das Problem macht mir aktuell der Variant an "SRCBLK", hier habe ich momentan eine Konstante (ohne optimierten Bausteinzugriff) angelegt.
Jedoch wird das bei 1.000 Programmen sehr aufwendig und wenn jemals die Anzahl der einzelnen Parameter angepasst wird, passt nichts mehr :eek::eek:!!!

Versuch nun schone einige Tage rum, bekomme jedoch den Variant nicht variabel hin :|.

Wäre sehr dankbar, wenn einer der Profis hier im Forum mir einen Tipp geben könnte :p.

Vielen Dank im Voraus für eure Hilfe!
 
Die S7-1200 hat auch eine Funktion zum Rezept-Speichern und -Laden auf der Speicherkarte:
Erweiterte Anweisungen -> Rezepte und DataLogging -> RecipeEx-/Import

Diese Funktionen sind speziell für Deinen Anwendungsfall gedacht.



Ich selbst nutze die Rezeptfunktion des Panels, da mir die 500 Datensätze je Rezept dort ausreichen.
Aber auch da könnte man z.B. mehrmals das gleiche Rezept erstellen und dann mit Datensätze 1-500, 501-1000 ... unterscheiden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo hucki,

vielen Dank für deine schnelle Rückmeldung :p.

Die Rezepturverwaltung im HMI habe ich auch schon im Auge gehabt, jedoch ist diese bei den basic Panels nicht ausreichend.

Über die RecipeEx-/Import Funktion kann ich jedoch keine "Blöcke" schreiben / lesen und begrenzt auf 255 Zeilen pro CSV.
Da ich jedoch nicht 255 Zeilen in den Remanezspeicher bekomme, müsste ich wieder mehrere Blöcke/CSV`s erstellen und diese dann einzeln Laden.

Gibt dann eine "reisen" CSV Sammelung :confused:

Gibts noch eine Alternative?
Bekomme ich den Variant nicht "aufgeteilt" sodass ich den Bereich zum Block-Load anpassen kann (Pointer)?
 
Geht denn kein symbolischer Zugriff auf die Array-Member?

So in etwa:
Code:
FOR #i := 0 TO 9 BY 1 DO
    READ_DBL(REQ := #Load_Block, SRCBLK := DB858.Programm[Block_Nummer * 10 + #i], BUSY => #RD_busy, DSTBLK => db25.Programm[#i]);
END_FOR;

Oder vielleicht das Array auch gleich in Blöcke einteilen:
Code:
DB858
 Programm : Array[0..18, 0..9] of "Programm_Normal";

DB25
 Programm : Array[0..9] of "Programm_Normal";


READ_DBL(REQ := #Load_Block, SRCBLK := DB858.Programm[Block_Nummer], BUSY => #RD_busy, DSTBLK => db25.Programm)
Aber keine Ahnung, ob das mit den Ladespeicherzugriffen auch so geht, wie z.B. beim MOVE.
 
Hallo hucki,

ja, wie sagt man immer, "einmal mit Profis arbeiten" :-) VIELEN DANK!
Die zwei Zeilen haben mir nun eine menge Arbeit abgenommen!

Hab beide Varianten versucht und funktionieren beide auch mit symbolischem Zugriff :) ohne Probleme.
(Bei KOP kam hier immer ein Fehler, dass es mit Struct im Array nicht geht :confused:)

Code:
#RD_Status := READ_DBL(REQ := #Load_Block, SRCBLK := "Speicher_Block".Programm[#Block_Nummer], BUSY => #RD_Busy, DSTBLK => "Parameter_Block".Programm);


#WIRT_Status := WRIT_DBL(REQ := #Speichern, SRCBLK := "Parameter_Block".Programm, BUSY => #WRIT_Busy, DSTBLK => "Speicher_Block".Programm[#Block_Nummer]);

Nochmals vielen Dank!
Hätte ich nur früher nachgefragt, hat mich schon zwei Tage rum versuchen gekostet.

Liebe Grüße
 
Zuviel Werbung?
-> Hier kostenlos registrieren
:D
Freut mich, dass ich Dir einen neuen Schub geben konnte.
Noch dazu voll symbolisch.



Für die 9 und 18 (bzw. später 100) solltest Du jeweils eine (globale) Konstante erstellen und diese zur Arrayerstellung nutzen, damit sichergestellt ist, dass die verschiedenen Arrays auch immer die gleiche Größe haben.
Mit dieser Konstante und LIMIT kannst Du dann z.B. auch die Block_Nummer im Zaum halten, dass diese nicht mal versehentlich (z.B. durch falsche HMI Vorgabe) außerhalb des zulässigen Arraybereichs landet und dadurch die CPU stoppt.
 
Kurze Anmerkung:
Vorsicht bei Daten in DB's die nur im Ladespeicher liegen! TIA behandelt diese als normalen Programmbaustein beim Laden!

Das bedeutet: Wurden von der SPS Daten im DB geändert so ist der Zeitstempel usw. nicht mehr gleich zum Projektstand. Die Folge, ist das TIA beim Programmübertragen den DB überschreibt!!!
 
Moin,

Kurze Anmerkung:
Vorsicht bei Daten in DB's die nur im Ladespeicher liegen! TIA behandelt diese als normalen Programmbaustein beim Laden!

Das bedeutet: Wurden von der SPS Daten im DB geändert so ist der Zeitstempel usw. nicht mehr gleich zum Projektstand. Die Folge, ist das TIA beim Programmübertragen den DB überschreibt!!!

Gut zu wissen. Und da gibt es keine Möglichkeit das Überschreiben von TIA zu umgehen?

VG

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hab beide Varianten versucht und funktionieren beide auch mit symbolischem Zugriff :) ohne Probleme.
(Bei KOP kam hier immer ein Fehler, dass es mit Struct im Array nicht geht :confused:)

Code:
#RD_Status := READ_DBL(REQ := #Load_Block, SRCBLK := "Speicher_Block".Programm[#Block_Nummer], BUSY => #RD_Busy, DSTBLK => "Parameter_Block".Programm);


#WIRT_Status := WRIT_DBL(REQ := #Speichern, SRCBLK := "Parameter_Block".Programm, BUSY => #WRIT_Busy, DSTBLK => "Speicher_Block".Programm[#Block_Nummer]);
Was geht denn da eigentlich genau in KOP bei Dir nicht?

Die beiden von Dir geposteten Code-Zeilen sollten IMHO auch in KOP machbar sein.
Nur die Eingabe ist etwas tricky, weil der Editor bei beiden Array-Eingaben, wenn man deren Eingabe wie üblich mit Enter bestätigt, zuerst "denkt", dass diese noch unvollständig seien und diese daher erst mal fälschlischerweise mit Klammern bzw. Komma erweitert.
Das kann man entweder durch mehrfaches Drücken von Enter wieder rückgängig machen oder die Eingabe gar nicht mit Enter abschließen sondern durch Mausklick außerhalb abbrechen.
 
Zurück
Oben