Handshaking and asynchronous data transfers

RMA

Member
Join Date
Sep 2004
Location
North of Hamburg, Germany
Posts
2,052
Unlike my usual questions, I've not labelled this one as being S7, because I'm really after a generalised answer. I've only tried asychronous data transfers a few times and it allways finishes up a disaster. Usually I finish up piling one handshake on top of another to cover some problem and then the next problem pops up, until the whole thing collapses under it's own weight.

The problem I've got is that my FM352-5 program works fine (or at least, it appears to) in Debug mode where the program is actually running in an FB in the CPU and the only communication over the backplane is to transfer the state of the I/O - read the inputs and set the outputs to the required state, but not when the program is running in the FM. In the Debug mode case of course, the communication between the FCs which are controlling things and the FB is direct and not over the backplane. When the program is actually running in the FM, then the communication between the two is via two DBs, CPU_In and CPU_Out over the backplane. The program is in each case identical, it is simply recompiled to a form appropriate to the FM's FPGA processor.

I think the first question is, is handshaking the best way of realising this or would I be better off using a simple state machine, as I did for the FTP transfer between the PLC and a PC, which works fine.

However, I would still like to know how to build a bullet-proof asynchronous data transfer with Handshaking.

What I've got at present is the FC sets a New_Data Bit and sets the Data to be transferred in four Data_Bytes in the CPU_Out DB. In the FB (or FM) when this Bit is seen, the FM_Busy Bit is set in the CPU_In DB. The FB/FM program then checks the data for errors and if the data is OK, stores it and sets the OK flag in the CPU_In DB, otherwise the Error_Flag is set. The setting of the OK or Error flag in the FM program also clears the FM_Busy flag.

When the program is running in the FM this will all execute in one cycle, i.e. 1 µs, so that the chance of the FC program seeing the FM_Busy flag is miniscule (Because of the asychronous data transfer over the backplane to the CPU_In DB, it's not quite zero though). Obviuosly, when the program is running in Debug mode in the FB, it will execute very much more slowly and I would guess that the updating of the CPU_IN and CPU_Out DBs is probably no longer truly asynchronous.

The next time the FC is called, after checking the Busy Bit in the CPU_In DB (and exiting if set), it checks to see if the New_Data Bit in the CPU_Out DB AND either the OK Bit OR the Error Bit in the CPU_In DB are set. If not, then the program runs through the New_Data sequence again, and exits. If OK or Error is present, then the program jumps over the New_Data part and instead clears the New_Data Bit and sets the FM_Data_RECD Bit (both in the CPU_Out DB) and sets Merker Flags to tell the calling FC that the data transfer for that module has completed, and whether or not the transfer was OK.

What happens in practice is that in Normal mode, running in the FM, the program gets stuck in an error condition on the first transfer and stops after three retries. However, if I switch to Debug mode, then everything appears to work fine. I suspect a part of the problem might be that at start up in the FM some spurious data condition is causing an error which I am then not clearing properly, but everything I've tried sofar has degenerated into the debacle I mentioned above, with Handshakes on top Handshakes.

I can post the relevant FCs and the FB if necessary, but first off I'd just like to see a generalised (theoretical?) version of how to approach asynchronous data transfer. I'm sure there must be plenty others out there who've also had problems in this area.
 
Instead of a new data bit, use two integers. Increment one of them when new data is ready, and have the receiving function increment the other integer when the new data has been received. In the initiator, compare the two integers to determine if the communication is complete, in progress, or timed out (if unequal for a pre-determined dwell period). In the other process, compare the registers and trigger the required operation when they are unequal. After the operation is complete, either increment the second integer or overwrite it with the value in the first. This way is simple, and you don't have to worry about one process having to "catch" a quick changing bit in another process.
OkiePC
 
Thanks for the suggestion OkiePC. I suspect my problem is being caused by the fact that the Error Bit is already set when I attempt to start the transfer and at the moment I'm not handling that possibility. If the problem persists, I'll come back and have a look at the counter setup. I've got spare space in the CPU_In and CPU_Out DBs (they have a predefined, fixed length of 14 Bytes), but the thing that worries me most is memory usage - I had to add an edge detector at one point and that took me two cells over the 1200 cell limit. I had to take out the network where I reflected the CPU_Out.New_Data Bit back to CPU_In.New_Data_Recvd, which I was using as part of my handshake, in order to get enough room and I don't have any more "redundant" Networks! In fact, I thought that was where my problems had started, now that I've found that the Error Bit is set from the word go, I'm not so sure!

Edit:

PS, I'm still interested in a theoretical discussion of what has to be taken into consideration when handling asynchronous data transfers - any takers, Jiri Toman, Ron Beaufort?
b020.gif
 
Last edited:
I have used the method suggested by OkiePC with incrementing integers.

I have a telegram counter and a datacounter.
If a new datatransfer is required, then both the telegram counter and the datacounter are incremented (this happens approx every 5 sec).
If no telegram transfer has been made within a timeout of 1 second, then only the telegram counter is incremented.

If the telegramcounter is incremented, then a telegram is sent.
Both the telegram counter and the datacounter are included in the telegram.
The recieving PLC monitors both counters to see when a telegram is recieved, and when new netto-data is recieved.
The recieving PLC sends the two counter values back to the sending PLC in another telegram.

Because a pair of telegrams is sent every second, even if no new data is present, a watchdog timeout can be implemented in both PLCs.

And because the recieving PLC gets both counters back, it gets confirmed that the data is really recieved in the other end.

All of this may not be possible to implement in your FM352-5.
Don't Siemens have an "approved" way of doing these things ?
 
As far as I understand your all talking about communication over db's, how should a communication over serial or any other means be solved? I still havn't been able to create a foolproof system. What if the receiveing plc can't read both integers?

Sorry if this is hijacking the thread...


Regards
Borte
 
The method I have described is as "protocol independent" as possible.

Last time, I used it with AB PLC's over DH+. But it can be used with any type of Protocol or PLC. You must simply be able to transfer a number of Words (or Bytes) in a block at a time.

It can even work with Profibus DP where one CPU is master and the other is slave. In that case the words that a CPU must send becomes output words, and the same data becomes input words in the recieving CPU.
 
I've had a look at a first implementation of a counter based system and it takes me way over my memory limit in the FMs. Just looking at it I can't see any way to substantially reduce the memory use.

However, I've come to the conclusion that I may be chasing the wrong problem. As I mentioned, the program appeared to work in Debug mode, but returned an error immediately after start-up in Normal mode. As I thought, my error handling was not handling this case properly, so I've corrected it. Now even if I permanently set the CLEAR Bit in the CPU_Out DB and don't even call the Data Transfer FC, I still get a permanent error returned in Normal mode. In Debug Mode, everything seems to work fine, regardless of what I do.

I don't think there's much else to do with this one, other than send an e-mail to Siemens. Wonder if I'll get an answer before the weekend?
 

Similar Topics

Good day - I have scoured the forum to no avail. I have a Siemens 555-1106 rack with a remote base on RS485. It does not currently, but will be...
Replies
3
Views
2,160
Hi, I am communicating with a LIN interface (PCAN-LIN) for a project. I am using a CompactLogix PLC with serial port. I was wondering if anyone...
Replies
1
Views
2,156
In FactoryTalk I can set up an alarm to set a tag to 1 in the PLC when I acknowledge the alarm in the HMI. Conversely I can set the acknowledged...
Replies
0
Views
1,847
I am converting a Panelview 1000 over to a RedLion G310. The panelview is using the handshaking and notification option quite often thru-out the...
Replies
14
Views
4,091
Okay, here is the situation. My PLC is a compact logix 5000, my HMI a Versa-View running Factorytalk. I need to create a database that contains a...
Replies
5
Views
3,009
Back
Top Bottom