ketam Posted December 21, 2017 Posted December 21, 2017 Hello AUTOIT team, This is my first post and I am a newbie and still learning. I am using Autoit to automate my process and it helps me a lot. Now I am facing a new challenge and it seems I could not find a solution yet hence I need help from autoit team. My PC is communicating with a PLC to activate a relay. Connection type: TCP/IP via ethernet cable. PLC IP address 192.168.1.5 Port: 9094 I need to send a command to PLC to activate the relay. The command to activate is %01#WCSR00001** Command send using Hyperterminal If successful the Hyperterminal will return a value of %01$WC14 By using Hyperterminal I also cannot trap the return value to further enhance the process control system. Now I am trying to use TCPconnect and TCPsend/rec to replace the use of Hyperterminal. My connection is successful using TCPconnect but I am stuck at how to send the command via TCP send and receive the return value from PLC. I need to mimic exactly what the Hyperterminal is doing. Here is my current code using Hyperterminal Run("PLC - HyperTerminal") Send("%01{#}WCSR00001**") Send("{ENTER}") Sleep (2000) Send("{ALT}{C}{D}") WinKill("PLC - HyperTerminal") I have tried the TCP connect sample but stuck at TCP send expandcollapse popup; == TCPConnect with timeout #include <MsgBoxConstants.au3> ; I am the client, start me after the server no more than 10sec ! (The server script is the TCPAccept example script). Example() Func Example() TCPStartup() ; Start the TCP service. ; Register OnAutoItExit to be called when the script is closed. OnAutoItExitRegister("OnAutoItExit") ; Assign Local variables the loopback IP Address and the Port. Local $sIPAddress = "192.168.1.5" ; This IP Address only works for testing on your own computer. Local $iPort = 9094 ; Port used for the connection. Opt("TCPTimeout", 1000) Local $nMaxTimeout = 10 ; script will abort if no server available after 10 secondes Local $iSocket, $iError While 1 ; Assign a Local variable the socket and connect to a Listening socket with the IP Address and Port specified. $iSocket = TCPConnect($sIPAddress, $iPort) ; If an error occurred display the error code and return False. If @error = 10060 Then ; Timeout occurs try again $nMaxTimeout -= 1 If $nMaxTimeout < 0 Then MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Could not connect, after " & 10 - $nMaxTimeout & " TimeOut") Return False EndIf ContinueLoop ElseIf @error Then $iError = @error ; The server is probably offline/port is not opened on the server. MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Could not connect, Error code: " & $iError) Return False Else MsgBox($MB_SYSTEMMODAL, "", "Connection successful after " & 10 - $nMaxTimeout & " TimeOut") ;;;;;TCP send here Sleep (2000) TCPSend ($iPort, "%01{#}WCSR00001**") ;;MsgBox($MB_SYSTEMMODAL, "", "Server:" & @CRLF & "%01#WCSR00011**") If TCPRec <> "" Then ;;MsgBox (0, "Server sended me response", $TCPRec,9) EndIf ExitLoop EndIf WEnd ; Close the socket. TCPCloseSocket($iSocket) EndFunc ;==>Example Func OnAutoItExit() TCPShutdown() ; Close the TCP service. EndFunc ;==>OnAutoItExit Any help from autoit team would be great help. Thanks ketam
Developers Jos Posted December 21, 2017 Developers Posted December 21, 2017 3 hours ago, ketam said: TCPSend ($iPort, "%01{#}WCSR00001**") Shouldn't this be: TCPSend ($iSocket, "%01{#}WCSR00001**") Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past.
ripdad Posted December 21, 2017 Posted December 21, 2017 (edited) Happy Holidays expandcollapse popup; Client Opt('MustDeclareVars', 1) OnAutoItExitRegister('OnAutoItExit') Example('%01#WCSR00001**'); start client Func Example($sData) ; ; start tcp service If Not TCPStartup() Then MsgBox(16, 'Client Error', 'TCPStartup - Cannot Start TCP') Exit EndIf ; Opt('TCPTimeout', 10); <- required (won't work properly without it) ; Local $sIPAddress = '192.168.1.5' Local $iPort = 9094 ; Local $iSocket = TCPConnect($sIPAddress, $iPort) If @error Or $iSocket < 1 Then MsgBox(16, 'Client Error', 'TCPConnect - Cannot Connect') Exit EndIf ; Local $iError, $sRecv, $str = '- Connection: ' ; ; receive connection response For $i = 1 To 200 $sRecv = TCPRecv($iSocket, 1048) $iError = @error If $iError <> 0 Or $sRecv < 0 Then MsgBox(16, 'Client Error', 'TCPRecv Error: ' & $iError) ExitLoop ElseIf $sRecv <> '' Then; received data $str &= $sRecv & @CRLF; assemble incoming data ExitLoop EndIf Sleep(10); <- part of time-out Next ; ; you have the connection at this point -- all you need to do is send it once. Local $nBytesSent = TCPSend($iSocket, $sData & @CRLF) If @error Or $nBytesSent < 1 Then MsgBox(16, 'Client Error', 'TCPSend - Cannot Send') Exit EndIf ; $str &= '- Sent: ' & $sData & @CRLF & '- Received: ' ; ; receive code response For $i = 1 To 200; <- time-out loop (~3 seconds) (for shorter or longer time-out adjust number) $sRecv = TCPRecv($iSocket, 1048) $iError = @error If $iError <> 0 Or $sRecv < 0 Then MsgBox(16, 'Client Error', 'TCPRecv Error: ' & $iError) ExitLoop ElseIf $sRecv <> '' Then; received data $str &= $sRecv; assemble incoming data If StringInStr($str, '%01$WC14') Then ExitLoop EndIf $i = 1; reset EndIf Sleep(10); <- part of time-out Next ; ; Close the socket TCPCloseSocket($iSocket) ; If $str <> '' Then MsgBox(0, 'Client - Server Response', $str) Else MsgBox(0, 'Client', 'Timed-Out') EndIf Exit EndFunc Func OnAutoItExit() ; Close the TCP service TCPShutdown() EndFunc ; Edited December 27, 2017 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
ketam Posted December 22, 2017 Author Posted December 22, 2017 On 12/21/2017 at 2:58 PM, Jos said: Shouldn't this be: TCPSend ($iSocket, "%01{#}WCSR00001**") Jos Hi Jos, Thanks for the correction.
ketam Posted December 22, 2017 Author Posted December 22, 2017 11 hours ago, ripdad said: Happy Holidays expandcollapse popup; Client Opt('MustDeclareVars', 1) OnAutoItExitRegister('OnAutoItExit') Example('%01#WCSR00001**'); start client Func Example($sData) ; start tcp service If Not TCPStartup() Then MsgBox(16, 'Client Error', 'TCPStartup - Cannot Start TCP') Exit EndIf Opt('TCPTimeout', 10); <- required (won't work properly without it) Local $sIPAddress = '192.168.1.5' Local $iPort = 9094 Local $iSocket = TCPConnect($sIPAddress, $iPort) If @error Or $iSocket < 1 Then MsgBox(16, 'Client Error', 'TCPConnect - Cannot Connect') Exit EndIf Local $iError, $sRecv, $str = '' ; you have the connection at this point -- all you need to do is send it once. Local $nBytesSent = TCPSend($iSocket, $sData) If @error Or $nBytesSent < 1 Then MsgBox(16, 'Client Error', 'TCPConnect - Cannot Send') Exit EndIf ; receive response For $i = 1 To 200; <- time-out loop (~3 seconds) (for shorter or longer time-out adjust number) $sRecv = TCPRecv($iSocket, 1048) $iError = @error If $iError <> 0 Or $sRecv < 0 Then MsgBox(16, 'Client Error', 'TCPRecv Error: ' & $iError) ExitLoop ElseIf $sRecv <> '' Then; received data $str &= $sRecv; assemble incoming data If StringInstr($str, '%01$WC14') Then ExitLoop EndIf $i = 1; reset EndIf Sleep(10); <- part of time-out Next ; Close the socket TCPCloseSocket($iSocket) If $str <> '' Then MsgBox(0, 'Client - Server Response', $str) Else MsgBox(0, 'Client', 'Timed-Out') EndIf Exit EndFunc Func OnAutoItExit() ; Close the TCP service TCPShutdown() EndFunc Hi ripdad, happy holidays! Many thanks for the code! After I run it prompts a Client Timeout error. I am still figuring out why and what is needed to fix this. I believe it still unable to TCPsend the data as the relay is not activated. Learn a lot from your code. Any help/advise would be much appreciated. Thanks ketam
ripdad Posted December 22, 2017 Posted December 22, 2017 (edited) It sent the data or else it would had failed at TCPSend(). The only things I can think of, is that the relay is either not accepting the code or is taking too long to respond. The first one is in your hands. For the second, you might have to increase the For-Loop timeout from 200 to 500 or more. I tested this script on the local IP 127.0.0.1 -- so, I know it works under normal conditions. --Edit Just covering all the bases, I thought of a few more things... -The IP address is incorrect. -The port number is incorrect. Edited December 22, 2017 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
ketam Posted December 27, 2017 Author Posted December 27, 2017 Hi ripdad, thanks for the advice. I may need to check with the manufacturer of the PLC if there is anything to do with the firmware. I believe your script is the solution to what I am looking for. The only obstacle is data send & receive from the PLC itself. I also tested using TELNET to send and receive data to the PLC and it works. I just need to figure out why this PLC is not accepting data direct from AUTOIT script and work out a solution from there. Thanks.
ketam Posted December 27, 2017 Author Posted December 27, 2017 Hi ripdad, IT WORKS!!!! MANY THANKS!!! After I study the TELNET script by @frank10 https://www.autoitscript.com/forum/topic/28068-learning-larry-tcp-func/ I just added @CRLF in the below lines at TCPsend and it works!!! ; you have the connection at this point -- all you need to do is send it once. Local $nBytesSent = TCPSend($iSocket, $sData & @CRLF) ;;;add @CRLF If @error Or $nBytesSent < 1 Then MsgBox(16, 'Client Error', 'TCPConnect - Cannot Send') Exit EndIf Thank you very much @ripdad and the AUTOIT team as well !! Great solutions!!
ripdad Posted December 27, 2017 Posted December 27, 2017 I have never studied Telnet before today. Apparently, Telnet requires a response from the host after a connection has been made before it will allow you to proceed any further as the user. So, I updated the script in Post #3, to receive the connection response first and then send the code. In any case, I'm glad you got it working! "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now