Libnodave Java HILFE

Bastueh89

Level-1
Beiträge
20
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab mich jetzt ein wenig mit Libnodave, Socket Kommunikation und ISOoverTCP beschäftigt. Ich soll für meine Bachelorarbeit eine Smartphone-App schreiben, die nach Einscannen eines Barcodes ein bestimmtes Bit setzt. Klappt nach einigen Anleitungen und Umprogrammieren auch sehr gut. Jedoch verstehe ich absolut nicht was im Einzelnen passiert :( Ich bin auch nicht sooo bewandert in Kommunikation etc. würde aber gerne grob wissen was in den Methoden so passiert. Ich habe mir mal die Mühe gemacht und Kommentare am Anfang jeder Methode gesetzt, um zu dokumentieren wann welche Methode aufgerufen wird: Anhang anzeigen 21266

Mich interessiert eigentlich nur was während …newTCPConnection();,
Code:
07-19 15:07:15.304: I/System.out(13703): S7Connection.S7Connection()
07-19 15:07:15.304: I/System.out(13703): S7Connection.Semaphore.Semaphore()
07-19 15:07:15.304: I/System.out(13703): ===== created this.value = value
07-19 15:07:15.304: I/System.out(13703): TCPConnection.TCPConnection()
07-19 15:07:15.304: I/System.out(13703): ===== created new TCPConnection()

…connectPLC();,
Code:
07-19 15:07:15.304: I/System.out(13703): TCPConnection.connectPLC()
07-19 15:07:15.304: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.304: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.334: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.334: I/System.out(13703): S7Connection.negPDUlengthRequest()
07-19 15:07:15.334: I/System.out(13703): PDU.PDU()
07-19 15:07:15.334: I/System.out(13703): PDU.initHeader()
07-19 15:07:15.334: I/System.out(13703): PDU.addParam()
07-19 15:07:15.334: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.334: I/System.out(13703): TCPConnection.exchange()
07-19 15:07:15.334: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.334: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.334: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.334: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.354: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.354: I/System.out(13703): PDU.PDU()
07-19 15:07:15.354: I/System.out(13703): PDU.setupReceivedPDU()
07-19 15:07:15.354: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.354: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.354: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.354: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.354: I/System.out(13703): ===== done connectPLC()

...readByte();,
Code:
07-19 15:07:15.354: I/System.out(13703): S7Connection.readBytes()
07-19 15:07:15.354: I/System.out(13703): S7Connection.Semaphore.enter()
07-19 15:07:15.354: I/System.out(13703): PDU.PDU()
07-19 15:07:15.354: I/System.out(13703): PDU.initReadRequest()
07-19 15:07:15.354: I/System.out(13703): PDU.initHeader()
07-19 15:07:15.354: I/System.out(13703): PDU.addParam()
07-19 15:07:15.354: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.354: I/System.out(13703): PDU.addVarToReadRequest()
07-19 15:07:15.354: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.354: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.354: I/System.out(13703): Nodave.USBELong()
07-19 15:07:15.354: I/System.out(13703): Nodave USByte() started
07-19 15:07:15.354: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.354: I/System.out(13703): TCPConnection.exchange()
07-19 15:07:15.354: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.354: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.354: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.354: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.404: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.414: I/System.out(13703): PDU.PDU()
07-19 15:07:15.414: I/System.out(13703): PDU.setupReceivedPDU()
07-19 15:07:15.414: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.414: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.414: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.414: I/System.out(13703): PDU.testReadResult()
07-19 15:07:15.414: I/System.out(13703): PDU testResultData() started
07-19 15:07:15.414: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.414: I/System.out(13703): ===== read Byte

…getByte();
Code:
07-19 15:07:15.414: I/System.out(13703): S7Connection.getByte()
07-19 15:07:15.414: I/System.out(13703): Nodave.SByte()
07-19 15:07:15.414: I/System.out(13703): Nodave.bswap_8()

und ...writeByte(); genau passiert!
Code:
07-19 15:07:15.414: I/System.out(13703): S7Connection.writeBytes()
07-19 15:07:15.414: I/System.out(13703): S7Connection.Semaphore.enter()
07-19 15:07:15.414: I/System.out(13703): PDU.PDU()
07-19 15:07:15.414: I/System.out(13703): PDU.prepareWriteRequest()
07-19 15:07:15.414: I/System.out(13703): PDU.initHeader()
07-19 15:07:15.414: I/System.out(13703): PDU.addParam()
07-19 15:07:15.414: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.414: I/System.out(13703): PDU.addVarToWriteRequest()
07-19 15:07:15.414: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.414: I/System.out(13703): PDU.addData(void)
07-19 15:07:15.414: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.414: I/System.out(13703): PDU.addValue()
07-19 15:07:15.414: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.414: I/System.out(13703): PDU.addData(void)
07-19 15:07:15.414: I/System.out(13703): Nodave.setUSBEWord()
07-19 15:07:15.414: I/System.out(13703): TCPConnection.exchange()
07-19 15:07:15.414: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.414: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.414: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.414: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.434: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.434: I/System.out(13703): PDU.PDU()
07-19 15:07:15.434: I/System.out(13703): PDU.setupReceivedPDU()
07-19 15:07:15.434: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.434: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.434: I/System.out(13703): Nodave.USBEWord()
07-19 15:07:15.434: I/System.out(13703): ===== wrote Byte

Mir haben die docs zu Libnodave leider nicht geholfen :/
Es muss ja auch nicht einer zu Allen antworten. Vielleicht weiß der Eine oder Andere was und es findet sich was zusammen. Wie gesagt brauche es auch schnell, weil ich gerne in der BA grob erläutern würde was die Methoden für Aufgaben haben.
 
warum werden 2 PDUs während der readBytes() oder writeBytes() erstellt und was haben die für Aufgaben?
Eine für das Paket, das an die SPS gesendet wird(Anforderung, request), die andere für das Paket, das die SPS zurücksendet (Antwort, response).
N.b.:
PDU steht für Protocol Data Unit
Das PDU-Objekt enthält NICHT die Daten, sondern dient zum VERWALTEN derselben. Die Daten befinden sich in byte[]-Arrays und im zugehörigen PDU-Objekt steht, wo die S7-Daten, der Header, die Parameter und die Nutzdaten anfangen und wie lang sie jeweils sind.
 
ok vielen dank, ich hatte mir schon so etwas in der Art gedacht, wusste aber nicht 100pro, ob es stimmt weil irgendwie bei der Herstellung der Verbindung die Methode negPDUlengthRequest() aufgerufen wird und diese ebenfalls eine PDU anlegt. Aber hier wird nur der Header der PDU angelegt oder? Kann jemand erklären, was es hier mit dem Header der PDU auf sich hat? Komme nie so richtig mit dem Begriff "header" klar. Im Header stehen doch nur Informationen über Sender und Empfänger oder?

PS: was macht addParam() genau?

andere Frage: was verriegelt der Semaphor in Libnodave genau? grob: dass nicht mehrere Prozesse auf die Verbindung zugreifen können?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ok vielen dank, ich hatte mir schon so etwas in der Art gedacht, wusste aber nicht 100pro, ob es stimmt weil irgendwie bei der Herstellung der Verbindung die Methode negPDUlengthRequest() aufgerufen wird und diese ebenfalls eine PDU anlegt. Aber hier wird nur der Header der PDU angelegt oder?
Müsste ich nachsehen...
Kann jemand erklären, was es hier mit dem Header der PDU auf sich hat? Komme nie so richtig mit dem Begriff "header" klar. Im Header stehen doch nur Informationen über Sender und Empfänger oder?
Wir sprechen hier über S7-Kommunikation. Da beginnt das Paket mit einem Header. Das ist nicht der TCP- und nicht der ISO-Header. Im S7-Header stehen gar keine Informationen über Sender und Empfänger.
Im S7-Header steht ein PDU-Typ (1,2,3 oder 7), eine optionale Nummer, die Länge der Parameter, die Länge der Daten und bei Typ 2 und 3 ein Fehlercode.
PS: was macht addParam() genau?
Es fügt Parameter zu einem Datenpaket hinzu und trägt deren Länge in das PDU-Objekt ein.
andere Frage: was verriegelt der Semaphor in Libnodave genau? grob: dass nicht mehrere Prozesse auf die Verbindung zugreifen können?
Libnodave geht davon aus, daß nicht mehrere Anfragen gleichzeitig laufen. Mit anderen Worten es verläßt sich darauf, daß die nächste Antwort von der SPS zu der letzten Anfrage gehört.
 
Zu den anderen Fragen aus der privaten Nachricht. Ich antworte lieber hier, dann können es alle lesen:
Bei einer S7- Verbindung über ISO over TCP spielen drei Protokolle eine Rolle: TCP/IP stellt eine Verbindung her, auf der ein Strom von Daten transportiert wird.
Als Nutzlast befördert TCP/IP dann Datenpakete nach ISO 8073. Wie diese Pakete über den TCP-Strom geschafft werden, beschreibt RFC1006.
ISO over TCP befördert dann wiederum Datenpakete der S7-Kommunikation. Die ist Siemens-eigen und es gibt es von Siemens keine Informationen darüber.
 
Ok danke das hilft mir weiter.

Nächste Frage...

welche Daten bzw. Informationen enthalten die ISO-Pakete? Beim Aufbau einer Verbindung werden in meiner TCPConnection-Klasse mehrmals ISO-Pakete gesendet, gelesen und in der PLCinterface-Klasse dazu write() und read()-Methoden aufgerufen ?! Ich verstehe die Zusammenhänge nicht:

Ausschnitt aus ...connectPLC...

Code:
...
07-19 15:07:15.304: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.304: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.334: I/System.out(13703): PLCinterface.read()
...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zu den anderen Fragen aus der privaten Nachricht. Ich antworte lieber hier, dann können es alle lesen:
Bei einer S7- Verbindung über ISO over TCP spielen drei Protokolle eine Rolle: TCP/IP stellt eine Verbindung her, auf der ein Strom von Daten transportiert wird.
Als Nutzlast befördert TCP/IP dann Datenpakete nach ISO 8073. Wie diese Pakete über den TCP-Strom geschafft werden, beschreibt RFC1006.
ISO over TCP befördert dann wiederum Datenpakete der S7-Kommunikation. Die ist Siemens-eigen und es gibt es von Siemens keine Informationen darüber.

Also liege ich schon richtig, dass das Ganze über TCP/IP per Stream-Sockets geschieht ja? laut wikipedia müssen doch aber immer 2 Sockets erstellt werden oder? Halt einen für den Client und einen für den Server. Liege ich überhaupt richtig in der Annahme, dass die S7 als Server selbst den einen anderen Socket verwaltet ? Und wird nun der Dienst Fetch/Write angewendet (weil mein Programm funktioniert und ich musste keine bausteine in S7 integrieren http://support.automation.siemens.c...objaction=csview&extranet=standard&viewreg=WW) oder lieg ich völlig falsch da es wirklich Siemens-eigen ist, gibt es DARÜBER keine wirklichen Informationen und ich beschreibe es einfach genau so!?


mal ganz kurz!!!:

ISOonTCP = ISOoverTCP ? Oder ist das was völlig unterschiedliches?
 
Also liege ich schon richtig, dass das Ganze über TCP/IP per Stream-Sockets geschieht ja?
Im Fall von ISO over TCP, ja. S7-Kommunikation kann aber auch über serielle Schnittstellen, Profibus u.a. transportiert werden.
laut wikipedia müssen doch aber immer 2 Sockets erstellt werden oder? Halt einen für den Client und einen für den Server.
Ja
Liege ich überhaupt richtig in der Annahme, dass die S7 als Server selbst den einen anderen Socket verwaltet ?
Ja
Und wird nun der Dienst Fetch/Write angewendet
Nein. Fetch/Write gehörte zur S5, aber diverse S7-CPs können es auch. ISO over TCP kann als Nutzdaten nicht nur Fetch/Write sondern halt auch S7-Kommunikation transportieren.
(weil mein Programm funktioniert und ich musste keine bausteine in S7 integrieren
Muß du ja auch nicht, wenn du mit dem PG Variablen beobachtest. Da läuft ist auch S7-Kommunikation.

Klick mal mal unter obigem Link auf:
Welche Eigenschaften, Vorteile und Besonderheiten bietet das S7-Protokoll?
Und dann der Dienst PUT/GET, das ist was Libnodave macht.
oder lieg ich völlig falsch da es wirklich Siemens-eigen ist, gibt es DARÜBER keine wirklichen Informationen...
Wenn ich's dir doch sage...
und ich beschreibe es einfach genau so!?
Das mußt du wissen oder frag deinen Prof.

mal ganz kurz!!!:

ISOonTCP = ISOoverTCP ? Oder ist das was völlig unterschiedliches?
Nee. Ist schon dasselbe gemeint.
 
Welche Eigenschaften, Vorteile und Besonderheiten bietet das S7-Protokoll?
Und dann der Dienst PUT/GET, das ist was Libnodave macht.

Ah ok ich verstehe :) Habe bis jetzt noch nicht gewusst, dass es dieses Protokoll gibt, dachte immer das ist ein Oberbegriff für ISOonTCP oder sowas.
Vielen vielen Dank jetzt wird mir einiges klar.

ok weiter zu #8
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok danke das hilft mir weiter.

Nächste Frage...

welche Daten bzw. Informationen enthalten die ISO-Pakete? Beim Aufbau einer Verbindung werden in meiner TCPConnection-Klasse mehrmals ISO-Pakete gesendet, gelesen und in der PLCinterface-Klasse dazu write() und read()-Methoden aufgerufen ?! Ich verstehe die Zusammenhänge nicht:

Ausschnitt aus ...connectPLC...

Code:
...
07-19 15:07:15.304: I/System.out(13703): TCPConnection.sendISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.write()
07-19 15:07:15.304: I/System.out(13703): TCPConnection.readISOPacket()
07-19 15:07:15.304: I/System.out(13703): PLCinterface.read()
07-19 15:07:15.334: I/System.out(13703): PLCinterface.read()
...

und außerdem würde ich gerne wissen, was die Methoden setUSBEWord(), USBEWord(), USBELong(), USByte() und SByte (alle in Klasse Nodave) machen !
 
Schau dir halt den Code an:
Code:
public static void setUSBEWord(byte[] b, int pos, int val) {
	b[pos] = ((byte) (val / 0x100));
	b[pos + 1] = ((byte) (val % 0x100));
}
Es werden übergeben:
Ein Array von bytes b
Eine Position pos
Ein Wert val(ue)

1.Anweisung:
b[pos] = ((byte) (val / 0x100));
Das Byte an der Stelle pos wird auf ein 256tel des Wertes gesetzt. Das ist das obere Byte von val. (bzw von val mod 0x10000, falls val den zulässigen Bereich für word überschreitet).

2.Anweisung:
b[pos + 1] = ((byte) (val % 0x100));
Das Byte an der Stelle pos+1 wird auf den Divisionsrest von seinem Wert/256. Das ist das untere Byte von val.

Fazit: Es wird es der Wert von val in der Reihenfolge high byte, low byte in das Array b ab position pos eingetragen.
Diese Umständlichkeit hat 2 Gründe:
1. Ein int ist in JAVA 4 Byte lang, die SPS erwartet aber nur 2.
2. Ein x86-PC speichert seine Werte little endian, eine S7 big endian, von JAVA weiß ich es gerade nicht.
 
TCPConnection.sendISOPacket() verschickt ein ISO-Paket
PLCinterface.write() schreibt auf ein socket
TCPConnection.readISOPacket() liest ein ISO-Paket
PLCinterface.read() liest vom Socket. Der erste Aufruf liest einen Teil des ISO-headers. Da steht die Länge drin.
PLCinterface.read() der folgende Aufruf liest den Rest des ISO-Paketes, unter Berücksichtigung der Länge.
 
Zurück
Oben