True 98ed6c72-1d8a-444d-b9fb-44a679624f78 00000000-0000-0000-0000-000000000000 6-Comms 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 e59dc300-e37a-4c37-997b-021563304d7e 738bea1e-99bb-4f04-90bb-a7a567e74e3a 639034841590379670 21af5390-2942-461a-bf89-951aaf6999f1 e59dc300-e37a-4c37-997b-021563304d7e atomLibrary -1 False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 00000000-0000-0000-0000-000000000000 ModbusMaster 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 98ed6c72-1d8a-444d-b9fb-44a679624f78 738bea1e-99bb-4f04-90bb-a7a567e74e3a 639034841590449813 21af5390-2942-461a-bf89-951aaf6999f1 98ed6c72-1d8a-444d-b9fb-44a679624f78 atomLibrary 6-Comms -1 False f228f401-6c74-4359-8ff1-b15b675180a4 00000000-0000-0000-0000-000000000000 atMbClientToString 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 2db5746d-d284-4425-9f7f-2663a34b0ebc a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841591030946 {attribute 'qualified_only'} {attribute 'strict'} TYPE atMbClientToString : ( noneOk := 0, someOk := 1, allOk := 2 ); END_TYPE f228f401-6c74-4359-8ff1-b15b675180a4_Decl_LineIds 11 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 43f52a7a-cd45-4c0a-8652-9b18c69324d7 00000000-0000-0000-0000-000000000000 atMBExceptionCodes 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 2db5746d-d284-4425-9f7f-2663a34b0ebc a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841590519807 {attribute 'qualified_only'} // {attribute 'strict'} NOT strict so can set with modbusFB.ExceptionCodes. TYPE atMBExceptionCodes : ( // Local / transport-level (non-Modbus) result TIMEOUT := -1, // Communication timeout / no response // Modbus exception codes (returned in exception response PDU) RESPONSE_SUCCESS := 16#00, // Everything OK (no exception) ILLEGAL_FUNCTION := 16#01, // Function code not supported by slave ILLEGAL_DATA_ADDRESS := 16#02, // Data address not valid for slave (out of range / not mapped) ILLEGAL_DATA_VALUE := 16#03, // Data value not valid (bad length/value/etc.) SLAVE_DEVICE_FAILURE := 16#04, // Unrecoverable error while performing the requested action ACKNOWLEDGE := 16#05, // Request accepted; processing started (use to avoid master timeout) SLAVE_DEVICE_BUSY := 16#06, // Slave busy (e.g. long operation in progress); retry later MEMORY_PARITY_ERROR := 16#08, // Memory parity error (special case; historically for FC 20/21) GATEWAY_PATH_UNAVAILABLE := 16#0A, // Gateway problem: path unavailable / misconfigured / overloaded GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND := 16#0B // Gateway problem: target device did not respond ); END_TYPE 43f52a7a-cd45-4c0a-8652-9b18c69324d7_Decl_LineIds 78 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa 00000000-0000-0000-0000-000000000000 atMbClient 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639251309599709549 None IF nativeMode THEN nativeCycle(); RETURN; END_IF; //Modbus connection //Connects to a modbus slave //2024-11-23 ATM Cleaned up code //2024-12-23 CWD Add statistics //2025-06-18 CWD Add Get priorities and interval working together //2026-03-26 ATM Clean up code, more testing //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests // ===== Main function call ===== IF (in_resetStats) THEN resetStats(); in_resetStats := FALSE; END_IF // ===== Connect and disconnect logic ===== //Timer to trigger a connection if not connected for to long reconnectTimer( IN := NOT client.xConnect AND NOT client.xConnected AND NOT client.xError, PT := RECONNECT_DELAY ); //Timer to trigger a disconnection if connect fails disconnectTimer( IN:=client.xConnect AND NOT client.xConnected, PT:=DISCONNECT_DELAY ); //All requests offline timer allRequestsOfflineTON( IN := allRequestsOffline AND client.xConnected, PT := ALL_OFFLINE_DELAY ); //Destroy Client delay timer recreateClientDly( IN:=destroyClient, PT:=RECREATE_CLIENT_DELAY ); IF disconnectTimer.Q OR allRequestsOfflineTON.Q OR client.xError OR recreateTest THEN //All requests are offline //Connection attempt failed so disconnect //If Client has error then disconnect connect := FALSE; recreateTest := FALSE; destroyClient := TRUE; setAllRequestsOffline(); ELSIF reconnectTimer.Q AND NOT destroyClient THEN //If not connected then attempt connect connect := TRUE; connectCnt := connectCnt + 1; //for debugging END_IF; IF recreateClientDly.Q THEN destroyClient := FALSE; recreateClient(); END_IF; // If some reason gets stuck at busy, (This shouldnt happen, but force a reconnect). forceConnect( in := connect <> client.xConnect, pt := FORCE_RECONNECT_DELAY ); // Only flip status of xConnect if no current request is active. IF (connect <> client.xConnect) AND_THEN (allRequestsComplete OR forceConnect.Q) THEN client.xConnect := connect; END_IF // Moved this lower down, so xConnect happens one scan sooner. client(); // If there are no requests, dont neeed to even do anything. IF requestCnt = 0 THEN numMsgSent := 0; numMsgReply := 0; allRequestsOnline := 0; allRequestsOffline := 0; RETURN; END_IF requestNotExecutingTON(IN := NOT requestExecuting, PT := NEXT_REQUEST_DELAY); //Only delaying 1 ms. This may not do much, was put in during testing, but now it almost seems unnecesary // ===== Execute next request ===== IF connect AND client.xConnect AND client.xConnected AND (requestNotExecutingTON.Q OR NEXT_REQUEST_DELAY = T#0MS) THEN //Find the lowest priority of overdue requests nextIdx := -1; priorityLowest := PRIORITY_NONE; highestTimeSinceRun := 0; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF (requests[i]^.in_priorityCurrent < priorityLowest OR (requests[i]^.in_priorityCurrent = priorityLowest AND requests[i]^.stats.sinceLastExec > highestTimeSinceRun)) AND requests[i]^.stats.sinceLastExec > TIME_TO_UDINT(requests[i]^.in_minDelay) THEN priorityLowest := requests[i]^.in_priorityCurrent; highestTimeSinceRun := requests[i]^.stats.sinceLastExec; nextIdx := i; END_IF END_FOR //Decriment all request priorities by one. IF priorityLowest < PRIORITY_NONE AND priorityLowest > 0 THEN //Only if priority FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO requests[i]^.in_priorityCurrent := requests[i]^.in_priorityCurrent - 1; IF requests[i]^.in_priorityCurrent < 0 THEN requests[i]^.in_priorityCurrent := 0; END_IF END_FOR END_IF IF nextIdx >= 0 THEN activeIndex := nextIdx; END_IF END_IF processAllRequests(); allRequestsOnline := (activeReqCnt > 0) AND (onlineCnt = activeReqCnt); allRequestsOffline := (activeReqCnt > 0) AND (onlineCnt = 0); // ===== Client statistics ===== //Get a sum of done and error counts from all requests reqErrSum := 0; reqDoneSum := 0; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO reqDoneSum := reqDoneSum + requests[i]^.stats.doneCnt; reqErrSum := reqErrSum + requests[i]^.stats.errorCnt; //copy stats to array for debugging reqStats[i] := ADR(requests[i]^.stats); END_FOR //Every time the tx message counter changes increment msg count and add last transaction time IF client.udiNumMsgSent <> msgCountLast THEN msgCountLast := client.udiNumMsgSent; msgTimeSum := msgTimeSum + client.udiLastTransactionTime; msgCountSum := msgCountSum + 1; END_IF //Every 1 second compute statistics pulse(); IF pulse.T_Sec_OS THEN msgLastSecondCnt := msgCountSum; msgCountSum := 0; msgLastSecondTime := msgTimeSum; msgTimeSum := 0; END_IF numMsgSent := client.udiNumMsgSent; numMsgReply := client.udiNumMsgReply; bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa_Impl_LineIds {attribute 'monitoring_display' := 'toString'} {attribute 'no_assign'} FUNCTION_BLOCK ABSTRACT atMbClient VAR_INPUT {attribute 'symbol' := 'none'} in_timeout: TIME := T#0MS; // If this is set, this will be used on requests, otherwise it will be calculated from in_dataRate. {attribute 'symbol' := 'none'} in_resetStats: BOOL; // Set this bool to true to reset statistics. END_VAR VAR_OUTPUT {attribute 'symbol' := 'none'} msgLastSecondCnt: UDINT; //Messages in the last second {attribute 'symbol' := 'none'} msgLastSecondTime: UDINT; //Total amount of time for all messages sent last second in ms {attribute 'symbol' := 'none'} numMsgSent: UDINT; {attribute 'symbol' := 'none'} numMsgReply: UDINT; {attribute 'symbol' := 'none'} allRequestsOnline: BOOL; //All requests are working //{attribute 'symbol' := 'none'} reqStats: ARRAY[0..99] OF POINTER TO atMbRequestStats; // For debugging modbus requests END_VAR VAR {attribute 'symbol' := 'none'} datarate: DINT := 0; //Bits per second data rate. Used to calculate reply timeout. Based on amount of time to transmit holding register read for max amount of registers. Default 154705 for Modbus TCP = 17ms to transmit 2650 bits {attribute 'symbol' := 'none'} client: REFERENCE TO ModbusFB.Client; // This is generated internally, no need to set. {attribute 'symbol' := 'none'} connectCnt: DINT; //Number of connection attempts {attribute 'symbol' := 'none'} initDone: BOOL; {attribute 'symbol' := 'none'} disconnectTimer: TON; //Connecting but not connected delay {attribute 'symbol' := 'none'} reconnectTimer: TON; //Not connecting and not connected delay {attribute 'symbol' := 'none'} msgCountLast: UDINT; //Last message count {attribute 'symbol' := 'none'} msgCountSum: UDINT; //Message count accumulator {attribute 'symbol' := 'none'} msgTimeSum: UDINT; //Amount of time for messsages accumulator {attribute 'symbol' := 'none'} pulse: atPulse; //Pulse generator {attribute 'symbol' := 'none'} requests: ARRAY[0..99] OF POINTER TO atMbReqBase; //list of request to direct {attribute 'symbol' := 'none'} requestCnt: UINT; //Number of active requests {attribute 'symbol' := 'none'} reqDoneSum: UDINT; //Count of done result on all requests {attribute 'symbol' := 'none'} reqErrSum: UDINT; //Count of error result on all requests {attribute 'symbol' := 'none'} i: DINT; //Loop variable {attribute 'symbol' := 'none'} nextIdx: DINT := -1; //Index of the active request {attribute 'symbol' := 'none'} priorityLowest: INT; //lowest request priority {attribute 'symbol' := 'none'} highestTimeSinceRun: UDINT; //lowest request priority {attribute 'symbol' := 'none'} allRequestsOfflineTON: TON; //All requests are offline delay {attribute 'symbol' := 'none'} requestNotExecutingTON: TON; //Delay after there are no requests execting {attribute 'symbol' := 'none'} recreateClientDly: TON; //Delay to make new client after force fail {attribute 'symbol' := 'none'} allRequestsOffline: BOOL; //All requests are offline {attribute 'symbol' := 'none'} connect: BOOL; // this is more of a "Request to connect, Requet to disconnect", will drop xConnect once all requests are done, wont start requests unless this is true. {attribute 'symbol' := 'none'} forceConnect: TON; //If after 5 seconds, all requests are still ofline, just force a reconnect. test1: REAL; test2: REAL; destroyClient: BOOL; recreateTest: BOOL; END_VAR VAR CONSTANT {attribute 'symbol' := 'none'} NEXT_REQUEST_DELAY: TIME := T#0MS; // Dont seem to need a delay {attribute 'symbol' := 'none'} RECONNECT_DELAY: TIME := T#500MS; {attribute 'symbol' := 'none'} DISCONNECT_DELAY: TIME := T#500MS; {attribute 'symbol' := 'none'} RECREATE_CLIENT_DELAY: TIME := T#1000MS; {attribute 'symbol' := 'none'} ALL_OFFLINE_DELAY: TIME := T#2S; {attribute 'symbol' := 'none'} FORCE_RECONNECT_DELAY: TIME := T#1S; {attribute 'symbol' := 'none'} PRIORITY_NONE: INT := 32767; END_VAR VAR nativeMode : BOOL; nativeHandle : UDINT; nativeIP : DWORD; nativePort : UINT; nativeNowUs : SYSTIME; nativeNowMs : ULINT; nativeStatus : ARRAY[0..23] OF UDINT; nativeActiveIndex : DINT := -1; nativeSelected : POINTER TO atMbReqBase; nativeResultReady : BOOL; nativeFinishedIndex : DINT := -1; nativeCallResult : UDINT; nativeWindowStart : ULINT; nativePrevConnected : BOOL; nativeEnable : BOOL := TRUE; nativeConnectTimeout : UDINT := 2000; nativeRetryDelay : UDINT := 1000; nativeHoldUncertainWrites : BOOL := FALSE; END_VAR VAR_INPUT {attribute 'symbol' := 'none'} nativeIO : ARRAY[0..1999] OF WORD; {attribute 'symbol' := 'none'} nativeActiveRequest : POINTER TO atMbReqBase; {attribute 'symbol' := 'none'} nativeArgUnit : BYTE; {attribute 'symbol' := 'none'} nativeArgFunction : BYTE; {attribute 'symbol' := 'none'} nativeArgAddress : UINT; {attribute 'symbol' := 'none'} nativeArgQuantity : UINT; {attribute 'symbol' := 'none'} nativeArgTimeout : UDINT := 1000; {attribute 'symbol' := 'none'} nativeSent : UDINT; {attribute 'symbol' := 'none'} nativeReplied : UDINT; {attribute 'symbol' := 'none'} nativeWindowCount : UDINT; {attribute 'symbol' := 'none'} nativeWindowTime : UDINT; END_VAR VAR_OUTPUT out_connected : BOOL; out_connectionState : UDINT; out_lastNativeError : UDINT; out_socketError : UDINT; out_reconnectCount : UDINT; out_registrationFull : BOOL; END_VAR bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa_Decl_LineIds 3369 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 17c2ab7a-4d60-48ec-966f-339ec83a75e9 00000000-0000-0000-0000-000000000000 atMbClientRTU 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574649591897 None //Modbus connection //Connects to a modbus slave //2024-06-27 CWD Initial create //2024-11-13 CWD Fix problem with not connecting properly on power up //2024-11-15 ATM Move from structure to defaults. //2024-11-23 ATM Cleaned up code //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests IF NOT setupClient() THEN RETURN; END_IF //Set dataRate //This is based on an 8 byte request and a 255 byte reply dataRate := in_baudRate; // ===== Initialization ===== // if the param changes, force a reinit IF _client^.iPort <> in_port OR _client^.dwBaudrate <> in_baudRate OR _client^.byDataBits <> in_dataBits OR _client^.eParity <> in_parity OR _client^.eStopBits <> in_stopBits THEN initDone := FALSE; END_IF; IF NOT initDone THEN initDone := TRUE; //Other configuration parameters _client^.iPort := in_port; _client^.dwBaudrate := in_baudRate; _client^.byDataBits := in_dataBits; _client^.eParity := in_parity; _client^.eStopBits := in_stopBits; _client^.eDTRcontrol := 0; _client^.eRTScontrol := 0; _client^.eRTUASCII := 0; _client^.udiLogOptions := ModbusFB.LoggingOptions.All; _client^.xConnect:=FALSE; END_IF SUPER^(); 17c2ab7a-4d60-48ec-966f-339ec83a75e9_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbClientRTU EXTENDS atMbClient VAR_INPUT {attribute 'symbol' := 'none'} in_port: BYTE := 0; //0=None, 1,2,3,4 {attribute 'symbol' := 'none'} in_baudRate: UINT := 9600; //4800, 9600, 19200, 38400, 57600, 115200 {attribute 'symbol' := 'none'} in_parity: BYTE := 0; //0=None, 1=Odd, 2=Even {attribute 'symbol' := 'none'} in_dataBits: BYTE := 8; //8=8 {attribute 'symbol' := 'none'} in_stopBits: BYTE := 1; //1=OneStopBit, 2=One5StopBits, 3=TwoStopBits END_VAR VAR {attribute 'symbol' := 'none'} _client: POINTER TO ModbusFB.ClientSerial; END_VAR 17c2ab7a-4d60-48ec-966f-339ec83a75e9_Decl_LineIds 607 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 00000000-0000-0000-0000-000000000000 atMbClientTCP 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574649747183 None nativeMode := TRUE; nativeIP := SHL(BYTE_TO_DWORD(in_ipAddress[0]),24) OR SHL(BYTE_TO_DWORD(in_ipAddress[1]),16) OR SHL(BYTE_TO_DWORD(in_ipAddress[2]),8) OR BYTE_TO_DWORD(in_ipAddress[3]); nativePort := in_port; nativeConnectTimeout := MAX(UDINT#1,TIME_TO_UDINT(in_connectTimeout)); nativeRetryDelay := MAX(UDINT#1,TIME_TO_UDINT(in_reconnectDelay)); nativeHoldUncertainWrites := in_holdUncertainWrites; IF nativeHandle <> 0 AND ((nativeEndpointIP <> nativeIP) OR (nativeEndpointPort <> nativePort) OR (nativeConfigConnect <> nativeConnectTimeout) OR (nativeConfigRetry <> nativeRetryDelay) OR NOT in_enable) THEN nativeRelease(); END_IF; nativeEndpointIP := nativeIP; nativeEndpointPort := nativePort; nativeConfigConnect := nativeConnectTimeout; nativeConfigRetry := nativeRetryDelay; nativeEnable := in_enable; IF in_baudrate <> 0 THEN dataRate := in_baudrate; ELSE dataRate := 105200; END_IF; SUPER^(); 269ad87c-8ffe-4a28-9e12-2f2da3f7c570_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbClientTCP EXTENDS atMbClient VAR_INPUT {attribute 'symbol' := 'none'} in_ipAddress: ARRAY[0..3] OF BYTE; // TCP IP Address {attribute 'symbol' := 'none'} in_port: UINT := 502; // TCP port {attribute 'symbol' := 'none'} in_baudrate: UINT := 0; // Set this if using RS485 to TCP Converter, used to calculate timeout. END_VAR VAR {attribute 'symbol' := 'none'} _client: POINTER TO ModbusFB.ClientTCP; END_VAR VAR_INPUT in_enable : BOOL := TRUE; in_connectTimeout : TIME := T#2S; in_reconnectDelay : TIME := T#1S; in_holdUncertainWrites : BOOL := FALSE; END_VAR VAR nativeEndpointIP : DWORD; nativeEndpointPort : UINT; nativeConfigConnect : UDINT; nativeConfigRetry : UDINT; END_VAR 269ad87c-8ffe-4a28-9e12-2f2da3f7c570_Decl_LineIds 1168 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 00000000-0000-0000-0000-000000000000 atMbReqBase 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574649837310 None //Modbus request //Makes a request using the start and quantity, puts the result into data //2024-06-27 CWD Initial create //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage IF NOT __ISVALIDREF(client) THEN RETURN; END_IF //Add this request to the clients request array client.addRequest(THIS); //fault logic //Fault if error //errTrig(CLK := stats.reqError); //IF errTrig.Q THEN // out_fault := TRUE; //END_IF //not faulted if a succesfull request //doneTrig(CLK := stats.reqDone); // also clear fault if not active //IF doneTrig.Q OR NOT stats.active THEN // out_fault := FALSE; //END_IF IF in_quantity <= dataSize THEN stats.reqLength := in_quantity; ELSE stats.reqLength := dataSize; END_IF; 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK ABSTRACT atMbReqBase VAR_INPUT {attribute 'symbol' := 'none'} client: REFERENCE TO atMbClient; // Instance of atMBClient {attribute 'symbol' := 'none'} in_startAddr: UINT; {attribute 'symbol' := 'none'} in_quantity: UINT; {attribute 'symbol' := 'none'} in_dataOffset: UINT; // Offset position for data into array. {attribute 'symbol' := 'none'} in_unitId: BYTE := 0; {attribute 'symbol' := 'none'} in_timeout: SYSTIME := 0; // timeout in ms, if not set, will be 1ms less than interval. {attribute 'symbol' := 'none'} in_minDelay: TIME := T#10MS; // This is the minimum delay between queries, only relevent if high priority. {attribute 'symbol' := 'none'} in_prioritySetpoint: INT := 50; // this requests priority compared to other requests. Lower value is higher priority. {attribute 'symbol' := 'none'} in_priorityCurrent: INT; //Current priority. This is decrimented and the request is executed when at zero. {attribute 'symbol' := 'none'} stats: atMbRequestStats; //Request stats END_VAR VAR_OUTPUT //{attribute 'symbol' := 'none'} //out_fault: BOOL; END_VAR VAR {attribute 'symbol' := 'none'} dataSize: UINT; //{attribute 'symbol' := 'none'} //quantUsed: UINT; //{attribute 'symbol' := 'none'} //doneTrig: R_TRIG; //Succesful request trigger //{attribute 'symbol' := 'none'} //errTrig: R_TRIG; //Error request result trigger {attribute 'symbol' := 'none'} request: REFERENCE TO ModbusFB.ClientRequest;; END_VAR VAR nativeFunction : BYTE; nativeCount : UINT; nativeOffset : UINT; nativeInFlight : BOOL; nativeReadComplete : BOOL; nativeCopyAllowed : BOOL; nativeWriteHold : BOOL; nativeStartMs : ULINT; nativeLoop : DINT; nativeRC : UDINT; END_VAR VAR_OUTPUT out_nativeError : UDINT; out_socketError : UDINT; out_writeUncertain : BOOL; out_validData : BOOL; out_dataAgeMs : ULINT; out_stale : BOOL := TRUE; out_parameterError : BOOL; END_VAR VAR_INPUT in_staleAfter : TIME := T#2S; END_VAR 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37_Decl_LineIds 3210 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False a77a90fd-541d-4ce9-ad97-7024224bbab4 00000000-0000-0000-0000-000000000000 atMbReqReadCoil 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502146913881 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-11-16 CWD Added read coil //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); a77a90fd-541d-4ce9-ad97-7024224bbab4_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqReadCoil EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF BOOL to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF BOOL; END_VAR VAR_OUTPUT END_VAR VAR {attribute 'symbol' := 'none'} readCoilReq: POINTER TO ModbusFB.ClientRequestReadCoils; END_VAR a77a90fd-541d-4ce9-ad97-7024224bbab4_Decl_LineIds 193 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 1a3278f4-a658-407c-968a-21aa53361562 00000000-0000-0000-0000-000000000000 atMbReqReadDiscrete 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147014015 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-06-27 CWD Initial Create //2024-10-21 CWD Set udiTimeout to 0 as this was causing problems with detecting an actual no reply timeout from the slave //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); 1a3278f4-a658-407c-968a-21aa53361562_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqReadDiscrete EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF BOOL to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF BOOL; END_VAR VAR_OUTPUT END_VAR VAR {attribute 'symbol' := 'none'} readDiscreteReq: POINTER TO ModbusFB.ClientRequestReadDiscreteInputs; END_VAR 1a3278f4-a658-407c-968a-21aa53361562_Decl_LineIds 184 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 73b10819-9112-4811-9583-e2735d2b13ea 00000000-0000-0000-0000-000000000000 atMbReqReadHolding 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147099228 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-06-27 CWD Initial Create //2024-10-21 CWD Set udiTimeout to 0 as this was causing problems with detecting an actual no reply timeout from the slave //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); 73b10819-9112-4811-9583-e2735d2b13ea_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqReadHolding EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF UINT to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF UINT; END_VAR VAR_OUTPUT END_VAR VAR {attribute 'symbol' := 'none'} readHoldReq: POINTER TO ModbusFB.ClientRequestReadHoldingRegisters; END_VAR 73b10819-9112-4811-9583-e2735d2b13ea_Decl_LineIds 173 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False a5dbc9b0-a1a1-4281-a685-ec85b35bb866 00000000-0000-0000-0000-000000000000 atMbReqReadInput 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147179217 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-06-27 CWD Initial Create //2024-10-21 CWD Set udiTimeout to 0 as this was causing problems with detecting an actual no reply timeout from the slave //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); a5dbc9b0-a1a1-4281-a685-ec85b35bb866_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqReadInput EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF UINT to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF UINT; END_VAR VAR_OUTPUT END_VAR VAR {attribute 'symbol' := 'none'} readInputReq: POINTER TO ModbusFB.ClientRequestReadInputRegisters; END_VAR a5dbc9b0-a1a1-4281-a685-ec85b35bb866_Decl_LineIds 167 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 48b508fd-2131-484c-ba4a-20e61e66a5b2 00000000-0000-0000-0000-000000000000 atMbRequestStats 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147425423 None SysTimeGetUs(TSSus); IF (reqLength = 0) THEN active := FALSE; doneCnt := 0; errorCnt := 0; lastErrorId := modbusFB.Error.OK; lastExceptionCode := atMBExceptionCodes.RESPONSE_SUCCESS; execute := FALSE; online := FALSE; offline := FALSE; reqDone := FALSE; reqBusy := FALSE; reqError := FALSE; sinceLastExec := 0; RETURN; END_IF active := TRUE; inDoneDeb(in_raw := reqDone, in_delOn := T#0S, in_DelOff := lightOn); reqDoneLight := inDoneDeb.out_val; inBusyDeb(in_raw := reqBusy, in_delOn := T#0S, in_DelOff := lightOn); reqBusyLight := inBusyDeb.out_val; inErrDeb(in_raw := reqError, in_delOn := T#0S, in_DelOff := lightOn); reqErrorLight := inErrDeb.out_val; //Debounced execute indicator for debbugging executeDeb(in_raw := _execute, in_delOn := T#0S, in_DelOff := lightOn); executeLight := executeDeb.out_val; //Set online status IF nativeResponseSeen OR doneCntRst >=3 THEN online := TRUE; offline := FALSE; END_IF //Set online status IF NOT nativeResponseSeen AND errorCntRst >= 3 THEN online := FALSE; offline := TRUE; END_IF //Record start time in ms on execute rising edge executeTrig(CLK := execute); IF executeTrig.Q THEN interval := ULINT_TO_UDINT((TSSus - lastReqStart)/1000); lastReqStart := TSSus; END_IF //Offline count offlineTrig(CLK := NOT online); IF offlineTrig.Q THEN offlineCnt := offlineCnt + 1; END_IF //Calculate ms since last execute //If the last request start is more then 1 minute ago then set it for 1 minute IF TSSus >= lastReqStart THEN IF TSSus - lastReqStart > 60000000 THEN lastReqStart := TSSus - 60000000; END_IF; ELSE lastReqStart := TSSus; END_IF; sinceLastExec := ULINT_TO_UDINT((TSSus - lastReqStart)/1000); 48b508fd-2131-484c-ba4a-20e61e66a5b2_Impl_LineIds {attribute 'monitoring_display' := 'toString'} {attribute 'no_assign'} FUNCTION_BLOCK atMbRequestStats VAR_INPUT lastErrorId: modbusFB.Error; //Last error id lastExceptionCode: atMBExceptionCodes; //Last modbus exception code. These are the standard modbus exceptions. lastValidDuration: UDINT; // How long last transaction took (ms) longestValidDuration: UDINT; //Longest valid duration (ms) interval: UDINT; // Start-to-start interval (ms) offlineCnt: UINT; //Count of how many times this request has gone offline doneCnt: UDINT; // Count of successful request errorCnt: UDINT; // Count of failed requests doneCntRst: UDINT; // Count of succesful requests, resets on error result errorCntRst: UDINT; // Count of failed requests, resets on succesful request sinceLastExec: UDINT; // Time since the last start (ms) timeoutCnt: UDINT; reqLength: UINT; //Number of registers requested in request, used to calc active. END_VAR VAR_OUTPUT executeLight: BOOL; //Execute that stays on momentarily reqDoneLight: BOOL; //Request done that stays on momentarily reqErrorLight: BOOL; //Request error that stays on momentarily reqBusyLight: BOOL; //Request busy that stays on momentarily online: BOOL; //Online means the requests are being replied to normally or with modbus exceptions. Communications are ok. offline: BOOL; //Opposite of online, but starts out as false on program start. active: BOOL; // This is true if its actually being used, and not having a count of 0 on the request. executeMbFb: BOOL; END_VAR VAR {attribute 'symbol' := 'none'} inDoneDeb: atDebounce; {attribute 'symbol' := 'none'} inErrDeb: atDebounce; {attribute 'symbol' := 'none'} inBusyDeb: atDebounce; {attribute 'symbol' := 'none'} executeDeb: atDebounce; toString: STRING(20); {attribute 'symbol' := 'none'} executeTrig: R_TRIG; //Execute trigger {attribute 'symbol' := 'none'} offlineTrig: R_TRIG; //Offline trigger {attribute 'symbol' := 'none'} lastReqStart: SYSTIME; //time of start of last request {attribute 'symbol' := 'none'} TSSus: SYSTIME; _execute: BOOL; //Execute trigger and status. Turn on to trigger request. Will turn off when request is complete _reqDone: BOOL; //Request done _reqBusy: BOOL; //Request busy _reqError: BOOL; //Request error END_VAR VAR CONSTANT {attribute 'symbol' := 'none'} lightOn: TIME:= T#100MS; //Light on time for debug indicators END_VAR VAR_INPUT nativeResponseSeen : BOOL; nativeLastSuccessMs : ULINT; END_VAR 48b508fd-2131-484c-ba4a-20e61e66a5b2_Decl_LineIds 286 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False f6ee860b-0951-41d0-93d8-6436c681d8f1 00000000-0000-0000-0000-000000000000 atMbReqWriteCoil 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147259331 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-06-27 CWD Initial Create //2024-10-21 CWD Set udiTimeout to 0 as this was causing problems with detecting an actual no reply timeout from the slave //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); f6ee860b-0951-41d0-93d8-6436c681d8f1_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqWriteCoil EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF BOOL to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF BOOL; END_VAR VAR {attribute 'symbol' := 'none'} writeCoilsReq: POINTER TO ModbusFB.ClientRequestWriteMultipleCoils; END_VAR f6ee860b-0951-41d0-93d8-6436c681d8f1_Decl_LineIds 206 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False bb7e18ba-2018-4681-875e-de1f291019ef 00000000-0000-0000-0000-000000000000 atMbReqWriteHolding 24568a24-c491-472c-a21f-ee5d33859fab 1024 False False False False 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147339348 None IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN out_parameterError := (UINT_TO_DINT(in_dataOffset) < LOWER_BOUND(data,1)) OR (UINT_TO_DINT(in_dataOffset) > UPPER_BOUND(data,1)); IF out_parameterError THEN dataSize := 0; ELSE dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - UINT_TO_DINT(in_dataOffset) + 1); END_IF; SUPER^(); RETURN; END_IF; //Modbus request input registers //2024-06-27 CWD Initial Create //2024-10-21 CWD Set udiTimeout to 0 as this was causing problems with detecting an actual no reply timeout from the slave //2024-11-15 ATM Moved from Work to main for easier debugging //2024-11-23 ATM Cleaned up code, added start array position //2025-10-28 CWD Updated to reduce symbol usage //2026-04-03 ATM Now Client makes the requests, calling this just passes data. Dynamically allocated requests //Verify data size is large enough, if not then only get as many registers that will fit. dataSize := DINT_TO_UINT(UPPER_BOUND(data,1) - LOWER_BOUND(data,1) + 1); SUPER^(); bb7e18ba-2018-4681-875e-de1f291019ef_Impl_LineIds {attribute 'no_assign'} FUNCTION_BLOCK atMbReqWriteHolding EXTENDS atMbReqBase VAR_IN_OUT // ARRAY[] OF UINT to hold received data {attribute 'symbol' := 'none'} data: ARRAY[*] OF UINT; END_VAR VAR_OUTPUT END_VAR VAR {attribute 'symbol' := 'none'} writeHoldReq: POINTER TO ModbusFB.ClientRequestWriteMultipleRegisters; END_VAR bb7e18ba-2018-4681-875e-de1f291019ef_Decl_LineIds 164 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 9499c60e-03a2-49d0-b086-43990a018e20 00000000-0000-0000-0000-000000000000 To_IPAddress 829a18f2-c514-4f6e-9634-1df173429203 21af5390-2942-461a-bf89-951aaf6999f1 8fc52b24-7436-4d4a-8b03-aa43d42302d0 6f9dac99-8de1-4efc-8465-68ac443b7d08 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841590489804 None //Convert parameters to array To_IPAddress[0] := byte1; To_IPAddress[1] := byte2; To_IPAddress[2] := byte3; To_IPAddress[3] := byte4; 9499c60e-03a2-49d0-b086-43990a018e20_Impl_LineIds FUNCTION To_IPAddress : ARRAY[0..3] OF BYTE VAR_INPUT byte1: BYTE; byte2: BYTE; byte3: BYTE; byte4: BYTE; END_VAR 9499c60e-03a2-49d0-b086-43990a018e20_Decl_LineIds 168 Standard False 8fc52b24-7436-4d4a-8b03-aa43d42302d0 atomLibrary 6-Comms ModbusMaster -1 False 9e99e368-853f-485b-911f-d9a2a4e46434 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa addRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502146468437 IF request = 0 THEN RETURN; END_IF; IF requestCnt > 0 THEN FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF request = requests[i] THEN RETURN; END_IF; END_FOR; END_IF; IF requestCnt >= 100 THEN out_registrationFull := TRUE; RETURN; END_IF; requests[requestCnt] := request; requestCnt := requestCnt + 1; 9e99e368-853f-485b-911f-d9a2a4e46434_Impl_LineIds //Adds the specified request to the global list METHOD PUBLIC addRequest VAR_INPUT request: POINTER TO atMbReqBase; END_VAR VAR i: UINT := 0; END_VAR 9e99e368-853f-485b-911f-d9a2a4e46434_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 685f7c69-c46a-4b34-b5e2-fb848c593f3e bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa processAllRequests f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148036583 IF requestCnt = 0 OR requestCnt > 100 THEN RETURN; END_IF; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[i] <> 0 THEN requests[i]^.processRequest(); END_IF; END_FOR; 685f7c69-c46a-4b34-b5e2-fb848c593f3e_Impl_LineIds METHOD processAllRequests VAR_INPUT END_VAR VAR i: DINT; // Loop bstisnlr END_VAR 685f7c69-c46a-4b34-b5e2-fb848c593f3e_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 39769d9e-08c1-472d-82ef-25c66891a065 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa recreateAllRequests f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148056585 IF requestCnt = 0 OR requestCnt > 100 THEN RETURN; END_IF; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[i] <> 0 THEN requests[i]^.recreateRequest(); END_IF; END_FOR; 39769d9e-08c1-472d-82ef-25c66891a065_Impl_LineIds METHOD PROTECTED recreateAllRequests VAR_INPUT END_VAR VAR i : DINT; END_VAR 39769d9e-08c1-472d-82ef-25c66891a065_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 60fd3bf3-849f-4af3-a1a5-18a73fd7b7fc bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa recreateClient f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574648119824 60fd3bf3-849f-4af3-a1a5-18a73fd7b7fc_Impl_LineIds METHOD ABSTRACT recreateClient VAR_INPUT END_VAR 60fd3bf3-849f-4af3-a1a5-18a73fd7b7fc_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False a7e27967-573f-4f9f-86e7-dd569b8cd943 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa resetStats f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 IF nativeMode THEN nativeSent := 0; nativeReplied := 0; nativeWindowCount := 0; nativeWindowTime := 0; msgLastSecondCnt := 0; msgLastSecondTime := 0; numMsgSent := 0; numMsgReply := 0; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO requests[i]^.stats.resetStats(); END_FOR; RETURN; END_IF; connectCnt := 0; val := ADR(client.udiNumMsgSent); val^ := 0; val := ADR(client.udiNumMsgReply); val^ := 0; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO requests[i]^.stats.resetStats(); END_FOR; a7e27967-573f-4f9f-86e7-dd569b8cd943_Impl_LineIds METHOD resetStats VAR_INPUT END_VAR VAR i: DINT; val: POINTER TO UDINT; END_VAR a7e27967-573f-4f9f-86e7-dd569b8cd943_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False ca1dfc70-ad93-43de-886d-39e56897aa6d bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa setAllRequestsOffline f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148106585 IF requestCnt = 0 OR requestCnt > 100 THEN RETURN; END_IF; FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[i] <> 0 THEN requests[i]^.stats.setClientOffline(); END_IF; END_FOR; ca1dfc70-ad93-43de-886d-39e56897aa6d_Impl_LineIds METHOD PROTECTED setAllRequestsOffline : BOOL VAR_INPUT END_VAR VAR i: DINT; END_VAR ca1dfc70-ad93-43de-886d-39e56897aa6d_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False d12c9bf2-320f-4e95-badb-68a2357c5783 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa setupClient f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574648239962 IF nativeMode THEN setupClient := nativeHandle <> 0; RETURN; END_IF; // Only create request if doesnt exist IF NOT __ISVALIDREF(client) THEN recreateClient(); IF NOT __ISVALIDREF(client) THEN atGVL.dynamicAllocationFail.in_raw := TRUE; setupClient := FALSE; RETURN; END_IF END_IF setupClient := TRUE; d12c9bf2-320f-4e95-badb-68a2357c5783_Impl_LineIds METHOD setupClient : BOOL VAR_INPUT END_VAR d12c9bf2-320f-4e95-badb-68a2357c5783_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa activeIndex 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841590625089 PROPERTY activeIndex : DINT 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32_Decl_LineIds 1 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 456b4953-57c9-4f76-ab5b-0db456dd9b58 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa activeReqCnt 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639108502146293051 PROPERTY PRIVATE activeReqCnt : UINT 456b4953-57c9-4f76-ab5b-0db456dd9b58_Decl_LineIds 1 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 4d9d378a-f256-4f23-b835-539ee9e287c3 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa allRequestsComplete 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639108502147921016 {attribute 'symbol' := 'none'} PROPERTY PRIVATE allRequestsComplete : BOOL 4d9d378a-f256-4f23-b835-539ee9e287c3_Decl_LineIds 2 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 89742962-f9b6-46c2-b9a5-b7e298f8495d bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa onlineCnt 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841590755417 {attribute 'symbol' := 'none'} PROPERTY onlineCnt : DINT//Count of requests that are online 89742962-f9b6-46c2-b9a5-b7e298f8495d_Decl_LineIds 3 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 27292866-0bc0-4848-a965-64c51a0bf960 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa requestExecuting 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841590845466 {attribute 'symbol' := 'none'} PROPERTY PRIVATE requestExecuting : BOOL //There is at least one request executing 27292866-0bc0-4848-a965-64c51a0bf960_Decl_LineIds 3 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 4950a3a1-f54f-434d-9252-b61a6cb4663d 17c2ab7a-4d60-48ec-966f-339ec83a75e9 recreateClient f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574649617058 old_client_id := _client; _client := __NEW(ModbusFB.ClientSerial); IF _client = 0 THEN atGVL.dynamicAllocationFail.in_raw := TRUE; END_IF; client REF= _client^; connect := FALSE; IF old_client_id <> 0 THEN __DELETE(old_client_id); old_client_id := 0; END_IF recreateAllRequests(); 4950a3a1-f54f-434d-9252-b61a6cb4663d_Impl_LineIds METHOD recreateClient VAR_INPUT old_client_id: POINTER TO ModbusFB.ClientSerial; END_VAR 4950a3a1-f54f-434d-9252-b61a6cb4663d_Decl_LineIds 17c2ab7a-4d60-48ec-966f-339ec83a75e9 atomLibrary 6-Comms ModbusMaster atMbClientRTU -1 False e8c6c80b-7bdb-4108-987e-4af107de4377 17c2ab7a-4d60-48ec-966f-339ec83a75e9 toString 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639207574650142720 {attribute 'symbol' := 'none'} PROPERTY toString : atMbClientToString //Client request status noneOk = no requests working, someOk = some requests are working some are failing, allOk = all requests are working e8c6c80b-7bdb-4108-987e-4af107de4377_Decl_LineIds 3 17c2ab7a-4d60-48ec-966f-339ec83a75e9 atomLibrary 6-Comms ModbusMaster atMbClientRTU -1 False 79dfe91d-6dbc-46b0-866c-4b880e44e02b 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 recreateClient f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574649757233 nativeRelease(); // Next scan creates a fresh native context with current endpoint settings. 79dfe91d-6dbc-46b0-866c-4b880e44e02b_Impl_LineIds METHOD recreateClient VAR END_VAR 79dfe91d-6dbc-46b0-866c-4b880e44e02b_Decl_LineIds 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 atomLibrary 6-Comms ModbusMaster atMbClientTCP -1 False a77f3143-e2cf-48a4-bafd-a0c18a11faeb 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 busy f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148176670 stats.reqBusy := in; IF NOT in THEN RETURN; END_IF; a77f3143-e2cf-48a4-bafd-a0c18a11faeb_Impl_LineIds METHOD busy : BOOL VAR_INPUT in: BOOL; END_VAR VAR executeTime: ULINT; replyTimeoutTime: ULINT; END_VAR a77f3143-e2cf-48a4-bafd-a0c18a11faeb_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 5350a8fa-8297-42db-b185-fcb966e45684 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 completeRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148196661 done(request.xDone); err(in := request.xError, errorId := request.eErrorId, exceptionCode := request.eException); busy(in := request.xBusy); stats(); IF (atGVL.reset) THEN // request.AbortModel(); request.ResetModel(TRUE); END_IF 5350a8fa-8297-42db-b185-fcb966e45684_Impl_LineIds METHOD completeRequest VAR_INPUT END_VAR 5350a8fa-8297-42db-b185-fcb966e45684_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 3bfc4f72-6ee6-4e83-9bf3-99339b388eac 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 done f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148206667 stats.reqDone := in; IF NOT in THEN RETURN; END_IF //Set priority for next request in_priorityCurrent := in_prioritySetpoint; 3bfc4f72-6ee6-4e83-9bf3-99339b388eac_Impl_LineIds METHOD done VAR_INPUT // Done state in: BOOL; END_VAR 3bfc4f72-6ee6-4e83-9bf3-99339b388eac_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False d7c69d5d-5192-4bf1-96fc-9ef0da66a62c 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 err f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148226656 stats.reqError := in; IF NOT in THEN RETURN; END_IF //Update error info stats.lastErrorId := errorId; stats.lastExceptionCode := ANY_TO_BYTE(exceptionCode); //Since we are here there was an exception. If the modbus response is 0, that means no modbus communication happened, so we are offline. If we would have had a succesful communication we would have got a actual modbus error. //IF stats.lastExceptionCode = atMBExceptionCodes.RESPONSE_SUCCESS THEN //Since there was no response from the device set the priority to higher number priority // in_priorityCurrent := in_prioritySetPoint * 5; //END_IF //Set priority for next request, priority gets higher after each error result priorityMultiplier := UDINT_TO_INT(stats.errorCntRst); IF priorityMultiplier > 3 THEN priorityMultiplier := 3; END_IF // set multiplier to exponential retry. in_priorityCurrent := 10 * priorityMultiplier * priorityMultiplier; //in_priorityCurrent := in_prioritySetpoint * priorityMultiplier; // NO idea what Reset Model does, hoping it fixes comms issues // request.ResetModel(TRUE); // I dont think this helped d7c69d5d-5192-4bf1-96fc-9ef0da66a62c_Impl_LineIds METHOD err VAR_INPUT // Error state in: BOOL; errorId: modbusFB.Error; //modbusFB error ID exceptionCode: modbusFB.ExceptionCodes; //ModbusFB exception code END_VAR VAR priorityMultiplier: INT; //Raise priority when not response END_VAR d7c69d5d-5192-4bf1-96fc-9ef0da66a62c_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 109d8e00-bf23-4306-a8d5-764aa6a03235 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148246723 109d8e00-bf23-4306-a8d5-764aa6a03235_Impl_LineIds METHOD ABSTRACT processRequest VAR_INPUT END_VAR 109d8e00-bf23-4306-a8d5-764aa6a03235_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False f64e9d26-0b0d-4e83-b6b3-1cfb43d906f8 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148266663 f64e9d26-0b0d-4e83-b6b3-1cfb43d906f8_Impl_LineIds METHOD ABSTRACT recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR f64e9d26-0b0d-4e83-b6b3-1cfb43d906f8_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False db40c392-b461-4198-851d-85857ed98ccf 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 setupClient f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148276644 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN setupClient := FALSE; // Native path has no ModbusFB request object. RETURN; END_IF; // Only create request if doesnt exist IF in_request = 0 THEN in_request := recreateRequest(); IF in_request = 0 THEN atGVL.dynamicAllocationFail.in_raw := TRUE; setupClient := FALSE; RETURN; END_IF END_IF IF NOT __ISVALIDREF(mbsClient) THEN setupClient := FALSE; RETURN; END_IF request REF= in_request^; setupClient := TRUE; RETURN; db40c392-b461-4198-851d-85857ed98ccf_Impl_LineIds METHOD setupClient : BOOL VAR_INPUT in_request: POINTER TO ModbusFB.ClientRequest; END_VAR db40c392-b461-4198-851d-85857ed98ccf_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 6159c037-e399-466d-8108-0c4f6570f9b2 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 mbsClient 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639207574650298004 PROPERTY PROTECTED mbsClient : REFERENCE TO ModbusFB.Client 6159c037-e399-466d-8108-0c4f6570f9b2_Decl_LineIds 1 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 4f361885-f95c-4244-84d6-8c3b6b9b8a18 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 replyTimeout 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639034841591196333 //Calculates the reply timout setting PROPERTY PROTECTED replyTimeout : UDINT 4f361885-f95c-4244-84d6-8c3b6b9b8a18_Decl_LineIds 2 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False ea5277e9-2ae8-417f-a88d-b571902c7d71 a77a90fd-541d-4ce9-ad97-7024224bbab4 processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639163341699321592 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); nativeProcess(1); IF nativeReadComplete AND nativeCopyAllowed THEN FOR nativeLoop := 0 TO UINT_TO_DINT(nativeCount)-1 DO data[UINT_TO_DINT(nativeOffset)+nativeLoop] := client.nativeIO[nativeLoop] <> 0; END_FOR; END_IF; RETURN; END_IF; IF NOT setupClient(readCoilReq) THEN RETURN; END_IF //Do request processing readCoilReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); ea5277e9-2ae8-417f-a88d-b571902c7d71_Impl_LineIds METHOD processRequest ea5277e9-2ae8-417f-a88d-b571902c7d71_Decl_LineIds a77a90fd-541d-4ce9-ad97-7024224bbab4 atomLibrary 6-Comms ModbusMaster atMbReqReadCoil -1 False 2c4e80c5-f4e7-4d01-97ec-5317c7e780b3 a77a90fd-541d-4ce9-ad97-7024224bbab4 recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148331930 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF readCoilReq <> 0 THEN __DELETE(readCoilReq); readCoilReq := 0; END_IF readCoilReq := __NEW(ModbusFB.ClientRequestReadCoils); recreateRequest := readCoilReq; 2c4e80c5-f4e7-4d01-97ec-5317c7e780b3_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR 2c4e80c5-f4e7-4d01-97ec-5317c7e780b3_Decl_LineIds a77a90fd-541d-4ce9-ad97-7024224bbab4 atomLibrary 6-Comms ModbusMaster atMbReqReadCoil -1 False 9df094f9-a173-4520-816f-7badcbb1bd34 1a3278f4-a658-407c-968a-21aa53361562 processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639163341699461941 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); nativeProcess(2); IF nativeReadComplete AND nativeCopyAllowed THEN FOR nativeLoop := 0 TO UINT_TO_DINT(nativeCount)-1 DO data[UINT_TO_DINT(nativeOffset)+nativeLoop] := client.nativeIO[nativeLoop] <> 0; END_FOR; END_IF; RETURN; END_IF; IF NOT setupClient(readDiscreteReq) THEN RETURN; END_IF //Do request processing readDiscreteReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); 9df094f9-a173-4520-816f-7badcbb1bd34_Impl_LineIds METHOD processRequest 9df094f9-a173-4520-816f-7badcbb1bd34_Decl_LineIds 1a3278f4-a658-407c-968a-21aa53361562 atomLibrary 6-Comms ModbusMaster atMbReqReadDiscrete -1 False d34866d4-1134-4650-b3d6-2e19d2fd09d1 1a3278f4-a658-407c-968a-21aa53361562 recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148362063 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF readDiscreteReq <> 0 THEN __DELETE(readDiscreteReq); readDiscreteReq := 0; END_IF readDiscreteReq := __NEW(ModbusFB.ClientRequestReadDiscreteInputs); recreateRequest := readDiscreteReq; d34866d4-1134-4650-b3d6-2e19d2fd09d1_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR d34866d4-1134-4650-b3d6-2e19d2fd09d1_Decl_LineIds 1a3278f4-a658-407c-968a-21aa53361562 atomLibrary 6-Comms ModbusMaster atMbReqReadDiscrete -1 False 7b978176-d206-4509-b9d8-7908d33a9a74 73b10819-9112-4811-9583-e2735d2b13ea processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148402056 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); nativeProcess(3); IF nativeReadComplete AND nativeCopyAllowed THEN FOR nativeLoop := 0 TO UINT_TO_DINT(nativeCount)-1 DO data[UINT_TO_DINT(nativeOffset)+nativeLoop] := WORD_TO_UINT(client.nativeIO[nativeLoop]); END_FOR; END_IF; RETURN; END_IF; IF NOT setupClient(readHoldReq) THEN RETURN; END_IF //Do request processing readHoldReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, // udiReplyTimeout := 1 * 1000 * 1000, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); 7b978176-d206-4509-b9d8-7908d33a9a74_Impl_LineIds METHOD processRequest 7b978176-d206-4509-b9d8-7908d33a9a74_Decl_LineIds 73b10819-9112-4811-9583-e2735d2b13ea atomLibrary 6-Comms ModbusMaster atMbReqReadHolding -1 False 52ffdba7-bf4a-4746-924c-8b86df6d9a83 73b10819-9112-4811-9583-e2735d2b13ea recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148422060 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF readHoldReq <> 0 THEN __DELETE(readHoldReq); readHoldReq := 0; END_IF readHoldReq := __NEW(ModbusFB.ClientRequestReadHoldingRegisters); recreateRequest := readHoldReq; 52ffdba7-bf4a-4746-924c-8b86df6d9a83_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR 52ffdba7-bf4a-4746-924c-8b86df6d9a83_Decl_LineIds 73b10819-9112-4811-9583-e2735d2b13ea atomLibrary 6-Comms ModbusMaster atMbReqReadHolding -1 False 1004c837-fbef-45ee-986d-977343f4bd8f a5dbc9b0-a1a1-4281-a685-ec85b35bb866 processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148442038 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); nativeProcess(4); IF nativeReadComplete AND nativeCopyAllowed THEN FOR nativeLoop := 0 TO UINT_TO_DINT(nativeCount)-1 DO data[UINT_TO_DINT(nativeOffset)+nativeLoop] := WORD_TO_UINT(client.nativeIO[nativeLoop]); END_FOR; END_IF; RETURN; END_IF; IF NOT setupClient(readInputReq) THEN RETURN; END_IF //Do request processing readInputReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); 1004c837-fbef-45ee-986d-977343f4bd8f_Impl_LineIds METHOD processRequest 1004c837-fbef-45ee-986d-977343f4bd8f_Decl_LineIds a5dbc9b0-a1a1-4281-a685-ec85b35bb866 atomLibrary 6-Comms ModbusMaster atMbReqReadInput -1 False 9903b949-e1b9-4e0b-a98f-b6f745ad3605 a5dbc9b0-a1a1-4281-a685-ec85b35bb866 recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148462074 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF readInputReq <> 0 THEN __DELETE(readInputReq); readInputReq := 0; END_IF readInputReq := __NEW(ModbusFB.ClientRequestReadInputRegisters); recreateRequest := readInputReq; 9903b949-e1b9-4e0b-a98f-b6f745ad3605_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR 9903b949-e1b9-4e0b-a98f-b6f745ad3605_Decl_LineIds a5dbc9b0-a1a1-4281-a685-ec85b35bb866 atomLibrary 6-Comms ModbusMaster atMbReqReadInput -1 False 94cb9a26-304d-46fc-a18d-a8ce0f1931ec 48b508fd-2131-484c-ba4a-20e61e66a5b2 resetStats f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148542250 doneCnt := 0; doneCntRst := 0; errorCnt := 0; errorCntRst := 0; 94cb9a26-304d-46fc-a18d-a8ce0f1931ec_Impl_LineIds METHOD resetStats VAR_INPUT END_VAR 94cb9a26-304d-46fc-a18d-a8ce0f1931ec_Decl_LineIds 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False b1508d1f-b7a7-40b5-b74f-3091afc5b834 48b508fd-2131-484c-ba4a-20e61e66a5b2 setClientOffline f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148552305 nativeResponseSeen := FALSE; doneCntRst := 0; online := FALSE; offline := TRUE; b1508d1f-b7a7-40b5-b74f-3091afc5b834_Impl_LineIds METHOD setClientOffline : BOOL VAR_INPUT END_VAR b1508d1f-b7a7-40b5-b74f-3091afc5b834_Decl_LineIds 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False 1c6ab99e-dc71-45a2-a024-45cf65b9af99 48b508fd-2131-484c-ba4a-20e61e66a5b2 setToString f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148572279 toString := CONCAT('OK:', CONCAT(TO_STRING(doneCnt), CONCAT('/Er:', TO_STRING(errorCnt)))); 1c6ab99e-dc71-45a2-a024-45cf65b9af99_Impl_LineIds METHOD PRIVATE setToString : BOOL VAR_INPUT END_VAR 1c6ab99e-dc71-45a2-a024-45cf65b9af99_Decl_LineIds 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False 89434b6a-7e3b-4095-9220-0a6fc3789a25 48b508fd-2131-484c-ba4a-20e61e66a5b2 execute 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639085160043399503 PROPERTY execute : BOOL 89434b6a-7e3b-4095-9220-0a6fc3789a25_Decl_LineIds 1 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False 13e3ae42-bdd9-49ee-b8c0-74b8339469cb 48b508fd-2131-484c-ba4a-20e61e66a5b2 reqBusy 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639085160043449644 PROPERTY reqBusy : BOOL 13e3ae42-bdd9-49ee-b8c0-74b8339469cb_Decl_LineIds 1 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False 80965ce1-9b6a-44d3-b272-a5c739ccbc70 48b508fd-2131-484c-ba4a-20e61e66a5b2 reqDone 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639085160043519638 PROPERTY reqDone : BOOL 80965ce1-9b6a-44d3-b272-a5c739ccbc70_Decl_LineIds 1 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False 30645d91-91c6-42eb-8399-c20f91ca0d3e 48b508fd-2131-484c-ba4a-20e61e66a5b2 reqError 5a3b8626-d3e9-4f37-98b5-66420063d91e a9ed5b7e-75c5-4651-af16-d2c27e98cb94 639085160043604994 PROPERTY reqError : BOOL 30645d91-91c6-42eb-8399-c20f91ca0d3e_Decl_LineIds 1 48b508fd-2131-484c-ba4a-20e61e66a5b2 atomLibrary 6-Comms ModbusMaster atMbRequestStats -1 False fbb41e61-f245-4f4e-bcd0-218ede01fcda f6ee860b-0951-41d0-93d8-6436c681d8f1 processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148472030 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); IF stats.execute AND NOT nativeInFlight AND client.nativeSelected = THIS AND NOT out_parameterError THEN FOR nativeLoop := 0 TO UINT_TO_DINT(stats.reqLength)-1 DO client.nativeIO[nativeLoop] := BOOL_TO_WORD(data[UINT_TO_DINT(in_dataOffset)+nativeLoop]); END_FOR; END_IF; nativeProcess(15); RETURN; END_IF; IF NOT setupClient(writeCoilsReq) THEN RETURN; END_IF //Do request processing writeCoilsReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); fbb41e61-f245-4f4e-bcd0-218ede01fcda_Impl_LineIds METHOD processRequest fbb41e61-f245-4f4e-bcd0-218ede01fcda_Decl_LineIds f6ee860b-0951-41d0-93d8-6436c681d8f1 atomLibrary 6-Comms ModbusMaster atMbReqWriteCoil -1 False a861d6e2-2501-43dc-bb37-34509923450c f6ee860b-0951-41d0-93d8-6436c681d8f1 recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148502269 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF writeCoilsReq <> 0 THEN __DELETE(writeCoilsReq); writeCoilsReq := 0; END_IF writeCoilsReq := __NEW(ModbusFB.ClientRequestWriteMultipleCoils); recreateRequest := writeCoilsReq; a861d6e2-2501-43dc-bb37-34509923450c_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR a861d6e2-2501-43dc-bb37-34509923450c_Decl_LineIds f6ee860b-0951-41d0-93d8-6436c681d8f1 atomLibrary 6-Comms ModbusMaster atMbReqWriteCoil -1 False df9b4fd1-9d38-4a54-a7e5-264a94a756ac f6ee860b-0951-41d0-93d8-6436c681d8f1 writeNow f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841591456658 nativeWriteHold := FALSE; out_writeUncertain := FALSE; in_priorityCurrent := 0; df9b4fd1-9d38-4a54-a7e5-264a94a756ac_Impl_LineIds METHOD writeNow : BOOL VAR_INPUT END_VAR df9b4fd1-9d38-4a54-a7e5-264a94a756ac_Decl_LineIds f6ee860b-0951-41d0-93d8-6436c681d8f1 atomLibrary 6-Comms ModbusMaster atMbReqWriteCoil -1 False 76621df2-a77c-4e0a-aba0-e3e4a53bd278 bb7e18ba-2018-4681-875e-de1f291019ef processRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148512269 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN nativeCopyAllowed := (UINT_TO_DINT(nativeOffset) >= LOWER_BOUND(data,1)) AND (UINT_TO_DINT(nativeOffset) + UINT_TO_DINT(nativeCount) - 1 <= UPPER_BOUND(data,1)); IF stats.execute AND NOT nativeInFlight AND client.nativeSelected = THIS AND NOT out_parameterError THEN FOR nativeLoop := 0 TO UINT_TO_DINT(stats.reqLength)-1 DO client.nativeIO[nativeLoop] := UINT_TO_WORD(data[UINT_TO_DINT(in_dataOffset)+nativeLoop]); END_FOR; END_IF; nativeProcess(16); RETURN; END_IF; IF NOT setupClient(writeHoldReq) THEN RETURN; END_IF //Do request processing writeHoldReq^( rClient := mbsClient, xExecute := stats.execute, udiTimeOut := 0, uiUnitId := in_unitId, udiReplyTimeout := replyTimeout, uiStartItem := in_startAddr, uiQuantity := stats.reqLength, pData := ADR(data[in_dataOffset]) ); completeRequest(); 76621df2-a77c-4e0a-aba0-e3e4a53bd278_Impl_LineIds METHOD processRequest 76621df2-a77c-4e0a-aba0-e3e4a53bd278_Decl_LineIds bb7e18ba-2018-4681-875e-de1f291019ef atomLibrary 6-Comms ModbusMaster atMbReqWriteHolding -1 False bd7ff184-1747-404c-9fa0-1b728376c927 bb7e18ba-2018-4681-875e-de1f291019ef recreateRequest f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148532258 IF __ISVALIDREF(client) AND_THEN client.nativeMode THEN IF client.nativeActiveRequest = THIS THEN client.recreateClient(); END_IF; nativeInFlight := FALSE; recreateRequest := 0; RETURN; END_IF; IF writeHoldReq <> 0 THEN __DELETE(writeHoldReq); writeHoldReq := 0; END_IF writeHoldReq := __NEW(ModbusFB.ClientRequestWriteMultipleRegisters); recreateRequest := writeHoldReq; bd7ff184-1747-404c-9fa0-1b728376c927_Impl_LineIds METHOD recreateRequest : POINTER TO ModbusFB.ClientRequest VAR_INPUT END_VAR bd7ff184-1747-404c-9fa0-1b728376c927_Decl_LineIds bb7e18ba-2018-4681-875e-de1f291019ef atomLibrary 6-Comms ModbusMaster atMbReqWriteHolding -1 False 5f9160f9-c4a4-4f65-a74c-2838020397f3 bb7e18ba-2018-4681-875e-de1f291019ef writeNow f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841591496600 nativeWriteHold := FALSE; out_writeUncertain := FALSE; in_priorityCurrent := 0; 5f9160f9-c4a4-4f65-a74c-2838020397f3_Impl_LineIds METHOD writeNow : BOOL VAR_INPUT END_VAR 5f9160f9-c4a4-4f65-a74c-2838020397f3_Decl_LineIds bb7e18ba-2018-4681-875e-de1f291019ef atomLibrary 6-Comms ModbusMaster atMbReqWriteHolding -1 False 0803920e-cc13-4b93-a08c-4d27afc1ff3c 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841590675071 IF nativeMode THEN activeIndex := nativeActiveIndex; RETURN; END_IF; // ===== Test for any requests executing ===== FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[i]^.stats.execute OR requests[i]^.stats.reqBusy THEN activeIndex := i; RETURN; END_IF END_FOR activeIndex := -1; 0803920e-cc13-4b93-a08c-4d27afc1ff3c_Impl_LineIds VAR i: DINT; //Loop variable END_VAR 0803920e-cc13-4b93-a08c-4d27afc1ff3c_Decl_LineIds True 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32 atomLibrary 6-Comms ModbusMaster atMbClient activeIndex -1 False 3b82f264-e41e-461d-9beb-263305a22a8d 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32 Set 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841590705101 // set request to active, which is how the active index gets calculated. requests[activeIndex]^.stats.execute := TRUE; 3b82f264-e41e-461d-9beb-263305a22a8d_Impl_LineIds VAR END_VAR 3b82f264-e41e-461d-9beb-263305a22a8d_Decl_LineIds False 5cc2fe1e-bdb2-429a-84e1-63e783ea3b32 atomLibrary 6-Comms ModbusMaster atMbClient activeIndex -1 False cc024b23-e5fe-4958-ad80-513feea6aeab 456b4953-57c9-4f76-ab5b-0db456dd9b58 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502146383170 cnt := 0; IF requestCnt = 0 THEN activeReqCnt := 0; RETURN; END_IF FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO //Test for any offline request IF requests[i]^.stats.active THEN cnt := cnt + 1; END_IF END_FOR; activeReqCnt := cnt; cc024b23-e5fe-4958-ad80-513feea6aeab_Impl_LineIds VAR i: UINT; //Loop variable cnt: UINT; END_VAR cc024b23-e5fe-4958-ad80-513feea6aeab_Decl_LineIds True 456b4953-57c9-4f76-ab5b-0db456dd9b58 atomLibrary 6-Comms ModbusMaster atMbClient activeReqCnt -1 False d59f404d-315d-4ea4-b16b-c8f0e8342d2e 4d9d378a-f256-4f23-b835-539ee9e287c3 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147990941 IF requestCnt = 0 THEN allRequestsComplete := 0; RETURN; END_IF FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO //Test for any offline request IF requests[i]^.stats.execute OR requests[i]^.stats.reqDone OR requests[i]^.stats.reqBusy OR requests[i]^.stats.reqError THEN allRequestsComplete := FALSE; RETURN; END_IF END_FOR; allRequestsComplete := TRUE; d59f404d-315d-4ea4-b16b-c8f0e8342d2e_Impl_LineIds VAR i: UINT; END_VAR d59f404d-315d-4ea4-b16b-c8f0e8342d2e_Decl_LineIds True 4d9d378a-f256-4f23-b835-539ee9e287c3 atomLibrary 6-Comms ModbusMaster atMbClient allRequestsComplete -1 False dceb6b17-86bf-4543-9652-2fd2b943953c 89742962-f9b6-46c2-b9a5-b7e298f8495d Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502146538436 cnt := 0; IF requestCnt = 0 THEN onlineCnt := 0; RETURN; END_IF FOR i := 0 TO UINT_TO_DINT(requestCnt)-1 DO //Test for any offline request IF requests[i]^.stats.online THEN cnt := cnt + 1; END_IF END_FOR; onlineCnt := cnt; dceb6b17-86bf-4543-9652-2fd2b943953c_Impl_LineIds VAR i: UINT; //Loop variable cnt: UINT; END_VAR dceb6b17-86bf-4543-9652-2fd2b943953c_Decl_LineIds True 89742962-f9b6-46c2-b9a5-b7e298f8495d atomLibrary 6-Comms ModbusMaster atMbClient onlineCnt -1 False 0006696f-29e2-441e-a325-e3481d025cec 27292866-0bc0-4848-a965-64c51a0bf960 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841590890993 // ===== Test for any requests executing ===== requestExecuting := activeIndex <> -1; 0006696f-29e2-441e-a325-e3481d025cec_Impl_LineIds VAR i: DINT; //Loop variable END_VAR 0006696f-29e2-441e-a325-e3481d025cec_Decl_LineIds True 27292866-0bc0-4848-a965-64c51a0bf960 atomLibrary 6-Comms ModbusMaster atMbClient requestExecuting -1 False 3d4da579-672d-4758-9b0f-e055a08e0da3 e8c6c80b-7bdb-4108-987e-4af107de4377 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574650278010 //Calculation for tostring IF onlineCnt = requestCnt THEN toString := atMbClientToString.allOk; ELSIF onlineCnt = 0 THEN toString := atMbClientToString.noneOk; ELSE toString := atMbClientToString.someOk; END_IF 3d4da579-672d-4758-9b0f-e055a08e0da3_Impl_LineIds 3d4da579-672d-4758-9b0f-e055a08e0da3_Decl_LineIds True e8c6c80b-7bdb-4108-987e-4af107de4377 atomLibrary 6-Comms ModbusMaster atMbClientRTU toString -1 False 4895a5bf-c631-4f8c-bee7-addb0b769548 6159c037-e399-466d-8108-0c4f6570f9b2 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639207574650328003 IF NOT __ISVALIDREF(client) OR_ELSE NOT __ISVALIDREF(client.client) THEN RETURN; END_IF mbsClient REF= client.client; 4895a5bf-c631-4f8c-bee7-addb0b769548_Impl_LineIds VAR END_VAR 4895a5bf-c631-4f8c-bee7-addb0b769548_Decl_LineIds True 6159c037-e399-466d-8108-0c4f6570f9b2 atomLibrary 6-Comms ModbusMaster atMbReqBase mbsClient -1 False f54a4cd6-8540-4892-a914-4aac4f8d9018 4f361885-f95c-4244-84d6-8c3b6b9b8a18 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639034841591226460 IF in_timeout > 0 THEN //Explicitly set timout replyTimeout := ANY_TO_UDINT((in_timeout) * 1000); ELSE // If client timeout is set, use that. IF client.in_timeout <> T#0MS THEN replyTimeout := TIME_TO_UDINT(client.in_timeout) * 1000; ELSIF client.dataRate <> 0 THEN //Data transmision time * 1.5 to get the timeout. Result is in ms //8 byte request, then 255 byte reply = 2630 bits. replyTimeout := REAL_TO_UDINT(2630 / DINT_TO_REAL(client.dataRate) * 1.5 * 1000000); ELSE //In case client datarate = zero replyTimeout := 1000000; //1 second? END_IF END_IF f54a4cd6-8540-4892-a914-4aac4f8d9018_Impl_LineIds VAR END_VAR f54a4cd6-8540-4892-a914-4aac4f8d9018_Decl_LineIds True 4f361885-f95c-4244-84d6-8c3b6b9b8a18 atomLibrary 6-Comms ModbusMaster atMbReqBase replyTimeout -1 False 465bf80a-0d6e-4363-ba1e-dd04aef379f7 89434b6a-7e3b-4095-9220-0a6fc3789a25 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043419500 execute := _execute; 465bf80a-0d6e-4363-ba1e-dd04aef379f7_Impl_LineIds VAR END_VAR 465bf80a-0d6e-4363-ba1e-dd04aef379f7_Decl_LineIds True 89434b6a-7e3b-4095-9220-0a6fc3789a25 atomLibrary 6-Comms ModbusMaster atMbRequestStats execute -1 False 8ff5fbe7-c047-436d-923c-942d0d66494c 89434b6a-7e3b-4095-9220-0a6fc3789a25 Set 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043439650 IF reqDone OR reqError THEN _execute := FALSE; RETURN; END_IF _execute := execute; 8ff5fbe7-c047-436d-923c-942d0d66494c_Impl_LineIds VAR END_VAR 8ff5fbe7-c047-436d-923c-942d0d66494c_Decl_LineIds False 89434b6a-7e3b-4095-9220-0a6fc3789a25 atomLibrary 6-Comms ModbusMaster atMbRequestStats execute -1 False db10f23e-d96b-4fd5-aec0-8b530ad288e1 13e3ae42-bdd9-49ee-b8c0-74b8339469cb Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043479636 reqBusy := _reqBusy; db10f23e-d96b-4fd5-aec0-8b530ad288e1_Impl_LineIds VAR END_VAR db10f23e-d96b-4fd5-aec0-8b530ad288e1_Decl_LineIds True 13e3ae42-bdd9-49ee-b8c0-74b8339469cb atomLibrary 6-Comms ModbusMaster atMbRequestStats reqBusy -1 False a239da3a-8f75-41da-a264-f06ca07143f4 13e3ae42-bdd9-49ee-b8c0-74b8339469cb Set 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043499661 _reqBusy := reqBusy; a239da3a-8f75-41da-a264-f06ca07143f4_Impl_LineIds VAR END_VAR a239da3a-8f75-41da-a264-f06ca07143f4_Decl_LineIds False 13e3ae42-bdd9-49ee-b8c0-74b8339469cb atomLibrary 6-Comms ModbusMaster atMbRequestStats reqBusy -1 False 61db378f-6029-4712-b562-fea707e5698b 80965ce1-9b6a-44d3-b272-a5c739ccbc70 Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043539625 reqDone := _reqDone; 61db378f-6029-4712-b562-fea707e5698b_Impl_LineIds VAR END_VAR 61db378f-6029-4712-b562-fea707e5698b_Decl_LineIds True 80965ce1-9b6a-44d3-b272-a5c739ccbc70 atomLibrary 6-Comms ModbusMaster atMbRequestStats reqDone -1 False 858ae7ab-7bd2-4c3e-9c4b-69064e0620a3 80965ce1-9b6a-44d3-b272-a5c739ccbc70 Set 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147505410 _reqDone := reqDone; IF (execute AND reqDone) THEN // ===== Request has just completed succesfully ===== //Update last valid duration lastValidDuration := ULINT_TO_UDINT((TSSus - lastReqStart)/1000); IF lastValidDuration > longestValidDuration THEN longestValidDuration := lastValidDuration; END_IF //Counters doneCnt := doneCnt + 1; doneCntRst := doneCntRst + 1; errorCntRst := 0; //Update error info lastErrorId := modbusFB.Error.OK; lastExceptionCode := atMBExceptionCodes.RESPONSE_SUCCESS; execute := FALSE; setToString(); END_IF 858ae7ab-7bd2-4c3e-9c4b-69064e0620a3_Impl_LineIds VAR END_VAR 858ae7ab-7bd2-4c3e-9c4b-69064e0620a3_Decl_LineIds False 80965ce1-9b6a-44d3-b272-a5c739ccbc70 atomLibrary 6-Comms ModbusMaster atMbRequestStats reqDone -1 False e44e83bd-8f84-4202-9ab4-784d09cf5506 30645d91-91c6-42eb-8399-c20f91ca0d3e Get 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639085160043645000 reqError := _reqError; e44e83bd-8f84-4202-9ab4-784d09cf5506_Impl_LineIds VAR END_VAR e44e83bd-8f84-4202-9ab4-784d09cf5506_Decl_LineIds True 30645d91-91c6-42eb-8399-c20f91ca0d3e atomLibrary 6-Comms ModbusMaster atMbRequestStats reqError -1 False 89b5f7bc-0c37-43f3-8984-14034b000d89 30645d91-91c6-42eb-8399-c20f91ca0d3e Set 792f2eb6-721e-4e64-ba20-bc98351056db a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502147595513 _reqError := reqError; IF (execute AND reqError) THEN // ===== Request has just completed with error ===== // Counters errorCnt := errorCnt + 1; errorCntRst := errorCntRst + 1; doneCntRst := 0; //Turn off execute execute := FALSE; //Since we are here there was an exception. If the modbus response is 0, that means no modbus communication happened, so we are offline. If we would have had a succesful communication we would have got a actual modbus error. IF lastExceptionCode = atMBExceptionCodes.RESPONSE_SUCCESS THEN timeoutCnt := timeoutCnt + 1; lastExceptionCode := atMBExceptionCodes.TIMEOUT; END_IF setToString(); END_IF 89b5f7bc-0c37-43f3-8984-14034b000d89_Impl_LineIds VAR END_VAR 89b5f7bc-0c37-43f3-8984-14034b000d89_Decl_LineIds False 30645d91-91c6-42eb-8399-c20f91ca0d3e atomLibrary 6-Comms ModbusMaster atMbRequestStats reqError -1 False f0be8440-a307-5b71-82c8-af27d8852e42 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa nativeCall f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 nativeCall := CmpAtomModbus.atMbCall_cext( command := command, handle := nativeHandle, ipAddress := nativeIP, port := nativePort, unitId := nativeArgUnit, functionCode := nativeArgFunction, startAddress := nativeArgAddress, quantity := nativeArgQuantity, pData := ADR(nativeIO[0]), dataCapacity := 2000, pStatus := ADR(nativeStatus[0]), statusCapacity := 24, nowMs := nativeNowMs, connectTimeoutMs := nativeConnectTimeout, responseTimeoutMs := nativeArgTimeout, retryDelayMs := nativeRetryDelay); f0be8440-a307-5b71-82c8-af27d8852e42_Impl_LineIds METHOD nativeCall : UDINT VAR_INPUT command : UDINT; END_VAR f0be8440-a307-5b71-82c8-af27d8852e42_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False 1233447d-8796-56cf-9291-c959801d2a63 bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa nativeCycle f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 SysTimeGetUs(nativeNowUs); nativeNowMs := nativeNowUs / 1000; IF in_resetStats THEN resetStats(); in_resetStats := FALSE; END_IF; IF nativeHandle = 0 AND nativeEnable THEN rc := nativeCall(1); IF rc <> 0 THEN out_lastNativeError := rc; RETURN; END_IF; nativeHandle := nativeStatus[0]; nativeArgTimeout := 1000; rc := nativeCall(9); IF rc <> 0 THEN out_lastNativeError := rc; nativeCall(2); nativeHandle := 0; RETURN; END_IF; nativeCall(3); END_IF; IF nativeHandle = 0 THEN out_connected := FALSE; out_connectionState := 0; RETURN; END_IF; rc := nativeCall(5); IF rc = 256 THEN nativeHandle := 0; IF nativeActiveRequest <> 0 THEN nativeActiveRequest^.nativeFinish(10); END_IF; nativeActiveRequest := 0; nativeActiveIndex := -1; RETURN; ELSIF rc <> 0 THEN out_lastNativeError := rc; RETURN; END_IF; out_connectionState := nativeStatus[1]; out_connected := (nativeStatus[1] >= 3) AND (nativeStatus[1] <= 5); out_lastNativeError := nativeStatus[6]; out_socketError := nativeStatus[7]; out_reconnectCount := nativeStatus[11]; IF nativePrevConnected AND NOT out_connected THEN setAllRequestsOffline(); END_IF; nativePrevConnected := out_connected; nativeFinishedIndex := -1; nativeResultReady := (nativeActiveRequest <> 0) AND ((nativeStatus[3] <> 0) OR (nativeStatus[4] <> 0)); IF nativeResultReady AND (nativeStatus[3] <> 0) AND (nativeStatus[18] <= 4) THEN rc := nativeCall(7); IF rc <> 0 THEN nativeStatus[3] := 0; nativeStatus[4] := 1; nativeStatus[5] := rc; END_IF; END_IF; processAllRequests(); IF nativeResultReady THEN nativeFinishedIndex := nativeActiveIndex; nativeCall(10); nativeActiveRequest := 0; nativeActiveIndex := -1; nativeSelected := 0; nativeResultReady := FALSE; END_IF; IF nativeEnable AND nativeStatus[1] = 3 AND nativeActiveRequest = 0 THEN best := -1; priority := 32767; age := 0; FOR j := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[j] <> 0 AND_THEN requests[j]^.stats.active AND NOT requests[j]^.nativeWriteHold AND j <> nativeFinishedIndex THEN IF requests[j]^.stats.sinceLastExec >= TIME_TO_UDINT(requests[j]^.in_minDelay) THEN IF (requests[j]^.in_priorityCurrent < priority) OR ((requests[j]^.in_priorityCurrent = priority) AND (requests[j]^.stats.sinceLastExec > age)) THEN best := j; priority := requests[j]^.in_priorityCurrent; age := requests[j]^.stats.sinceLastExec; END_IF; END_IF; END_IF; END_FOR; IF best >= 0 THEN IF priority > 0 THEN FOR j := 0 TO UINT_TO_DINT(requestCnt)-1 DO IF requests[j]^.in_priorityCurrent > 0 THEN requests[j]^.in_priorityCurrent := requests[j]^.in_priorityCurrent - 1; END_IF; END_FOR; END_IF; nativeSelected := requests[best]; nativeActiveIndex := best; nativeSelected^.stats.execute := TRUE; nativeSelected^.processRequest(); IF nativeActiveRequest = 0 THEN nativeActiveIndex := -1; nativeSelected := 0; END_IF; END_IF; END_IF; allRequestsOnline := (activeReqCnt > 0) AND (onlineCnt = activeReqCnt); allRequestsOffline := (activeReqCnt > 0) AND (onlineCnt = 0); numMsgSent := nativeSent; numMsgReply := nativeReplied; FOR j := 0 TO UINT_TO_DINT(requestCnt)-1 DO reqStats[j] := ADR(requests[j]^.stats); END_FOR; IF nativeWindowStart = 0 THEN nativeWindowStart := nativeNowMs; END_IF; IF nativeNowMs - nativeWindowStart >= 1000 THEN msgLastSecondCnt := nativeWindowCount; msgLastSecondTime := nativeWindowTime; nativeWindowCount := 0; nativeWindowTime := 0; nativeWindowStart := nativeNowMs; END_IF; 1233447d-8796-56cf-9291-c959801d2a63_Impl_LineIds METHOD nativeCycle VAR j : DINT; best : DINT; priority : INT; age : UDINT; rc : UDINT; END_VAR 1233447d-8796-56cf-9291-c959801d2a63_Decl_LineIds bc7fa96e-8ba3-4e3e-9cec-4d50ab57e6fa atomLibrary 6-Comms ModbusMaster atMbClient -1 False c08712ba-3cf5-54e9-89a1-76a1c3183975 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 nativeRelease f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 IF nativeHandle <> 0 THEN nativeCall(2); IF nativeActiveRequest <> 0 THEN nativeActiveRequest^.nativeFinish(10); END_IF; nativeHandle := 0; END_IF; nativeActiveRequest := 0; nativeSelected := 0; nativeActiveIndex := -1; nativeResultReady := FALSE; out_connected := FALSE; out_connectionState := 0; setAllRequestsOffline(); FOR j := 0 TO UINT_TO_DINT(requestCnt)-1 DO requests[j]^.invalidateNativeData(); END_FOR; nativeRelease := TRUE; c08712ba-3cf5-54e9-89a1-76a1c3183975_Impl_LineIds METHOD nativeRelease : BOOL VAR j : DINT; END_VAR c08712ba-3cf5-54e9-89a1-76a1c3183975_Decl_LineIds 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 atomLibrary 6-Comms ModbusMaster atMbClientTCP -1 False 2a6d360f-01c4-5b27-81fa-337b6b33a1b6 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 release f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 in_enable := FALSE; release := nativeRelease(); 2a6d360f-01c4-5b27-81fa-337b6b33a1b6_Impl_LineIds METHOD release : BOOL 2a6d360f-01c4-5b27-81fa-337b6b33a1b6_Decl_LineIds 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 atomLibrary 6-Comms ModbusMaster atMbClientTCP -1 False b2fda51f-6f2a-5b12-bc9c-2985dd3a44b4 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 FB_exit f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 FB_exit := nativeRelease(); b2fda51f-6f2a-5b12-bc9c-2985dd3a44b4_Impl_LineIds METHOD FB_exit : BOOL VAR_INPUT bInCopyCode : BOOL; END_VAR b2fda51f-6f2a-5b12-bc9c-2985dd3a44b4_Decl_LineIds 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 atomLibrary 6-Comms ModbusMaster atMbClientTCP -1 False 7568f58a-e795-5d22-a622-3f070deb32b0 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 FB_reinit f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 nativeHandle := 0; nativeActiveRequest := 0; nativeSelected := 0; nativeActiveIndex := -1; nativeResultReady := FALSE; nativePrevConnected := FALSE; requestCnt := 0; out_registrationFull := FALSE; FOR j := 0 TO 99 DO requests[j] := 0; reqStats[j] := 0; END_FOR; FB_reinit := TRUE; 7568f58a-e795-5d22-a622-3f070deb32b0_Impl_LineIds METHOD FB_reinit : BOOL VAR j : DINT; END_VAR 7568f58a-e795-5d22-a622-3f070deb32b0_Decl_LineIds 269ad87c-8ffe-4a28-9e12-2f2da3f7c570 atomLibrary 6-Comms ModbusMaster atMbClientTCP -1 False 28ccddd0-4531-5168-aa3e-ac56dddcb68d 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 invalidateNativeData f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 out_validData := FALSE; out_stale := TRUE; 28ccddd0-4531-5168-aa3e-ac56dddcb68d_Impl_LineIds METHOD PUBLIC invalidateNativeData 28ccddd0-4531-5168-aa3e-ac56dddcb68d_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 1c14b96c-a77e-5cd3-b853-c18bf9b5ea87 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 nativeFinish f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 out_nativeError := result; out_socketError := client.nativeStatus[7]; out_writeUncertain := nativeInFlight AND (client.nativeStatus[9] <> 0); IF (result = 10) AND nativeInFlight AND (nativeFunction >= 15) THEN out_writeUncertain := TRUE; END_IF; IF out_writeUncertain AND client.nativeHoldUncertainWrites THEN nativeWriteHold := TRUE; END_IF; stats.reqBusy := FALSE; IF result = 0 THEN duration := ULINT_TO_UDINT(client.nativeNowMs - nativeStartMs); stats.lastValidDuration := duration; IF duration > stats.longestValidDuration THEN stats.longestValidDuration := duration; END_IF; client.nativeReplied := client.nativeReplied + 1; client.nativeWindowTime := client.nativeWindowTime + duration; stats.nativeResponseSeen := TRUE; IF nativeFunction <= 4 THEN nativeReadComplete := TRUE; stats.nativeLastSuccessMs := client.nativeNowMs; out_validData := TRUE; END_IF; done(TRUE); ELSE CASE result OF 1,258: mapped := ModbusFB.Error.RequestParameterError; 4,7: mapped := ModbusFB.Error.TcpSocketError; 5: mapped := ModbusFB.Error.TcpConnectTimeout; 6: mapped := ModbusFB.Error.ReplyTimeout; 8: mapped := ModbusFB.Error.InvalidReply; 9: mapped := ModbusFB.Error.RequestException; 10: mapped := ModbusFB.Error.RequestCancelled; ELSE mapped := ModbusFB.Error.InternalError; END_CASE; ex := ModbusFB.ExceptionCodes.RESPONSE_SUCCESS; IF result = 9 THEN CASE client.nativeStatus[8] OF 1: ex := ModbusFB.ExceptionCodes.ILLEGAL_FUNCTION; 2: ex := ModbusFB.ExceptionCodes.ILLEGAL_DATA_ADDRESS; 3: ex := ModbusFB.ExceptionCodes.ILLEGAL_DATA_VALUE; 4: ex := ModbusFB.ExceptionCodes.SLAVE_DEVICE_FAILURE; 5: ex := ModbusFB.ExceptionCodes.ACKNOWLEDGE; 6: ex := ModbusFB.ExceptionCodes.SLAVE_DEVICE_BUSY; 8: ex := ModbusFB.ExceptionCodes.MEMORY_PARITY_ERROR; 10: ex := ModbusFB.ExceptionCodes.GATEWAY_PATH_UNAVAILABLE; 11: ex := ModbusFB.ExceptionCodes.GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND; END_CASE; client.nativeReplied := client.nativeReplied + 1; stats.nativeResponseSeen := TRUE; ELSE stats.nativeResponseSeen := FALSE; END_IF; err(in := TRUE,errorId := mapped,exceptionCode := ex); END_IF; nativeInFlight := FALSE; stats(); 1c14b96c-a77e-5cd3-b853-c18bf9b5ea87_Impl_LineIds METHOD nativeFinish VAR_INPUT result : UDINT; END_VAR VAR mapped : ModbusFB.Error; ex : ModbusFB.ExceptionCodes; duration : UDINT; END_VAR 1c14b96c-a77e-5cd3-b853-c18bf9b5ea87_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False fd4b7cdb-3c7f-5110-af32-341f71321132 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 nativeProcess f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 nativeReadComplete := FALSE; stats.reqDone := FALSE; stats.reqError := FALSE; stats(); IF NOT client.out_connected THEN stats.setClientOffline(); END_IF; IF client.nativeActiveRequest = THIS AND client.nativeResultReady THEN IF (client.nativeStatus[3] <> 0) AND (nativeFunction <= 4) AND NOT nativeCopyAllowed THEN nativeFinish(1); ELSE nativeFinish(client.nativeStatus[5]); END_IF; RETURN; END_IF; IF stats.execute AND NOT nativeInFlight AND client.nativeSelected = THIS THEN nativeFunction := functionCode; nativeCount := stats.reqLength; nativeOffset := in_dataOffset; nativeStartMs := client.nativeNowMs; IF out_parameterError OR nativeCount = 0 THEN nativeFinish(1); RETURN; END_IF; client.nativeArgUnit := in_unitId; client.nativeArgFunction := functionCode; client.nativeArgAddress := in_startAddr; client.nativeArgQuantity := nativeCount; client.nativeArgTimeout := MAX(UDINT#1,(replyTimeout + 999)/1000); nativeRC := client.nativeCall(11); IF nativeRC = 0 THEN nativeRC := client.nativeCall(6); END_IF; IF nativeRC = 0 THEN client.nativeActiveRequest := THIS; nativeInFlight := TRUE; stats.reqBusy := TRUE; client.nativeSent := client.nativeSent + 1; client.nativeWindowCount := client.nativeWindowCount + 1; ELSE nativeFinish(nativeRC); END_IF; stats(); END_IF; IF out_validData THEN out_dataAgeMs := client.nativeNowMs - stats.nativeLastSuccessMs; out_stale := out_dataAgeMs > TIME_TO_UDINT(in_staleAfter); ELSE out_stale := TRUE; END_IF; fd4b7cdb-3c7f-5110-af32-341f71321132_Impl_LineIds METHOD nativeProcess VAR_INPUT functionCode : BYTE; END_VAR fd4b7cdb-3c7f-5110-af32-341f71321132_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 False 9ee1081f-903d-595c-ab0c-17c64f4fbe75 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 FB_reinit f8a58466-d7f6-439f-bbb8-d4600e41d099 a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc 639108502148096636 nativeInFlight := FALSE; stats.execute := FALSE; stats.reqBusy := FALSE; stats.reqDone := FALSE; stats.reqError := FALSE; FB_reinit := TRUE; 9ee1081f-903d-595c-ab0c-17c64f4fbe75_Impl_LineIds METHOD FB_reinit : BOOL 9ee1081f-903d-595c-ab0c-17c64f4fbe75_Decl_LineIds 3ad7cda5-e8b7-44c8-b264-165eb4cd7d37 atomLibrary 6-Comms ModbusMaster atMbReqBase -1 CODESYS V3.5 SP21 Patch 4