Author Topic: Monitoring of Com 1 and Com 3 for Ascii  (Read 890 times)

can

  • Full Member
  • Posts: 160
  • I'm a llama!
    • View Profile
Monitoring of Com 1 and Com 3 for Ascii
« on: October 24, 2021, 08:39:45 PM »
Hi. I'm trying to use FMD88 as an Ascii interchange where Ascii command will be coming in from Com 1 and send out to Com 3 or vice versa. Any idea can it be done?

garysdickinson

  • Expert Member
  • Posts: 480
  • Old PLC Coder
    • View Profile
Re: Monitoring of Com 1 and Com 3 for Ascii
« Reply #1 on: October 25, 2021, 04:09:59 PM »
The short answer is yes. It is possible to use the FMD PLC to handle serial communications on both serial ports.

The TBASIC has a full set of statements and functions to support user written communication protocol over the serial ports.

To provide a better answer, you would need to provide a bit more detail about the communication protocol that you intend to use.

Gary Dickinson
« Last Edit: October 25, 2021, 04:21:37 PM by garysdickinson »

can

  • Full Member
  • Posts: 160
  • I'm a llama!
    • View Profile
Re: Monitoring of Com 1 and Com 3 for Ascii
« Reply #2 on: October 27, 2021, 10:25:14 PM »
Hi. I was playing around with FMD88 and run into a problem. I wanted to use FMD88 to emulate a computer sending out a command "PASS/n" but failed. /n is CR right? So I left it out since CR is automatically sent at the end of the sentence. Correct me if I'm wrong.

Print#1 "PASS"
Outcomm 1, 26

The receiving computer software always prompt that end of line is not received. Any idea why?

garysdickinson

  • Expert Member
  • Posts: 480
  • Old PLC Coder
    • View Profile
Re: Monitoring of Com 1 and Com 3 for Ascii
« Reply #3 on: October 28, 2021, 02:14:39 PM »
can,

In regards to the meaning of the C programming construct of "\n" or newline, this is an operating system dependent behavior.  In UNIX \n translated to a linefeed.  In other operating systems it translated to a carriage return.  In CPM it was 2 characters a carriage return and a linefeed. So I have no clue what your device expects as a line termination sequence.

I think your example would output "PASS<CR><SUB>".  The 26 value used by the outcomm statement got you the  < SUB > character.  I haven’t seen a communication protocol use this character.

The Print #n statement prints 0 or more arguments separated by a semicolons, ";". if there is an ";" at the end of the statement, then print #n will not append an end of line character to the output characters.

If there is no  ";" at the end of the statement, then the print #n statement will append an ASCII carriage return, CR or 0x0d, to the output.

Samples:

print #1 "hello";                      ---> sends "hello" only
print #1 "hello"                       ---> sends "hello" and an ASCII CR
Print #1                                 ---> sends ASCII CR only
Print #1 "hello";"\0a";            ---> sends "hello" and an ASCII LF (linefeed) with a hex value of 0x0a
print #1 "hello";"\0d\0a";       ---> sends "hello and an ASCII CR followed by an ASCII LF

So you  are not to limited in controlling the end of line character(s).

If you have to send an ASCII NUL or 0x00 then you need to use OUTCOMM.

Gary D
« Last Edit: October 29, 2021, 08:48:09 AM by garysdickinson »

can

  • Full Member
  • Posts: 160
  • I'm a llama!
    • View Profile
Re: Monitoring of Com 1 and Com 3 for Ascii
« Reply #4 on: November 10, 2021, 11:59:13 PM »
Hi Gary. Thanks for the advice. Had it sorted out. However, I have a question. What can I do if I want to receive, modify portion of the string, and  send out a super long string that consists 400 character from Port 1 to Port 3? Can it be done?

garysdickinson

  • Expert Member
  • Posts: 480
  • Old PLC Coder
    • View Profile
Re: Monitoring of Com 1 and Com 3 for Ascii
« Reply #5 on: November 12, 2021, 11:42:13 AM »
can,

If your application is just to act as a simple store and forward device and does not interpret or validate the received messages, then you just need to check the state of the receive buffer on each scan of the ladder logic and copy any and all received data bytes to the transmit port.

I am assuming that your issue is non-trivial.

The simple answer about communication protocols that require > 256 characters to be transmitted or received is "maybe".

    Let's talk about sending long messages:
    • There is a 256 byte output buffer for each communication port. Characters are placed in the buffer as the result of OUTCOMM and PRINT statements. Characters are removed from this buffer by low-level PLC firmware.  This firmware moves the data into a second buffer of 16 to 32 characters that are managed by the the UART. The UART is responsible for converting the data into a series of bits and shipping them out as a serial data stream.
    • If you your outbound message is greater than 256 characters you will have to divide the message into chunks less than 256 to fit into the output buffer.
    • There is no mechanism in TBASIC to determine the state of the output buffer.  The only way to prevent corruption of the buffer is to pace the OUPUTCOM or PRINT statements.  If you communicating at 9600 BAUD each character takes 1.042 ms to transmit. If each of your PRINT statements sends 256 characters you will have to wait at least 267 ms between PRINT statements to prevent corruption of the output buffer.  You are hoping that the output buffer is empty before the next PRINT statement.

      Let's talk about receiving long messages:
      • There is a 256 byte receive buffer for each communication port. Received characters are placed into the 256 byte buffer by means of low-level PLC firmware.
      • The INCOMM(ch) command returns a value of -1 if the receive buffer is empty. I would suggest reading received data with this command and buffer it in DM[].
      • It is the responsibility of your TBASIC code to pull characters out of the receive buffer faster than they are received.  Failure to do so will result in corruption of the input buffer. If you are at 9600 BAUD then you must be able to receive 256 characters in 267 ms.
      • I would suggest checking for received characters on each scan of the ladder logic and reading all characters from the receive buffer if any are detected. Remember that at 9600 BAUD that characters will arrive every 0.001 seconds. You will have to buffer the received characters using DM[] or EPP (if you have installed the RTC 256K module).

        Let's talk about your communication protocol:
        • How tolerant is it with gaps in the messages that you will be transmitting?
        • If you are sending messages in chunks, then there will be gaps in time when no characters are transmitted. If you protocol has some sort of timeout mechanism, you will have to ensure that the transmit gaps are short enough so that the receiving end does not timeout and long enough that to prevent corruption of the PLC output buffer.
        • Modbus RTU expects a message to be sent without gaps between characters.  A gap is interpreted as an end of message. In order to not have a gap in output Modbus RTU frames, I buffer everything, compute the CRC and send the entire frame in one tight loop.  I limit the message size to less than 256 characters to avoid any gaps in the transmission.


        Gary D[/list][/list][/list]
        « Last Edit: November 12, 2021, 03:19:43 PM by garysdickinson »

        garysdickinson

        • Expert Member
        • Posts: 480
        • Old PLC Coder
          • View Profile
        Re: Monitoring of Com 1 and Com 3 for Ascii
        « Reply #6 on: November 13, 2021, 09:19:53 AM »
        can,

        On the receiving end, I would suggest that you not bother with the INPUT$(ch) function. The documentation leaves out a bit of its behavior:


        To return a string obtained from communication port # ch.
        ch must be a numeric constant between 1 and 8. The actual target hardware determines the valid port #. This function returns an empty string if there is no valid string waiting at serial port in order not to hold up the CPU.



        These are some of the things not documented:

        The maximum number of characters returned is limited by the string variable.  Most of TRI's PLC’s strings are limited to 70 characters.  EEP$ strings are usually 40 characters max.  If the message is 80 characters in length, you will have to make multiple calls to read the message.

        The actual function does not return the end of line character.  So if your protocol uses an end of line character you will not see it.  If your protocol uses a pair of characters to mark end of line, CR and LF, it will discard one of the pair of characters and the other will be returned in the string.  I don’t remember what the function considers end of line.

        If you receive a 0 length message, then the receive buffer is empty.  This does not always indicate that you have reached the end of message. If you wait a few milliseconds you may find that more characters have arrived.

        Because of the string variable length issue, the loss of the end of line character and the detection that the receive buffer is empty, I find that INPUT$() is not worth the effort.

        I use the function INCOMM(ch)  as it has fewer limitations. And, since you see all characters it is easy to detect the end of message.  It is an easier function to determine if the receive buffer is empty as it returns the value -1 on this condition.

        Gary d

        can

        • Full Member
        • Posts: 160
        • I'm a llama!
          • View Profile
        Re: Monitoring of Com 1 and Com 3 for Ascii
        « Reply #7 on: November 18, 2021, 04:14:09 AM »
        Hi Gary.

        Thanks for the advice. Your advice has been most useful. I'm using incomm(1) and managed to read 170 characters into dm, converting them into 3 string and send them out using print #3 A$; print# 3 B$; print #3 C$. However, the receiving system at #3 cannot get the correct sent message. It can however, get the correct message if the string is 12 characters long. Any idea why? Port speed mismatch?

        garysdickinson

        • Expert Member
        • Posts: 480
        • Old PLC Coder
          • View Profile
        Re: Monitoring of Com 1 and Com 3 for Ascii
        « Reply #8 on: November 18, 2021, 12:42:35 PM »
        can,

        I don't have an answer to why long messages are not accepted by the target device.

        I assume that the target device is not a PLC.  So you don't have much visibility into what the device is "seeing" on it's end of the serial cable.

        Since all of your print statements are are all on the same line of TBASIC and the total number of characters is less than the PLC transmit buffer size of 256 then my usual idea about gaps in the data stream probably do not apply.

        OK so now I am down to other reasons that things might go south...

        BAUD rate might be a problem.  If the target devices firmware is dumb, has a very short buffer or is just badly implemented firmware, then you may be sending characters faster that the target device can handle.  Drop the BAUD rate to something like 300 (about 30 characters per second).  If this fixes the problem then you have learned something about the target device. 

        I run 9600 for my Modbus communications because it is fast enough for my applications. It is slow enough to not need termination resistors even with long cables.

        If I  suspect the PLC programming is messing up the transmitted string, then i monitor the serial line to see exactly what is being transmitted.

        COMM3 is RS485, you will need  a RS485 to USB dongle for your PC.  I use a shareware program named "Tera Term" to monitor the serial port that the USB dongle has been assigned by your PC.  This will allow you to both observe and log the data that is being transmitted from the PLC's COMM 3 port.

        If you have one of the "smart" sampling oscilloscope most can decode ASCII serial data.

        Good luck,

        Gary D

        « Last Edit: November 18, 2021, 06:28:59 PM by garysdickinson »