# Libnodave und Visual Basic 2008



## Hocheck (31 März 2010)

Hallo Helfer,

Ich verwende das VB Beispielprogramm für VBA von Libnodave.
Nachdem das in Excel bei mir alles Funktioniert hat, möchte ich gerne Libnodave in Verbindung mit VB 2008 Express probieren.

Ich erstelle ein neues win Projekt und füge ganz stupide den Quelltext des VBA Beispiels in die Form1.vb ein. Start des BeispielCodes:

PublicClass Form1
'
' Part of Libnodave, a free communication libray for Siemens S7 200/300/400 via
' the MPI adapter 6ES7 972-0CA22-0XAC


Das ist nun natürlich bestimmt besonders blöde... Ist ja VBA Code... Aber ich kriege es nicht selbst geändert... Ich kann die Cells ja durch Textboxes ersetzen usw. Aber bei den Variablen mit $ hört es bei mir schon auf, da ich nicht weis, was alles benötigt wird...

Kann mir bitte jemand erklären was ich genau aus dem Beispiel weglassen kann und ändern muss, damit ich da mit Visual Basic 2008 eine Verbindung bekomme...

Könnte mir vielleicht sogar jemand ein VB-Projekt hochladen, das irgendetwas ausführt, damit ich lernen kann? 

*EDIT Aufgabenstellung konkret:*

Beispiel:

Datenbaustein 1

Nr Name Typ Wert
0 Test1 Int 33
2 Test2 Byte 34
3 Test3 DINT 5433

Datenbaustein 2

Nr Name Typ Wert
0 Test1 Byte 445
1 Test2 Byte 34
2 Test3 DINT 5433

Nun soll mit dem gewünschten VB Programm der Inhalt der Datenbausteine geladen, geändert, gespeichert und zurückgeladen werden können.
Es könnten noch weitere Datenbausteine vorhanden sein mit unterschiedlicher Struktur.
Die Struktur der DBs ist vorher bekannt. Jedoch sollte das VB-Programm nicht mehr geändert werden.

Welche Möglichkeiten gibt es so etwas zu realisieren?


----------



## Earny (31 März 2010)

Hallo Hocheck,

ich setze LibNoDave zusammen mit VB2005 ein. Der Code dürfte aber mit VB2008 Express auch funktionieren. Ich setze nicht den Wrapper (libnodave.net.dll) ein, der hier im Forum beim Einsatz von LibNoDave zusammen mit .Net empfohlen wird.

An dem alten Modul12.bas, der für Excel und VB6.0 gedacht ist, musst Du einige kleinere Änderungen vornehmen. Die wesentliche Änderung ist die Umstellung vom Datentyp Long (VB6.0) auf Integer (VB.Net), da der alte 32-Bit-Ganzzahldatentyp Long bei VB.Net "Integer" heißt.

Für den MPI2-Verbindungsauf- und -abbau setze ich folgende Anweisungen ein:

Globale Variablen:
Dim ph As Integer 'Informationen zum Kommunikationskanal
Dim di As Integer 'Informationen zum Interface
Dim dc As Integer 'Informationen zur CPU
Dim res As Integer = 0

Verbindungsaufbau:

```
[COLOR=blue][FONT=Verdana]Dim[/FONT][/COLOR][COLOR=black][FONT=Verdana] baud [/FONT][/COLOR][COLOR=blue][FONT=Verdana]As[/FONT][/COLOR][COLOR=blue][FONT=Verdana]String[/FONT][/COLOR][COLOR=black][FONT=Verdana], port [/FONT][/COLOR][COLOR=blue][FONT=Verdana]As[/FONT][/COLOR][COLOR=blue][FONT=Verdana]String[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]Dim[/FONT][/COLOR][COLOR=black][FONT=Verdana] Rack [/FONT][/COLOR][COLOR=blue][FONT=Verdana]As[/FONT][/COLOR][COLOR=blue][FONT=Verdana]String[/FONT][/COLOR][COLOR=black][FONT=Verdana], Slot [/FONT][/COLOR][COLOR=blue][FONT=Verdana]As[/FONT][/COLOR][COLOR=blue][FONT=Verdana]String[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]port = cbxCOM.Text[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]baud = cbxSpeed.Text[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]ph = setPort(port, baud, Asc([/FONT][/COLOR][COLOR=maroon][FONT=Verdana]"O"[/FONT][/COLOR][COLOR=black][FONT=Verdana]))[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]If[/FONT][/COLOR][COLOR=black][FONT=Verdana] (ph > 0) [/FONT][/COLOR][COLOR=blue][FONT=Verdana]Then[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]di = daveNewInterface(ph, ph, [/FONT][/COLOR][COLOR=maroon][FONT=Verdana]"IF1"[/FONT][/COLOR][COLOR=black][FONT=Verdana], 0, daveProtoMPI2, daveSpeed187k)[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]Call[/FONT][/COLOR][COLOR=black][FONT=Verdana] daveSetTimeout(di, 1000000)[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]res = daveInitAdapter(di)[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]If[/FONT][/COLOR][COLOR=black][FONT=Verdana] res = 0 [/FONT][/COLOR][COLOR=blue][FONT=Verdana]Then[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]Rack = 0[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]Slot = 0[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]dc = daveNewConnection(di, 2, Rack, Slot)[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]res = daveConnectPLC(dc)[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]End[/FONT][/COLOR][COLOR=blue][FONT=Verdana]If[/FONT][/COLOR]
```
 
Verbindungsabbau:

```
[COLOR=blue][FONT=Verdana]If[/FONT][/COLOR][COLOR=black][FONT=Verdana] dc <> 0 [/FONT][/COLOR][COLOR=blue][FONT=Verdana]Then[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]res = daveDisconnectPLC(dc)[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]Call[/FONT][/COLOR][COLOR=black][FONT=Verdana] daveFree(dc)[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]dc = 0[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]End[/FONT][/COLOR][COLOR=blue][FONT=Verdana]If[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]If[/FONT][/COLOR][COLOR=black][FONT=Verdana] di <> 0 [/FONT][/COLOR][COLOR=blue][FONT=Verdana]Then[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]res = daveDisconnectAdapter(di)[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]Call[/FONT][/COLOR][COLOR=black][FONT=Verdana] daveFree(di)[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]di = 0[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]End[/FONT][/COLOR][COLOR=blue][FONT=Verdana]If[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]If[/FONT][/COLOR][COLOR=black][FONT=Verdana] ph <> 0 [/FONT][/COLOR][COLOR=blue][FONT=Verdana]Then[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]res = closePort(ph)[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]ph = 0[/FONT][/COLOR]
[COLOR=blue][FONT=Verdana]End[/FONT][/COLOR][COLOR=blue][FONT=Verdana]If[/FONT][/COLOR]
```
 

Gruß
Earny


----------



## Hocheck (31 März 2010)

Hallo Earny, 

Vielen Dank für deine ausführliche Hilfe!
Durch stöbern im Forum bin ich auf folgendem Beitrag von dir aufmerksam geworden: http://www.sps-forum.de/showthread.php?t=24391

Du hast in diesem Beitrag ein VB-Projekt zur Verfügung gestellt. Erstmal große Klasse von dir, dass du das offen legst! Ich habe mir dies mal angeschaut und das beeinhaltet doch genau das was ich benötige, oder?

Ich möchte gerne dein Programm mal mit einer CPU 315 2 PN/DP über Ethernet TCP/IP (crossoverkabel) mit meinem PC laufen lassen. Das ist doch möglich? Einfach die IP der CPU im VB-Programm eintragen, oder?

Habe nur leider wegen des Studiums nicht immer die Möglichkeit eine "freie" SPS zu ergattern...

Solltest du die Zeit für mich haben, so habe ich da eine weitere Sache, die mir Probleme bereitet:

Programmverwaltung

Ich möchte gerne in einem VB-Prog. wie deinem es ermöglichen über ein Formular anzugeben, welchen Datenbaustein und welchen Bereich (also wie eine Art Any-Pointer) geladen/gespeichert werden soll. Die aus dem DB geladenen Daten (INT;DINT;REAL alle unterschiedlich angeordnet) sollten angezeigt und auf dem PC gespeichert werden können (Excel vielleicht?!). Ziel ist es also ein Abbild eines DBs auf dem PC zu schaffen, das frei editierbar ist. Nach einer Änderung der Daten sollten diese wieder in den DB zurückgeladen werden können. 

Nach meiner Recherche bisher ist das obige so wohl nicht umsetzbar, wenn INT, DINT Und REAL Daten "bunt" gemischt sind oder?

Falls das nicht geht würde ich gerne eine Möglichkeit schaffen mir einen "Datenbaustein" als Formular im VB-Programm zu generieren und anschließend nach dieser Struktur die Daten mit Libnodave zu laden und zu verwalten. 

Was hältst du davon? Ist das überhaupt möglich? Ist so etwas für einen Newbe wie mich umzusetzen? Ich habe die Motivation dazu, mir fehlt leider nur jemand der mir Hilfestellung geben kann


----------



## vladi (31 März 2010)

*VB und SPS*

Hallo Kollege,

die Funktionalität um Daten zu Lesen bzw. schreiben hast du ja mit LibNoDave, umsonst. 
Das ganze drum herum in VB zu machen(dein Vorhaben) muss man sich überlegen und programmieren, aber so zum Spass ist das nicht. 
Vor allem die ganze Dynamik..hm.

Und du möchtest doch sicher nicht deinem Prof. Sachen zeigen, die andere
Leute entwickelt haben.. 

Gruss: V.


----------



## Hocheck (31 März 2010)

Hallo Kollege, 

du hast recht, im Nachhinein betrachtet war die Aussage ziemlich blöde
Ich will ja was damit lernen und nicht irgendwo gut darstehen...

Dennoch wäre ich um jede Hilfe, egal in welcher Form dankbar



> die Funktionalität um Daten zu Lesen bzw. schreiben hast du ja mit  LibNoDave, umsonst.
> Das ganze drum herum in VB zu machen(dein Vorhaben) muss man sich  überlegen und programmieren, aber so zum Spass ist das nicht.
> Vor allem die ganze Dynamik..hm.



Ja das mit VB beschäftigt mich schon ziemlich lange, damit ich das Ziel erreichen kann.. Denke ständig dran, wie es am besten gehen könnte 

hätte da schon einen Vorschlag...


----------



## vladi (31 März 2010)

*Vb*

Hi,
ja, ok.



> Ich möchte gerne in einem VB-Prog. wie deinem es ermöglichen über ein Formular anzugeben, welchen Datenbaustein und welchen Bereich (also wie eine Art Any-Pointer) geladen/gespeichert werden soll. Die aus dem DB geladenen Daten (INT;DINT;REAL alle unterschiedlich angeordnet) sollten angezeigt und auf dem PC gespeichert werden können (Excel vielleicht?!)



Möchtest du etwa, man sagt in deiner Anwendung: hole die Daten
aus dem DBxyz(gemischte Typen), 200 Bytes, und dann sollen die Daten richtig dargestellt werden, je nach Typ? Ohne zu wissen, wie der DB wirklich aufgebaut ist? Das glaube ich nicht wirklich..


Vladi


----------



## Hocheck (31 März 2010)

Ich komme nicht klar, weil ich keinen Ansatz finde...
Ich brauche einfach Hilfe dabei

Das Problem:
Die Daten können bunt gemixt sein 1. INT, 2.DINT, 3.Real, 4.Byte...usw Wie der Datenbaustein aufgebaut ist- das zu wissen setze ich nun voraus. Trotzdem weis das ja mein VB-Programm nicht- ich weis es wie die DBs dann aussehen, aber wie bringe ich das meinem Programm bei?

Wenn nun die Daten in VB geladen, bearbeitet und zurückgeladen werden sollen weis ich folgendes nicht:
1. Woher weis ich vorher welchen Datentyp ich lade, wenn mir Funktionen wie:
daveGetU8
daveGetU16
daveGetU32
...
zur Verfügung stehen. Ohne vorher in VB eine Struktur zu hinterlegen wie das Programm aussieht soll kann ich das doch garnicht oder?!

Ich komme einfach nicht weiter....


Vorschlag zur Umsetzung:

Als Form dient das Bild im Anhang.

Beschreibung der Funktion:

Nach der Eingabe der DB NR und der Anzahl der Dateien (hier: 3) wird über die Generieren Taste ein Abbild eines Datenbausteins erstellt. Diese Daten bilden den Programmkopf.
Nach dem Drücken der Generieren Taste werden (hier:3) Daten angezeigt und können parametriert werden. Durch Drücken der Taste "Aus SPS Laden" werden die Daten aus dem DB in die Textfelder "Wert" gefüllt.
Zusätzlich wird die Länge des Datenblocks ermittelt und ergibt die Variable: Summe.

So stelle ich mir vor dass der Ladegang funktionieren könnte...

Aber ich kann den Code nicht umsetzen:shock:


----------



## Hocheck (31 März 2010)

Hallo vladi,


```
Möchtest du etwa, man sagt in deiner Anwendung: hole die Daten
aus dem DBxyz(gemischte Typen), 200 Bytes, und dann sollen die Daten richtig dargestellt werden, je nach Typ? Ohne zu wissen, wie der DB wirklich aufgebaut ist? Das glaube ich nicht wirklich..
```
 
Ja im Grunde möchte ich genau das, bis auf der Ausnahme, dass ich weis wie der Datenbaustein aussieht, also welche Daten und Struktur er hat.

Nur genau das möchte ich nicht Fest und Statisch a la:
daveGetU16
daveGetU32
machen, sondern so dass ich im VB Programm festlegen kann wie der DB aussieht und demnach Daten lade, darstelle und speichern kann...

Ich hoffe du verstehst was ich meine..


Beispiel:

Datenbaustein 1

Nr    Name       Typ     Wert
0      Test1      Int       33
2      Test2      Byte     34
3      Test3      DINT    5433

Datenbaustein 2

Nr    Name       Typ     Wert
0      Test1      Byte     445
1      Test2      Byte     34
2      Test3      DINT    5433

Nun soll mit dem gewünschten VB Programm der Inhalt der Datenbausteine geladen, geändert, gespeichert und zurückgeladen werden können.
Es könnten noch weitere Datenbausteine vorhanden sein mit unterschiedlicher Struktur.
Die Struktur der DBs ist vorher bekannt. Jedoch sollte das VB-Programm nicht mehr geändert werden.
Wie können die Daten mit Libnodave geladen und auch geändert werden?


----------



## vladi (31 März 2010)

*Vb*

Hi,
ich kann dir schon eine Idee geben:

In VB hast du eine Form, links ist ein TreeView Baum mit ein paar Felder, so:
-DB Typen
--- Byte
--- Integer
--- DINT
--- Real
--- Bool
Rechts eine freie Fläche, wo man in einem neuen TreeView Baum sich Elemente per DragUndDrop von links ziehen kann, z.B.:
-DB Vorlage
---Integer
---Integer
---Real
---Real    usw.
so kann man sich die DB Struktur schnel zusammenbauen, die dann noch mit einer Nummer abspeichrebar, für später evtl.,  und je nach den Einträge in diesem Container holt das Programm die Daten aus der SPS. Die Darstellung erfolgt auch dynamisch, je nach dem, was man eingegeben hat..

So in der Art wäre eine gute Sache. Leicht zu programmieren ist es nicht, aber auch nicht sooo schwer, wenn man die entspr. VB Elemente kennt.
Im Internet gibt es sehr viele VB Beispiele, Foren usw.

Vladi


----------



## Hocheck (31 März 2010)

Vielen vielen Dank Vladi für den Tipp

Ich werde mir das mal anschauen und mich da einarbeiten!

Ich hoffe du wirst mir weiter helfen, falls ich wieder einmal nicht weiter komme!!

Ich melde mich sofort, sobald ich ein Ergebnis erziehlt habe...


----------



## vladi (31 März 2010)

*-*

Hi,

klar, nur muss ich leider morgen verreisen, für die nächsten 10 Jahre, wünsche dir viel Spass..


Vladi



(war nur a witz..)


----------



## Ralle (31 März 2010)

Ich hab das in einem Delphi-Programm ähnlich gemacht. Die Daten werden einfach als Bytearray aus der SPS gelesen. Im Delphi-Programm hinterlege ich die Struktur, mit deren Hilfe ich dann die Daten aus dem Array of Byte heraushole und entsprechend zusammenbaue.


----------



## Earny (31 März 2010)

Ich habe mich dazu entschlossen, diesmal kein VB-Projekt, sondern meine Beschreibung von LibNoDave für den Einsatz mit VB.Net hier im Forum einzustellen. 

Ich möchte darauf hinweisen, dass ich ohne die libnodave.net.dll arbeite.

Sämtliche Konstanten, Prozeduren und Funktionen habe ich deshalb in einen Modul gepackt und ihm den Namen LibnodaveModul.vb gegeben. Der Modul muss, wie in der Beschreibung zu sehen, in die VB-Projektverwaltung aufgenommen werden. Im Modul habe ich gegenüber dem Original einige Änderungen vorgenommen. Die Deklaration von Long-Variablen wurde durch Integer-Variablen ersetzt. Gelegentlich musste beim letzten Argument einer Funktion oder Prozedur die Parameterkennzeichnung von ByVal (Wert-Parameter) auf ByRef (Zeiger-Parameter) gestellt werden. 

Puritaner der .Net-Programmierung mögen es mir verzeihen, dass ich hier den sauberen Weg der objektorientierten Programmierung verlassen habe und einen Modul einsetze (VB6.0 lässt grüßen). Da alle Konstanten, Prozeduren und Funktionen mit Public deklariert wurden, kann ohne Einschränkungen darauf zugegriffen werden. Natürlich funktioniert dann kein Intellisence. Das ist aber kein Nachteil, weil die Konstanten und Methoden aussagekräftige Namen (dave...) tragen.
Ein Vorteil beim Modul-Einsatz ist auch, dass sich kurze Ausdrücke ergeben und solche Zusätze wie libnodave, dc, usw. entfallen können. 

Nicht unerwähnt bleiben darf die Tatsache, dass die ursprüngliche Fassung dieser Beschreibung von Andreas138 verfasst wurde, was damals (Frühjahr 2009) eine tolle Leistung war. Im SPS-Forum hat sich Andreas leider etwas rar gemacht. 

An die Experten dieses Forums hätte ich die Bitte, die Beschreibung kritisch zu durchforsten und mir etwaige Fehler mitzuteilen.

Ich mache gerade noch die Feststellung, dass mein LibnodaveModul.vb nicht hochgeladen werden kann. Ich ändere deshalb die Endung von vb in txt. Ich hoffe, dass es keinen Ärger gibt und funktioniert. Selbstverständlich muss die Endung wieder auf vb umgestellt werden, bevor der Modul eingesetzt werden kann.


Gruß
Earny


----------



## Hocheck (1 April 2010)

Der Schock saß tief bis das ich folgendes lesen konnte



> (war nur a witz..:smile


 
Zum Stand:

Habe durch ändern eines Beispiel Projekts mir diese Sache mit Drag&Drop erstellen können. Projekt Siehe Anhang

So muss mal schlafen

Und vielen Dank für all die Hilfe die man bekommt!

Ich werde alles Offen legen und Hochladen, sobald das Programm fertig ist und funktioniert!

*EDIT:*

Die DragDrop funktioniert nun und habe eine Möglichkeit gefunden diese Struktur dann zu verwenden. Mal schauen wann es funktioniert...


----------



## Hocheck (1 April 2010)

@ Earny

Super Vielen Dank!!!:TOOL:


----------



## Earny (14 April 2010)

Hallo Hocheck,

die Beschreibung, die ich oben eingestellt habe, war für VB2005 bestimmt.

Wenn Du unter Excel programmierst, musst Du da was ändern:
Die Deklaration der daveGetOrderCode-Funktion lautet:

```
Private Declare Function daveGetOrderCode Lib "libnodave.dll" (ByVal en As Long, ByRef buffer As Byte) As Long
```
 
Hinweis: Der Datentyp "Long" von Excel (und VB6.0) ist ein 32-Bit-Integer.
Würdest Du die gleiche Funktion bei VB2005 einsetzen müsstest Du "Long" durch "Integer" ersetzen, weil der 32-Bit-Integer-Datentyp von VB2005 "Integer" heißt.

Ich habe hier noch ein Excel-Beispiel angehängt. Bei diesem Beispiel werden 5 verschiedene Ganzzahlen bei Mausklick in einen Datenbaustein DB1 geschrieben. Du kannst die Werte dann zu Kontrollzwecken auch wieder lesen und in die Excel-Mappe schreiben.
Dieses Beispiel ist an ein Beispiel angelehnt, dass vierlagig mal hier im Forum eingestellt hat.
Die Excel-Mappe enthält auch den Modul12, in dem alle Libnodave-Funktion, 
-Prozeduren und -Konstante aufgeführt sind. Der eigentliche Programmcode, mit den tatsächlich benötigten Funktionen, .... ist dem Tabellenblatt1 zugeordnet.

Vorgehensweise:
Du lädst zuerst die S7-Bausteine in die ACCONtrol-CPU. Dann öffnest Du die Excel-Mappe und musst dabei natürlich die "Makros aktivieren". Wenn Du dann auf die Buttons klickst, kannst Du beobachten, wie Werte in die ACCONtrol-CPU geschrieben und auch wieder aus der CPU gelesen werden. 
In dem Word-Dokument stehen noch ein paar Tips, die Du auch beachten solltest.

Gruß
Earny


----------



## Hocheck (15 April 2010)

Hallo Earny, 

Vielen Dank für die Beschreibung und Daten!

 Ich glaube da lag ein kleines Missverständnis meinerseits vor, da ich eine klare Aussage, dass ich VB 2008 nehme, vergessen habe. Ich habe die Verbindung und die Funktionen mit Excel hinbekommen. Konnte u.a auch SZL usw. erhalten.

Meine Frage war, wie ich die S7-Nummer in Visual Basic 2005 bzw. 2008 auslesen kann- daher kam auch das Programmbeispiel:

PrivateConst daveOrderCodeSize = 21
PrivateDeclareFunction daveGetOrderCode Lib"libnodave.dll" (ByVal en AsInteger, ByRef buf AsByte) AsInteger

Dim buf(50) AsByte
Dim en AsInteger
Dim res2 AsInteger
Dim oc AsChar
dc = New libnodave.daveConnection(di, plcMPI, 0, 2)
res = daveGetOrderCode(dc, buf(0))
For i AsInteger = 0 To daveOrderCodeSize - 2 
oc = oc + Chr(buf(i))
Next i
lblSeriennummer1.Text = oc

Es erscheint eine Fehlermeldung, dass dc in
res = daveGetOrderCode(dc, buf(0))
nicht in integer konvertiert werden kann.


----------



## Earny (15 April 2010)

ich fürchte, da muss ich passen.
Die Funktion "daveGetOrderCode" habe ich noch nicht eingesetzt.
Woraus hast Du abgeleitet, dass Du für "en" (erstes Argument der Funktion) den Wert von "dc" einsetzen kannst?


Gruß
Earny


----------



## Hocheck (16 April 2010)

Hallo Earny,

Also eigentlich habe ich mir nur das Excel Beispiel von Libnodave angeschaut und versucht dieses so zu editieren, dass es in dem Beispiel von dir laufen könnte, aber das funktioniert so wohl nicht...

Hier die Vorlage:

   [FONT=&quot]Private Declare Function daveGetOrderCode Lib "libnodave.dll" (ByVal en As Long, ByRef buffer As Byte) As Long[/FONT]


    [FONT=&quot]'[/FONT]
  [FONT=&quot]Private Function initialize(ByRef ph As Long, ByRef di As Long, ByRef dc As Long)[/FONT]
  [FONT=&quot]ph = 0[/FONT]
  [FONT=&quot]di = 0[/FONT]
  [FONT=&quot]dc = 0[/FONT]
  [FONT=&quot]rem uncomment the daveSetDebug... line, save your sheet[/FONT]
  [FONT=&quot]rem run excel from dos box with: excel yoursheet >debugout.txt[/FONT]
  [FONT=&quot]rem send me the file debugout.txt if you have trouble.[/FONT]
  [FONT=&quot]rem call daveSetDebug(daveDebugAll)[/FONT]
  [FONT=&quot]initialize = -1[/FONT]
  [FONT=&quot]baud$ = Cells(3, 5)[/FONT]
  [FONT=&quot]If (baud$ = "") Then Call initTable[/FONT]
  [FONT=&quot]Cells(12, 2) = "Running"[/FONT]
  [FONT=&quot]res = -1[/FONT]
  [FONT=&quot]port = Cells(2, 5)[/FONT]
  [FONT=&quot]baud$ = Cells(3, 5)[/FONT]
  [FONT=&quot]parity$ = Cells(4, 5)[/FONT]
  [FONT=&quot]peer$ = Cells(7, 5)[/FONT]
  [FONT=&quot]acspnt$ = Cells(8, 5)[/FONT]
  [FONT=&quot]ph = setPort(port, baud$, Asc(Left$(parity$, 1)))[/FONT]
  [FONT=&quot]' Alternatives:[/FONT]
  [FONT=&quot]Rem ph = openSocket(102, peer$)    ' for ISO over TCP[/FONT]
  [FONT=&quot]Rem ph = openSocket(1099, peer$)' for IBH NetLink[/FONT]
  [FONT=&quot]Rem ph = openS7online(acspnt$) ' to use Siemes libraries for transport (s7online)[/FONT]
  [FONT=&quot]Cells(2, 1) = "port handle:"[/FONT]
  [FONT=&quot]Cells(2, 2) = ph[/FONT]
  [FONT=&quot]If (ph > 0) Then[/FONT]
  [FONT=&quot]    di = daveNewInterface(ph, ph, "IF1", 0, daveProtoMPI, daveSpeed187k)[/FONT]
  [FONT=&quot]' Alternatives:[/FONT]
  [FONT=&quot]'di = daveNewInterface(ph, ph, "IF1", 0, daveProtoPPI, daveSpeed187k)[/FONT]
  [FONT=&quot]'di = daveNewInterface(ph, ph, "IF1", 0, daveProtoMPI_IBH, daveSpeed187k)[/FONT]
  [FONT=&quot]'di = daveNewInterface(ph, ph, "IF1", 0, daveProtoISOTCP, daveSpeed187k)[/FONT]
  [FONT=&quot]'di = daveNewInterface(ph, ph, "IF1", 0, daveProtoS7online, daveSpeed187k)[/FONT]
  [FONT=&quot]'[/FONT]
  [FONT=&quot]'You can set longer timeout here, if you have  a slow connection[/FONT]
  [FONT=&quot]'    Call daveSetTimeout(di, 500000)[/FONT]
  [FONT=&quot]    res = daveInitAdapter(di)[/FONT]
  [FONT=&quot]    Cells(3, 1) = "result from initAdapter:"[/FONT]
  [FONT=&quot]    Cells(3, 2) = res[/FONT]
  [FONT=&quot]    If res = 0 Then[/FONT]
  [FONT=&quot]        MpiPpi = Cells(6, 5)[/FONT]
  [FONT=&quot]'[/FONT]
  [FONT=&quot]' with ISO over TCP, set correct values for rack and slot of the CPU[/FONT]
  [FONT=&quot]'[/FONT]
  [FONT=&quot]        dc = daveNewConnection(di, MpiPpi, Rack, Slot)[/FONT]
  [FONT=&quot]        res = daveConnectPLC(dc)[/FONT]
  [FONT=&quot]        Cells(4, 1) = "result from connectPLC:"[/FONT]
  [FONT=&quot]        Cells(4, 2) = res[/FONT]
  [FONT=&quot]        If res = 0 Then[/FONT]
  [FONT=&quot]            initialize = 0[/FONT]
  [FONT=&quot]        End If[/FONT]
  [FONT=&quot]    End If[/FONT]
  [FONT=&quot]End If[/FONT]
  [FONT=&quot]End Function[/FONT]

[FONT=&quot][/FONT]
      [FONT=&quot]Sub readOrderCode()[/FONT]
  [FONT=&quot]Cells(1, 2) = "Testing read Order code"[/FONT]
  [FONT=&quot]Dim ph As Long, di As Long, dc As Long[/FONT]
  [FONT=&quot]Dim buffer(50) As Byte[/FONT]
  [FONT=&quot]res = initialize(ph, di, dc)[/FONT]
  [FONT=&quot]If res = 0 Then[/FONT]
  [FONT=&quot]    res2 = daveGetOrderCode(dc, buffer(0))[/FONT]
  [FONT=&quot]    Cells(14, 2) = res2[/FONT]
  [FONT=&quot]    If res2 = 0 Then[/FONT]
  [FONT=&quot]        For i = 0 To daveOrderCodeSize - 2 'last character is chr$(0), don't copy it[/FONT]
  [FONT=&quot]            oc$ = oc$ + Chr$(buffer(i))[/FONT]
  [FONT=&quot]        Next i[/FONT]
  [FONT=&quot]        Cells(14, 3) = oc$[/FONT]
  [FONT=&quot]    Else[/FONT]
  [FONT=&quot]        e$ = daveStrError(res)[/FONT]
  [FONT=&quot]        Cells(9, 4) = "error:"[/FONT]
  [FONT=&quot]        Cells(9, 5) = e$[/FONT]
  [FONT=&quot]    End If[/FONT]
  [FONT=&quot]End If[/FONT]
  [FONT=&quot]Call cleanUp(ph, di, dc)[/FONT]
  [FONT=&quot]End Sub[/FONT]


----------



## Earny (16 April 2010)

Du musst die Deklaration ändern. Anstelle von:

Dim oc as char

muss es

Dim oc as String

lauten.


```
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Private[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] btnSeriennummer_Click([/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] sender [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] System.Object, _[/SIZE]
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] e [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] System.EventArgs) [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Handles[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] btnSeriennummer.Click[/SIZE]
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] buf(50) [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Byte[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] oc [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]String[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] res2 [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Integer[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] res = 0 [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]And[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] livebit = [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]True[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=3]txtDC1.Text = dc[/SIZE]
[SIZE=3]res2 = daveGetOrderCode(dc, buf(0))[/SIZE]
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] i [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Integer[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] = 0 [/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]To[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] daveOrderCodeSize - 2[/SIZE]
[SIZE=3]oc = oc + Chr(buf(i))[/SIZE]
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Next[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3] i[/SIZE]
[SIZE=3]txtSeriennummer.Text = oc[/SIZE]
[SIZE=3]txtDC2.Text = dc[/SIZE]
[SIZE=3]txtRes2.Text = res2[/SIZE]
[SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=3][COLOR=#0000ff][SIZE=3][COLOR=#0000ff]Sub[/COLOR][/SIZE]
[/COLOR][/SIZE]
```
 

Gruß
Earny


----------



## Jochen Kühner (16 April 2010)

*DB Struktur....*

Warum die DB Struktur im VB Programm definieren und nicht von der SPS laden?
Die Grundlegenden Datentypen des DBs sind doch auch in der S7 gespeichert.


----------



## Hocheck (20 April 2010)

Hmm also das mit der Seriennummer klappt Aufgrund der dc Variable nicht...

Siehe Screenshot


----------



## Earny (20 April 2010)

habe Dir das VB-Programm mit dem zugehörigen S7-Programm angehängt.

Der Fehler, den Du beobachtest, dürfte aus dem Umstand resultieren, dass Du den Wrapper (libnodave.net.dll) verwendest. Hierbei wird ein anderer Verbindungsauf- und Abbau gemacht und "dc" mit keinem Wert versorgt.

Ich benutze, wie ich schon gesagt habe, einen Modul, auch wenn das nicht ganz .Net-konform ist. Es gibt bei mir nicht den Wrapper und deshalb auch keinen Verweis auf den Wrapper! 

"Mein" LibnodaveModul.vb (der den Wrapper ersetzt) wurde aus dem alten Modul12 für Excel und VB6.0 abgeleitet, in dem ich den alten Typ "Long" durch "Integer" ersetzt habe. Im Modul stehen alle Libnodave-Konstanten, -prozeduren und -funktionen. Sie sind mit "Public" deklariert und deshalb im gesamten VB-Projekt bekannt!

Das VB-Programm ermöglicht die Verbindung zu Accontrol. In diesem Fall musst Du die IP-Adresse 127.0.0.1 auswählen. Die IP-Adressen 192.168.53.51, .52 und .53 sind für die Kommunikation mit MPI-LAN-Kabel bestimmt. 

Das MPI2-Protokoll funktioniert mit den alten Siemens-PC-Adaptern mit 19200 und 38400 Bit/s und ermöglicht eine Kommunikation über die serielle Schnittstelle eines Rechners.

Wenn Du die "Daten" in eine Excel-Mappe schreiben willst, dann muss eine Excel-Mappe im Defaultordner des VB-Projekts liegen (in diesem Ordner sucht CurDir). Falls Du nicht mit CurDir arbeiten willst, kannst Du auch den absoluten Pfad angeben.
Die Startroutinen für Excel entsprechen nicht den strengen .Net-Vorgaben. Ich habe bisher noch keinen Weg gefunden, auf die Zellen (cells) mit der frühen Bindung zuzugreifen. Die "Methode", die ich hier zeige, stammt aus der MSDN-Hilfe für VB6.0 und funktioniert auch mit VB2005 Prof. Dabei habe ich leichte Änderungen vorgenommen.

Mein VB-Programmm kann die Seriennummer der CPU bestimmen, INT-, DINT- und REAL-Variablen lesen, Bits in Datenbausteine schreiben und daraus lesen und auch 1000 Integerwerte in einen DB schreiben und wieder lesen.

Das S7-Programm hat nur die Aufgabe, den M90.0 zyklisch auf "1" zu setzen. Der M90.0 ist das "livebit", dass ich in meinem VB-Programm zur Überprüfung der Verbindung abfrage und dann wieder auf 0 setze. Im S7-Programm sind noch ein paar DBs zu Testzwecken eingefügt.

Außerdem habe ich hier nochmal mein Beschreibung angehängt.

Viel Spaß beim Testen.

Gruß
Earny


----------



## Hocheck (6 Mai 2010)

Hallo Earny,

Konnte heute endlich wieder ein Zeitfenster finden um im Labor zu testen. Nun funktioniert es einwandfrei und die Siemens Nummer kann ausgelesen werden und die anderen Libnodave Befehle sind auch verfügbar

Danke!!


----------



## AxelArnoldBangert (19 Dezember 2010)

*Hi Earny,*
zunächst einmal Kompliment zu dem prima Tutorial. Ich bin völliger S7 Anfänger (völlig unbeleckt) und bastele an einer SAP <-> S7 Verbindung.

Also - ich habe Accontrol installiert - und habe in die Accontrol dein S7 Programm geladen und die libnodave.dll in system32 eingefügt.





Ich habe unter Extras -> CPU Konfiguration -> CPU Kopplung -> die 127.0.0.1 eingetragen.
Danach habe ich die Excel gestartet und zunächst alle Makros aktiviert etc.
Wenn ich die Buttons anklicke tut sich aber nichts. Es gibt auch keine Fehlermeldung. Ich habe in Excel für das 
eine MsgBox in Initialize () ausgegeben, die einen Verbindungsfehler (ph = 0)  meldet. Dieser Verbindungsfehler bestätigt sich
auch mit dem TestTool von  libnodave -> testISO_TCP.exe.




Wo liegt mein Konfigurationsfehler?
Liebe Grüße*
SB- Herzogenrath 2010*


----------



## Earny (20 Dezember 2010)

Hallo Axel,

wo Dein Verbindungsfehler liegt, dürfte schwer herauszufinden sein.

Ich habe Dir mal ein LibNoDave-Projekt für Excel2007 angefügt. In der Voreinstellung ist das VB2005-Projekt für die Kommunikation mit ACCONTrol eingestellt. Das zugehörige S7-Programm ist auch dabei.

In ACCONtrol habel ich noch nie irgendwelche Einstellungen vorgenommen.
Evtl. musst Du aber noch den IEPG-Help-Service abschalten - ein bekanntes Problem von ACCONtrol, an dem Siemens "schuld" sein soll. 

Die Beschreibung passt nicht 100%-ig zur Excel-Mappe. In meiner Excel-Mappe ist der Programmcode nicht einer Tabelle, sondern einem Formular zugeordnet. Das Formular wird durch Klick auf den Button in der Tabelle gestartet.

Nach dem Öffnen der Excel-Mappe müssen erst noch die Makros aktiviert werden. Ohne diese Einstellung bleibt der Klick auf den Button wirkungslos.

Achtung: Da die ursprüngliche Excel-Mappe wegen der Endung "xls" nicht angehängt werden konnte, habe ich die Endung auf "rar" gestellt. Vor dem Öffnen mit Excel muss deshalb die Endung wieder auf "xls" gestellt werden!!! 

Gruß
Earny


----------



## AxelArnoldBangert (22 Dezember 2010)

*Hi Earny,*
also zunächst vielen herzlichen Dank für die Antwort. Das Problem wurde unter Server 2003 R2 SP2 durch libnodave verursacht und nicht durch ACcontrol. 

Unter Win XP SP3 funktioniert alles einwandfrei. Da ich aber eine SAP<-> ACcontrol Verbindung zunächst auf dem gleichen Rechner simulieren wollte, 
musste ich Win Server 2003 benutzen. 

Dort (Server 2003) funktionieren nur normale .net-Socketverbindungen aber keine libnodave Sockets.  

Wie der Entwickler von libnoadave - Thomas Hergenhahn - mitteilte, liegt dies an .net 4.0 Sicherheitsmechanismen, die den Aufruf von win32 Sockets,  
die aus der .net.libnodave.dll -> über die libnodave.dll aufgerufen werden, unterbinden.

Ich habe übrigens eine ganz tolle Sache gefunden, die ich mir jetzt genauer ansehen werde und zwar das Mitsubishi  MES-IT Interface Modul für SAP®-Systeme.

Liebe Grüße
*Axel Arnold Bangert - Herzogenrath 2010*


----------



## Earny (22 Dezember 2010)

Hallo Axel,

von Win Server 2003 u.a. sowie SAP habe ich keinen blassen Dunst.
In unserem "Betrieb" mit ca. 200 Rechnern, die unter irgendeinem Win Server laufen, konnten wir, das war wohl im Jahr 2007, keine VB-Projekte in der Entwicklungsumgebung im Debug-Modus betreiben, weil immer eine Fehlermeldung kam: "Projektspeicherort ist nicht vertrauenswürdig". Unser Admin war natürlich geknickt und wusste nicht, was zu tun war.
Im .Net-Forum habe ich dann eine Abhilfe gefunden (Anlage). Vielleicht kommt etwas in dieser Art auch für Dich in frage. 


Gruß
Earny


----------

