I'm working with a project that involves communication between a LabView PC, a cRIO-9073 and a few Crouzet PLC's with XN05 modbus extentions. The issue I'm having is to get a stable and reliable connection between the units. The cRIO is communicating with the PLC's by Modbus RTU over TCP and I've created code that read and write to them in a sequential order to avoid possible ModBus conflicts. The LabView PC is sending a "ping" (boolean true) every second to the cRIO over UDP and the cRIO is then sending the "ping" to the PLC over Modbus/TCP. The PLC has a timer that waits for pings, if no ping has been recieved in 7 seconds the emergency brakes are applied and the system shuts down.
The main problems right now is:
* After a while I lose the connection between the LabView PC and the cRIO. "Connection with RealTime target cRIO-9073 has been lost".
- I also get either error code 56 or 66 on the TCP link.
* The second problem is that if I quickly pull a TP-cable from, let's say, a PLC and then directly plug it back in I want the TCP connection to quickly reestablish. However what happens is that the "pings" from the cRIO stops coming to the PLC for like 5-6 seconds (time to reestablish link?), which means the 7 second timer is almost full. One option would be to raise that timer value, but the drawback is that the system will take longer time to respond to an true error which could be bad.. My question is simply, does it really take 5-6 seconds to establish a TCP connection between a cRIO and a PLC? What affects the time?
I would greatly appreciate help or respons on this one. I attach a simplified version of the code I use (all variables and such has been replaced with constants).
Is this a good way to do a ModBus communication over TCP with 3 PLC's? Is there a better, safer, more reliable way? All suggestions on improvment is appreciated 🙂
You have to do some modification in your code to make it reliable and executable.
1. In your code you merge all RTU errors. This indicates that if you got error in any system you are going to consider that your complete system is faulty.
2. No need to Open and close TCP connection again and again. Error-56 shows that connection is there but you are not getting any data on TCP so its give you timeout error. You can ignore this error and no need to close connection, you have to check your other end code or some time synchronization is required to communicate. Error-66 show that connection is closed from other side but you still want to read something on Network i.e.. no connection available.
Personally I suggest you to use State Machine Architecture to remove these errors and you can provide the flexibility to your code. If your communication setting are perfect then the connection will establish immediately no wait is there.
3. In your MB_PLC VI if loop is running only one time then no use of while loop remove it.
4. If you want to stop the system and you press the stop button but you inner while loop is working fine so it will never come out from this loop so your program will run continuously.
5. In your code you are using sequence structure. It's indicate that when your first acquisition complete then only it goes to forward for second, third and so on. In this case you have 200-200 delay between each sequence. so your normal acquisition for one cycle 600ms,
Thanks for your answer!
But does the TCP connection really open and close again and again? My idea was that if there is some error on the connection (in the inner loop) then and only then will the TCP connection restart. Because if I pull the TP cable quickly and put it back I get an error from the MB Write register and the Modbus stops working, that's why I restart the TCP Open, is that wrong?
Do you know any good examples for a State Machine Architecture? Would you suggest some other layout instead of using a sequence to communicate with each of the PLC? Earlier they were separated in parallell loops, but that caused problems as well and I was suggested to use sequencial communication.
Is it bad to merge all errors, except that I restart all connections?
I'm aware that the cycle time for each PLC is 600ms, but that is okay.
Check the state machine Architecture here.
1. In your acquisition if you got error in any system you close all TCP connections that is not right your other systems are working fine.
2. You go with parallel loop connection. For each PLC you run separate code with error handlers.
3. Check the attached VI for TCP Read. Same VI you can modify and use for your ModBUS operations.
4. In you Sub VI you are passing a constant cluster. I am not able to understand what is the use of case structure inside the subVI, In you code you are passing the constant so its always same.
As you done previously made 3 loops or VIs to read the data in a main VI. First try to made one VI with one PLC, remove your all bugs and errors and copy it 3-time with different-different configurations.
Thanks for the example,
I have modified it slightly and tried it but the same problem persists. I made 3 copies of that State Machine, one for each PLC. But it still takes about 6-7 seconds for the connection to be reestablished when I pull the TP-cable from a PLC and I get error 66. The timeout in the PLC is set to 10 mins and there are no other options there.
2. Another problem when I run parallell loops instead of sequential is that once I pull the cable I stop getting data from my other two PLC's. It seems like all other TCP connections are halted on the RT when one of them get an error and loses connection. How can that be?
4. It's not just constants in the real code, it's variables and more states in the cases, I just simplified it for posting here.