# Libnodave<->S7 Verbindungsprobleme



## Magoo50 (3 April 2011)

Hallo liebes Forum,

ich bin seit Tagen damit beschäftigt, Daten aus einer S7 auszulesen.
Prinzipiell funktioniert es auch, doch hin und wieder bricht die Verbindung ab.
Machmal mit Timeout, manchmal ohne Message.

Nach einem Neustart des Excelprogrammes läuft die Verbindung wieder.

Kann ich diesen Fehler in der Prozedur quittieren und / oder die Verbindung wieder aktivieren.

Hat jemand eine Idee, warum die Verbindung abgebrochen wird. (geschieht auch auch im Einzelschritt)

Viele Grüße
Maggoo50


----------



## Jochen Kühner (3 April 2011)

Lässt du deine Verbindung bestehen, oder connectest du immer neu?

Bekommst du denn Fehlercodes von libnodave bei Abbruch, oder bei Neuaufbau? welche? 

Was für eine Verbindung? (TCP, S7Online, Seriell, Netlink,..)?

Poste mal etwas Code!


----------



## Magoo50 (3 April 2011)

-Die Verbindung sollte eigentlich bestehen bleiben

-Die Verbindung geht über ISOTCP

-Ich versuche Daten aus mehreren DB's auszulesen
Das Auslesen geschieht über eine DO ..WHILE Schleife.
Es können alle Daten (1.000 Daten/DB)=(100 Schleifen a 10 Daten) gelesen werden.
Nach der 9 bis 10 Schleife meldet "daveConnectPLC(dc)" res = -1 aus der Initialisierung und es können keine Bits mehr gelesen/geschrieben werden.

ClearData = löschen des Excelbereiches für die DB-Daten
ReadPLCFlags = 1.Initialisierung der Communication
                      2. Auslesen eines Bytes und Selektierung in 8 Bit

Der Code ist nur für den 1. DB und ohne dem Schleifenende.

Sub ReadFromPLC()

Dim buffer(128) As Boolean
Dim ByteNr As Integer
Dim Laenge As Integer

Dim ph As Long, di As Long, dc As Long
res = initialize(ph, di, dc)

ClearData
ReadPLCFlags
If AufzStart = True Or AufzLaeuft = True Then
    If AufzStart = True Then
        res = daveWriteBits(dc, daveDB, DB, 320, 1, 0)       'lösche Flag "Aufzeichnung Start"
        res = daveWriteBits(dc, daveDB, DB, 322, 1, 1)       'setze Flag "Aufzeichnung läuft"
    End If
    ReadPLCFlags
    If AufzLaeuft = True Then
        Aufz1DS_Nr = 0
        Aufz2DS_Nr = 0
        Aufz3DS_Nr = 0
        Aufz4DS_Nr = 0
        ByteNr = 0
        ZeilenNr = 10
        Do
        If Aufz1DS_Nr < Aufz1DB_Len Then
            ReadPLCFlags
            ByteNr = Aufz1DS_Nr * 4
            res1 = daveReadBytes(dc, daveDB, Aufz1DB_Nr, ByteNr, 40, 0)
            If res1 = 0 Then
                Tabelle1.Cells(ZeilenNr, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 1, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 2, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 3, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 4, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 5, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 6, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 7, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 8, 6) = daveGetFloat(dc)
                Tabelle1.Cells(ZeilenNr + 9, 6) = daveGetFloat(dc)
            Else
                e$ = daveStrError(res1)
                Tabelle2.Cells(3, 6) = e$
                GoTo Ende1
            End If
            Aufz1DS_Nr = Aufz1DS_Nr + 10
            Tabelle2.Cells(1, 6) = Aufz1DS_Nr
            Tabelle2.Cells(2, 6) = ZeilenNr
        End If


----------



## Jochen Kühner (3 April 2011)

Magoo50 schrieb:


> -Die Verbindung sollte eigentlich bestehen bleiben





Magoo50 schrieb:


> Nach der 9 bis 10 Schleife meldet "daveConnectPLC(dc)" res = -1 aus der Initialisierung und es können keine Bits mehr gelesen/geschrieben werden.



diese 2 aussagen widersprechen sich doch eigentlich!

Kannst auch noch den Code von initialize(ph, di, dc) und ReadPLCFlags posten?

Und da fehlt ja ein Teil des Codes, vielleicht kannst du ja auch das Excel Sheet anhängen!)


----------



## Magoo50 (3 April 2011)

Das Excel Sheet ist aus dem "libnodave_excel_test.xls"


Private Function initialize(ByRef ph As Long, ByRef di As Long, ByRef dc As Long)
ph = 0
di = 0
dc = 0
DB = Tabelle1.Cells(7, 2)

initialize = -1

port$ = Tabelle1.Cells(3, 2)
peer$ = Tabelle1.Cells(4, 2)
Rack$ = Tabelle1.Cells(5, 2)
Slot$ = Tabelle1.Cells(6, 2)

ph = openSocket(port$, peer$)

If (ph > 0) Then
    di = daveNewInterface(ph, ph, "IF1", 0, daveProtoISOTCP, daveSpeed187k)
    res = daveInitAdapter(di)

    If res = 0 Then
        dc = daveNewConnection(di, 0, Rack$, Slot$)
        res = daveConnectPLC(dc)

        If res = 0 Then
            initialize = 0
        End If
    End If
End If
End Function


Private Sub ReadPLCFlags()

res = initialize(ph, di, dc)
If res = 0 Then

    res = daveReadBytes(dc, daveDB, DB, 40, 1, 0)
        v0 = daveGetS8(dc)

    v1 = v0 - 128
    If v1 >= 0 Then
        v0 = v1
    End If

    v1 = v0 - 64
    If v1 >= 0 Then
        v0 = v1
    End If

    v1 = v0 - 32
    If v1 >= 0 Then
        v0 = v1
    End If

    v1 = v0 - 16
    If v1 >= 0 Then
        v0 = v1
    End If

    v1 = v0 - 8
    ReadData = False
    If v1 >= 0 Then
        v0 = v1
        ReadData = True
    End If

    v1 = v0 - 4
    AufzLaeuft = False
    If v1 >= 0 Then
        v0 = v1
        AufzLaeuft = True
    End If

    v1 = v0 - 2
    AufzStopp = False
    If v1 >= 0 Then
        v0 = v1
        AufzStopp = True
    End If

    v1 = v0 - 1
    AufzStart = False
    If v1 >= 0 Then
        v0 = v1
        AufzStart = True
    End If
End If


----------



## Jochen Kühner (3 April 2011)

heist das du rufst res = initialize(ph, di, dc) 2 mal auf ?

einmal direkt und einmal in ReadPLCFlags() ?

Und da du ReadPLCFlags in einer Do Schleife aufrufst, machst du das immer wieder, ohne die Verbindung vorher zu schließen...


----------



## Magoo50 (4 April 2011)

Frage: 
-muss ich nach jedem "initialize(ph, di, dc)" die Verbindung wieder schliessen ?

-was muss ich machen, um Daten lesen / schreiben zu können ohne vorherigem "initialize(ph, di, dc)"

Dazu noch eine grundsätzliche Frage
Ich möchte über einen längeren Zeitraum (mehrere Stunden / Tage) dynamische Daten aus SPSen sammeln. 
Jetzt sammle ich die Daten in einem DB in der SPS und lese die Daten auf einmal aus.
Gibt es eine sinnvolle Variante, die Prozedur zu triggern um nur die relevanten Daten auszulesen. 
Entweder durch die SPS oder durch die Prozedur selbst. 
Ist dann die Prozedur in einer Schleife, die keine weitere Funktion zulässt?

Bis später


----------



## Jochen Kühner (4 April 2011)

Magoo50 schrieb:


> Frage:
> -muss ich nach jedem "initialize(ph, di, dc)" die Verbindung wieder schliessen ?


Jo, musst du!



Magoo50 schrieb:


> -was muss ich machen, um Daten lesen / schreiben zu können ohne vorherigem "initialize(ph, di, dc)"


du hast doch schon ein dc Instanz, daher brauchst du die nicht nochmals erzeugen!


----------



## Magoo50 (4 April 2011)

Hallo Jochen,

nachdem ich die Prozedur "bereinigt" habe und nur noch einmal initialisiere funktioniert der Datenaustausch.

Vielen Dank für Deine Unterstützung

Bis zum nächsten Mal
Magoo50


----------

