-> Hier kostenlos registrieren
Hallo!
Für ein Projekt brauche ich eine RTU Modbus-Kommunikation um Parameter zu lesen. Ich habe den folgenden FB geschrieben, der auf den Wago-FB fbmbmasterserial (eine Instanz davon hier masterModbus genannt) basiert ist. Damit kann ich dynamisch die Slave-Adresse, die Registeradresse und die Registeranzahl eingeben und ein Antwort bekommen.
FUNCTION_BLOCK readFromFC
VAR_INPUT
bUnitID:BYTE;
uiReadAddress: UINT;
uiReadQuantity: UINT;
END_VAR
VAR_OUTPUT
returnValue: DWORD;
errorSignal: BOOL;
END_VAR
VAR
utQuery: typMbQuery;
xTxTrigger: BOOL;
utResponse: typMbResponse;
tonDelay : TON := (PT := T#200MS);
sInfo:STRING;
END_VAR
utQuery.bUnitId:= bUnitID;
utQuery.bFunctionCode:= 3;
utQuery.uiReadAddress:= uiReadAddress;
utQuery.uiReadQuantity:= uiReadQuantity;
xTxTrigger:=TRUE;
errorSignal:=TRUE;
modbus.masterModbus(
xConnect := TRUE,
I_Port := IoConfig_Globals.COM1,
udiBaudrate := 19200,
usiDataBits := 8,
eParity := WagoTypesCom.eTTYParity.None,
eStopBits := WagoTypesCom.eTTYStopBits.One,
eHandshake := WagoTypesCom.eTTYHandshake.None,
ePhysical := WagoTypesCom.eTTYPhysicalLayer.RS485_HalfDuplex,
eFrameType := eMbFrameType.RTU,
tTimeOut := T#50MS,
utQuery := utQuery,
xTrigger := xTxTrigger,
utResponse := utResponse
);
IF (uiReadAddress=utResponse.uiAddress) THEN
errorSignal:=FALSE;
IF uiReadQuantity=2 THEN
returnValue:=DWORD_OF_WORD(W1:=utResponse.awData[0] ,
W0:=utResponse.awData[1] );
ELSIF uiReadQuantity=1 THEN
returnValue:=TO_DWORD(utResponse.awData[0]);
END_IF
ELSE errorSignal:=TRUE;
END_IF
Das Problem liegt daran, dass ich diesen FB nur durch Ereignisse aufrufen kann(mit den Visualisierungswerkzeugen). Wenn ich die folgenden Anweisungen in einem zyklischen Programm hinzufüge, wird nur die erste Anweisung durchgeführt:
readFC(bUnitID:=GVL_P.availableFCs.modbusAddress,uiReadAddress:=16#03E7, uiReadQuantity:=1, returnValue=>configurationMode , errorSignal=>eConfigurationMode);
readFC(bUnitID:=GVL_P.availableFCs.modbusAddress,uiReadAddress:=16#0405, uiReadQuantity:=1, returnValue=>torqueChar , errorSignal=>eTorqueChar);
Ich habe versucht verschiedene Instanzen von fbmbmasterserial und readFromFC zu verwenden aber hatte ich dann die Fehlermeldung dass, der Modbus belegt ist.
Es gibt manche Parameter, die müssen echtzeitig gelesen werden. Den FB manuell aufzurufen wäre dann suboptimal.
Was sagt ihr dazu?
Für ein Projekt brauche ich eine RTU Modbus-Kommunikation um Parameter zu lesen. Ich habe den folgenden FB geschrieben, der auf den Wago-FB fbmbmasterserial (eine Instanz davon hier masterModbus genannt) basiert ist. Damit kann ich dynamisch die Slave-Adresse, die Registeradresse und die Registeranzahl eingeben und ein Antwort bekommen.
FUNCTION_BLOCK readFromFC
VAR_INPUT
bUnitID:BYTE;
uiReadAddress: UINT;
uiReadQuantity: UINT;
END_VAR
VAR_OUTPUT
returnValue: DWORD;
errorSignal: BOOL;
END_VAR
VAR
utQuery: typMbQuery;
xTxTrigger: BOOL;
utResponse: typMbResponse;
tonDelay : TON := (PT := T#200MS);
sInfo:STRING;
END_VAR
utQuery.bUnitId:= bUnitID;
utQuery.bFunctionCode:= 3;
utQuery.uiReadAddress:= uiReadAddress;
utQuery.uiReadQuantity:= uiReadQuantity;
xTxTrigger:=TRUE;
errorSignal:=TRUE;
modbus.masterModbus(
xConnect := TRUE,
I_Port := IoConfig_Globals.COM1,
udiBaudrate := 19200,
usiDataBits := 8,
eParity := WagoTypesCom.eTTYParity.None,
eStopBits := WagoTypesCom.eTTYStopBits.One,
eHandshake := WagoTypesCom.eTTYHandshake.None,
ePhysical := WagoTypesCom.eTTYPhysicalLayer.RS485_HalfDuplex,
eFrameType := eMbFrameType.RTU,
tTimeOut := T#50MS,
utQuery := utQuery,
xTrigger := xTxTrigger,
utResponse := utResponse
);
IF (uiReadAddress=utResponse.uiAddress) THEN
errorSignal:=FALSE;
IF uiReadQuantity=2 THEN
returnValue:=DWORD_OF_WORD(W1:=utResponse.awData[0] ,
W0:=utResponse.awData[1] );
ELSIF uiReadQuantity=1 THEN
returnValue:=TO_DWORD(utResponse.awData[0]);
END_IF
ELSE errorSignal:=TRUE;
END_IF
Das Problem liegt daran, dass ich diesen FB nur durch Ereignisse aufrufen kann(mit den Visualisierungswerkzeugen). Wenn ich die folgenden Anweisungen in einem zyklischen Programm hinzufüge, wird nur die erste Anweisung durchgeführt:
readFC(bUnitID:=GVL_P.availableFCs.modbusAddress,uiReadAddress:=16#03E7, uiReadQuantity:=1, returnValue=>configurationMode , errorSignal=>eConfigurationMode);
readFC(bUnitID:=GVL_P.availableFCs.modbusAddress,uiReadAddress:=16#0405, uiReadQuantity:=1, returnValue=>torqueChar , errorSignal=>eTorqueChar);
Ich habe versucht verschiedene Instanzen von fbmbmasterserial und readFromFC zu verwenden aber hatte ich dann die Fehlermeldung dass, der Modbus belegt ist.
Es gibt manche Parameter, die müssen echtzeitig gelesen werden. Den FB manuell aufzurufen wäre dann suboptimal.
Was sagt ihr dazu?