# Messwerte aus Excel Tabelle in S7-300 einlesen



## yone (22 Oktober 2013)

Hey,
ich wuerde gerne Messwerte aus einer Exceltabelle einlesen und ueber meine S7-300 an meinen Antrieb uebermitteln. Hab von der software libnodave gelesen, allerdings blicke ich da noch nicht so wirklich durch. Gibt es da Einstiegsinformationen, um mein Problem loesen zu koennen?


----------



## PN/DP (22 Oktober 2013)

Nicht die SPS liest aus der Excel-Tabelle, sondern die Excel-Tabelle schreibt in die SPS.

Schau Dir mal diesen FAQ zu LibNoDave + Excel an.
In dem Excel-Beispiel wird zwar nur aus der SPS gelesen - das Schreiben in die SPS ist aber einfach zu realisieren.

Harald


----------



## yone (23 Oktober 2013)

Super, danke! 
Mit VB hab ich zwar schonmal programmiert, aber das ist etwas her. Aus dem Programmcode werd ich zwar noch nicht so ganz schlau, aber wird mir bestimmt bald weiterhelfen! 

Versteh ich das also richtig, dass libnodave eine Bibliothek ist, die weitere Funktionen wie "daveGetU8()" zur Verfügung stellt, um Excel mit Step7 interagieren lassen zu können? Gibt's zu den Befehlen, die diese Bibliothek zur Verfügung stellt, eine kleine Übersicht + Erklärung?


----------



## PN/DP (23 Oktober 2013)

Excel nutzt die in der libnodave.dll bereitgestellten Funktionen, um mit S7-SPS zu kommunizieren. Die libnodave.dll ist schon fertig kompiliert im Libnodave-Paket enthalten.

Der Libnodave-Code ist für mich aufgrund der Programmkommentare und Debug-Ausgaben im Quelltext weitgehend selbsterklärend. Weiters gibt es diverse Readme-Dateien. Für die richtige Funktionsreihenfolge und das grundsätzliche Vorgehen siehe die Quelltexte test*.c, z.B. testISO_TCP.c

Ich vermute, die für Dich übersichtlichste Informationsquelle ist wahrscheinlich die Modul12.bas.
Nachdem dieses Modul im Excel-VBA-Editor eingefügt ist, kannst Du eine kurze Beschreibung jeder Funktion und der Konstanten im Abschnitt "(Deklarationen)" lesen.

Für ein erstes Kennenlernen von LibNodave und Programmierversuche in Excel ala "Hello World" empfehle ich die "ungefährliche" Funktion daveGetOrderCode(...) zum Auslesen der CPU-Bestellnummer (damit hatte ich "damals" auch angefangen) oder mein Excel-Beispiel aus der FAQ .

Harald


----------



## zako (23 Oktober 2013)

> wuerde gerne Messwerte aus einer Exceltabelle einlesen und ueber meine S7-300 an meinen Antrieb uebermitteln



wenn Du einen SINAMICS S120 hast, dann kannst Du je nach Anwendung direkt von EXCEL auf Antriebsparameter schreiben.
Z.B. Kurvenscheiben werden in EXCEL hinterlegt und man schreibt von EXCEL direkt auf die Antriebsparameter - es gibt sogar "Freaks" die ohne Starter arbeiten und alles in EXCEL machen (von EXCEL aus ONLINE gehen und direkt reinschreiben). Mir reicht es schon, wenn ich per Script auf STARTER- Ebene EXCEL- Inhalte übertrage. 
Anwendungen, z.B. Kurvenscheibendownload, aber auch Verwaltung sehr vieler Datenmengen (z.B. Papiermaschinen mit großer Achsanzahl und man hinterlegt die Bezugsdrehzahlen, Getriebefaktoren, usw. usw. in EXCEL und parametriert alle Antriebe mit einen Mausklick).


----------



## yone (29 Oktober 2013)

@ zako: Du meinst, dass man die SPS mit Hilfe von Excel "umgehen" kann und man direkt an den FU geht? Was meinst du denn mit Kurvenscheiben? Mit den Parametern möchte ich zunächst sowieso nicht rumspielen, weil ich diese ja erstmal über STARTER soweit wie nötig eingestellt habe und eventuell noch die ein oder andere Veränderung später tätigen werde!

Ich habe dann aber mal eine Frage zum Verbindungsaufbau mit der SPS, da ich mich mit dem Kram echt zu wenig auskenne.
Ich habe meinen PC über LAN mit der SPS S7-300 verbunden, die SPS ist dann via Profinet am Sinamics S120, welcher dann mit dem Motor verbunden ist.

Ausschnitt aus Programmcode zur Initialisierung der Verbindung



> ' Here begins the demo program
> Sub initTable()
> Cells(2, 4) = "Serial port:"
> Cells(2, 5) = "COM1"
> ...





> Private Function initialize(ByRef ph As Long, ByRef di As Long, ByRef dc As Long)
> ph = 0
> di = 0
> dc = 0
> ...



Dort werden neben der IP-Adresse auch noch MPI-Adresse etc gesetzt, die ich ja eigentlich garnicht benötige bzw angeschlossen habe.

Folgendermaßen sieht mein Code aus (die Funktion InitTable will ich nicht nutzen, stattdessen in der Funktion initialize direkt die Werte eingeben)



> Private Function initialize(ByRef ph As Long, ByRef di As Long, ByRef dc As Long)
> Dim res, resmb, peer$, Rack, Slot
> 
> ' Initialisierung von Zustands-Variablen
> ...



Siehe Nummern im Code:
(1) Wieso werden sowohl im FAQ was PN/DP gepostet hat als auch im libnodave Quelltext diese Variablen gesetzt, obwohl die Verbindung über LAN aufgebaut werden soll und nicht über MPI?
(2) Wann benutze ich diese Zeile, d.h. wann verwende ich diese anstatt "ph = openSocket(102, peer$)"?
(3) In der Funktion davenewconnection() wird die Variable MpiPpi verwendet. Aus welchem Grund?

Sind in meiner Initialize Funktion ansonsten irgendwelche Fehler?

Vielen Dank für die Hilfe!


----------



## yone (5 November 2013)

Hey Jungs, kann mir da keiner helfen? Kann ja leider momentan den Rechner nicht mit der SPS verbinden und es selber ausprobieren, deshalb muss ich durch Recherche schauen, dass der Code einigermaßen funktionstüchtig ist! Durchstöber schon das ganze Internet danach und wäre erstmal froh, wenn der Verbindungsauf- und abbau vernünftig programmiert ist und ich mich danach auf das Einlesen der Bestellnummer stürzen kann. Das sollte ja relativ flott gehen und wenn ich mich vergewissert habe, dass der Zugriff auf die SPS möglich ist, könnte ich dann der SPS die Werte aus der Exceltabelle übergeben.


----------



## yone (12 November 2013)

Habe nun den Verbindungsauf- und -abbau programmiert und wuerde gerne zum Testen einen Wert aus dem DB56 auslesen! Habe via Step7 einen DB56 angelegt, einen Wert an die erste Stelle geschrieben und diesen dann in die SPS geladen.
Das Programm zum Einlesen dieses Wertes habe ich dann wie folgt realisiert:



> Private Sub DB_Lesen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DB_Lesen.Click
> Dim buf(0) As Byte
> If fds.rfd > 0 Then
> result = dc.readBytes(libnodave.daveDB, 56, 0, 1, buf)
> ...



In der Textbox wird allerdings immer "240" zurueckgegeben, obwohl der Wert 20 ausgegeben werden muesste.

Meine Verbindung wird durch



> Public Sub Verbinde()
> Dim ip As String
> ip = "192.168.0.3"                          ' IP-Adresse der SPS
> fds.rfd = libnodave.openSocket(102, ip)     ' Portstatus, baut TCP Verbindung auf: int openSocket(const int port, const char * ip), 102 ist Portnummer fuer TCP Protokoll
> ...



aufgebaut. Was mich allerdings wundert, ist, dass bei falscher IP-Eingabe (d.h. wenn ip nicht der IP-Adresse der SPS entspricht) ebenfalls Verbindungsaufbau erfolgreich ausgegeben wird, allerdings nach deutlich laengerer Wartezeit. Muss sich die SPS eigentlich im Start Zustand befinden, wenn ich mein VB Code ausfuehre? Wenn ich keinen Verbindungsaufbau mache und dann etwas lesen will, wird garnichts eingelesen, also muesste der Fehler doch irgendwie daran liegen, dass die Verbindung besteht, aber ein falscher Wert weswegen auch immer eingelesen wird! Danke schonmal!

EDIT: Fehler gefunden



> Private Sub DB_Lesen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DB_Lesen.Click
> Dim buf(0) As Byte
> If fds.rfd > 0 Then
> result = dc.readBytes(libnodave.daveDB, 56, 0, *2*, buf)
> ...


----------



## yone (19 November 2013)

> Public Sub Verbinde()
> Dim ip As String
> ip = "192.168.0.3"                          ' IP-Adresse der SPS
> fds.rfd = libnodave.openSocket(102, ip)     ' Portstatus, baut TCP Verbindung auf: int openSocket(const int port, const char * ip), 102 ist Portnummer fuer TCP Protokoll
> ...



Gebe ich 'ip' den falschen Wert, wird nach laengerer Zeit "verbindungsaufbau erfolgreich" ausgegeben, obwohl er garnicht in diese Verzweigung reingehen duerfte. Das Auslesen des DBs funktioniert dann nicht: es besteht also keine Verbindung zur SPS! Warum wird nicht in die Verzweigung "Fehler bei Verbindungsaufbau" gesprungen?


----------



## PN/DP (19 November 2013)

```
Public Sub Verbinde()
Dim ip As String
ip = "192.168.0.3" ' IP-Adresse der SPS
fds.rfd = libnodave.openSocket(102, ip) ' Portstatus, baut TCP Verbindung auf: int openSocket(const int port, const char * ip), 102 ist Portnummer fuer TCP Protokoll 
fds.wfd = fds.rfd ' Portstatus schreiben = Portstatus lesen

di = New libnodave.daveInterface(fds, "Interface", localMPI, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
di.setTimeout(1000000)

result = di.initAdapter

If result = 0 Then
  dc = New libnodave.daveConnection(di, plcMPI, 0, 2) ' daveNewConnection(di, MPI, rack, slot), MPI irrelevant bei Verbindung ueber ISO/TCP
  result = dc.connectPLC()
  [COLOR="#FF0000"]If result = 0 Then[/COLOR]
    MsgBox("Verbindungsaufbau erfolgreich", MsgBoxStyle.Information)
  Else
    MsgBox("Fehler bei Verbindungsaufbau", MsgBoxStyle.Information)
[COLOR="#FF0000"]  End If
Else
  MsgBox("Fehler beim Initialisieren TCP-Interface!", MsgBoxStyle.Information)[/COLOR]
End If
End Sub
```

PS:
Bitte benutze für den Programmcode die CODE-Tags, nicht die QUOTE-Tags (der nächste Button mit dem #).

Harald


----------



## yone (20 November 2013)

Danke  Darauf haette ich auch selbst kommen koennen...

EDIT:

```
Private Sub DB_schreiben_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bt_DBSchreiben.Click
        Dim buf(0) As Byte

        If fds.rfd > 0 Then
            buf(0) = Lb_DBEingabe.Text
            result = dc.writeBytes(libnodave.daveDB, 56, 0, 1, buf)
        End If
    End Sub
```
Mir stehen ja mit buf nur 8 Bits zur Verfuegung, dementsprechend ist meine Eingabe auch nur auf 256 begrenzt. Wie teile ich denn meine Textboxeingabe Lb_DBEingabe.Text auf buf(0) und buf(1) auf, sodass ich auch Werte > 255 eingeben kann, ohne dass es zum overflow error kommt?

EDIT: Geloest mit buf = BitConverter.GetBytes(eingabe) (in der Deklaration dim buf(1) as byte), wobei ich eingabe (datentyp short) den Inhalt der Textbox vorher zugewiesen habe. Anschliessend musste ich noch die beiden Arrayelemente vertauschen!


----------



## yone (10 Dezember 2013)

Ich habe mein Programm soweit fertig, aber frage mich noch, welche Telegramme ich für Drehzahl- bzw eine Drehmomentregelung einstellen muss. Ich brauche nicht wirklich viele Informationen über meinen Antrieb, von daher sollte doch eigentlich ein 2 Wort Telegramm (Sollwert und Steuerwort für Freigaben etc) ausreichen, oder?

Welches Telegramm stell ich für die Einspeisung (den Umrichter) und für die Sinamics CU310PN (Control Unit des Umrichters) ein? Die Kommunikation erfolgt zwischen PC -> SPS -> Control Unit! Was hat das Telegramm für die Einspeisung für einen Sinn? 

Gruß und Danke! ;o)


----------



## zako (10 Dezember 2013)

Hallo, 

die CU310PN hat kein Telegramm für die Einspeisung, da die CU nur  AC/AC Geräte unterstützt - sonst hättest Du eine CU320-2PN.
 Du kannst ganz einfach Telegramm 1 verwenden und über eine Telegrammerweitung nochmal p1501 und p1503 versorgen (soweit ich die Parameternummern im Kopf habe). Also einfach nochmal ein Bit zum Umschaltung in Drehmomentregelung spendieren und über ein weiteres Wort den Drehmomentsollwert vorgeben.
Du kannst ja wirklich das Telegramm beliebig aufboren, um z.B. Drehmomentistwert, Motortemperatur, Warn-/Störcode und was Dich sonst noch so interessiert zu übertragen.

Was hast Du eigentlich für eine Anwendung? 
Z.B. Prüfstandstechnik - da gibt es ganz gute Zusatzfeatures von SIEMENS,


----------



## yone (11 Dezember 2013)

Ich habe fuer die Einspeisung Telegramm 1, fuer die CU Telegramm 390 PZD2/2 ausgewaehlt und das scheint auch soweit jetzt richtig eingestellt zu sein (siehe Bilder).

Der Motor soll im Pruefstand einen Drehmoment/Drehzahlverlauf abfahren. Dazu schreibe ich mit Hilfe von libnodave momentan in ein DB und den Inhalt des DBs uebergebe ich dann an die Peripherieadresse des Umrichters. Was bietet Siemens denn da in diesem Fall an?

Ich waere erstmal froh, wenn ich einen Drehzahlwert einlesen koennte, allerdings funktioniert das noch nicht so ganz (siehe Bild Programm). Egal welche Eingangsbits oder Sollwerte ich setze (Setzen der Freigaben, Fuehrung durch PLC etc wird in "steuerung_word" geschrieben und an die Peripherieadresse uebergeben, Sollwert wird normiert und ebenfalls uebergeben), die zurueckgegebenen Zustandswoerter (IW256, IW258) veraendern sich nicht. Ich weiss aber nicht, woran es liegt. Hat jemand vielleicht eine Idee?

Danke 

P.S: Habe nur die wichtigsten Programmbausteine im Bild "Programm" via Snapshot ausgeschnitten und in ein Bild zusammengepackt. Die Bloecke befinden sich natuerlich in einzelnen Netzwerken und Fehler liegen auch keine vor! Die eigentliche Funktion des Programms sollte passen, nur scheint am Umrichter nichts anzukommen.


----------



## zako (11 Dezember 2013)

... Du hast keine seperate Einspeisung - Du hast einen AC/AC- Antrieb 
Wenn Du den Antrieb addressieren willst , dann ist der auf Adresse 300 - auf 256 ist ´Deine CU.

Schick doch erstmal FFFF zum Antrieb, damit auch sicher das Lebensbit gesetzt ist (LB = Bit 10).
Bit0 = AUS1
Bit1 = AUS2
...

UND die Zusatzdaten musst Du im TIA Portal auch noch nachziehen. Brauchst ja nur noch unterhalb von Telegramm 1 reinziehen (Zusatzdaten 2/2)


----------



## yone (16 Dezember 2013)

Soll ich also einfach FFFF in QW256 "reinschieben"? Werd ich nach der Mittagspause mal ausprobieren! Hatte bis gerade noch Fehler bzgl der Telegramme, aber hab die Adressierung jetzt soweit angepasst und die Fehler behoben!


----------



## zako (16 Dezember 2013)

Auf 256 ist doch Deine CU, oder?
Der Antrieb ist aber ab Adresse 300 (soweit ich das in Deinem Screenshot erkennen konnte). Also einfach mal FFFF auf QW300 schreiben, bzw. QD300 = FFFF_FFFF, dann ist auch noch die Drehzahl mit drin. Zumindest müsstest Du es am Antrieb unter Kommunikation sehen, dass was ankommt.
Bzgl. Zusatzdaten brauchst Du nur in der Gerätesicht die Zusatzdaten von "rechts nach links" per Drag&Drop reinziehen.

Übrigens: Dazu gibt es auch einen FAQ von SIEMENS, wie man mit TIA und S120 arbeitet. Ich würde es aber möglichst mit TIAP V12SP1 machen.


----------



## yone (16 Dezember 2013)

Ich hab die Adressierung der CU auf 300 geaendert, der Antrieb hat jetzt die Anfangsadresse 256. Uebergebe ich FFFF an QW256 (dieser wird auch definitiv uebernommen, habe Zustaende beobachtet), wird bei IW256 "0000" zurueckgegeben, d.h. es kommt scheinbar nichts an. 

Auf Grundlage der FAQs und der Beispiele habe ich ja dieses Programm erstellt, aber das hilft mir nicht herauszufinden, warum die Zustaende nicht gesetzt werden!

EDIT: Jetzt sind  beide Zustandswoerter auf 0, d.h. nicht wie im Bild oben, wo das erste Zustandswort "0A40" war. Egal was ich setze, die Zustaende scheinen davon unbeeinflusst zu sein! Schreibe ich hinter meine Zustandswoerter "" (wie auch im Bild gezeigt, scheint mir also dann der Zugriff aufs Prozessabbild zu sein, was eigentlich ja keinen Unterschied machen duerfte..) wird bei "0CFC" der Zustand "0E40" zurueckgegeben, aber weiterhin unabhaengig davon, was ich uebergebe.
Meine Variablentabelle sieht so aus. Mithilfe der Simulationsbaugruppe (I3) kann ich mein "steuerung_word" beeinflussen!


----------



## zako (16 Dezember 2013)

... hast Du eigentlich schon den Profinet - Namen Deinen Antrieb zugeordnet?
Einfach mal in der Netzsicht ONLINE gehen, Profinet- Bus anklicken (ich glaube rechte Maustaste) und ggf. noch Namen zuweisen.

Die IP Adresse allein reicht nicht aus.


----------



## yone (18 Dezember 2013)

Habe ich gemacht, sonst würde er ja auch meinen Umrichter garnicht erkennen. Das Problem hatte ich ganz am Anfang mal  Alles ist mit grünen Punkten und Haken versehen, keine Fehlermeldungen etc. aber...es tut sich nix! Über Starter kann ich den Antrieb ohne Weiteres starten, über TIA wird aber auf kein Steuerwort reagiert.


----------

