TIA s7-1500 und Modbus over TCP

vollmi

Level-3
Beiträge
5.454
Reaktionspunkte
1.419
Hi

Ich versuche grade eine Modbusverbindung zu mehreren Servern aufzubauen.
Die S7-1500 bringt ja einen Modbustreiber mit. Mit dem habe ich auch schon erfolgreich eine Verbinung zu EINEM Server aufgebaut. Jetzt habe ich aber deren 5 und wollte das einfach für jeden Server Instanzieren.
Das hat aber nicht so wirklich geklappt, der Erste hat die Daten immer gebracht die Nächsten blieben einfach auf 0.

Dann habe ich es jetzt so gemacht dass ich nur einen Treiber Starte und die Verbindung nach done oder error kappe und zum nächsten aufbaue. Macht aber die ganze Sache unnötig komplex.

Hat schonmal jemand mehrere Instanzen des MB_Client paralell erfolgreich laufen lassen?
Mich irritiert etwas die Aussage in der Hilfe.


Heisst das ich muss mit den anderen Instanzen auswerten ob schon eine fremdinstanz aktiv ist und mit dem Req warten? Das wird ja richtig übel wenn man dann diverse aktive Verbindungen gegeneinander verriegeln muss und mit einer Statemaschine jede einzelne Kommunikationsanfrage ankicken muss.
Wozu dann überhaupt mehrere Verbindungen projektieren. Dann kann man sie auch ab und aufbauen.

Ich hätte gerne mehrere MB_Clienten Instanziert und nur für sich abgearbeitet. Das heisst es laufen mehrere IDs paralell.
Halt wie wenn man BSEND/BRECV auf mehreren Verbindungen laufen lässt. Die laufen ja auch paralell gleichzeitig ohne gegeneinander verriegelt zu sein.

mfG René
 
Hallo René,

ich kenne mich da nicht aus, doch aus der Beschreibung des MB_Client entnehme ich, daß man für jede Verbindung eine eigene Instanz des MB_Client braucht, wobei der MB_Client offenbar nicht multiinstanzfähig ist, sondern einen eigenen IDB braucht. Weiters braucht man für jede Verbindung eine eigene Verbindungsbeschreibungs-Struktur an CONNECT mit eindeutiger/verschiedener Verbindungs-ID.

Harald
 
Zuletzt bearbeitet:
Dann muss ich das mit zwei instanzen nochmal ausprobieren. Ich hab den MB_Client nämlich in einer eigenen Instanz laufen lassen. Aber zusammen sind sie dann trotzdem nicht gelaufen.

mfg René
 
So hab noch etwas rumprobiert.
Das ist mal ein erster Wurf. Diesen Baustein habe ich 5 mal instanziert in einer Multiinstanz eines optimierten FBs.
Der FB selbst ist ja nicht optimiert (wegen AT Überlagerung)

Code:
FUNCTION_BLOCK "Modbus_Diris"{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      ID : Word;
   END_VAR


   VAR_OUTPUT 
      Energy { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : "DirisA41_C550_Table";
   END_VAR


   VAR 
      MB_CLIENT {OriginalPartName := 'MB_CLIENT_FB_1084_S71500'; LibVersion := '4.0'} : MB_CLIENT;
      LDB_Config {OriginalPartName := 'TCON_Configured'; LibVersion := '1.0'} : TCON_Configured;
      Req : Bool;
      Disconnect : Bool;
      IEC_Timer_0_Instance {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      IEC_Timer_0_Instance_1 {OriginalPartName := 'IEC_TIMER'; LibVersion := '1.0'} : TON_TIME;
      Zaehler : Int;
      F_TRIG_Instance {OriginalPartName := 'F_TRIG_1500'; LibVersion := '1.0'} : F_TRIG;
      R_TRIG_error {OriginalPartName := 'R_TRIG_1500'; LibVersion := '1.0'} : R_TRIG;
      R_TRIG_Done {OriginalPartName := 'R_TRIG_1500'; LibVersion := '1.0'} : R_TRIG;
      AktuellerLDB : Int;
      Status_Save : Word;
      Config_Save {OriginalPartName := 'TCON_Configured'; LibVersion := '1.0'} : Array[0..100] of TCON_Configured;
      ReqTrigger {OriginalPartName := 'R_TRIG_1500'; LibVersion := '1.0'} : R_TRIG;
      Daten : Array[0..50] of Int;
      strDaten { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} AT Daten : "DirisA41_C550_Table";
   END_VAR


   VAR_TEMP 
      index : Int;
      RET_val : Int;
   END_VAR


   VAR CONSTANT 
      Datenlänge : UInt := 20;
   END_VAR




BEGIN
	        #LDB_Config.ConnectionType := 254;
	        #LDB_Config.InterfaceId := 100;
	        #LDB_Config.ID := #ID;
	        
	#MB_CLIENT(REQ := #Req,
	           DISCONNECT := false,
	           MB_MODE := 0,
	           MB_DATA_ADDR := 40001,
	           MB_DATA_LEN := #Datenlänge,
	           MB_DATA_PTR := #Daten,
	           CONNECT := #LDB_Config);
	
	#Energy := #strDaten;
	
	
	
	#Req := true;
	 
	#R_TRIG_error(CLK:=#MB_CLIENT.ERROR);
	#R_TRIG_Done(CLK:=#MB_CLIENT.DONE);
	
	
	
	IF #R_TRIG_Done.Q OR #R_TRIG_error.Q OR #IEC_Timer_0_Instance.Q THEN
	    #Req := false;
	END_IF;
	
	#IEC_Timer_0_Instance(IN:=#Req,
	                      PT:=t#10s);
	
	IF #IEC_Timer_0_Instance.Q THEN
	        #Req := false;
	END_IF;
	
	IF #MB_CLIENT.ERROR THEN
	    #Status_Save := #MB_CLIENT.STATUS;
	    
	END_IF;
END_FUNCTION_BLOCK

Ich schreibe die Daten also erstmal in einen Statischen Bereich der eigenen Instanz und kopiere sie dann auf die Schnittstelle.

In der Hilfe zum modbus Baustein steht aber das es zwingend ein globaler DB mit optimiertem Zugrif sein muss. Funktioniert aber auch mit einem nicht optimierten Zugriff in einer Instanz.


Da sieht man mal wieder, die Bausteine programmiert sicher jemand der noch nie ein Wort mit dem Dokuschreiber gesprochen bzw gemailt hat. Ich bezweifle auch dass die dieselbe Sprache sprechen.

mfG René
 
In der Hilfe zum modbus Baustein steht aber das es zwingend ein globaler DB mit optimiertem Zugrif sein muss. Funktioniert aber auch mit einem nicht optimierten Zugriff in einer Instanz.
Oh, interessant.

Hatte mich nämlich auch schon gefragt wie man am vernünftig (blockweise) von einem optimierten Array_of_WORD des Empfangspuffers in einen optimierten Struct im Zieldatenbereich kopieren soll? Dafür geht keiner der MOVE-Befehle. Nicht optimiert ginge der zumindest SFC20 oder AT.
 
Zuletzt bearbeitet:
Für die Nutzung dieser Website sind Cookies erforderlich. Du musst diese akzeptieren, um die Website weiter nutzen zu können. Erfahre mehr…