c# libnodave - DotNetSiemensPLCToolBoxLibrary - itemdoesnotexist, readmanybytes

SPSSlash

Level-1
Beiträge
5
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich habe den ganzen morgen die Suche vergewaltigt, aber die wollte nicht helfen ;) Ich schreibe gerade eine Software in C# die mittels S7 1500 kommuniziert und daten ausliest und visualisiert.
Hierzu benütze ich die lib dotnetsiemensplctoolboxlibrary von Jochen Kühner. Erstmal Danke fürs entwickeln solch einer Lib. Super Sache!
Dennoch habe ich ein kleines Problem. Ich habe einen DB der ist mit Bytes gefüllt bis DBB27. Diesen möchte ich auslesen, hierzu sieht mein Code wie folgt aus:

for (int n = 11, i = 2; n <(Convert.ToInt32(tag_temp[0].Value)*4+8); n = n + 4, i = i + 42)
string dbadress = "DB1" + Convert.ToString(Anlage) + ".DBB" + n;
tag_num_DB1x_Mldg_Zustand.Add(new PLCTag(dbadress, TagDataType.Byte)); ........usw.........
conn.ReadValues(tag_num_DB1x_Mldg_Zustand);

So schau ich mit die erstellte Liste an, stimmt diese und zwar sieht die so aus:
DB13.DBB11
DB13.DBB15
DB13.DBB19
DB13.DBB23
DB13.DBB27
beim ReadValues kommt immer bei allen "itemdoesnotexist"

Lese ich die Variablen mit
ReadValue(tag_num_DB1x_Mldg_Zustand[0...4])
aus, so passt der gelesene Wert kein "itemdoesnotexist" .Wenn ich die erste Methode anwende und in meiner SPS den DB nach DBB27 um ein BOOL erweiter funktioniert auch die erste Methode...

Wo liegt hier das Problem?

2te. Frage gibt es in der lib die möglichkeit von readmanybytes? Wenn ich mit ReadValues daten größer 460byte von der SPS lese werden alle werte ab 460 zu null. Das liegt ja an der PDU, allerdings kann readmanybytes dies einzeln lesen? Oder muss ich das selber machen?

Viele Grüße
SPSlash
Und vielen Dank im vorraus!
 
Zuletzt bearbeitet:
zu 1.) wie groß ist der db genau 27bytes? hast du eine kleines bsp wie der code genau aussieht
zu 2.) sollte auch funktionieren, schau ich mir aber erst am donnerstag an, ok?
 
Hallo Jochen, erstmal Danke für deine Rückmeldung.
Donnerstag ist super ;)

zu 1.)

Der DB:

Static
Static_1 Int 0.0 5 True True True False
Static_2 Byte 2.0 16#0 True True True False
Static_3 Byte 3.0 16#0 True True True False
Static_4 Byte 4.0 16#0 True True True False
Static_5 Byte 5.0 16#0 True True True False
Static_6 Byte 6.0 16#0 True True True False
Static_7 Byte 7.0 16#0 True True True False
Static_8 Byte 8.0 16#0 True True True False
Static_9 Byte 9.0 16#0 True True True False
Static_10 Byte 10.0 16#0 True True True False
Static_11 Byte 11.0 16#0 True True True False
Static_13 Byte 12.0 16#0 True True True False
Static_14 Byte 13.0 16#0 True True True False
Static_15 Byte 14.0 16#0 True True True False
Static_16 Byte 15.0 16#0 True True True False
Static_17 Byte 16.0 16#0 True True True False
Static_18 Byte 17.0 16#0 True True True False
Static_19 Byte 18.0 16#0 True True True False
Static_20 Byte 19.0 16#0 True True True False
Static_21 Byte 20.0 16#0 True True True False
Static_22 Byte 21.0 16#0 True True True False
Static_23 Byte 22.0 16#0 True True True False
Static_24 Byte 23.0 16#0 True True True False
Static_25 Byte 24.0 16#0 True True True False
Static_26 Byte 25.0 16#0 True True True False
Static_27 Byte 26.0 16#0 True True True False
Static_28 Byte 27.0 16#0 True True True False

C# Code

Erstellen von Tags:

public void E13generateMldgTags(int Anlage)
{


tag_temp.Clear();
tag_num_DB1x_Mldg_Zustand.Clear();
tag_num_DB1x_Mldg_Deklaration.Clear();
tag_txt_DB11x_Mldg.Clear();




Anlage = Anlage - 1;


tag_temp.Add(new PLCTag("DB1" + Anlage + ".DBW0", TagDataType.Int));
conn.ReadValues(tag_temp);





for (int n = 11, i = 2; n < (Convert.ToInt32(tag_temp[0].Value) * 4 + 8); n = n + 4, i = i + 42)
{


//Zustand
string dbadress = "DB1" + Convert.ToString(Anlage) + ".DBB" + n;
tag_num_DB1x_Mldg_Zustand.Add(new PLCTag(dbadress, TagDataType.Byte)); //ME Zustand




//Deklaration
dbadress = "DB1" + Convert.ToString(Anlage) + ".DBB" + (n - 1);
tag_num_DB1x_Mldg_Deklaration.Add(new PLCTag(dbadress, TagDataType.Byte)); //ME Deklaration




//Texte


dbadress = "P#DB11"+ Convert.ToString(Anlage) + ".DBX" + i + ".BYTE 28"; //Meldungstext
tag_txt_DB11x_Mldg.Add(new PLCTag(dbadress, TagDataType.String)); //ME Text


dbadress = "P#DB11" + Convert.ToString(Anlage) + ".DBX" + (i+30) + ".BYTE 4"; //Text OK
tag_txt_DB11x_Mldg.Add(new PLCTag(dbadress, TagDataType.String)); //ME Text


dbadress = "P#DB11" + Convert.ToString(Anlage) + ".DBX" + (i+36) + ".BYTE 4"; //Text nOK
tag_txt_DB11x_Mldg.Add(new PLCTag(dbadress, TagDataType.String)); //ME Text


}

}

Lesen der Tags:

public void E13readMldgTags()
{
conn.ReadValues(tag_num_DB1x_Mldg_Zustand);
}


Diese zwei Methoden werden nacheinander von der Main_Form Klasse aufgerufen!
Hier geht es um den Tag "tag_num_DB1x_Mldg_Zustand"

Was ich nicht verstehe ist, das wenn ich die Tags einzeln mit ReadValue(tag_num_DB1x_Mldg_Zustand[5]) abrufe es funktioniert?... Wieso benötigt ReadValues noch ein zusätliches Bool am schluss, also quasi das Bit 28.0...


Zu 2.)

im Oberen Code siehst du "Texte" dort der erste Tag "tag_txt_DB11x_Mldg" diese Liste kann beliebig viele Adressen enthalten, hier sind es dann mal mehr wie 460Bytes, dort führe ich dann auch ReadValues aus, aber dies scheint kein ReadManyValues auszuführen, weil ab Byte 464 stehen einfach nullen im Value. Gibt es dort eine extra funktion? ReadManyBytes finde ich in der lib nicht.

Viele Grüße
 
Zu 2.)

im Oberen Code siehst du "Texte" dort der erste Tag "tag_txt_DB11x_Mldg" diese Liste kann beliebig viele Adressen enthalten, hier sind es dann mal mehr wie 460Bytes, dort führe ich dann auch ReadValues aus, aber dies scheint kein ReadManyValues auszuführen, weil ab Byte 464 stehen einfach nullen im Value. Gibt es dort eine extra funktion? ReadManyBytes finde ich in der lib nicht.

Was passiert wenn die "useReadOptimization" auf true setzt?

Code:
[COLOR=#333333]conn.ReadValues(tag_num_DB1x_Mldg_Zustand, true);[/COLOR]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das habe ich versucht.
Leider kein Erfolg.

Im DBB110.DBX464 BYTE30 steht der Letzte richtige Text. Danach kommt im Value ““.

Edit:

Habe nun die PDULength ausgelesen, dort kommt 960 raus. Allerdings kann die S7 1500 das wohl irgendwie nicht.
Ist klar das "readmanybytes" dann nicht funktioniert. Wird hier auch schon diskutiert: http://www.sps-forum.de/simatic/57822-s7-1500-und-libnodave-oder-aglink-6.html
Kann man die PDU in der CPU einstellen? Bin in diesem Thema noch nicht so ganz bewandert ;)

Bzw. wie änder ich die lib ab, damit die immer nur 480Bytes ran nimmt? Mir reicht das, wenn er größer 480Bytes es splittet.

Edit ende.

Zum Thema 1.) habe ich rausgefunden, das wenn das letzte Byte ungerade ist also wie in meinem Fall DBB27 so kommt itemdoesnotexist ist das letzte Byte gerade wie z.B. 26 oder 28 so funktioniert alles!
Also liegt ihr irgendwo der Bug?

Viele Grüße
 
Zuletzt bearbeitet:
Hab einen Parametzer eingebaut: "ForcedPduSize"

kannst mal das versuchen:
conn.ReadValues(tag_num_DB1x_Mldg_Zustand, false);

Da smit dem ungearden ist nicht ganz so einfach zu fixen, muß ich erst schaun
 
So hallo, danke!

Also das
conn.ReadValues(tag_num_DB1x_Mldg_Zustand, false); funktioniert. Nun werden auch die ungeraden gelesen!
DANKE!

Zum PDU Thema, folglich habe ich es einprogrammiert:

conn.ForcedPduSize = 480;
conn._TestNewReadValues(tag_txt_DB11x_Mldg, true);

Bei True liest er einfach die Daten, aber diese sind unvollständig und nicht sortiert. Der Text der an letzter Stelle kommen soll steht an erster Stelle, aber nur teilweise. <- Wenn PDU kleiner 540, ab 540 stehen die Daten wie Anfangs zur Verfügung. Letzte Daten fehlen.
Bei False kommt immer PDU Size incorrect. Ich habe mehrere PDU größen ausprobiert. Ich habe nun noch WireShark mitlaufen lassen. Folgendes konnte ich sehen.
whireshark.jpg
Die Daten ab Payload 509, genau diese Daten fehlen!
Aber hier kenn ich mich zu wenig aus....?

PDU Größen um 508-522 habe ich auch ausprobiert!

Liegt das wohl an der S7 1511-1?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
bitte diese funktion "[FONT=&quot]conn._TestNewReadValues" nicht verwenden... die sollt eig. nicht public sein. werde ich auch wieder entfernen. Ok, hab gesehen das Ich die ForcedPduSize nur da verwendet habe. Ist nun gefixt

[/FONT]
conn.ReadValues(tag_num_DB1x_Mldg_Zustand, false); optimiert halt nicht, aber ich such nach dem fehler und mach in raus, weiß aber nicht ob ich das vor dem urlaub schaffe
 
Hallo Jochen,

vielen Dank es funktioniert!!!

Die Ungeraden Bytes werden mit Readopti auch gelesen nun!

Das mit der PDU funktioniert auch soweit. Allerdings ist aufgefallen, das wenn du das Paket splittest und das Paket wird gerade so gesplittet das beim zweiten Read ganz wenig Bits sind, so kommt die Meldung "short paket from PLC".

Gelöst habe ich das vorerst, das ich mein letztes Byte das ich empfangen möchte abfrage, dann vergleiche mit der PDU von 480. Ist das letzte Byte knapp über die 480, so wird die PDU verkleinert, so das im "zweiten" Read Paket mehr Daten gelesen werden.

Vielen Dank für deine Bemühungen! Schönen Urlaub!
 
Zurück
Oben