Started Modbus Master for Levitronix Pumps and Flow sensors
This commit is contained in:
17
PLC/LibraryCandidates/ModbusMaster/E_Modbus_Cmd.TcDUT
Normal file
17
PLC/LibraryCandidates/ModbusMaster/E_Modbus_Cmd.TcDUT
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<DUT Name="E_Modbus_Cmd" Id="{750955bf-9dc1-4cb7-bee0-c1c010c28bac}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
{attribute 'strict'}
|
||||
{attribute 'to_string'}
|
||||
TYPE E_Modbus_Cmd :
|
||||
(
|
||||
NONE := 0,
|
||||
READ_HOLDING,
|
||||
READ_INPUTS,
|
||||
WRITE_HOLDING
|
||||
);
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
147
PLC/LibraryCandidates/ModbusMaster/FB_ModbusMaster.TcPOU
Normal file
147
PLC/LibraryCandidates/ModbusMaster/FB_ModbusMaster.TcPOU
Normal file
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ModbusMaster" Id="{90292ada-f5b3-4b38-a85e-d6dc52e68612}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ModbusMaster
|
||||
VAR_INPUT
|
||||
timGapTime : TIME := T#20MS;
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
xBusy : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
// Modbus master comm fb
|
||||
_fbMaster : ModbusRtuMasterV2_KL6x22B;
|
||||
|
||||
// Request queue
|
||||
_astReqQueue : ARRAY[0..(GVL_ModbusMaster.QUEUE_SIZE - 1)] OF ST_Modbus_Req;
|
||||
_iHead : INT := 0;
|
||||
_iTail : INT := 0;
|
||||
|
||||
// Current request from queue
|
||||
_stCurrReq : ST_Modbus_Req;
|
||||
|
||||
// Gap timer so that we dont send requests back to back
|
||||
_tonGapTimer : TON;
|
||||
|
||||
// State machine state
|
||||
_iState : INT := 0;
|
||||
|
||||
// Rerun flag for faster state machine
|
||||
_xSMCycleDone : BOOL := TRUE;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Main state machine
|
||||
REPEAT
|
||||
// Safety reset
|
||||
_xSMCycleDone := TRUE;
|
||||
|
||||
CASE _iState OF
|
||||
// Wait for gap timer to be expired
|
||||
0:
|
||||
_tonGapTimer(IN := TRUE);
|
||||
|
||||
IF _tonGapTimer.Q THEN
|
||||
_tonGapTimer(IN := FALSE);
|
||||
_xSMCycleDone := FALSE;
|
||||
_iState := 1;
|
||||
END_IF
|
||||
|
||||
// Get next request if there is one in the queue
|
||||
1:
|
||||
// Get next request from queue if there is one
|
||||
IF M_Dequeue() THEN
|
||||
// Set fb data
|
||||
_fbMaster.UnitID := _stCurrReq.bySlaveAddr;
|
||||
_fbMaster.MBAddr := _stCurrReq.wStartAddr;
|
||||
_fbMaster.Quantity := _stCurrReq.wQuantity;
|
||||
_fbMaster.cbLength := _stCurrReq.wDataSize;
|
||||
_fbMaster.pMemoryAddr := _stCurrReq.pvData;
|
||||
|
||||
// Rerun statemachine this cycle
|
||||
_xSMCycleDone := FALSE;
|
||||
_iState := 10;
|
||||
END_IF
|
||||
|
||||
// Execute dequeued command
|
||||
10:
|
||||
// Call modbus master corresponding function
|
||||
CASE _stCurrReq.eCmd OF
|
||||
E_Modbus_Cmd.READ_HOLDING:
|
||||
_fbMaster.ReadRegs();
|
||||
|
||||
E_Modbus_Cmd.READ_INPUTS:
|
||||
_fbMaster.ReadInputRegs();
|
||||
|
||||
E_Modbus_Cmd.WRITE_HOLDING:
|
||||
_fbMaster.WriteRegs();
|
||||
|
||||
// Reject unknown commands
|
||||
ELSE
|
||||
_stCurrReq.pxError^ := TRUE;
|
||||
_iState := 0;
|
||||
END_CASE
|
||||
|
||||
// Wait for fb to be done
|
||||
IF (NOT _fbMaster.BUSY) THEN
|
||||
_stCurrReq.pxDone^ := TRUE;
|
||||
// Rerun statemachine this cycle
|
||||
_xSMCycleDone := FALSE;
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
IF _fbMaster.Error THEN
|
||||
_stCurrReq.pxError^ := TRUE;
|
||||
// Rerun statemachine this cycle
|
||||
_xSMCycleDone := FALSE;
|
||||
_iState := 0;
|
||||
END_IF
|
||||
END_CASE
|
||||
|
||||
// Check if we want to rerun the state machine
|
||||
UNTIL _xSMCycleDone
|
||||
END_REPEAT
|
||||
]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="M_Dequeue" Id="{083aa9a5-ac23-4366-b080-ab00cfa6b4ce}">
|
||||
<Declaration><![CDATA[METHOD PRIVATE M_Dequeue : BOOL
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// No entries in queue
|
||||
IF _iHead = _iTail THEN
|
||||
M_Dequeue := FALSE;
|
||||
ELSE
|
||||
// Get next entry
|
||||
_stCurrReq := _astReqQueue;
|
||||
_iHead := (_iHead + 1) MOD GVL_ModbusMaster.QUEUE_SIZE;
|
||||
M_Dequeue := TRUE;
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="M_Enqueue" Id="{37963eb3-9b4c-4945-ba35-cfefd78cb427}">
|
||||
<Declaration><![CDATA[METHOD M_Enqueue : BOOL
|
||||
VAR_INPUT
|
||||
stReq : ST_Modbus_Req;
|
||||
END_VAR
|
||||
VAR
|
||||
_iNextTail : INT;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Calculate next entry
|
||||
_iNextTail := (_iTail + 1) MOD GVL_ModbusMaster.QUEUE_SIZE;
|
||||
|
||||
// If next tail euqals head, the buffer is full
|
||||
// so disgard this request
|
||||
IF _iNextTail = _iHead THEN
|
||||
M_Enqueue := FALSE;
|
||||
ELSE
|
||||
_astReqQueue[_iNextTail] := stReq;
|
||||
_iTail := _iNextTail;
|
||||
M_Enqueue := TRUE;
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<GVL Name="GVL_ModbusMaster" Id="{ea0aca47-a85c-4c28-9c28-281101181bed}">
|
||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||
VAR_GLOBAL CONSTANT
|
||||
QUEUE_SIZE : INT := 10;
|
||||
END_VAR]]></Declaration>
|
||||
</GVL>
|
||||
</TcPlcObject>
|
||||
18
PLC/LibraryCandidates/ModbusMaster/ST_Modbus_Req.TcDUT
Normal file
18
PLC/LibraryCandidates/ModbusMaster/ST_Modbus_Req.TcDUT
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<DUT Name="ST_Modbus_Req" Id="{6734b81c-4e20-45e9-85c3-05db86b740c0}">
|
||||
<Declaration><![CDATA[TYPE ST_Modbus_Req :
|
||||
STRUCT
|
||||
bySlaveAddr : BYTE;
|
||||
eCmd : E_Modbus_Cmd;
|
||||
wStartAddr : WORD;
|
||||
wQuantity : WORD;
|
||||
pvData : PVOID;
|
||||
wDataSize : WORD;
|
||||
pxDone : POINTER TO BOOL;
|
||||
pxError : POINTER TO BOOL;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
Reference in New Issue
Block a user