Libnodave Version 0.8

Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zottel,
wie les ich denn am gescheidsten Wörter und Doppelwörter bzw. wie kann man die am einfachsten aus zwei/vier Bytes errechnen?

Danke und Gruß Sebastian

Edit: Habe es schon... geht ja ganz einfach. So in etwa müsste das sein: (byte1)*2^8 + (byte0)*2^0 = word
 
seeba schrieb:
Hallo Zottel,
wie les ich denn am gescheidsten Wörter und Doppelwörter bzw. wie kann man die am einfachsten aus zwei/vier Bytes errechnen?

Danke und Gruß Sebastian

Edit: Habe es schon... geht ja ganz einfach. So in etwa müsste das sein: (byte1)*2^8 + (byte0)*2^0 = word
Wozu stellst du solche Rechnungen an? Die sind alle schon drin:
daveGetU16, daveGetS16, daveGetU32, daveGetS32, daveGetFloat.
Gibt's da irgendwo ein fundamentales Mißverständnis?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zottel schrieb:
seeba schrieb:
Hallo Zottel,
wie les ich denn am gescheidsten Wörter und Doppelwörter bzw. wie kann man die am einfachsten aus zwei/vier Bytes errechnen?

Danke und Gruß Sebastian

Edit: Habe es schon... geht ja ganz einfach. So in etwa müsste das sein: (byte1)*2^8 + (byte0)*2^0 = word
Wozu stellst du solche Rechnungen an? Die sind alle schon drin:
daveGetU16, daveGetS16, daveGetU32, daveGetS32, daveGetFloat.
Gibt's da irgendwo ein fundamentales Mißverständnis?

Ja, denn wo übergeb ich den Funktionen die Bytes bzw. was sie umrechnen sollen?
 
seeba schrieb:
Ja, denn wo übergeb ich den Funktionen die Bytes bzw. was sie umrechnen sollen?
Gar nicht.
Nehmen wir an du hast einen DB der so aus sieht:
a WORD ein Wort
b BYTE ein Byte
c REAL ein real, fängt extra auf DBB3 an, damits schwerer aussieht
d WORD ein Wort
e DWORD ein Doppel-Wort
f Integer ein Wort mit Vorzeichen
g WORD ein Wort

Du liest den ganzen Kram ein:
daveReadBytes(dc, daveDB, DBnummer, 0, 17, NULL);
jetzt stehen 17 Bytes im internen Puffer der daveConnection.
a=daveGetU16(dc);
b=daveGetU8(dc);
c=daveGetFloat(dc);
d=daveGetU16(dc);
e=daveGetU32(dc);
f=daveGetS16(dc);
g=daveGetU16(dc);

Es gibt die ganzen Dinger auch noch als daveGetFrom... Da kannst du einen eigenen Puffer und eine Position angeben.
 
RE

Tach Zottel!
Muss ich für die Libnodave.dll Step7 installieren damit es mit s7online funktioniert??
Oder geht das auch wenn ich nur z.B. den Treiber für den Adapter installiere??(Wird da die s7onlinx.dll mit installiert?)

Gruß Ronnie
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Re: RE

ronnie.b schrieb:
Tach Zottel!
Muss ich für die Libnodave.dll Step7 installieren damit es mit s7online funktioniert??
Oder geht das auch wenn ich nur z.B. den Treiber für den Adapter installiere??(Wird da die s7onlinx.dll mit installiert?)

Gruß Ronnie

Wenn du die S7online Funktion nutzen willst, reicht es wenn du z.B. SIMATIC NET installierst. Das brauchst du dann auch nicht authorisieren!
 
Irgendwas ist faul.

Kann es sein, daß daveReadBytes irgenwas ruiniert?

Wenn man mehrmals disconnectet und wieder connectet (ist mit der Delphi-Demo mit großen Blöcken gut nachvollziebar) bleibt das Ganze irgendwann beim Connect oder Disconnect stehen, oder bringt eine Schutzrechtsverletzung (Häufig Zugriffsverletzung bei Adresse 10008AAA in Modul Libnodave.dll, wenn das Problem beim connect auftritt). Wenn man keine Daten mit daveReadBytes liest, dann kann man beliebig oft connect und disconnect ausführen. Ich kann leider nicht sagen, ob das nur bei der s7Onlinx.dll so ist, da ich im Moment keinen anderen Adapter als den CP5511 zur Verfügung hab. Kann es evtl. sein, das daveFree irgenwelche Leichen zurückläßt, die mit dem Buffer zu tun haben?

Beim Disconnect passiert folgendes:

Code:
FLastError := daveDisconnectPLC(DaveConn);
      daveFree(DaveConn);
      FLastError := daveDisconnectAdapter(DaveIntf);
      daveFree(DaveIntf);
 
Ralle schrieb:
Irgendwas ist faul.

Kann es sein, daß daveReadBytes irgenwas ruiniert?

Wenn man mehrmals disconnectet und wieder connectet (ist mit der Delphi-Demo mit großen Blöcken gut nachvollziebar) bleibt das Ganze irgendwann beim Connect oder Disconnect stehen, oder bringt eine Schutzrechtsverletzung (Häufig Zugriffsverletzung bei Adresse 10008AAA in Modul Libnodave.dll, wenn das Problem beim connect auftritt). Wenn man keine Daten mit daveReadBytes liest, dann kann man beliebig oft connect und disconnect ausführen. Ich kann leider nicht sagen, ob das nur bei der s7Onlinx.dll so ist, da ich im Moment keinen anderen Adapter als den CP5511 zur Verfügung hab. Kann es evtl. sein, das daveFree irgenwelche Leichen zurückläßt, die mit dem Buffer zu tun haben?

Kann ich nicht sagen, aber eher unwahrscheinlich. Ich habe geschrieben, daß s7online als Protkoll ALPHA ist.
Solange nicht eindeutig überprüft wird, ob ein von der s7onlinx.dll an daveGetResponseS7online zurückgegebener Puffer wirklich Daten von der SPS enthält, kann alles mögliche passieren, dessen Details mich ehrlich gesagt nicht interessieren.

Meine Anwendungen verbinden sich eigentlich nur einmal mit der CPU. Wenn du das auch so machst, kannst du s7online als Protkoll verwenden, wenn du aber einen Grund hast, warum du disconnect() und connect() mehrfach aufrufen mußt, warte bitte auf die nächste Version.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, Daten kommen an. Es ist eine Anwendung, in der man die Kommunikation starten und stoppen kann. Wenn der Nutzer das mehrmals hintereinader tut (warum auch immer), sollte die Applikation nicht einfrieren bzw. abstürzen. Ich habe den Eindruck gewonnen, daß es an der DLL liegt, da ich das Problem sowohl bei der Demo, als auch bei meiner Umsetzung "zu Fuß" habe. Das der Code Alpha ist ist ja klar, irgendwas passiert wohl beim Disconnect, leider habe ich keinen C-Compiler und bin in C auch nicht so ganz sattelfest, da trau ich mir nicht zu in der DLL rumzudebuggen und das Problem zu finden.
 
Ralle schrieb:
Ja, Daten kommen an. Es ist eine Anwendung, in der man die Kommunikation starten und stoppen kann.
Wozu? bzw. wenn du nicht kommunizierst, laß doch die Verbindung offen.
... irgendwas passiert wohl beim Disconnect, leider habe ich
disconnectPLC tut gar nichts.
disconnectAdapter schließt das handle der Verbindung zur s7onlinx.dll.
Das ist eigentlich was sonst closePort macht.
Daher kannst du nach disconnectAdapter gar nichts mehr tun, ohne mit openS7online ein neues handle zu holen. Das ist unschön und anders als bei allen anderen Protokollen, aber ich habe noch keine gute Lösung dafür.

Da disconnectPLC nichts tut, wird connectPLC möglicherweise die CPU-inetenen Verbindungen nacheinander belegen, bis nichts mehr geht. Kannst du dir parallel in Step7 angucken.
 
Mußte nochmal anfangen mit schreiben, beim Testen hat es mit das XP zerhauen :cry: .

Also, wenn Step7 online ist, bricht beim Connect über libnodave und s7onlinx.dll die Verbindung von Step7 ab, libnodave meldet wechselnd -124 und -128. Wenn ich zuerst die Verbindung mit libnodave aufbaue, kann ich anschließend mit Step7 online gehen, darf aber libnodave nicht stoppen, da es dann nicht nocheinmal zu einer Verbindung bewegt werden kann (-124, -128). Klar kann ich die Verbindung offen lassen, aber sie muß auch ordentlich abgebaut werden können. Wenn jemand ausversehen das Kabel abzieht und dann wieder ansteckt nehme ich normalerweise (prodave) die Verbindung wieder auf und weiter geht es.
Ich werde mal weitertesten, was passiert, wenn ich grundsätzlich einmal die Verbindung aufbaue und dann stehen lasse.

Test: Ja, nachdem man die Verbindung gestört hat muß man dann das Programm schließen, hmm.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ralle schrieb:
Mußte nochmal anfangen mit schreiben, beim Testen hat es mit das XP zerhauen :cry: .
Und ich dachte schon, Windows wäre inzwischen soweit, daß eine Amok laufende Anwendung nicht mehr das System zerschießt.
Also, wenn Step7 online ist, bricht beim Connect über libnodave und s7onlinx.dll die Verbindung von Step7 ab...
Sehe ich mir heute abend an.
Test: Ja, nachdem man die Verbindung gestört hat muß man dann das Programm schließen, hmm.
Abgesehn davon, das Libnodave wahrscheinlich noch nicht jeden Fehler korrekt erkennt:
Wenn daveReadBytes einen Fehler meldet, der mit der Verbindung zu tun hat (und nicht damit, daß es einen DB nicht gibt oder er nicht genug Daten enthält), solltest du in folgender Reihenfolge die Verbindung abbauen und eine ganz neue aufbauen können:
Code:
daveDisconnectPLC(dc) // auch wenn's noch nichts tut
daveFree(dc)  
// wenn es jetzt oder als Folge dieses Aufrufs von daveFree einen Zugriffsfehler gibt, dann
// müßte es so sein, daß ein Zeiger auf den Pufferspeicher in daveConnection an s7onlinx.dll
// übergeben wurde und s7onlinx.dll ihn noch für gültig hält.
daveDisconnectAdapter
daveFree(di) ;
fds.rfd=openS7online("name"),
fds.wfd=fds.rfd;
di=daveNewInterface(fds...);
daveInitAdapter(di);
dc=daveNewConnection(di)
daveConnectPLC(dc);
Wenn das nicht geht wegen dem vermuteten Problem, daß die s7Onlinx noch im Besitz eines Puffers ist, könnte es so gehen:
Code:
daveDisconnectPLC(dc) // auch wenn's noch nichts tut
daveDisconnectAdapter
daveFree(dc)  
daveFree(di) ;
fds.rfd=openS7online("name"),
fds.wfd=fds.rfd;
di=daveNewInterface(fds...);
daveInitAdapter(di);
dc=daveNewConnection(di)
daveConnectPLC(dc);
Geht auch das nicht, laß einfach daveFree() weg und guck was passiert. Ich weiß, das macht Löcher in den Speicher, aber es sind jedesmal nur 2-3 kByte, das kann ein heutiger PC längere Zeit verkraften. Und wenn du die Anwendung beendest, holt sich Windows den Speicher schon wieder.
[/code]
 
Danke Zottel, das werde ich mal testen.
Im Moment mache ich es nach deinem 1. Tip, wenn die Verbindung einmal aufgebaut ist, lasse ich sie stehen. Wenn DaveReadBytes einen Fehler bringt (Kabel ab) , bau ich die Verbindung komplett ab und später wieder auf. Nach einem Fehler kann ich eigenartiger Weise die Verbindung immer (15 mal probiert) aufbauen, ohne daß die Anwendung abschmiert. So geht es immerhin ersteinmal, vielleicht findest du mit den Hinweisen auch noch etwas.
Erstmal super, daß es überhaut geht, daß kann man nicht von vielen Alphas (ich meine den s7Onlinx.dll Zugriff) sagen :lol: .
 
@Zottel

Die Funktion ReadBytes bringt mir bei daveProtoS7Online immer die Daten der ersten angelegten DaveConn (mit daveNewConnection) zurück, egal ob ich eine zweite erzeugt habe und von dieser auch die Daten lesen will.
Die beiden Rückgabewerte von daveNewConnection sind jeweils unterschiedlich und es gab keine Fehlermeldung.
 
seeba schrieb:
@ Zottel: mal kurz zu Bits... wie kann ich da nun 1 oder 0 auslesen? Array und dann aussuchen?
Aus dem Ergebnis von daveReadBytes:
b=daveGetU8(dc) //holt ein Byte
if (b & 128) bit7=1; else bit7=0;

Aus dem Ergebnis von daveReadBits:
b=daveGetU8(dc) //holt ein Byte
if (b =0) bitx=1; else bitx=0;
bitx ist halt das, dessen Adresse du gelesen hast.
Und um es nochmal deutlich zu sagen: Die S7 liefert bei readBits ein Byte zurück. Wenn es nicht 0 ist, ist das Bit 1.
Beispiele sind testMPI.c, vielleicht auch in testMPI.cs.
 
Code:
Imports System
Imports System.Threading

Class test
	Shared fds As libnodave.daveOSserialType
	Shared di As libnodave.daveInterface
	Shared dc As libnodave.daveConnection
	Shared rack As Integer = 0
	Shared slot As Integer = 2

	Public Shared Function Main(ByVal args As String()) As Integer
		Dim i As Integer
		Dim a As Integer = 0
		Dim j As Integer
		Dim res As Integer
		Dim b As Integer = 0
		Dim c As Integer = 0
		Dim d As Single = 0
		fds.rfd = libnodave.openSocket(102, "192.168.0.241")
		fds.wfd = fds.rfd
		If fds.rfd > 0 Then
			di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
			di.setTimeout(1000000)
			dc = New libnodave.daveConnection(di, 0, rack, slot)
			Do
				If 0 = dc.connectPLC Then
					res = dc.readBytes(libnodave.daveDB, 50, 0, 10, Nothing)
					If res = 0 Then
						a = dc.getS32
						b = dc.getS32
						c = dc.getS32
						d = dc.getFloat
						Console.WriteLine("FD0: " + a.ToString)
						Console.WriteLine("FD4: " + b.ToString)
						Console.WriteLine("FD8: " + c.ToString)
						Console.WriteLine("FD12: " + d.ToString)
					Else
						Console.WriteLine("error " + res.ToString + " " + libnodave.daveStrerror(res))
					End If
				End If
				Thread.Sleep(100)
			Loop Until 1 < 0
			dc.disconnectPLC
			libnodave.closePort(fds.rfd)
		Else
			Console.WriteLine("Couldn't open TCP connaction to PLC")
			Return -1
		End If
		Return 0
	End Function
End Class

Jetzt versuch ich mal die Werte dauernd zu aktualisieren... Sprich Endlos-Schleife! Einmal geht's und das zweite Mal geht's nicht mehr!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
    If 0 = dc.connectPLC Then
   Do
    res = dc.readBytes(libnodave.daveDB, 50, 0, 10, Nothing)
...
    Thread.Sleep(100)
   Loop Until 1 < 0
   dc.disconnectPLC

Jedes connectPLC belegt eine Verbindung ind der CPU!
Liest keiner die Beispielprogramme?
Die benchmarks (testXXX -b lesen) auch wiederholt in Schleifen!
 
Zottel schrieb:
Code:
    If 0 = dc.connectPLC Then
   Do
    res = dc.readBytes(libnodave.daveDB, 50, 0, 10, Nothing)
...
    Thread.Sleep(100)
   Loop Until 1 < 0
   dc.disconnectPLC

Jedes connectPLC belegt eine Verbindung ind der CPU!
Liest keiner die Beispielprogramme?
Die benchmarks (testXXX -b lesen) auch wiederholt in Schleifen!

Zottel, das Problem ist einfach, dass jeder die Beispielprogramme liest, welche er versteht! Das ist bei mir VB.NET und etwas C#! Du solltest nicht erwarten, dass jeder alle Beispiele lesen will und kann!
 
seeba schrieb:
Zottel, das Problem ist einfach, dass jeder die Beispielprogramme liest, welche er versteht! Das ist bei mir VB.NET und etwas C#! Du solltest nicht erwarten, dass jeder alle Beispiele lesen will und kann!
Nein, da hast du wohl recht, aber ich habe auch schon eine Menge Bibliotheken und Sachen von anderen Leuten benutzt und meiner Meinung nach war und ist das meiste davon zwar vielleicht von mehr Dokumentation begleitet, aber im Programmtext weitaus schlechter kommentiert.
Wenn ich mehr Dokumentation schreibe, bekomme ich das Problem, die Dokumentation auf dem Stand des Programmcodes zu halten. Doppelte Arbeit :-(

Trotzdem sind mit jedem release neue Readmes und FAQs dabei.

Das Programm testMPI.cs in Dot.Net/CS enthält die Benchmarks auch. Daß sie nun ausgerechnet im VB.net-Beispiel nicht drin sind, liegt daran daß der VB-Compiler von MONO (freier Dot.Net-Nachbau) noch ziemlich unfertig ist und mit längeren Programmen gar nicht klar kommt. Und ich will keine Programme verteilen, die ich selbst nicht ausprobieren kann.

Was mich ein bißchen nervt, ist daß kaum etwas zurückkomt, was die Entwicklung von Libnodave voranbringt (es gibt einige wenige rühmliche Ausnahmen).
Andererseits erhalte ich häufig Anfragen (ich meine jetzt nicht deine), wo ich denke, ich muß das ABC des Programmierens erklären. Jemand auf dem Level vieler Fragesteller käme sicher auch mit keinem kommerziellen Produkt zurecht.
Dann geht mir durch den Kopf, daß so einer sowas wohl auch nicht kaufen würde, weil ihm das durchaus klar ist. Aber weil Libnodave nichts kostet, lädt es Hans und Franz zum Probieren runter und fragt dann, wie sein Compiler funktioniert oder so was.
 
Zurück
Oben