Hello
Thank for libnodave library.
I've try to write program to connect to s7-200 wit CP243-1it thru ethernet with libnodave.
I found example in VisualBasic 2005 how to use libnodave library.
I use VisualaBasic 2008 Express.
When there are no problem with communication everything works quick and fine.
I have some problem:
I have right communication with PLC and I (for example) remove from PLC ethernet cable and connect cable again, then I can't get response from PLC even more.
I use my disconnect function and then connect function as described above
When I execute my connect function
from
dc.connectPLC()
I got result
-1.
The same effect is when with starting connection I start Connect function again.
When I wait some time I can connect again properly.
Another problem is when there are problem with communication function
this line of code
fds.rfd = libnodave.openSocket(102, IP)
execute very long.
With this problem my system isn robust, so I need help how to surely and quick reconnect.
Thank you.
To connect I have:
Public Sub ISO_TCP()
Dim IP As String
IP = cbxIP.Text
If IP <> "" Then 'Kontrolliert, ob der Bediener eine Eingabe gemacht hat
fds.rfd = libnodave.openSocket(102, IP) 'Portstatus - lesen
fds.wfd = fds.rfd 'Portstatus schreiben = Portstatus - lesen
di = New libnodave.daveInterface(fds, "IF1", localMPI, _
libnodave.daveProtoISOTCP243, libnodave.daveSpeed187k)
di.setTimeout(1000000)
res = di.initAdapter
'dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
'res = dc.disconnectPLC
If res = 0 Then 'initAdapter OK
' Rack und Slot spielen keine Rolle bei diesem Protokoll
dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
res = dc.connectPLC()
End If
Else
MsgBox("Bitte Comport angeben", MsgBoxStyle.Information, "Fehler")
End If
End Sub
And below function to disconnect:
Private Sub btnAbbau_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAbbau.Click
dc.disconnectPLC()
di.disconnectAdapter()
libnodave.closePort(fds.rfd)
fds.rfd = 0
res = 1
di = Nothing
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
One of the problems you have is that Ethernet has a timeout of 20 seconds
So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.
To get you connection working again you need to initiate the whole connection.
So call the ISO_TCP sub again.
My code (for a S7-300):
'try to read MB0, just to see if the connection works)
res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
If res = 0 Then
'Do the things you want when connected
ElseIf res < 0 Then
'when less then 0 there is no connection.
Try
'Try to connect again
InitPlcCom()
Catch ex As Exception
End Try
End If
Protected Function InitPlcCom() As Boolean
Dim retVal As Boolean
Try
fds.rfd = libnodave.openSocket(102, sPLCip)
fds.wfd = fds.rfd
If fds.rfd > 0 Then
Application.DoEvents()
di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
di.setTimeout(1000)
Application.DoEvents()
dc = New libnodave.daveConnection(di, 0, rack, Slot)
Application.DoEvents()
If dc.connectPLC() = 0 Then
'LogInfo("Connected to PLC " + sPLCip)
retVal = True
Else
'LogError("Couldn't open tcp connection to " + sPLCip)
retVal = False
End If
End If
Catch ex As Exception
' Error("Couldn't open tcp connection to " + sPLCip)
retVal = False
End Try
Return retVal
End Function
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thak you very much.
It works very good.
I'm still checking is the reconecting is sure, but till this time it works great.
I execute your function periodicaly with Timer and set and reset one output on PLC so I can easy check communication.
You've wrote:
One of the problems you have is that Ethernet has a timeout of 20 seconds
So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.
This what you wrote for me reconnect automaticly, but is there any possibiliteis to make recconection quicker, and without hanging on my applications?
Once again thank you very much,
have a nice weekend!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well i dont know a way to make reconnection faster. the 20 seconds timeout comes from within windows, its the tcp/ip timeout.
To make sure your app doesn't hang, you can make the connect functuion as a thread. that way the app will go on, while the thread connects to the plc.
Below is the code for the class i use to connect to a PLC. It has code to connect using a thread. And there is a second thread that can be started and stopped to communicate to the PLC, and it will detect if the connection is interrupted or not. Keep in mind that I modified the code, so only the usefull stuff is still in there.
Public Class clsPLCCommunicatie
'Constants declarations
Private Const rack As Integer = 0
Private Const Slot As Integer = 2
'Private declarations
Private fds As libnodave.daveOSserialType
Private di As libnodave.daveInterface
Private dc As libnodave.daveConnection
Private sPLC_IP As String
Private bIsConnected As Boolean = False
Private thdPLC_Watch As Thread = New Thread(AddressOf PLC_Com)
Private thdConnectPlc As Thread
Private _bQuit As Boolean
Friend ReadOnly Property IsConnectedToPLc() As Boolean
Get
Return bIsConnected
End Get
End Property
Public Sub New()
End Sub
Friend Sub Dispose()
_bQuit = True
If Not thdConnectPlc Is Nothing Then
If thdConnectPlc.IsAlive Then
thdConnectPlc.Abort()
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
End If
thdConnectPlc = Nothing
End If
If Not thdPLC_Watch Is Nothing Then
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
thdPLC_Watch = Nothing
End If
Try
dc.disconnectPLC()
dc = Nothing
libnodave.closePort(fds.rfd)
Catch ex As Exception
End Try
End Sub
Friend Function ConnectPLC(ByVal sIPAdress As String) As Boolean
sPLC_IP = sIPAdress
InitCommunicatie()
Return bIsConnected
End Function
Friend Sub startCommunication()
Try
If thdPLC_Watch Is Nothing Then
thdPLC_Watch = New Thread(AddressOf PLC_Com)
thdPLC_Watch.TrySetApartmentState(ApartmentState.MTA)
thdPLC_Watch.Start()
End If
Catch ex As Exception
End Try
End Sub
Friend Sub StopCommunication()
_bQuit = True
If Not thdPLC_Watch Is Nothing Then
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
thdPLC_Watch = Nothing
End If
End Sub
Private Sub InitCommunicatie()
If IsValidIP(sPLC_IP) Then
If thdConnectPlc Is Nothing Then
thdConnectPlc = New Thread(AddressOf connectPLCthd)
thdConnectPlc.TrySetApartmentState(ApartmentState.MTA)
thdConnectPlc.Start()
End If
If Not thdConnectPlc.IsAlive Then
thdConnectPlc = Nothing
End If
Else
bIsConnected = False
End If
End Sub
Private Sub connectPLCthd()
Try
fds.rfd = libnodave.openSocket(102, sPLC_IP)
fds.wfd = fds.rfd
If fds.rfd > 0 Then
di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
di.setTimeout(1000)
dc = New libnodave.daveConnection(di, 0, rack, Slot)
If dc.connectPLC() = 0 Then
bIsConnected = True
Else
bIsConnected = False
End If
Else
bIsConnected = False
End If
Catch ex As Exception
bIsConnected = False
End Try
End Sub
Private Sub PLC_Com()
Dim _Entry As plcEvent
Dim res As Integer
Do
If bIsConnected Then
Try
'Check communicatie, try to read mb0
res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
If res = 0 Then
'connection is there, and read action succesfull
ElseIf res < 0 Then
bIsConnected = False
End If
Catch ex As Exception
End Try
Else
InitCommunicatie()
End If
Thread.Sleep(100)
Loop Until _bQuit
End Sub
Private Function IsValidIP(ByVal addr As String) As Boolean
'create our match pattern
Dim pattern As String = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\." & _
"([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"
'create our Regular Expression object
Dim check As New System.Text.RegularExpressions.Regex(pattern)
'boolean variable to hold the status
Dim valid As Boolean = False
'check to make sure an ip address was provided
If addr = "" Then
'no address provided so return false
valid = False
Else
'address provided so use the IsMatch Method
'of the Regular Expression object
valid = check.IsMatch(addr, 0)
End If
'return the results
Return valid
End Function
End Class
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello
Thank for libnodave library.
I've try to write program to connect to s7-200 wit CP243-1it thru ethernet with libnodave.
I found example in VisualBasic 2005 how to use libnodave library.
I use VisualaBasic 2008 Express.
When there are no problem with communication everything works quick and fine.
I have some problem:
I have right communication with PLC and I (for example) remove from PLC ethernet cable and connect cable again, then I can't get response from PLC even more.
I use my disconnect function and then connect function as described above
When I execute my connect function
from
dc.connectPLC()
I got result
-1.
The same effect is when with starting connection I start Connect function again.
When I wait some time I can connect again properly.
Another problem is when there are problem with communication function
this line of code
fds.rfd = libnodave.openSocket(102, IP)
execute very long.
With this problem my system isn robust, so I need help how to surely and quick reconnect.
Thank you.
To connect I have:
Public Sub ISO_TCP()
Dim IP As String
IP = cbxIP.Text
If IP <> "" Then 'Kontrolliert, ob der Bediener eine Eingabe gemacht hat
fds.rfd = libnodave.openSocket(102, IP) 'Portstatus - lesen
fds.wfd = fds.rfd 'Portstatus schreiben = Portstatus - lesen
di = New libnodave.daveInterface(fds, "IF1", localMPI, _
libnodave.daveProtoISOTCP243, libnodave.daveSpeed187k)
di.setTimeout(1000000)
res = di.initAdapter
'dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
'res = dc.disconnectPLC
If res = 0 Then 'initAdapter OK
' Rack und Slot spielen keine Rolle bei diesem Protokoll
dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
res = dc.connectPLC()
End If
Else
MsgBox("Bitte Comport angeben", MsgBoxStyle.Information, "Fehler")
End If
End Sub
And below function to disconnect:
Private Sub btnAbbau_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAbbau.Click
dc.disconnectPLC()
di.disconnectAdapter()
libnodave.closePort(fds.rfd)
fds.rfd = 0
res = 1
di = Nothing
End Sub
One of the problems you have is that Ethernet has a timeout of 20 seconds
So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.
To get you connection working again you need to initiate the whole connection.
So call the ISO_TCP sub again.
My code (for a S7-300):
'try to read MB0, just to see if the connection works)
res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
If res = 0 Then
'Do the things you want when connected
ElseIf res < 0 Then
'when less then 0 there is no connection.
Try
'Try to connect again
InitPlcCom()
Catch ex As Exception
End Try
End If
Protected Function InitPlcCom() As Boolean
Dim retVal As Boolean
Try
fds.rfd = libnodave.openSocket(102, sPLCip)
fds.wfd = fds.rfd
If fds.rfd > 0 Then
Application.DoEvents()
di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
di.setTimeout(1000)
Application.DoEvents()
dc = New libnodave.daveConnection(di, 0, rack, Slot)
Application.DoEvents()
If dc.connectPLC() = 0 Then
'LogInfo("Connected to PLC " + sPLCip)
retVal = True
Else
'LogError("Couldn't open tcp connection to " + sPLCip)
retVal = False
End If
End If
Catch ex As Exception
' Error("Couldn't open tcp connection to " + sPLCip)
retVal = False
End Try
Return retVal
End Function
Thak you very much.
It works very good.
I'm still checking is the reconecting is sure, but till this time it works great.
I execute your function periodicaly with Timer and set and reset one output on PLC so I can easy check communication.
You've wrote:
One of the problems you have is that Ethernet has a timeout of 20 seconds
So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.
This what you wrote for me reconnect automaticly, but is there any possibiliteis to make recconection quicker, and without hanging on my applications?
Once again thank you very much,
have a nice weekend!
Well i dont know a way to make reconnection faster. the 20 seconds timeout comes from within windows, its the tcp/ip timeout.
To make sure your app doesn't hang, you can make the connect functuion as a thread. that way the app will go on, while the thread connects to the plc.
Below is the code for the class i use to connect to a PLC. It has code to connect using a thread. And there is a second thread that can be started and stopped to communicate to the PLC, and it will detect if the connection is interrupted or not. Keep in mind that I modified the code, so only the usefull stuff is still in there.
Good luck with your application,
Leon.
Imports System.Windows.Forms
Imports System.Text
Imports System.Globalization
Imports System.Threading
Imports System.Diagnostics
Public Class clsPLCCommunicatie
'Constants declarations
Private Const rack As Integer = 0
Private Const Slot As Integer = 2
'Private declarations
Private fds As libnodave.daveOSserialType
Private di As libnodave.daveInterface
Private dc As libnodave.daveConnection
Private sPLC_IP As String
Private bIsConnected As Boolean = False
Private thdPLC_Watch As Thread = New Thread(AddressOf PLC_Com)
Private thdConnectPlc As Thread
Private _bQuit As Boolean
Friend ReadOnly Property IsConnectedToPLc() As Boolean
Get
Return bIsConnected
End Get
End Property
Public Sub New()
End Sub
Friend Sub Dispose()
_bQuit = True
If Not thdConnectPlc Is Nothing Then
If thdConnectPlc.IsAlive Then
thdConnectPlc.Abort()
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
End If
thdConnectPlc = Nothing
End If
If Not thdPLC_Watch Is Nothing Then
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
thdPLC_Watch = Nothing
End If
Try
dc.disconnectPLC()
dc = Nothing
libnodave.closePort(fds.rfd)
Catch ex As Exception
End Try
End Sub
Friend Function ConnectPLC(ByVal sIPAdress As String) As Boolean
sPLC_IP = sIPAdress
InitCommunicatie()
Return bIsConnected
End Function
Friend Sub startCommunication()
Try
If thdPLC_Watch Is Nothing Then
thdPLC_Watch = New Thread(AddressOf PLC_Com)
thdPLC_Watch.TrySetApartmentState(ApartmentState.MTA)
thdPLC_Watch.Start()
End If
Catch ex As Exception
End Try
End Sub
Friend Sub StopCommunication()
_bQuit = True
If Not thdPLC_Watch Is Nothing Then
Do
Application.DoEvents()
Loop Until thdPLC_Watch.IsAlive = False
thdPLC_Watch = Nothing
End If
End Sub
Private Sub InitCommunicatie()
If IsValidIP(sPLC_IP) Then
If thdConnectPlc Is Nothing Then
thdConnectPlc = New Thread(AddressOf connectPLCthd)
thdConnectPlc.TrySetApartmentState(ApartmentState.MTA)
thdConnectPlc.Start()
End If
If Not thdConnectPlc.IsAlive Then
thdConnectPlc = Nothing
End If
Else
bIsConnected = False
End If
End Sub
Private Sub connectPLCthd()
Try
fds.rfd = libnodave.openSocket(102, sPLC_IP)
fds.wfd = fds.rfd
If fds.rfd > 0 Then
di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
di.setTimeout(1000)
dc = New libnodave.daveConnection(di, 0, rack, Slot)
If dc.connectPLC() = 0 Then
bIsConnected = True
Else
bIsConnected = False
End If
Else
bIsConnected = False
End If
Catch ex As Exception
bIsConnected = False
End Try
End Sub
Private Sub PLC_Com()
Dim _Entry As plcEvent
Dim res As Integer
Do
If bIsConnected Then
Try
'Check communicatie, try to read mb0
res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
If res = 0 Then
'connection is there, and read action succesfull
ElseIf res < 0 Then
bIsConnected = False
End If
Catch ex As Exception
End Try
Else
InitCommunicatie()
End If
Thread.Sleep(100)
Loop Until _bQuit
End Sub
Private Function IsValidIP(ByVal addr As String) As Boolean
'create our match pattern
Dim pattern As String = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\." & _
"([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"
'create our Regular Expression object
Dim check As New System.Text.RegularExpressions.Regex(pattern)
'boolean variable to hold the status
Dim valid As Boolean = False
'check to make sure an ip address was provided
If addr = "" Then
'no address provided so return false
valid = False
Else
'address provided so use the IsMatch Method
'of the Regular Expression object
valid = check.IsMatch(addr, 0)
End If
'return the results
Return valid
End Function
End Class