I setup a serial link a few years ago (with much research on this forum) between my KUKA krc2 ed05 (KSS 5.6.need to check the rest) and an Omron G9SP safety plc which handles the robot cell safety, some critical functions (not ejecting the tool while the spindle is running, not releasing the ATC when the tool is not in the nest etc) and gives some additional IO. The serial communications is handled through the submit interpreter in the sps.sub file.
It has been running well EXCEPT sometimes when I'm copying or moving large files between the usb thumb drive and the robot controller it hangs. After this I have to change to T2 (or T1), cancel the submit interpreter then start it again.
I've included a copy of the relavent sections of the sps.sub file below (declarations and the actual code which runs within the main loop of the sps file). Some of the variables not defined here are defined globally in the config.dat file.
;****************Serial Initializations*********************
CheckSumFail=0
Handle=3
Offset=199
Timeout=5.0
TX_State={RET1 #CMD_OK,MSG_NO 0,HITS 1,LENGTH 0}
RX_State={RET1 #DATA_END,MSG_NO 0,HITS 1,LENGTH 199}
CH_State={RET1 #CMD_OK,MSG_NO 0,HITS 0,LENGTH 0}
Modey=#ABS
FOR I = 1 to 32
PLCOut[I] = FALSE
ENDFOR
MistOn=0
;**************End Serial Initializations*******************
Display More
;-----------------------------------------------------------
; Serial module for communicating with Omron G9SP Safety PLC
;-----------------------------------------------------------
;********************Start Send Data************************
SerialDebug=0
SendString[]="'H40''H00''H00''H0F''H4B''H03''H4D''H00''H01'" ;Add PLC Header to SendString (9 characters)
;Compile the 32 Robot to PLC signals into 4 bytes of data to send to the PLC and add them to SendString
SerialDebug=1
K=1
FOR I = 1 to 4
SerialDebug=2
CharValue=0
FOR J = 1 to 8
IF PLCOut[J+((I-1)*8)] THEN
SerialDebug=3
CharValue=CharValue+K
ENDIF
K=K*2
ENDFOR
SendString[I+9]=CharValue
SerialDebug=4
K=1
ENDFOR
SerialDebug=5
;Add the two additional dummy bytes to the string, should now be 15 characters long
FOR I = 1 to 2
SendString[I+13] = "'H00'"
ENDFOR
SerialDebug=6
;Calculate Check Sum on first 15 characters of SendString
CheckSumCalc=0
FOR I = 1 TO 15
CharValue = (SendString[I])
CheckSumCalc = CheckSumCalc + CharValue
ENDFOR
SerialDebug=7
CheckSum[1]=(CheckSumCalc B_AND 'B1111111100000000')/256 ;Upper byte of CheckSum
SerialDebug=8
CheckSum[2]=CheckSumCalc B_AND 'B0000000011111111';Lower byte of CheckSum
SerialDebug=9
;Finish building string to send
FOR I = 1 to 2
SendString[I+15] = CheckSum[I] ;Add the CheckSum to the SendString, should now be 17 characters long
ENDFOR
SerialDebug=10
SendString[18]="'H2A'" ;Add 2 footer characters to string
SendString[19]="'H0D'" ;should now be the full 19 characters long
SerialDebug=11
COPEN (:SER_3, Handle) ; open serial port COM3
SerialDebug=12
CWRITE (Handle, TX_State, Modey, "%r", SendString[]) ; send TX string to G9SP
SerialDebug=13
;*********************End Send Data*************************
;*******************Start Receive Data**********************
Modey = #ABS ; CREAD waits for data or timeout
SerialDebug=14
WAIT FOR ($DATA_SER3 <> 0) ; wait for data in COM3 buffer
SerialDebug=15
offset=0 ; start from string first character
CREAD (Handle, RX_State, Modey, Timeout, Offset, "%r", Response[]) ; read serial buffer into RX string
SerialDebug=16
CCLOSE (Handle, CH_State) ; close serial channel
SerialDebug=17
;Calculate CheckSum on first 195 bytes
CheckSumCalc=0
FOR I = 1 to 195
SerialDebug=18
CharValue = (Response[I])
CheckSumCalc = CheckSumCalc + CharValue
ENDFOR
SerialDebug=19
;Read CheckSum bytes and compare to calculated value.
CharValue = Response[196]
CheckSumRet = CharValue*256
SerialDebug=20
CharValue = Response[197]
CheckSumRet = CheckSumRet + CharValue
SerialDebug=21
IF CheckSumRet <> CheckSumCalc THEN
CheckSumFail = CheckSumFail+1
IF CheckSumFail == 5 THEN
SerialDebug=22
;Halt ;Communications with PLC has failed 5 times in a row, so stop program
ENDIF
ELSE
SerialDebug=23
;Extract data in bytes 8 to 11 and map them to the PLCIn PLC to Robot Inputs
CheckSumFail = 0
K=1
FOR I = 1 to 4
FOR J = 1 to 8
IF Response[7+I] B_AND K >0 THEN
PLCIn[J+(I-1)*8]=TRUE
ELSE
PLCIn[J+(I-1)*8]=FALSE
ENDIF
K=K*2
ENDFOR
K=1
ENDFOR
ENDIF
SerialDebug=24
;**********************End Receive Data*********************
;*********************End Serial Module*********************
Display More
I added the integer SerialDebug to find where it was hanging, and it's value is 14 so it's on the following line:
I think basically the copying of large files messes up the timing of the serial port sending data to the Omron PLC. As such, the PLC doesn't respond. As such I'd like to add some sort of a timeout, so if nothing has been received in the COM3 buffer after say 500ms, it skips the receive data section and tries sending again. My first thought is to use a WHILE loop that also includes a small delay and counter to keep checking the buffer, and abort if it takes to long, but would like to know what best practice is given it's in the submit interpreter in terms of keeping loop time down etc. Would welcome any thoughts on optimising other sections of the code too (my background definitely isn't in programming...) or if there is a completely different way I should be doing this. Hopefully the code may be of help to others looking to implement serial comms too.