Author Topic: Serial communications  (Read 28062 times)

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #15 on: April 13, 2011, 02:38:59 AM »
Hi Guys,

Thanks for your response (Gary and Tri).  I have re arranged and modified the code a bit and now it works as required  :)

******CODE******

CLRIO NEXT_CALL

A$ = INPUT$(1)                        ' CHECK FOR DATA ON COMM PORT 1

IF LEN(A$)= 0
SETLCD 0,0,chr$(1)                     ' 1 SENT TO LCD WILL CLEAR SCREEN
SETLCD 0,1,CHR$(12)                   ' NO CURSOR
SETLCD 1,1, "NO TIMING MAP DATA"    
B = B + 1                           ' COUNTS NO DATA RECEIVED
ENDIF

IF LEN(A$) > 0                        ' LOOK TO SEE IF RETURN STRING IS > 0
A = A + 1                           ' COUNTS DATA RECEIVED
SETIO RX_LED_RELAY                     ' SET RX LED
B$ = MID$(A$, LEN(A$)-5, 4)               ' COPY LAST FOUR BYTES (-5) AND NUMBER OF BYTES LONG
ENDIF

DM[1] = HEXVAL(B$)                      'CONVERT RECEIVED DATA FROM HEX TO DEC

SETLCD 0,0,CHR$(1)                     ' 1 SENT TO LCD WILL CLEAR SCREEN        
SETLCD 0,1,CHR$(12)                   ' NO CURSOR
SETLCD 1,1, "TIMING MAP = " +STR$(DM[1],2)

IF A = 0
SETIO TX_LED_RELAY                     ' SET TX LED
PRINT #1 "50002402000E00027A"              ' ASK CCM FOR SPEED TIMING MAP 0 -255
ENDIF

IF
A > 0                              ' WHEN NUMBER OF REPLIES = 1 MOVE ON TO NEXT CALL
SETIO NEXT_CALL
B = 0
A = 0
ENDIF


*******************

On another note... the following will not compile. I have tried many different permutation with () and "" but cannot get it right!!


PRINT #1 "50003402000E000DFF" + STR$(C$) +"50"

the C$ contains a hex variable I want to add to the string (F).

The other the problem is calculating the new checksum.  In this case "50" is the check sum of the whole message.  I use =CheckSum(xx) in excel to calculate the whole message CS but was wondering if it can be calculated in the PLC before sending?

Otherwise I could use a load of IF statements i.e

IF
C$ = xx
Print #1 "A"
ENDIF

IF
C$ = xx
Print #1 "B"
ENDIF

etc

Cheers

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #16 on: April 13, 2011, 08:32:27 AM »
Can't help with your PRINT statement.  The isolated statement complies for me.  I'm guessing that your have messed up the "(" or some other syntax junk in a previous line.

In regards to calculating a Checksum (sumcheck) it is pretty simple.

If you concatenate the strings that need the the sumcheck in  A$, then call a custom function that appends the appropriate sumcheck value onto A$, then you can send A$ on it's way.  Something like this is a good starting point:


' SumCheck
'
' On entry A$ holds ASCII string
'
' On exit A$ holds ASCII string with checksum appended
'   Integer variable used: I,S,N
'
'
S = 0               'Starting point for SumCheck
N = LEN(A$)   

FOR I = 1 TO N         ' For each ASCII char in string
   S = S + ASC(A$,I)
NEXT

S = S & &HFF         ' Toss out everything but 8 bits
A$ = A$ + HEX$(S,2)   ' Tack on sucmcheck



Since there are no absolute rules on how checksums are calculated, you may need to adjust the algorithm to fit the rules for your communication protocol.

Gary d.

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #17 on: April 13, 2011, 08:53:19 AM »
Thanks Gary,

I'm not sure why I can't compile that will carry on trying!


BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #18 on: April 20, 2011, 04:30:39 PM »
Hello all.

Can the PLC receive HEX data on the serial port that doesn't have a carriage return terminator?

I looked at incomm but this is binary only?

cheers.

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #19 on: April 20, 2011, 08:49:06 PM »
incomm() is your last resort.

If your incoming data is not delimitated by ASCII <cr> characters, then your only choice is to use incomm().  In these cases, your code will have to handle each character received from the external device and figure out what is data and what is chaff.

Yes this function does return an 8-bit integer value.  If you need to convert the value returned by incomm() to an ASCII character, you can use chr$()

A$ = chr$(incomm(4)) 'poof a$ now contains a single ASCII character

Gary d

Gary d

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #20 on: April 20, 2011, 08:57:47 PM »
In regards to your error in compilation

PRINT #1 "50003402000E000DFF" + STR$(C$) +"50"

This line should NOT compile.  The problem is with str$(c$).  Str$() expects an integer as an argument.  C$ is a string!

Sorry for not catching this, earlier.

Gary d

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #21 on: April 21, 2011, 12:52:20 AM »
Hi Gary,

Thanks for the info.  

Regarding converting the data back to ascii, I see each ascii character in A$ but only one character at a time (8-bit integer value)  how do I reconstruct the entire string? i.e copy each value from a$ to x$ in the right order?  also the a$ returns a /FF at the end of the received string, I guess this is the PLC confirming job done!

Cheers

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #22 on: April 21, 2011, 07:54:14 AM »
Concatenation.

if A$ +"A" and X$ = "B",
    then  concatenate:

         A$ = A$+X$

A$ will now be "AB"

As for the /FF you are seeing returned from INCOMM() is probably one of 2 things:

1.  It is actual data received from your external device
2.  -- OR -- INCOMM() is documented to return a numeric -1 value
     to indicate that NO character has been
     received from the external device since the last time that
     you called INCOMM().

     Remember that a decimal -1 is a string of "f"s in hexadecimal.

Gary D


BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #23 on: April 21, 2011, 09:51:04 AM »
Hi Gary,

Thanks for that. I may have led you down the garden path with the x$.... The problem I have is that the the incomm string is converted into A$, each character appers one after the other for a short duration  a bit like the message boards with the moving text! (I see this in the simulator). What  I need to do is copy each individual value before it changes in to another string, B$ for example.

Thinking about it I guess I could use
If
B$ <> A$
B$ = B$ + A$
Endif

What do you think?

Cheers

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #24 on: April 21, 2011, 11:47:04 AM »
I don't actually think that I can really help all that much.

Your description that strings change value with time is nonsensical. If a string variable changes, it is because your programming changed the string.

Sorry,

Gary d

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #25 on: April 21, 2011, 12:34:05 PM »
Hi Gary,

Try it!  I'm sendind a string like 001234567800 to comm port 1

Run a fm incomm on that port, convert to ascii and copy to A$ and you see 0 delay 0 delay 1 delay 2 delay etc

The delay is probably caused by me calling the fm via a 1 sec contact. I suspect this is because the data is being transferred from the serial buffer to the A$???
Cheers

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3170
    • View Profile
    • Internet Programmable PLCs
Re:Serial communications
« Reply #26 on: April 21, 2011, 01:14:28 PM »
Gary thanks for helping up with questions posted by BC System. I hope the following helps to clear up things a bit:

The PLC has a 256 bytes circular buffer that can keep incoming byte data. Each time you call the INCOMM command it removes one byte of data from the buffer and return to you. All data returned are positive number between 0 and 255. When it runs out of data (buffer empty) it returns a -1.  That marks the end of the buffer.

You do have to know what is the delimiter to know how to assemble a series of data into a string if that's what you want to do. The delimiter is either a special character or a sequence of a few characters to mark the end of a packet, so your program need to check that in order to return a complete packet of data.  The concatenation method that Gary mentioned will work to assemble incoming bytes and translate them into string characters, but it is really up to you to program when the delimiter has been received and end the string concatenation.

« Last Edit: April 21, 2011, 03:37:53 PM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #27 on: April 21, 2011, 02:21:56 PM »
Guys,

Thanks for the pointers. I'm not trying to assemble two separate strings but make one complete string form the data received using the income fm.

If I send the following to port 1:

12345

Then use the following fn to convert to ASCII

A$ =chr$(incomm(1))

I get (looking @ online monitor) 1 delay 2 delay 3 delay etc

How can I reassemble the complete string and store in B$?

Cheers.




garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Serial communications
« Reply #28 on: April 21, 2011, 02:59:42 PM »
I'll give it one more try.  

Let's say your did something like this:

1. Did something to request data from some external device.

2. Wait 1 second to ensure:
    Request was sent to the external device
    Request was processed by the external device
    External device sent the requested data.
    PLC has buffered up all received data bytes

3. Now, assuming everything went as planned,  do something like the following to build a string in A$:


A$ = ""                ' Empty string
D  = INCOMM(1)         ' get first data byte (if any)

WHILE(D <> -1)         ' While data is available
   A$ = A$ + CHR$(D)   '   assemble string
   D  = INCOMM(1)      '   get next data byte (if any)
ENDWHILE

' At this point, A$ contains any and all data received from the
' external device.
'



Gary D.

BC SYSTEMS

  • Full Member
  • Posts: 146
    • View Profile
Re:Serial communications
« Reply #29 on: April 21, 2011, 11:17:22 PM »
Thanks Gary,

I was going to re assemmble the string in a much more incumbent manor!

I'm sure this will get me going in the right direction.

Cheers