Modicon PAC Forum
A forum for topics related to the scope of Modicon PAC offers and ecosystem along the whole lifecycle: Modicon M580 and 340, EcoStruxure Control Expert, EcoStruxure Process Expert (Unity Pro) and more.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 12:21 PM
Hi
For the real question, jump straight to TL;DR. But here comes some background story first...
I have a "modbus TCP" slave that refuse to handle more than one request at a time acting more like if it was a RTU device. The DTM browser wont let you do that I guess as it is acting on time based trigging only so communication fails with more than one request added. I need three requests in total, one read and two writes. Next I tried read_var and write_var. That seemed to work at first as I got 0 in second word of GEST for all three function blocks and exchange number was counting fast. Fine I thought so I went on with this project thinking everything was working just great but I couldn't figure out why this seemed to work so flawlessly when the DTM browser just refused. But it turns out that it didn't work very good at all, the writes are not even processed by the slave, probably because the operation of the first read_var is blocking the processing of the writes in the slave even when it seems to respond okay to the FC16, otherwise there would not be 0 in second GEST word. Maybe communication and processing is done by different processes in the slave and they do not sync very well, no idea why it would do this otherwise...
I then thought I could connect ENO to EN on the next block in a chain and that the ENO would fire once the block had received a response and was done but a pulse seems to go straight through all three blocks trigging them at the same time. I now tried a timer and a counter that was counting 0,1,2 and send a pulse on EN on one of the values for each read/write_var. Communication is quite slow as I have to set the timer high to be sure previous request has finished ๐
TL;DR
Can I detect then a read/write_var is done so I can go on and send another request straight after the previous has finished so a slave only needs to worry about one request simultaneously?
The most significant byte of word 1 of GEST will change but I guess this number changes at the start of each request, not when it finishes so that can't be used here I guess?
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 09:01 PM
@dnordenberg1 Are using 3 seperate GEST arrays? I've had the best luck using a seperate array for each FB instance.
Bit rank 0 of the least significant byte of the first word in the array (GEST[1].0) is the activity bit, on means the FB is doing something, off means it is done.
You should have 2 options:
1) trigger one communication FB using the EN pin, but make sure to reset it to 0 before the next task execution, once the FB is not ENabled and it's corresponding activy bit is off, you should be able to trigger then next FB in a similar fashion.
2) Specifically for writing, you should be able to use one FB and one GEST array, just change the object number and data while the activity bit is zero. In theory if the FB is executed continously it'll keep using the same socket on the server (not super helpful if you need to pause for a read).
Unfortunately, you might still need a timer inbetween calling the FBs, since you can't know for sure then the TCP socket on the server is released.
search the help file for "Communication Functions Management" to get more detail about initiating a single communication.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 10:09 PM
Read_Var or Write_Var is done when word 1 bit 0 of the GEST array has a falling edge.
If GEST word 2 is equal to 0 when done occurs then it was successfully done, if not equal to 0 then it was a failed transaction.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-21 09:40 PM . Last Modified: โ2024-05-21 09:47 PM
Behaviour should be the same on both CPUs. If the EN on the READ_VAR (or WRITE_VAR) is on all the time, you will never visually see the activity bit drop off, but you will see the high byte of 1st GEST word incrementing with each execution, and if you put an F_TRIG of Activity bit to a CTU, you should see it counting up.
This example is from an M340, but should work just the same on M580:
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 09:01 PM
@dnordenberg1 Are using 3 seperate GEST arrays? I've had the best luck using a seperate array for each FB instance.
Bit rank 0 of the least significant byte of the first word in the array (GEST[1].0) is the activity bit, on means the FB is doing something, off means it is done.
You should have 2 options:
1) trigger one communication FB using the EN pin, but make sure to reset it to 0 before the next task execution, once the FB is not ENabled and it's corresponding activy bit is off, you should be able to trigger then next FB in a similar fashion.
2) Specifically for writing, you should be able to use one FB and one GEST array, just change the object number and data while the activity bit is zero. In theory if the FB is executed continously it'll keep using the same socket on the server (not super helpful if you need to pause for a read).
Unfortunately, you might still need a timer inbetween calling the FBs, since you can't know for sure then the TCP socket on the server is released.
search the help file for "Communication Functions Management" to get more detail about initiating a single communication.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 10:09 PM
Yes, bit 0 of the 1st GEST word is the 'Activity' bit. This bit remains on while the READ_VAR is doing something/waiting for a response. I use an F_TRIG on the Activity bit of first operation to trigger the EN of the second, and so on. When no Activity bits are on for a couple seconds, I kick off the first one again (with an R_TRIG).
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-20 10:09 PM
Read_Var or Write_Var is done when word 1 bit 0 of the GEST array has a falling edge.
If GEST word 2 is equal to 0 when done occurs then it was successfully done, if not equal to 0 then it was a failed transaction.
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-21 12:15 AM
Yes I use separate GEST arrays for each of the three blocks.
I also thought about the activity bit, I used that one on M340s but now on M580 it seems to be high constantly so it might work differently here?
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-21 09:40 PM . Last Modified: โ2024-05-21 09:47 PM
Behaviour should be the same on both CPUs. If the EN on the READ_VAR (or WRITE_VAR) is on all the time, you will never visually see the activity bit drop off, but you will see the high byte of 1st GEST word incrementing with each execution, and if you put an F_TRIG of Activity bit to a CTU, you should see it counting up.
This example is from an M340, but should work just the same on M580:
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-22 07:02 AM
Oh, activity bit do seem to work today when I tried it now. I did something very similar to your example and it worked. No idea what I did wrong the other day when I also tried something similar ๐
One important thing I noted is that the activity bit management is not in sync with the program cycle so it is not possible to launch the first block by simply looking at if all the activity bits are zero. There is a need for a slight delay here too (your example has 100ms, I got away with only 5ms) otherwise when the first block is done the program cycle will reach the start of the code with all bits set to 0 again and the first block will trigger over and over again. It is not the block itself that resets the bit in sync with the program cycle...
Thanks for your help! ๐
Link copied. Please paste this link to share this article on your social media post.
Link copied. Please paste this link to share this article on your social media post.
Posted: โ2024-05-22 12:58 PM
Be careful making that timer too fast in case the scan time of the CPU changes. You could trigger the first one in the chain off using the timer to kick it off (and as a fail-safe to make sure if something goes pear shaped it will always re-start the sequence), OR'd with the F_TRIG of Activity bit from the last READ/WRITE_VAR in the chain, making it a full circle.
Link copied. Please paste this link to share this article on your social media post.
Create your free account or log in to subscribe to the board - and gain access to more than 10,000+ support articles along with insights from experts and peers.