Step 7 Libnodave mit C# als Datenlogger

Maddin*

Level-2
Beiträge
14
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hardware Siemens 300er Station (EC31)
Software C# mit libnodave.dll

folgendes Problem: Ich habe einen Datenbaustein in dem sämmtliche Daten gesammelt werden. Dieser kann bis
zur Max. Größe eines DBs heranwachsen. Gehen wir davon aus das die 65534 Bytes des DBs belegt sind.
Ich möchte mit einem C# Programm alle Daten auslesen und auf der Konsole ausgeben bzw. später in einer Textdatei abspeichern.

Nun habe ich folgendes Problem. ich bau die Verbindung auf und lese mit davereadbytes alle bytes aus dem DB. Also 65534...

res = dc.readBytes(libnodave.daveDB, 1, 0, 65534, null)
... weiterer code..

Dies geht jedoch nicht, hab auch schon gehört das des Probleme macht, kam aber mit den lösungen nicht klar.

In meinem Fall kann ich ca. 460 Bytes auslesen (also 65534 durch 460 ersetzen) und mir ausgeben lassen. Wenn ich mehr will mekert der Compiler und ich bekomm keine Werte in der Konsole angezeigt.

Hab auch schon mal davereadmanybytes versucht. Die Parameter sind ja die selben aber da bekomm ich seltsamer weiße gar keine Ausgabe in der Konsole
, er ließt also gar nix aus. Es werden also net mal die 460 bytes ausgelesen.
Hab auch schön gehört das welche den readbytes aufruf mehrfach machen. Aber das muss ja auch anders gehen. Da ich halt sehr viele Bytes aus dem DB auslesen will (sprich alle 65534)

hoffe mir kann da jemand helfen.
 
Du kannst readManyBytes() verwenden. Die Funktion teilt deinen großen Datenblock intern in die entsprechende Anzahl an readBytes() Aufrufen auf, und prüft auch welche Datenblockgröße die CPU mit der du gerade kommunizierst unterstützt. 480 Bytes schaffen nämlich nicht alle S7. Eigentlich sollten bei deiner SPS wenn, dann bei einem Datenblock aber 462 Bytes am Stück gehen.

Und was heißt "kommt gar keine Ausgabe auf der Konsole". Du hast das Programm doch anscheinend selber geschrieben, warum gibst du denn nichts aus z.B. den Rückgabewert der Funktion?
 
Du kannst readManyBytes() verwenden. Die Funktion teilt deinen großen Datenblock intern in die entsprechende Anzahl an readBytes() Aufrufen auf, und prüft auch welche Datenblockgröße die CPU mit der du gerade kommunizierst unterstützt. 480 Bytes schaffen nämlich nicht alle S7. Eigentlich sollten bei deiner SPS wenn, dann bei einem Datenblock aber 462 Bytes am Stück gehen.

Und was heißt "kommt gar keine Ausgabe auf der Konsole". Du hast das Programm doch anscheinend selber geschrieben, warum gibst du denn nichts aus z.B. den Rückgabewert der Funktion?


Hallo Thomas,

Da war ich etwas ungenau, also es gehen wie du sagst nur 462 Bytes am Stück.
Irgendwie klappt bei mir das mit readManyBytes nicht.

Hier am besten mal ein Codeausschnitt:

res1 = dc.readManyBytes(libnodave.daveDB, 810, 0, 600, null);
if (res1 == 0)
{
//test in Array schreiben
for (int n = 1; n < 30; n++) //23 durchläufe
{
id[n] = dc.getS16();
date_1[n] = dc.getS32();
date_2[n] = dc.getS32();
info_1[n] = dc.getS32();
info_2[n] = dc.getS32();

Console.Write("\nID \t: " + n);
Console.Write("\t= " + id[n]);

Console.Write("\nD_A_T_1 : " + n);
Console.Write("\t= " + date_1[n]);

Console.Write("\nD_A_T_2 : " + n);
Console.Write("\t= " + date_2[n]);

Console.Write("\nINFO_1 \t: " + n);
Console.Write("\t= " + info_1[n]);

Console.Write("\nINFO_2 \t: " + n);
Console.Write("\t= " + info_2[n]);
Console.Write(" \n ");
}
Console.ReadKey();
}
else
Console.WriteLine("error MANYbytes " + res1 + " " + libnodave.daveStrerror(res1));
Console.ReadKey();

natürlich wurd vorher sockel aufgemacht etc.

Wenn ich das ausführe bekomme ich in der Konsole:

error MANYbytes -130 ??????????????????????


Aber ich komm trotzdem grad nicht weiter.
Ach und ich wollt hier nur beispielhaft 600 Bytes auslesen normal brauch ich ja alle.


@Jochen Kühner

Danke für das Angebot, aber ich will da was eigenes schreiben. ;-)
 
Du kannst readManyBytes() verwenden. Die Funktion teilt deinen großen Datenblock intern in die entsprechende Anzahl an readBytes() Aufrufen auf, und prüft auch welche Datenblockgröße die CPU mit der du gerade kommunizierst unterstützt. 480 Bytes schaffen nämlich nicht alle S7. Eigentlich sollten bei deiner SPS wenn, dann bei einem Datenblock aber 462 Bytes am Stück gehen.

Und was heißt "kommt gar keine Ausgabe auf der Konsole". Du hast das Programm doch anscheinend selber geschrieben, warum gibst du denn nichts aus z.B. den Rückgabewert der Funktion?


Hallo Thomas,

Da war ich etwas ungenau, also es gehen wie du sagst nur 462 Bytes am Stück.
Irgendwie klappt bei mir das mit readManyBytes nicht.

Hier am besten mal ein Codeausschnitt:

res1 = dc.readManyBytes(libnodave.daveDB, 810, 0, 600, null);
if (res1 == 0)
{
//test in Array schreiben
for (int n = 1; n < 30; n++) //23 durchläufe
{
id[n] = dc.getS16();
date_1[n] = dc.getS32();
date_2[n] = dc.getS32();
info_1[n] = dc.getS32();
info_2[n] = dc.getS32();

Console.Write("\nID \t: " + n);
Console.Write("\t= " + id[n]);

Console.Write("\nD_A_T_1 : " + n);
Console.Write("\t= " + date_1[n]);

Console.Write("\nD_A_T_2 : " + n);
Console.Write("\t= " + date_2[n]);

Console.Write("\nINFO_1 \t: " + n);
Console.Write("\t= " + info_1[n]);

Console.Write("\nINFO_2 \t: " + n);
Console.Write("\t= " + info_2[n]);
Console.Write(" \n ");
}
Console.ReadKey();
}
else
Console.WriteLine("error MANYbytes " + res1 + " " + libnodave.daveStrerror(res1));
Console.ReadKey();

natürlich wurd vorher sockel aufgemacht etc.

Wenn ich das ausführe bekomme ich in der Konsole:

error MANYbytes -130 ??????????????????????


Aber ich komm trotzdem grad nicht weiter.
Ach und ich wollt hier nur beispielhaft 600 Bytes auslesen normal brauch ich ja alle.


@Jochen Kühner

Danke für das Angebot, aber ich will da was eigenes schreiben. ;-)



Das hab ich in der Doku gefunden, was aber auch sehr wenig info gibt.

The function returns 0 on success. Nonzero return codes may be passed to daveStrerror() to get a textual explanation of what happened. Generally, positive error codes represent errors reported by the PLC, while negative ones represent errors detected by LIBNODAVE, e.g. no response from the PLC.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@ Jochen Kühner

Danke, aber will das selbst auf meine Art machen ;-)


@ Thomas_v2.1

Ja hab mich da etwas dumm ausgedrückt, also kann 462 byte einlesen!
Also bekomme den fehlercode -130 bei davereadmanybytes !Wenn ich den Parameter für buffer leer lasse, hier als bsp:

res1 = dc.readManyBytes(libnodave.daveDB, 810, 0, 16000,null);
if (res1 == 0)
{
//test in Array schreiben
for (int n = 1; n < 50; n++) //23 durchläufe
{
id[n] = dc.getS16();
date_1[n] = dc.getS32();
date_2[n] = dc.getS32();
info_1[n] = dc.getS32();
info_2[n] = dc.getS32();

Console.Write("\nID \t: " + n);
Console.Write("\t= " + id[n]);

Console.Write("\nD_A_T_1 : " + n);
Console.Write("\t= " + date_1[n]);

Console.Write("\nD_A_T_2 : " + n);
Console.Write("\t= " + date_2[n]);

Console.Write("\nINFO_1 \t: " + n);
Console.Write("\t= " + info_1[n]);

Console.Write("\nINFO_2 \t: " + n);
Console.Write("\t= " + info_2[n]);
Console.Write(" \n ");
}
Console.ReadKey();
}
else
Console.WriteLine("error MANYbytes " + res1 + " " + libnodave.daveStrerror(res1));
Console.ReadKey();


Wenn ich mir einen buffer deklarier mit

byte[] buffer = new byte[65543]; // beispielhaft

und dann diesen aufruf mache

res1 = dc.readManyBytes(libnodave.daveDB, 810, 0, 16000,buffer);

bekomme ich zwar eine Ausgabe, aber wieder nur 462 byte...




Das kann ansich keine Große sache sein, ich komm aber net drauf.
Ach und mir ist bewusst das in der libnodave doku steht:

The function returns 0 on success. Nonzero return codes may be passed to daveStrerror() to get a textual explanation of what happened. Generally, positive error codes represent errors reported by the PLC, while negative ones represent errors detected by LIBNODAVE, e.g. no response from the PLC.
 
Wenn ich mir einen buffer deklarier mit

byte[] buffer = new byte[65543]; // beispielhaft

und dann diesen aufruf mache

res1 = dc.readManyBytes(libnodave.daveDB, 810, 0, 16000,buffer);

bekomme ich zwar eine Ausgabe, aber wieder nur 462 byte...

Folgende Fragen:
- Wer macht die Ausgabe und wie stellst du fest dass nur 462 Bytes kommen?
- Wie lang ist der DB810 in der SPS?
 
sorry für diesen dreifachpost.... hab das mit der prüfung durch mod vergesse...

also die ausgabe lass ich mir über die console geben
Der DB ist von der SPS seite her zzt. Voll beschrieben (immoment zu testzwecken 18000byte)
Die konsolenausgabe gibt mir genau die ersten 462 byte, dann stehen nur noch nullen in der Ausgabe.

im DB810 habe ich einen UDT der 18Byte groß ist, Dieser ist dort immmoent 1000 mal aufgerufen,
sprich es sind 18000 byte belegt.
Der soll aber später 3642 mal hinterlegt sein.
Also geht dieser dann über die Maximale länge des DBs.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Für eine sinnvolle Verwendung von readManyBytes ist der Puffer obligatorisch.
Danach MÜSSEN natürlich auch die Werte aus diesem Puffer gelesen werden! Das geht mit getU32from(buffer, position) usw.
dc.getS32() und Freunde lesen immer aus dem INTERNEN Puffer des dc-Objekts. Dieser enthält nach einem Lesezugriff mit maximaler Größe bei 480 Byte PDU-Größe tatsächlich 462 Bytes Nutzdaten.
 
Zurück
Oben