R1 + SNAP-SCM-485-422 "Turnaround Time"

Hi All,
I’m using a SNAP-PAC-R1 and a SNAP-SCM-485-422 to communicate via RS485 (2-wire mode) to a custom I/O controller on a machine. When the R1 issues a command that requires a response I found that I had to add a delay in the I/O controller code before returning the response. This seems to work fine with a delay of 10-milliseconds between when the I/O controller receives the command packet and returns a response. Without the delay the R1 receives garbage characters in the receive buffer which seems to indicate the R1 wasn’t yet ready for the response.

For clarity, the command packet is 5 characters: SOF,AddrHi,AddrLo,Command,EOF and the response is 6 Ascii Hex characters. I’m using the following method in PAC Control:
“Transmit String” immediately followed by “Receive N Characters” (6 in this case).

Is there a worse case spec for how long it takes the R1 to switch back (turnaround) to receive mode after transmitting?

Thanks for your help.
Fritz E Noll

Is it possible for you to post your code? I suspect something else may be going on as I haven’t had the same experience. I have used these modules for modbus communication without any delay between transmit and receive just fine, however there are some commands in between the transmit and receive.

Do you use GetNumCharsWaiting prior to the receive?
Are you checking your return codes?
If communication fails, do you clear the receive buffer (ClearCommunicationReceiveBuffer)?

Also, before I begin a communication transmit I run the following code (which also opens the comm handle if needed):

if (GetNumCharsWaiting(chCommHandle) < 0 or not IsCommunicationOpen(chCommHandle)) then
  nStatus = OpenOutgoingCommunication(chCommHandle);
  nStatus = 0;

I then check nStatus and make sure it is 0.

Interesting (to me) Note: On the serial modules, it is easy to overrun the transmit buffer. I have found if I am transmitting bulk data I have to throttle the data I’m sending through the serial modules with an appropriate delay based on the baud rate. Unfortunately the serial modules give no indication when their 1000 byte transmit buffer is full. I don’t remember if they were dropping the data (I think it was!), but communications did slow way down. They SHOULD return a -531 error on transmit, but they don’t. I need to get around to filing a bug report on that, but I don’t have a personal need to get that fixed at the moment. Maybe someone at Opto can build a test setup and check it out (Just send 1024 byte string at 300 baud and see what happens). I believe I was transmitting to a telnet client when I was testing the serial modules for max baud rate when I found this. Without putting in a “baud rate transmit delay” (PayloadSizeBytes * RawBitsPerByte / BaudRate) I wasn’t getting the expected throughput (something like 20% of max of 115,200). With the delay, I was able to transmit at the full baud rate.

Thanks Phillip. I don’t check the error codes within the routine, but I have been monitoring them during debug mode (in a scanning window) as well as the 6-character returned string variable. I never get any error code (always 0) and the string variable has the correct returned string with a delay as small as 1ms (the lowest I can currently set). With the delay OFF, the data in the string variable is always 6 repeatable garbage characters.

My I/O controller will return the 6-character response string immediately upon receiving the EOF unless the “response delay” is set.

My routine is a chart that is started by another Master chart and once started it runs to completion until it’s started again. It’s very short and executes the following four commands at the beginning:
1 - “Open Outgoing Communication” (unconditionally)
2 - “Clear Communication Receive Buffer” (unconditionally)
3 - “Transmit String” (the string is *11I:)
4 - “Receive N Characters” (N = 6)
5 -… The routine then converts Ascii to Hex and sets/clears some global variables then it’s done and stops running until started again. So yes, the routine enables communication and without checking for a need, clears the Comm Receive buffer. The issues is certainly between 3 and 4 when the I/O response is too quick.

I can live with the small delay by the I/O controller and can reduce the delay by adding a uS rather than mS routine no problem. But IMO there has to be some time required by the R1 between sending the last character and switching the SCM back into receive mode. That “turnaround” time may be variable since the R1 is running a multi-tasking kernel. I was hoping to find a “worse case” value just to make sure the delay used was sufficient.

If you really need to see the actual code I suppose I can recode it in OptoScript and include it in a later post in this thread.

Thanks again for your help.

Fritz E Noll

Okay, now I understand, you are adding a delay on the device you are talking to - I thought you were adding a delay on the Opto side - makes much more sense now.

I don’t know how long it takes for the transceiver to switch to receive and that would be good to know, but it is normal for slave devices to have a turn around delay before they respond to allow the transceiver to switch (I know this is in the modbus spec, 3.5 character time).

I think this is going to be a function of the serial module itself and is likely deterministic and may be based on the baud clock even, so faster baud rates would switch faster. I would try a 1 character delay and verify at different baud rates and see if it works reliably.

This tells me that you are only missing part of the first character, and a single character delay will take care of this. So 10 bit character (with start and stop bit) at 9600bps would be a approx 1.05ms delay.

1 Like

Thanks again Philip,
My apologies for not knowing how to quote a line from your post, as you have so nicely highlighted mine, so I’ll copy and paste with quotes:

“I think this is going to be a function of the serial module itself and is likely deterministic and may be based on the baud clock even, so faster baud rates would switch faster.”

So, the serial module (SCM-485-422) is a “smart” module with deterministic delay(?) and doesn’t depend on the R1’s other activities at the time? Your use of “likely” does bother me though. OK then. I knew all along that part of my IO controller response was lost because of being faster than the combination R1 and SCM “turnaround time”, thus resulting in a partial (garbage) message at the receiver end, so we are in total agreement on that.

“I don’t know how long it takes for the transceiver to switch to receive and that would be good to know, but it is normal for slave devices to have a turn around delay before they respond to allow the transceiver to switch (I know this is in the modbus spec, 3.5 character time).”

You’re 100% correct about having a “turn around delay” but it has to be specified. I just need to know what the worst case delay would be and set my delay accordingly and with margin. The Modbus Spec (which I have used many times) came up with that rather awkward 3.5 time value as a safe delay to allow controllers to switch from Tx to Rx without missing an important and perhaps critical response.

However, independent of baud rate (mine happens to be 38400/no parity/1-stop) the turnaround time at the Opto22 end should be known and published and guaranteed in order to ensure normal communication and prevent possibly disastrous results for interpreting an erroneous response that doesn’t show up in the “status” variable.

For me, my engineering side says that even though my “guessed” delay of 10ms or my shorter 1ms value made communication from the I/O controller work very well, it still leaves me a bit uncertain that I’ve covered all real world circumstances.

Someone at Opto22 should know whether the SCM “turnaround time” is a deterministic value, as you suggest, and if so what is that value? If not deterministic, being for example that the “turnaround time” is partially a function of the real-time kernel the R1 Chart is operating under, then someone at Opto22 should know the worse case “turnaround time”.

A value for either the deterministic or worst case scenario, whichever it is, as long it’s accurate, will help me sleep better knowing that the machine will not crash randomly with no trace as to why (followed by a lot of yelling and screaming, threats of tar and feathers and much broken glass). If I missed this critical number somewhere in Opto22’s docs, I apologize. Please lead me directly to that doc.

By the way, the machine bottles Beer, so your beers are on me if you can help.

Highest regards to all,
Fritz E Noll

Using R1+SNAP-SCM-485-422, it is very convenient to realize serial communication.

To quote, highlight the text and a quote button will show up.

I don’t see this specified anywhere, you may want to e-mail support and see if they can ask an engineer if they know what it is.

For what it’s worth, I tested a serial module by listening to a constant data stream from another module, had the serial module transmit one character, then went back to listening. I would see the expected data at the bit level after 11 bits were received after the transmit ended. This was the case if the baud rate was 300 or 115200, so a turn-around in units of time will be irrelevant. I would think a one byte delay would probably work, but a two byte delay would be safest. (521 uS @ 38400bps). I understand you want official confirmation though.

In my opinion, if you’re in control of the protocol and want to avoid the above scenario, I would add a checksum/CRC. Sending data over a wire is never perfect all the time. I would suggest using parity, but PAC Control won’t tell you if there is a parity error when receiving, it will just give you garbage data - sad :sob:. Parity isn’t as good as having a CRC anyways.