# Libnodave und S7Online



## Ralle (12 Dezember 2006)

Ich teste gerade Libnodave (V0.8.2) mit der S7Online-Schnittstelle.
Ich kann einmal die Verbindung herstellen, Daten auslesen, das beliebig lange.
Nach einem Beenden der Verbindung (z.Bsp. STOP beim Delphi-Testprogramm).
Kann die Verbindung nicht noch einmal hergestellt werden. Erst wenn man das Programm komplett beendet und neu startet geht es wieder (für 1 Mal).
Hat jemand Ähnliches auch schon festgestellt? Die Delphi-Demo aus Libnodave wird nach einem 2. gescheiterten Startversuch bei einem Beenden, mit einer Schutzrechtsverletzung geschlossen. Ich habe den Eindruck, daß es mit der Verknüpfung zwischen der Libnodave-DLL und dem Simatic-Progamm zu tun hat. Irgendein Funktionsaufruf (o.ä.), wird nicht richtig abgeschlossen.


----------



## afk (12 Dezember 2006)

Ralle schrieb:


> Ich habe den Eindruck, daß es mit der Verknüpfung zwischen der Libnodave-DLL und dem Simatic-Progamm zu tun hat. Irgendein Funktionsaufruf (o.ä.), wird nicht richtig abgeschlossen.


Das kann durchaus auch an meiner Delphi-Komponente liegen. Ich habe die Funktionen für das S7Online-Protokoll in der Komponente implementiert, da war das Protokoll in libnodave noch im Teststadium (ich glaube, damals waren wir über das libnodave-Forum in Kontakt ?), und seither hab ich nichts mehr daran gemacht, da ich das Protokoll selbst nicht verwende. Falls Zottel danach noch was an dem Protokoll in libnodave geändert hat, muß meine Komponente evtl. noch angepaßt werden, aber darüber habe ich im Moment zumindest keine Infos.

Hat hier jemand Erfahrungen, ob das beschriebene Problem beim Protokoll S7Online auch in Verbindung mit anderen Programmiersprachen existiert ?


Gruß Axel


----------



## Ralle (12 Dezember 2006)

Hallo Axel,

in meinem Programm nutze ich nicht deine Komponente, sondern hab ein paar Funktionen davon genutzt beziehungsweise auch abgewandelt . Das liegt daran, daß ich auch noch den Weg über Prodave implementiert habe, bzw. libnodave dazugebaut habe. Hat mir sicher viel Zeit gespart, danke nochmal, für deine gute Komponente. Mein Programm bringt zwar keine Schutzrechtsverletzung, ansonsten zeigt es aber gleiches Verhalten, ein zweiter Verbindungsufbau geht nicht. Meldung meistens -124. S7Online scheint problematisch zu sein, man kann auch nur mit einer Steuerung Verbindung aufnehmen, eine zweite zeigt dann die Werte der Ersten an. Ich muß nochmal testen, ob es auch davon abhängt, welchen Weg man man mit S7Online nutzt (CP5512, USB via Teleservice II). Was Siemens zwischendurch ändert weiß auch niemand. Interessant ist übrigens, daß bei Prodave Mini (V4) nur die DLL installiert werden muß, wenn Step7 auf dem PC zu Hause ist, schon läuft die Verbindung und das absolut problemlos. Muß also irgenwie gehen. Ich hab auch schon, daß ich die Verbindung beenden und problemlos mit Libnodave wieder aufbauen konnte. Ein Schema hab ich dabei noch nicht erkannt. Was ganz böse endet, ist ein Ziehen des Kabels während eine S7-Verbindung mit S7Online und libnodave steht. Dann kann danach selbst der Simatic-Manager keiner Verbindung mehr herstellen, da hilft nut die CP5512 zu entfernen. Ich kann libnodave halt nicht mit einem seriellen oder USB-Adapter nutzen, da ich keinen hab :???:. Was bisher völlig problemlos ging, war Ethernet und libnodave mit einer 319.


----------



## Vbxler (12 Dezember 2006)

Hallo!
Dieses Problem, dass man die Verbindung nicht nochmals aufbauen kann, 
habe ich bereits vor längerem berichtet.

http://www.esatex.com/SPS-Forum/showthread.php?t=8271&highlight=libnodave

Ich habe mit eine Krücke gebaut, indem ich die Verbindung und das Ausslesen
der Daten in einem eigenem Process starte.
Schön wäre natürlich wenn ich das nicht machen müsste und alles in einem
Thread laufen lassen könnte. 

Servus

Vbxler


----------



## Ralle (12 Dezember 2006)

MIt TCP und einer Delphi-Applikation hatte ich keinerlei Probleme, S7Online scheint das Problemkind zu sein.


----------



## Ralle (18 Dezember 2006)

So geht es wieder: closeport statt closeS7online

         closePort(DaveInterface.Remote_.DaveFDS.rfd);
//          closeS7online(DaveInterface.Remote.DaveFDS.rfd);

Das werd ich morgen nochmal vertiefen ._


----------



## afk (19 Dezember 2006)

*Ich hab da 'ne Idee ...*



Ralle schrieb:


> So geht es wieder: closeport statt closeS7online
> 
> closePort(DaveInterface.Remote_.DaveFDS.rfd);
> //          closeS7online(DaveInterface.Remote.DaveFDS.rfd);
> ...


_

Heißt das, du rufst openS7online auf, kommuniziert mit der SPS, und beendest die Verbindung jetzt mit closePort statt mit closeS7online, und dann funktioniert es ohne Probleme ? :shock: 

Dann lass uns das doch mal vertiefen, denn ich glaub noch nicht, daß das die Lösung ist. Ich hab mal in den libnodave-Quellen nachgeschaut, und wundere mich jetzt ein wenig. :sb10: 

Die Funktion closePort hat in den Quellen mit der Funktion openS7online gar nichts zu tun, demnach sollte es die gleiche Wirkung haben, wenn Du closePort auch weglässt, probier das doch mal aus. Wenn dem so ist, dann liegt das Problem wohl tatsächlich am Aufruf von closeS7Online, aber durch das Weglassen dieses Aufrufs werden vermutlich in der S7onlinx.dll mit jedem Aufruf von openS7online Resourcen belegt, die dann nicht mehr freigegeben werden (Speicherfresser !?).

Im Siemens-Handbuch zur FDL-Programmierschnittstelle habe ich den Hinweis gelesen, das unter Windows nach dem Öffnen der Schnittstelle die Routine SetSinecHWnd mit einem Fenster-Handle aufgerufen werden muß. Diese Funktion findet sich auch in der S7Onlinx.dll, wird von libnodave aber nicht aufgerufen.

Ich hab das mal abgeändert, kann das bei mir aber im Moment nicht ausprobieren. Schick mir mal 'ne Mail (an die Adresse in der Quelle der Delphi-Komponente), dann schicke ich Dir die dll zum Testen zu.


Gruß Axel_


----------



## Ralle (19 Dezember 2006)

Genau so ist es, ohne closeport geht es auch, aber die rfd "DaveInterface.Remote_.DaveFDS.rfd" wird mit jedem Start/Stop hochgezählt. Irgenwann kommt dann wahrscheinlich der Absturz .

Mail kommt, Danke._


----------



## Leuschman (31 Januar 2007)

*Status libnodave*

Nun habe ich versucht alle Beiträge zum Thema "Verbindungsprobleme" zwischen libnodave und der entsprechenden Schnittstelle (IBH, S7 ...) zu lesen und habe hier noch keine wirklich richtige Lösung, die zur Behebung des Problemes beiträgt, gefunden.
Ich selber versuche gerade unter VC++ mit einem IBH-NetLink mich an eine S7-315 zu hängen und von dort Daten auszulesen (die Verbindung klappt!). Da ich diese Prozedur als DLL für ein anderes Programm zur Verfügung stellen will (Grund ist die einzig mögliche Programmierschnittstelle des Progs), passiert mir genau das, wass auch Vbxler aus dem Tritt gebracht hatte (siehe http://www.esatex.com/SPS-Forum/show...ight=libnodave ) und jetzt so auch in ähnlicher Form hier von Ralle berichtet wird:
Der geöffnete PORT, den ich mittels 
fds.rfd=openSocket(1099, "172.20.48.170") 
aufrufe, bleibt auch nach dem Disconnect offen. Sollte ich die Prozedur nun mehrmals aufrufen, werden weitere PORTs auf meinem PC geöffnet... Bis nichts mehr geht - d.h. ich bekomme keine Verbindung mehr zum NetLink (mehr als 2 offne Verbindungen werden von dem Teil nicht verkraftet) .
Schliesse ich nun das Hauptprogramm (dass auf die DLL-Zugriffe ausführt) werden auch die PORTs geschlossen...

Wie nun weiter ?

So wie Vbxler kann ich leider nicht verfahren...

(Anbei ein Screenshot meiner Firewall und der PORTs auf NetLink

Gruss Marco


----------



## Zottel (31 Januar 2007)

openSocket() öffnet eine TCP/IP Verbindung zum IBHLink
daveConnectPLC() weist den IBHLink an, eine (MPI-)Verbindung mit einer bestimmten MPI-Adresse aufzubauen.
daveDisconnectPLC(dc) weist den IBHLink an, die durch dc referenzierte  (MPI-)Verbindung abzubauen. Die TCP/IP Verbindung zum IBHLink bleibt natürlich bestehen. 
close (fd.rfd) schließt die TCP/IP Verbindung zum IBHLink.
close() sollte einfach das close aus winsock.dll sein. Oder heißt das da anders? Oder konnte man das aus VB nicht aufrufen? Aus so einem ähnlichen Grund habe ich, glaube ich, mal eine daveClose() Funktion hinzugefügt?


----------



## Ralle (1 Februar 2007)

@Leuschman

Also bei einer TCP/IP-Verbindung zu einer 317PN funtioniert das bei mir bisher problemlos, oder ist mir das nur nicht aufgefallen? Ich kann das nächste Woche mal nachprüfen. Wie oft kannst du denn deine Verbindung herstellen, bis es nicht mehr funktioniert?

 Das Problem, das ich hatte betraf die s7Online -Schnittstelle, da hat AFK wqas an der DLL geändert, ich hoffe, Zottel hat das schon von ihm bekommen. Was mir bei TCP/IP auffiel, daß mein Programm nach jedem Abbau der Verbindung zwei Handels nicht mehr hergab.



> Hallo Ralle,
> 
> Zitat:
> Zitat von *Ralle*
> ...


Da wird er demnächst sicherlich mal nachsehen. 

PS: Teste doch mal mit dem Delphi-Beispielprogramm in Libnodave.

@Zottel

Hast du zu dem Problem der s7Online-Verbindung (immer nur die 1. CPU liefert die Daten, auch wenn man versucht mehrere auszulesen) irgendeine Idee?


----------



## Question_mark (2 Februar 2007)

*Da war noch irgendwas ....*

Hallo Ralle,



			
				Ralle schrieb:
			
		

> Hast du zu dem Problem der s7Online-Verbindung (immer nur die 1. CPU liefert die Daten, auch wenn man versucht mehrere auszulesen) irgendeine Idee?



Ich habe dazu mal irgendwann vor mehr als einem Jahr darüber hier im Forum gelästert (Zottel, verzeih mir bitte), da stimmen irgendwie die Parameter nicht. Ich werde nochmal nachsehen, weiss das im Moment nicht mehr aus dem Stegreif. 

Gruss

Question_mark


----------



## afk (2 Februar 2007)

Ralle schrieb:


> Da wird er demnächst sicherlich mal nachsehen.


Stimmt, wird er machen. Sobald er wieder zu Hause ist und mal ordentlich ausgeschlafen hat ... :sm13: 

Schönen Gruß aus Manila
Axel


----------



## Leuschman (2 Februar 2007)

*Verbindungen*

@RALLE

Ich kann maximal 2 Verbindungen aufbauen und diese werden dann weiter offengehalten - sonst wird keine weitere Verbindung akzeptiert.
Nehme ich die Routine in eine normale EXE (wie die Beispiele aus dem libnodave-Verzeichnis), so wird nach dem Beenden der MAIN-Funktion auch die Verbindung geschlossen. Nur hier - beim Aufruf der DLL - passiert so etwas nicht.

@ALL
Nur mal so als Info - ich nutze hier: WinXP, MsVC++6.0, libnodave-0.8.2

Was mir nun mittlerweile aufgefallen ist, nachdem ZOTTEL mich auch die CloseSocket Funktion gestossen hat, dass es diese in der eigentlichen "openSocket.h" nicht gibt. ABER es ist eine "openSocketW.c" vorhanden, in der auch close-Funktionen enthalten sind... 
Und in der filelist-Datei steht:
...
openSocket.c    Opens a TCP/IP connection. Library source code file
openSocket.h    Library header file (UNIX only)
openSocketw.c    Library header file (Win32 only)
...

Heisst dies, wenn ich hier unter Windof arbeite, dass ich die "opensocket.h" eigentlich nicht nutzen kann und dann irgendwie die "openSocketw.c" einbinden muss? 

Da meine letzten C++ Gehversuche schon ein weilchen her sind, wäre ich bei der möglichen Umstellung dann für eine kleine Hilfe recht dankbar. 

Gruss
Marco


----------



## Zottel (2 Februar 2007)

Leuschman schrieb:


> @RALLE
> 
> Was mir nun mittlerweile aufgefallen ist, nachdem ZOTTEL mich auch die CloseSocket Funktion gestossen hat, dass es diese in der eigentlichen "openSocket.h" nicht gibt. ABER es ist eine "openSocketW.c" vorhanden, in der auch close-Funktionen enthalten sind...


Falsch. Die sind da nicht enthalten. Die Funktion closesocket() wird darin lediglich genutzt. Enthalten ist sie in winsock2.dll ! Du kannst si selbst nutzen, indem du winsock.h einbindest und dein programm mit winsock2.dll linkst. 
Dein Programm wird auch nicht größer, da Libnodave.dll eh winsock2.dll anfordert.


Leuschman schrieb:


> @RALLE
> Heisst dies, wenn ich hier unter Windof arbeite, dass ich die "opensocket.h" eigentlich nicht nutzen kann...


Du kannst, aber du mußt nicht. Weil du nicht mußt, gibt es diese separate Headerdatei: Du könntest dein socket auch "zu Fuß" aufmachen, indem du Funktionen aus winsock2.dll nutzt. Das kann nützlich sein, wenn du Eigenschaften des Sockets ändern möchtest und das nach bind() oder connect() nicht mehr geht. 
Die Funktion openSocket() bietet dir einfach den Komfort, im Standardfall nicht alles selbst schreiben zu müssen.
Eine Funktion close() in "openSocketw.c" ein zubauen, wäre nicht so sinnvoll. Sie sähe so aus:

```
close(HANDLE h) {
 closesocket(h);
}
```
und würde den Code nur um ein paar Anweisungen aufblähen.  


Leuschman schrieb:


> @RALLE
> ... und dann irgendwie die "openSocketw.c" einbinden muss?


Der (kompilierte) Code aus openSocketw.c ist Bestandteil von libnodave.dll. Da mußt du gar nichts weiter tun.


----------

