# Libnodave



## Human (8 Mai 2007)

Ich hab jetzt mal Libnodave, nachdem das auf dem Forumstreffen des öfteren Thema war, einmal ausprobiert.

Ich habe die Delphi-Komponente in Delphi 6 hinzugefügt bekommen, geht das auch irgendwie unter Delphi 2006, habe es dort leider nicht hinbekommen und würde auch lieber damit arbeiten?

Ich hab es geschafft mit der Delphi-Komponente eine Verbindung herzustellen und auch auf die Daten auf meiner S7 315-PN/DP zuzugreifen.

Nun habe ich mal wieder meinen 1024 Byte großen Datenbaustein und möchte diesen natürlich auch wieder auf einmal komplett übertragen. Bis zu ca. 200 Bytes kommen die Werte aus dem Datenbaustein richtig an, bei ca. 220 Bytes bekomme ich nach dem Compilieren, wenn ich das Programm starte sofort eine Zugriffsverletzung und das Programm läuft nicht weiter, darüber bekomme ich dann irgendwelche seltsame Werte, die hinten und vorne nicht stimmen.


----------



## Zottel (8 Mai 2007)

Ich kann nicht sagen, wie das mit der Delphi-Komponente gehen muß, da ist Axel der Spezialist. Allgemein: CPU und Libnodave handeln aus, wie groß eine PDU sein darf. Damit steht fest, wie groß ein einzelnes Telegramm sein darf, häufig 240 Bytes. Davon gehen einige Bytes ab, so daß sich 222 Bytes mit einem Telegrammaustausch übertragen lassen. Um einen DB von 1000 Byte zu lesen, müßtest du 222 Byte ab DBB0, danach 222 Byte ab DBB222, 222 Byte ab DBB444, 222 Byte ab DBB666 und 112 Byte ab DBB888 lesen. Diese Einteilung automatisiert daveReadManyBytes()  für dich, aber jedes Telegramm dauert seine Zeit... Das ist eine Beschränkung der S7-Kommunikation, nicht von Libnodave.


----------



## Human (8 Mai 2007)

Danke, Zottel!
Ich hab die Funktion daveReadBytes() in der Komponente durch daveReadManyBytes() ersetzt und es hat funktioniert. :-D
Mit 42 - 47ms für 1 kB bin ich da zeitlich immernoch sehr zufrieden, besonders, weil es auch noch über einen Switch läuft.

[EDIT]
Nachdem ich die ListBox rauskommentiert habe braucht es nurnoch 0,2 - 0,5 ms. :-D
[/EDIT]


----------



## afk (8 Mai 2007)

Human schrieb:


> Ich habe die Delphi-Komponente in Delphi 6 hinzugefügt bekommen, geht das auch irgendwie unter Delphi 2006, habe es dort leider nicht hinbekommen und würde auch lieber damit arbeiten?


Bei mir läuft es unter Delphi 2006. Ich habe die Komponente einfach in ein Package eingebunden, das ich für diverse andere Komponenten schon erstellt hatte. 



Human schrieb:


> Bis zu ca. 200 Bytes kommen die Werte aus dem Datenbaustein richtig an, bei ca. 220 Bytes bekomme ich nach dem Compilieren, wenn ich das Programm starte sofort eine Zugriffsverletzung und das Programm läuft nicht weiter, darüber bekomme ich dann irgendwelche seltsame Werte, die hinten und vorne nicht stimmen.


Mit meinem Demo-Programm und einer VIPA-CPU 315 SB funktioniert das bei 1024 Bytes in einem DB ohne Probleme ...  


Gruß Axel


----------



## afk (8 Mai 2007)

Human schrieb:


> Ich hab die Funktion daveReadBytes() in der Komponente durch daveReadManyBytes() ersetzt und es hat funktioniert. :-D


Das ist aber seltsam, daveReadBytes wird in TNoDave.DoReadBytes aufgerufen, die Methode macht aber im Grunde das gleiche wie daveReadManyBytes, es macht also eigentlich keinen Sinn, von dort noch daveReadManyBytes aufzurufen.



Human schrieb:


> Mit 42 - 47ms für 1 kB bin ich da zeitlich immernoch sehr zufrieden, besonders, weil es auch noch über einen Switch läuft.
> 
> [EDIT]
> Nachdem ich die ListBox rauskommentiert habe braucht es nurnoch 0,2 - 0,5 ms. :-D
> [/EDIT]


Jetzt wird es ganz komisch. Bei allen CPUs, die ich kenne, hat die Antwort normalerweise ca 5-10 ms gedauert. Und Du brauchst bei einer 300er CPU 5 Antworten mit gut 200 Bytes, um 1024 Bytes zu übertragen. Hast Du vielleicht ein wenig zu viel auskommentiert ?


Gruß Axel


----------



## Human (8 Mai 2007)

afk schrieb:


> Das ist aber seltsam, daveReadBytes wird in TNoDave.DoReadBytes aufgerufen, die Methode macht aber im Grunde das gleiche wie daveReadManyBytes, es macht also eigentlich keinen Sinn, von dort noch daveReadManyBytes aufzurufen.
> 
> 
> > Jetzt wo ich mir die Funktion nochmal durchlese stelle ich das auch fest, dass das das gleiche ist... :???:
> ...


----------



## afk (8 Mai 2007)

Human schrieb:


> Das Testprogramm wird bei 999 Bytes sehr langsam und zeigt mir wenn überhaupt noch '0' oder '?' an und dazu den Fehler: Error [5]: the desired address is beyond limit for this PLC


Das es so langsam wird, das liegt an der Ausgabe der Daten in der Liste, nicht am Lesen von der CPU. Ist halt nur ein einfaches, mal eben so zwischendurch programmiertes Demo-Programm ...



Human schrieb:


> In meinem Programm bekomme ich die richtigen Werte, auch, wenn ich die selbe Fehlermeldung bekomme. Ich hole die Werte aus einem DB1006, kann das vieleicht etwas damit zu tun haben?
> Die DB-Länge kann es nicht sein, der DB ist 1024 Byte lang und existieren tut er auch...


Weiß nicht, ob das an der DB-Nummer liegen kann, probier es doch mal mit 'ner kleineren Nummer aus. Aber daß Dein Programm trotz der Fehlermeldung die korrekten Werte bekommt, das kann ich gar nicht glauben, denn dann ist das Lesen ab irgendeiener Adresse fehlgeschlagen. Kann es sein, daß in deinem Puffer schon vor dem Lesen etwas vernünftiges drin steht ?


Gruß Axel


----------



## Human (8 Mai 2007)

afk schrieb:


> Kann es sein, daß in deinem Puffer schon vor dem Lesen etwas vernünftiges drin steht ?


 
Ich hol mir gerade die Werte noch auf Knopfdruck, wenn ich auf ein Button klicke und lass mir die Fehlermeldung in einem Edit-Feld anzeigen.

Ein Word im DB lasse ich ständig hochzählen. Wenn ich jetzt auf den Button klicke kommt manchmal die Fehlermeldung und manchmal nicht, auf jeden Fall wir das Word, das hochgezählt wird bei jedem Klick aktualisiert und die Werte, die ankommen klingen mehr als nur plausibel, sondern sind richtig und das trotz einer Fehlermeldung...  

Jetzt habe ich das gleiche noch mit einem Datenbaustein DB100 ausprobiert: Die gleiche Fehlermeldung, aber das selbe gute Ergebnis, die Fehlermeldung erscheint, im Demo-Programm geht es bei der Fehlermeldung nicht weiter, aber das Ergebnis, wenn es denn mal kommt, stimmt da auch...


----------



## afk (8 Mai 2007)

Human schrieb:


> Ein Word im DB lasse ich ständig hochzählen. Wenn ich jetzt auf den Button klicke kommt manchmal die Fehlermeldung und manchmal nicht, auf jeden Fall wir das Word, das hochgezählt wird bei jedem Klick aktualisiert und die Werte, die ankommen klingen mehr als nur plausibel, sondern sind richtig und das trotz einer Fehlermeldung...


Ich vermute mal, daß immer der gleiche Buffer verwendet wird. Wenn Du keinen eigenen Buffer verwendest, dann wird in der Komponente ein interner Buffer verwendet, und dann ist es auf jeden Fall immer der gleiche Buffer.

Durch den Button wird das Lesen gestartet, das, bedingt durch die DB-Größe, in mehreren Teilschritten ausgeführt wird. Kommt dabei, z.B. beim letzten Teilschritt, ein Fehlercode von der SPS, so ist der vordere Teil vom Buffer (in Deinem Fall ca. 4/5) bereits mit den neuen Werten aktualisiert worden, und im Rest stehen noch die Werte vom letzten Lesezyklus. 

Pack mal deinen Zähler ganz ans Ende des DBs, dann dürfte der beim Auftreten des Fehlers jedesmal nicht hochzählen, sofern ich richtig vermute.

Noch mehr würde mich der Grund für das Problem interessieren. Hast Du auch Zugriff auf eine andere CPU ?


Gruß Axel


----------



## Human (9 Mai 2007)

Ich habe gerade keine andere CPU da, aber wenn ich die IP ändere, von der jetztigen und dann wieder drauf zugreife, dann sieht das immernoch genau gleich aus.

Ich habe in dem DB alle 100 Bytes den Zähler rein und bekomme an allen Stellen ein gutes Ergebnis, auch wenn sich der Erste und der letzte Zählerstande ein wenig unterscheiden, aber sie ändern sich jedes mal (der Zähler zählt jeden Zyklus der CPU den Zählerstand um 1 hoch).
´
Eigentlich stört es mich ja nicht, wenn da irgendwelche komischen Meldungen kommen, aber die kommen ja normalerweise nicht einfach so aus Jux und Dollerei, da hat sich sicher irgendjemand deswegen Gedanken gemacht... :???:

Zumindest hab ich das mit der Delphi-Komponente hinbekommen, dass ich die im D2k6 verwenden kann.


----------



## afk (9 Mai 2007)

Human schrieb:


> Eigentlich stört es mich ja nicht, wenn da irgendwelche komischen Meldungen kommen, aber die kommen ja normalerweise nicht einfach so aus Jux und Dollerei, da hat sich sicher irgendjemand deswegen Gedanken gemacht... :???:


Wenn ein ReturnCode <> 0 beim Aufruf von Read(Many)Bytes zurückgegeben wird, dann wurde auf jeden Fall mindestens ein Datenpaket in der Übertragung verworfen und die entsprechenden Daten sind nicht in den Buffer kopiert worden. Daher wäre es ratsam, erst einmal die Ursache für das Verhalten herauszufinden. Leider habe ich momentan keine PN-CPU zur Verfügung, erst recht keine 315er.


Gruß Axel


----------



## Ralle (9 Mai 2007)

Also ich mach das Ganze mit D7 und einer 317PN und bekomme ordentlich 0 als Return. Ich lese so ca. 1K Daten aus.


----------

