Nummer des InstanzDBs variabel uebergeben

heinerbollo

Level-1
Beiträge
4
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe die Aufgabe ca. 200 Regelkreise mit einer SPS S7 in Verbindung mit FB58 TCONT_CP zu realisieren.
Da ich die Regelkreise zu Gruppen zusammenfassen kann, wiederholen sich eigentlich die Parameter am FB.

Ich moechte also den FB58 in einer Schleife aufrufen und dort die entsprechende Zuordnung treffen. Hand/Auto,PV_IN, SP_INT......
Aber den Aufruf des FB58 muss ich mit der InstanzDB Angabe machen.
Diese DB-Nummer moechte ich als Variable uebergeben.
also etwas in der Art:
call FB58, DB[MW80]

Hat jemand eine Loesung hierzu.
Gruesse aus Manaus (AM) Brazil
 
Nee, nee, nee...
immer diese Sonderwünsche*ROFL*

Mach es doch einfach so wie die Steuerung es auch hergibt.
Also instanz-DB's variabel aufrufen geht nicht!
Wäre auch Schwachsinn!!!:evil:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo heinerbollo,

es gibt eine Möglichkeit den Instanz-DB variabel zu übergeben, aber es ist ziemlich tricky!

Als Erstes muss Du natürlich die entsprechenden Instanz-DB's erstellen.
Zweitens alle zu übergebenden Parameter versorgen.
Dann mit AUF DI [#DI_NR] den entsprechenden Instanz-DB öffnen.
Mit
L P#Byte.Bit
LAR2
das Adressregister 2 auf den Anfang Deiner Parameterliste setzen.
Jetzt kannst Du mit
UC FB 58 bzw.
CC FB 58
den FB aufrufen.

Ich hoffe ich konnte Dir helfen.

Grüße
Gebs
 
Hier schon mal 2 Themen in dieser Richtung:

http://www.sps-forum.de/showthread.php?t=10019
http://www.sps-forum.de/showthread.php?t=14604

Es wäre auch möglich mit einem festen Instanzdb zu arbeiten, den Du vor Aufruf mit den entsprechenden Daten versorgst aus dem variablen DB, und nach dem Aufruf wieder in den variablen DB sicherst.Ist zwar nicht so schön anzuschauen aber zur Not machbar.

Ich finde dieses Ansinnen nicht

Thomas

Danke Thomas.
Ich finde mein Anliegen auch nicht "Schwachsinn".
Jeder Aufruf eines Bauteins kostet nur Speicherplatz.
Und da der Kunde leider eine harte SPS verlangt,
und kein WinLC moechte. jeder Regleraufruf kostet mich
ueber 100Byte das Ganze mal 200 da schnell ueber 20kB weg.

.
Diese Idee hatte ich bereits verworfen, da ich nicht jeweils
532 Bytes hin und herschieben wollte.

Ich denke die Regleroptimierung ( Kundenanliegen), wird auch in diesem
fall funktionieren. Muss ich mal ausprobieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo heinerbollo,

es gibt eine Möglichkeit den Instanz-DB variabel zu übergeben, aber es ist ziemlich tricky!

Als Erstes muss Du natürlich die entsprechenden Instanz-DB's erstellen.
Zweitens alle zu übergebenden Parameter versorgen.
Dann mit AUF DI [#DI_NR] den entsprechenden Instanz-DB öffnen.
Mit
L P#Byte.Bit
LAR2
das Adressregister 2 auf den Anfang Deiner Parameterliste setzen.
Jetzt kannst Du mit
UC FB 58 bzw.
CC FB 58
den FB aufrufen.

Ich hoffe ich konnte Dir helfen.

Grüße
Gebs

Danke gebs,

das probier ich gleich mal aus.

Gruesse aus Manaus (AM) Brazil
 
Hallo heinerbollo,

ich hab' nochmal nachgedacht:
Du kannst auch alle Regler in einen (nicht ganz wegen der Längenbeschränkung) DB packen.

Als Beispiel hab ich mal eine AWL-Quelle erstellt:

Code:
TYPE "UDT_TCONT"
AUTHOR : Gebs
FAMILY : Control
 
 
  STRUCT     
   PV_IN : REAL ;    
   PV_PER : INT ;    
   DISV : REAL ;    
   INT_HPOS : BOOL ;    
   INT_HNEG : BOOL ;    
   SELECT : INT ;    
   PV : REAL ;    
   LMN : REAL ;    
   LMN_PER : INT ;    
   QPULSE : BOOL ;    
   QLMN_HLM : BOOL ;    
   QLMN_LLM : BOOL ;    
   QC_ACT : BOOL ;    
   CYCLE : REAL ;    
   CYCLE_P : REAL ;    
   SP_INT : REAL ;    
   MAN : REAL ;    
   COM_RST : BOOL ;    
   MAN_ON : BOOL ;    
   DEADB_W : REAL ;    
   I_ITLVAL : REAL ;    
   LMN_HLM : REAL ;    
   LMN_LLM : REAL ;    
   PV_FAC : REAL ;    
   PV_OFFS : REAL ;    
   LMN_FAC : REAL ;    
   LMN_OFFS : REAL ;    
   PER_TM : REAL ;    
   P_B_TM : REAL ;    
   TUN_DLMN : REAL ;    
   PER_MODE : INT ;    
   PVPER_ON : BOOL ;    
   I_ITL_ON : BOOL ;    
   PULSE_ON : BOOL ;    
   TUN_KEEP : BOOL ;    
   ER : REAL ;    
   LMN_P : REAL ;    
   LMN_I : REAL ;    
   LMN_D : REAL ;    
   PHASE : INT ;    
   STATUS_H : INT ;    
   STATUS_D : INT ;    
   QTUN_RUN : BOOL ;    
   PI_CON_GAIN : REAL ;    
   PI_CON_TI : REAL ;    
   PID_CON_GAIN : REAL ;    
   PID_CON_TI : REAL ;    
   PID_CON_TD : REAL ;    
   PAR_SAVE_PFAC_SP : REAL ;    
   PAR_SAVE_GAIN : REAL ;    
   PAR_SAVE_TI : REAL ;    
   PAR_SAVE_TD : REAL ;    
   PAR_SAVE_D_F : REAL ;    
   PAR_SAVE_CON_ZONE : REAL ;    
   PAR_SAVE_CONZ_ON : BOOL ;    
   PFAC_SP : REAL ;    
   GAIN : REAL ;    
   TI : REAL ;    
   TD : REAL ;    
   D_F : REAL ;    
   CON_ZONE : REAL ;    
   CONZ_ON : BOOL ;    
   TUN_ON : BOOL ;    
   TUN_ST : BOOL ;    
   UNDO_PAR : BOOL ;    
   SAVE_PAR : BOOL ;    
   LOAD_PID : BOOL ;    
   PID_ON : BOOL ;    
   GAIN_P : REAL ;    
   TU : REAL ;    
   TA : REAL ;    
   KIG : REAL ;    
   N_PTN : REAL ;    
   TM_LAG_P : REAL ;    
   T_P_INF : REAL ;    
   P_INF : REAL ;    
   LMN0 : REAL ;    
   PV0 : REAL ;    
   PVDT0 : REAL ;    
   PVDT : REAL ;    
   PVDT_MAX : REAL ;    
   NOI_PVDT : REAL ;    
   NOISE_PV : REAL ;    
   FIL_CYC : INT ;    
   POI_CMAX : INT ;    
   POI_CYCL : INT ;    
   sctFil : INT ;    
   srPv : REAL ;    
   srNoise : REAL ;    
   srPvdt2 : REAL ;    
   srPvdtMax2 : REAL ;    
   srNoise2 : REAL ;    
   srPvOld2 : REAL ;    
   siStatus : INT ;    
   siSpDir : INT ;    
   srTime : REAL ;    
   sPvOld : REAL ;    
   sSpOld : REAL ;    
   srPvMin : REAL ;    
   srPVsim : REAL ;    
   srEffDlmn : REAL ;    
   sInvAlt : REAL ;    
   sIanteilAlt : REAL ;    
   sRestInt : REAL ;    
   sRestDif : REAL ;    
   sRueck : REAL ;    
   sLmn : REAL ;    
   spassPTm : REAL ;    
   sCycTmPass : REAL ;    
   sPTm : REAL ;    
   srOptLmn : REAL ;    
   sbOptLmn : BOOL ;    
   sbConzOn : BOOL ;    
   sbSpChange : BOOL ;    
   sbReOpt : BOOL ;    
   sLmnHlmOld : REAL ;    
   sLmnLlmOld : REAL ;    
   srDiffSp : REAL ;    
   siTime : DINT ;    
   siCycle : DINT ;    
   siCycleP : DINT ;    
   siPulsFil : INT ;    
   srPulsPv : REAL ;    
   srDPvdt : REAL ;    
   srDPvdt2 : REAL ;    
   sNpInf : REAL ;    
   sCycleM : REAL ;    
   sGf11_30 : REAL ;    
   sGf12_30 : REAL ;    
   sGf21_30 : REAL ;    
   sGf22_30 : REAL ;    
   sPv0Sim_30 : REAL ;    
   srPVsim3_30 : REAL ;    
   srPVsim2_30 : REAL ;    
   srPVsim1_30 : REAL ;    
   srDelPvsim_30 : REAL ;    
   sGf11_20 : REAL ;    
   sGf12_20 : REAL ;    
   sGf21_20 : REAL ;    
   sGf22_20 : REAL ;    
   sPv0Sim_20 : REAL ;    
   srPVsim2_20 : REAL ;    
   srPVsim1_20 : REAL ;    
   srDelPvsim_20 : REAL ;    
   sGf11_15 : REAL ;    
   sGf12_15 : REAL ;    
   sGf21_15 : REAL ;    
   sGf22_15 : REAL ;    
   sPv0Sim_15 : REAL ;    
   srPVsim2_15 : REAL ;    
   srPVsim1_15 : REAL ;    
   srDelPvsim_15 : REAL ;    
  END_STRUCT ;    
END_TYPE
 
DATA_BLOCK "DB_TCONT1"
TITLE =
AUTHOR : Gebs
FAMILY : Control
VERSION : 0.1
 
 
  STRUCT     
   Anzahl_Regler : INT  := 1;    //Anzahl parametrierter Regler
   Laenge_Datensatz : INT  := 496;    //Länge des Reglerdatensatzes in Byte
   Offset : INT  := 10;    //1. Byte vom 1. Regler
   Reserve6 : WORD ;    
   Reserve8 : WORD ;    
   Regler : ARRAY  [1 .. 100 ] OF "UDT_TCONT";    
  END_STRUCT ;    
  BEGIN
END_DATA_BLOCK
 
DATA_BLOCK "DB_TCONT2"
TITLE =
AUTHOR : Gebs
FAMILY : Control
VERSION : 0.1
 
 
  STRUCT     
   Anzahl_Regler : INT  := 1;    //Anzahl parametrierter Regler
   Laenge_Datensatz : INT  := 496;    //Länge des Reglerdatensatzes in Byte
   Offset : INT  := 10;    //1. Byte vom 1. Regler
   Reserve6 : WORD ;    
   Reserve8 : WORD ;    
   Regler : ARRAY  [1 .. 100 ] OF "UDT_TCONT";    
  END_STRUCT ;
  BEGIN    
END_DATA_BLOCK
 
 
FUNCTION "UP_T_CONT" : VOID
TITLE =Unterprogramm für FB 58
VERSION : 0.1
 
 
VAR_TEMP
  LoopCounter : INT ;    
  Anzahl : INT ;    
  Laenge : INT ;    
  Offset : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Bearbeitung der Regler 1 - 100
 
// Temp.-Variablen initialisieren
 
      L     "DB_TCONT1".Anzahl_Regler; 
      T     #Anzahl; 
 
      L     "DB_TCONT1".Laenge_Datensatz; 
      T     #Laenge; 
 
      L     "DB_TCONT1".Offset; 
      T     #Offset; 
 
// Schleife über alle parametrierten Regler
 
      AUF   DI    58; 
      L     #Anzahl; 
L100: T     #LoopCounter; 
      L     #Anzahl; 
      TAK   ; 
      -I    ; 
      L     #Laenge; 
      *I    ; 
      L     #Offset; 
      +I    ; 
      SLD   3; 
      LAR2  ; 
 
      UC    "TCONT_CP"; 
 
      L     #LoopCounter; 
      LOOP  L100; 
NETWORK
TITLE =Bearbeitung der Regler 101 - 200
 
// Temp.-Variablen initialisieren
 
      L     "DB_TCONT2".Anzahl_Regler; 
      T     #Anzahl; 
 
      L     "DB_TCONT2".Laenge_Datensatz; 
      T     #Laenge; 
 
      L     "DB_TCONT2".Offset; 
      T     #Offset; 
 
// Schleife über alle parametrierten Regler
 
      AUF   DI    59; 
      L     #Anzahl; 
L200: T     #LoopCounter; 
      L     #Anzahl; 
      TAK   ; 
      -I    ; 
      L     #Laenge; 
      *I    ; 
      L     #Offset; 
      +I    ; 
      SLD   3; 
      LAR2  ; 
 
      UC    "TCONT_CP"; 
 
      L     #LoopCounter; 
      LOOP  L200; 
END_FUNCTION
Grüße
Gebs

[edit]
War noch ein kleiner Fehler drin!
[/edit]
 
Zuletzt bearbeitet:
Eine andere Möglichkeit wäre noch folgende:

Für den entsprechenden FB wird ein Instanz-Db angelegt, der immer gleich bleibt. Für jede Instanz wird jetzt ein normaler DB angelegt. (kann auch online geschehen) Vor dem eigentlichen FB-Aufruf wird dann per BlkMov einer dieser DBs in den InstanzDB kopiert, nach dem Aufruf wieder zurückkopiert.
Somit kann der FB normal aufgerufen werden und würde auch keine Änderungen (für evtl. schon bestehende FBs) nötig machen.
Das einzige, was noch gemacht werden muss, ist eine kleine Funktion, um aus der variablen DB-Nummer einen Zeiger für BLKMOV zu bauen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Grubba,

über Deine Lösung

Eine andere Möglichkeit wäre noch folgende:

Für den entsprechenden FB wird ein Instanz-Db angelegt, der immer gleich bleibt. Für jede Instanz wird jetzt ein normaler DB angelegt. (kann auch online geschehen) Vor dem eigentlichen FB-Aufruf wird dann per BlkMov einer dieser DBs in den InstanzDB kopiert, nach dem Aufruf wieder zurückkopiert.
Somit kann der FB normal aufgerufen werden und würde auch keine Änderungen (für evtl. schon bestehende FBs) nötig machen.
Das einzige, was noch gemacht werden muss, ist eine kleine Funktion, um aus der variablen DB-Nummer einen Zeiger für BLKMOV zu bauen.

hatte heinerbollo schon nach gedacht:

Diese Idee hatte ich bereits verworfen, da ich nicht jeweils
532 Bytes hin und herschieben wollte.

Grüße
Gebs
 
Zurück
Oben