Delphi - S7 300 - MPI

gogl

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich möchte in einem MPI Netz von 3 SPS daten abrufen / reinschreiben.

Bisher benutze ich Prodave (möchte ich auch gerne behalten!) und baue zu jeder Adresse der SPS die Verbindung auf, lese Daten aus und baue die Verbindung wieder ab. Danach Verbindungsaufbau zur nächsten SPS usw. Das fuktioniert so auch tadellos, das Problem liegt darin, das das Programm eine Systemauslastung von 90% aufweist durch diesen ständigen auf und abbau der Verbindung.

Ich möchte also einmal eine Verbindung zu allen 3 SPS aufbauen und nur zwischen den Verbindungen schalten. Am Ende des Programms Verbindung abbauen. Die Frage ist nun, wie stelle ich das in Delphi an ?

Vielen Dank, gogl
 
Wird hierzu der PC-Adapter oder eine CP 5x1x verwendet? Welche Version von prodave kommt zum Einsatz?
[Werbung]
Als Alternative zu prodave kann ich (natürlich ;) ) ACCON-AGlink http://www.deltalogic.de/software/aglink/aglink.htm empfehlen. Dies unterstützt ebenfalls die S7-Online-Schnittstelle und mehrere parallele Verbindungen. Der läste Verbindungsab- und Wiederaufbau kann (außer natürlich im Fehlerfalle) entfallen. Die Rechnerbelastung ist ebenfalls minimal, auch bei mehreren SPSen parallel. Beispiel für Delphi ist enthalten. Zusätzlich bietet AGLink die Möglichkeit der Kommunikation im Hintergrund, die Applikation bleibt somit immer optimal bedienbar.
[/Werbung]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich benutze den MPI- PC Adapter und benutze Prodave s7 mini version 5.5.

Wäre gerne an der Lösung mit Prodave interessiert, allein schon aus kostengründen.
 
Zuletzt bearbeitet:
Ich vermute, dass dies mit prodave schwierig wird. Soweit ich weiss, wird durch new_ss automatisch die alte Verbindung abgebaut und die neue aufgebaut. In Version 6 ist ein Hinweis auf eine Funktion SetActiveConnection_ex6 enthalten. Diese Funktion ist allerdings sonst nicht dokumentiert. Aber vermutlich geht es genau in diese Richtung. Ich "darf" an Wochenende sowieso etwas mit prodave testen. Schaue mir dann das Ganze und die Auswirkungen bzgl. Kommunikation an und melde mich dann.
 
Ich mache das Gleiche mit 3 SPS und habe keine derartigen Probleme.
Zum Verbindungsaufbau wird einmal Loadtool() mit den entsprechenden Parametern aufgerufen, danach vor dem Daten lesen jeder SPS new_ss() und read_db() zum Daten holen. Das holen und schreiben von Daten erfolgt in einem eigenen Thread, Delphi-Anwendung hat bei mit inzwischen 'normal_priority_class' (früher 'high_priority_class', muß aber anscheinend nicht sein), derThread hat 'tpHigher'.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
wie genau stellst du das an? die funktion new_ss kenne ich aus dem Handbuch, kann sie jedoch nicht anwenden. Ein Beispielcode könnte mir sicher weiterhelfen.
 
Und wie erfolgt sonst der Wechsel auf eine andere SPS? Doch nicht etwa über unload_tool/load_tool? Und warum kann die Funktion nicht angewandt werden?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In dem Array mit den Verbindungsparametern einfach alle SPSen eintragen und einen Leereintrag anhängen. Dann mit load_tool starten und danach nur noch mit new_ss nur zwischen den einzelnen SPSen umschalten. Ich hoffe, ich habe mich klar ausgedrückt.
 
Code:
type
  plcadrtype = record
    adr: Byte;
    SEGMENTID: Byte;
    SLOTNO: Byte;
    RACKNO: Byte;
  end;
 
BPuf = array[0..1024] of Byte;                            {* Bytepuffer *}
 
var
  plc_adr_table : array of plcadrtype;
  plc_name:array[0..255] of char;
  plc_res ,plc_amount: longint;
  plc_buffer : array[0..512] of word;
  DBAR: BPuf;
 
z.Bsp. in OnCreate der Form
 
Variable SPS-Anzahl
SetLength(plc_adr_table, SimNInt + 2);                  //benötigt wird Array[1..SimN+1] --> Länge dann SimN + 2 wegen Array[0..SimN+1]
 
3 SPS --> kann man dann auch fest in Var vereinbaren
SetLength(plc_adr_table, 4);      
 
for I := 0 to SimDatenListe.SimN - 1 do //je nach SPS-Anzahl anders
begin
  plc_adr_table[i].adr := SimDatenListe.SimEintrag[I + 1].MPIRemote; {adresse}
  plc_adr_table[i].SEGMENTID := 0; {segment id}
  plc_adr_table[i].SLOTNO := 2; {slot nr}
  plc_adr_table[i].RACKNO := 0; {rack nr}
end;
plc_adr_table[SimDatenListe.SimN].adr := 0;
strcopy(plc_name,'S7ONLINE');
 
Bei Aktivierung der Kommunikation
 
InitPG1Fehler := Load_tool(1,addr(plc_name),addr(plc_adr_table[0]));
 
Bei Beenden der Kommunikation
 
InitPG1Fehler := Unload_tool;
 
Beim Lesen der Daten:
 
if (SimDatenListe.MPI_Driver = mpiProdave) then
begin
  //MPI ProDaveS7
  plc_amount := 1024;
  Y[SPS] := new_ss(SPS);
  if Y[SPS] = 0 then
  begin
    Y[SPS] := DB_read(SimDatenListe.SimEintrag[SPS].DBSim,0,plc_amount,DBAR);
    if Y[SPS] = $303 then          //$303 --> DB ist zu kurz
      Y[SPS] := 0;
    if Y[SPS] = 0 then
      DBDat.SPSBuf[SPS] := DBAR;
  end;
 
was hat es mit
SimDatenListe.SimN und SimNInt bzw. SimDatenListe.MPI_Driver = mpiprodave auf sich ?

Ansonsten hilft mir der quelltext schon weiter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das sind interne Variablen aus meinem Progamm. Ich greife auf eine "beliebige" Anzahl von SPS'en zu. SimDatenListe ist eine Strucktur, die für jede SPS, einen Datenbereich enthält. SimN ist die Anzahl der SPS'en, die vom Programm bedient werden.
SimDatenListe.SimN und SimNInt enthält die Anzahl der SPS'en. SimNInt ist nur nochmal eine Kopie von SimDatenliste.SimN, und wird in Setlength zum dynamischen Ändern der Arraygrößen (je nach Anzahl der SPS'en) genutzt.

SimDatenListe.MPI_Driver = mpiprodave enthält den aktiven "Treiber", da mein Programm auch über Libnodave und einen S5-Treiber auf eine SPS zugreifen kann.

Wenn du 3 SPS'en bedienen willst, kannst du SimDatenListe.SimN und SimNInt durch 3 ersetzen, SimDatenListe.MPI_Driver = mpiprodave läßt du weg.
 
hat so super geklappt ! Endlich eine schnelle Kommunikation zwischen verschiedenen SPS'en.

Vielen Dank
 
Zurück
Oben