Reputation: 41
I am working on a legacy modbus program for an industrial SCADA system.
Currently, the c++ program acts as both a modbus TCP server and client.
Client behaviour: It reads from a number of vendor PLCs (servers) on site, performs calculations and sends control commands back to the PLCs based on the data received across the site.
Server behaviour: responds to a variety of TCP read and write requests from web interfaces and laptops on site.
Until now, this has worked fine, but we have recently installed a logging client on the network which polls our program very frequently (sub-second) and this has revealed timing issues: the program can potentially take a very long time in its client loop performing calculations and reading PLC values before acting as a server and responding to incoming requests.
Easy solution would be to split the programs into a modbus server and client instance, and keep them both running on the same embedded PC.
The issue I have is that the remote web interface (HMI) must be able to control the behaviour of vendor PLC 2 and Vendor PLC 2 will only allow one TCP connection from the embedded PC. In the past the program has handled writes requests from the HMI by forwarding them on to the PLC 2 via the open socket.
I'd be keen to gather thoughts on best practices here.
My thinking: the modbus server program will need to respond to the HMI requests and somehow store the information required for vendor PLC 2, and it will also need to set a status register to inform the modbus client that there is data for vendor PLC 2. The modbus client program will need to read the status register (and data) from the server and pass this on to vendor PLC 2.
Am I heading in the right direction?
Upvotes: 0
Views: 547
Reputation: 8636
Without having details on your implementation I can only guess the problem is that your program is single-threaded, and delays are caused by waiting responses from PLCs.
So, if my assumption is correct, you need to switch to 'select' function and redesign your software to be totally async. You have to put all sockets (both connected and accepted) in a FDs set and wait events on them.
win32: https://learn.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-select
linux: https://www.opennet.ru/cgi-bin/opennet/man.cgi?topic=select&category=2
I've written the same app ages ago on win32 (but without calculations) and it easily processed about 200 PLCs, working on the same machine with SCADA.
Upvotes: 1