# Libnodave C# - WORD und STRING aus S7 lesen/schreiben



## dolo280 (10 Januar 2011)

Hallo Zusammen!

bin jetzt schon eine ganze weile am still lesen, nur leider habe ich im moment ein Problem bei dem mir auch die Suchfunktion nicht so wirklich weiterhilft!

Ich Programmiere mit Libnodave in C# im Visual Studio. Verbindung zu der S7-300 kann ich auch herstellen, alles kein Problem!

Nun habe ich in einem *DB* ( DB 12 Ab 216 bis 220) die Zahl *519 als WORD* stehen und will diese auslesen!
Was ich hierbei als *Ergebniss* erhalte *ist 17519* ?!
Weiß jemand was ich hier genau falsch mache.. ich weiß die S7 dreht beim Lesen die Dinge um, aber wirklich weiter hilft mir dies auch nicht!

Hier mal der Codeschnippsel:

int a;
libnodave.PDU p = dc.prepareReadRequest();
p.addVarToReadRequest(libnodave.daveDB, 12, 216, 2);
libnodave.resultSet rs = new libnodave.resultSet();
res = dc.execReadRequest(p, rs);
res = dc.useResult(rs, 0); 
if (res == 0)
{
Console.Write("DB 12 Word 216: ");
a = dc.getS16();
Console.WriteLine(a);
}

Meine Grundidee ist es einen STRING aus ca 35.Zeichen in C# Einzulesen und dann in die S7 zu schreiben, bis jetzt bin ich da allerdings noch nicht auch einen wirklichen Durchbruch gestoßen, wäre nett wenn mir jemand dazu noch nen Tipp oder ein Beispiel geben könnte, mir ist lediglich klar, das ich den String vorher komplett zerlegen müsste...

Ich wäre für jeden Hinweis, Tipp, etc. dankbar!

Gruss
Dominik


----------



## Jochen Kühner (10 Januar 2011)

Sicher als Word, da du ja von Byte 216-220 sprichst?

Dein Code sieht so auf den ersten Blick eigendlich richtig aus, poste mal den Inhalt von den DB Bytes!

Wenn du nur eine Variable direkt lesen willst, brauchst du nicht prepareReadRequest verwenden, da kannst du auch daveReadBytes verwenden.

Wenn du meine SiemensPLCToolboxLib anschauen willst, da hab Ich direkt Funktionen für Strings eingebaut (http://jochensserver.dyndns.org/wordpress/?page_id=55) (benutzt LibNoDave)


----------



## Rainer Hönle (10 Januar 2011)

Jochen Kühner schrieb:


> Sicher als Word, da du ja von Byte 216-220 sprichst?


Das sind fünf Bytes und passt nicht so recht. Eventuell ein String mit dem Inhalt 519?


----------



## dolo280 (11 Januar 2011)

Hallo! Erstmal vielen Dank für die schnellen Antorten!

Ok,sorry ich meinte natürlich 216 bis 219!

Ok, der Fehler lag bei mir! Es handelte sich nicht um ein WORD sondern um ein REAL-Wert! Über 

a = Convert.ToInt16(dc.getFloat());
Console.WriteLine(a);

Habe ich dann 956 - also den richtigen Wert aus der DB bekommen!


So jetzt nochmal zum Thema STRING/CHAR

Ich habe jetzt erstmal versucht einen *CHAR Variable* auszulesen,
in DB234 habe ich auf Adresse 21. *'S'* stehen 
Jetzt versuchte ich diese auszulesen mit
....
p.addVarToReadRequest(libnodave.daveDB, 234, 21, 1);
....
a = dc.getS16();
Console.WriteLine("   Als S16 = " + a);
a = dc.getU16();
Console.WriteLine("   Als U16 = " + a);
a = dc.getS32();
Console.WriteLine("   Als S32 = " + a);

und Erhalte
*Als S16 = 21253
Als U16 = 51200
Als S32 = 268814336*

womit ich nicht wirklich viel anfangen kann... ich dachte vielleicht ich bekomme den ASCII-Wert zurück oder sowas?! damit ich diesen umwandeln kann... 

Ich habe mal in die SiemensPLCToolboxLib reingeschaut, allerdings finde ich da auf anhieb nichts wirkliches zu STRINGS in die S7 übertragen?! Kannst du mir nen Anhaltspunkt geben wo ich in der Lib. das dazugehörige finde?!

Gruss Dominik


----------



## Rainer Hönle (11 Januar 2011)

Die dc.getXXX inkrmentieren doch intern einen Zeiger, oder nicht? Dann liest Du immer von einer anderen Adresse.
Und um ein Char zu lesen sollte doch nicht die Funktion für Int16, UInt16 oder Int32 verwendet werden.


----------



## dolo280 (11 Januar 2011)

uf...ok jetzt bin ich ganz durcheinander... 
ich hab mich beim programmieren immer an der "testS7online.cs" orientiert... da wurden Werte aus der DB etc. immer mit getXX verarbeitet.. heißt das ich muss ganz anderst vorgehen?

Die Int Werte die ich aus der DB mit getS16 auslese stimmen ja alle soweit?!


----------



## Rainer Hönle (11 Januar 2011)

dolo280 schrieb:


> uf...ok jetzt bin ich ganz durcheinander...
> ich hab mich beim programmieren immer an der "testS7online.cs" orientiert... da wurden Werte aus der DB etc. immer mit getXX verarbeitet.. heißt das ich muss ganz anderst vorgehen?
> 
> Die Int Werte die ich aus der DB mit getS16 auslese stimmen ja alle soweit?!



Da werden doch sicher mehrere Werte gelesen, nicht nur einer und immer der nächste ausgegeben, oder nicht? Aber da wird Jochen sicher noch was dazu schreiben. Der kennt sich mit libnodave besser aus als ich.
Eine Int16 mit getS16 auszulesen ist ok.


----------



## Jochen Kühner (11 Januar 2011)

Um die einzelnen Zeichen eines Strings auszulesen, musst du getU8 nehmen!

dann kannst du mit

string aa="";
for (int n=0;n<5;n++)
{
a += (char)dc.getU8();
}

zusammenbauen...

Zur ToolBoxLIb
um mit meiner Lib einen String zu lesen kannst du es so machen:


```
LibNoDaveValue myVal = new LibNoDaveValue("P#DB2.DBX2160.BYTE 5");
myVal.ChangeDataTypeFromString("string");
myConn.ReadValue(myVal);
```


----------



## dolo280 (12 Januar 2011)

Nochmal vielen Danke! Int/Real Werte auslesen klappt jetzt problemlos!! 


Hab das mit dem String auf gelöst - habe diverse funktionen in .NET gefunden, damit wandle ich jedes Zeichen in einen char-Wert und schreib sie nacheinandner ( ja nach länge des Strings ) mit einer for-Schleife in die Adressen...


Bin jetzt etwas am Testen und zwar versuch ich *Eingänge/Ausgänge auszulesen...*
habe jetzt zum Testen

p.addVarReadRequest(libnodave.daveInputs, 3, 2, 1) // *Für E3.2 ?!*
p.addVarReadRequest(libnodave.daveOutputs, 70, 0, 1) //*Für A70.0 ?!*

-> Das ganze dann wieder in libnodave.resultSet 

wieder über dc.getS16

allerdings erhalte ich so Int-Werte... ( z.B. 21234 ) ich will eigentlich nur ein bool-wert 1 oder 0 ?! 

Wahrscheinlich muss ich mit p.addBitVarReadRequest ran?! Irgendwie steh ich grad auf dem Schlauch!


----------



## Jochen Kühner (12 Januar 2011)

dolo280 schrieb:


> Nochmal vielen Danke! Int/Real Werte auslesen klappt jetzt problemlos!!
> 
> 
> Hab das mit dem String auf gelöst - habe diverse funktionen in .NET gefunden, damit wandle ich jedes Zeichen in einen char-Wert und schreib sie nacheinandner ( ja nach länge des Strings ) mit einer for-Schleife in die Adressen...
> ...



Ich les da immer ein Byte und prüfe dann das bit, da sowieso mit einem read request immer ein byte übertragen werden muss!


```
public static bool getBit(int Byte, int Bit)
    {
        int wrt = System.Convert.ToInt32(System.Math.Pow(2, Bit));
        return ((Byte & wrt) > 0);
    }
```

weiss jetzt gar nicht mehr ob die funktion getBit direkt in libnodave.net drinn ist oder ich die reinprogrammiert hab, aber damit gehts!


----------



## dolo280 (13 Januar 2011)

Vielen Dank, ich komm so langsam immer ein Stück weiter... also ich bin immernoch verwirrt ^^ habe mich eben mal dran und hab zwei Merker ausgelesen :

Merker:
*M1000.5 = 1
M1000.0 = 0*
Jetzt bin ich dran mit
_______________________________________________________________________________
int saveDebug = libnodave.daveGetDebug();
libnodave.daveSetDebug(libnodave.daveGetDebug() | libnodave.daveDebugPDU);
Console.WriteLine("Trying to read a single bit from Merker1000.0 mit 1.Bit\n");
*res = dc.readBits(libnodave.daveFlags, 1000, 0, 1, null);
*Console.WriteLine("function result:" + res + "=" + libnodave.daveStrerror(res));
Console.WriteLine("Trying to read a single bit from Merker1000.5 mit 1.Bit\n");
*res = dc.readBits(libnodave.daveFlags, 1000, 5, 1, null);
*Console.WriteLine("function result:" + res + "=" + libnodave.daveStrerror(res));
________________________________________________________________________________
*In die res Variable schreibt er mir jetzt immer 0 ?! 
*Was der Error Code unter Data mit Data für 
*M1000.0  
-> 0:0x00*
und für
*M1000.5
-> 0:0x01*
sieht ja perfekt aus?! aber wie komme ich da dran?!



Vielleicht kann jemand mit dem komplette Ergebniss mehr anfangen?!:
PDU header:
0:0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,
plen: 14 dlen: 0
Parameter:
0:0x04,0x01,0x12,0x0A,0x10,0x01,0x00,0x01,0x03,0xE8,0x83,0x00,0x00,0x00,
PDU header:
0:0x32,0x03,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x05,0x00,0x00,
plen: 2 dlen: 5
Parameter:
0:0x04,0x01,
Data     :
0:0xFF,0x03,0x00,0x01,0x00,
Data hdr :
0:0xFF,0x03,0x00,0x01,
Data     :
0:0x00,
error: ok
_daveSetupReceivedPDU() returned: 0=ok
_daveTestReadResult() returned: 0=ok
got 1 bytes of data
*function result:0=?*
Trying to read a single bit from Merker1000.5 mit 1.Bit
PDU header:
0:0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,
plen: 14 dlen: 0
Parameter:
0:0x04,0x01,0x12,0x0A,0x10,0x01,0x00,0x01,0x03,0xE8,0x83,0x00,0x00,0x05,
PDU header:
0:0x32,0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x05,0x00,0x00,
plen: 2 dlen: 5
Parameter:
0:0x04,0x01,
Data     :
0:0xFF,0x03,0x00,0x01,0x01,
Data hdr :
0:0xFF,0x03,0x00,0x01,
Data     :
0:0x01,
error: ok
_daveSetupReceivedPDU() returned: 0=ok
_daveTestReadResult() returned: 0=ok
got 1 bytes of data
*function result:0=?*


----------

