daveToPLCFloat(float f) liefert ein formal ein Integer. Die 4 Bytes enthalten eine Gleikommazahl im Format der SPS. Daß der Rückgabetyp int ist, liegt daran, daß verhindert werden soll, daß die Laufzeitumgebung bei der Zuweisung an eine PC-Variable auf Gültigkeit prüft.seeba schrieb:Hallo Zottel,
Hallo Forum Mitbenutzer,
folgende Frag: Gibt es auch eine Funktion um einen Floatwert wieder zurück zu wandel? Ähnlich daveGetFloat? Also sowas wie daveGetBytes(Floatwert)?
Gruß Sebastian
In C gibt es das, aber ich habe nur einen Teil davon in die C#-Schnittstelle integriert. Der Grund ist, daß man Funktionen der Dot.NET CLR benutzen sollte, damit die CLR Gültigkeit von Referenzen und Grenzen von Arrays prüfen kann (was in C nicht getan wird).seeba schrieb:Ich will mal meinen Wunsch äußern, wenn ich darf: Ich würd mir Funktionen wünschen der man den Buffer vorgeben kann.
z.B: daveGetU8(buffer, position)
und auch umgekehrt!
z.B.: daveGetBytesFromU16(buffer, position)
Das würde die Arbeit mit libnodave noch um einiges vereinfachen.
Wäre schön, wenn du sowas integrierst, aber kann auch sein das ich mal wieder blind bin.
Zottel schrieb:In C gibt es das, aber ich habe nur einen Teil davon in die C#-Schnittstelle integriert. Der Grund ist, daß man Funktionen der Dot.NET CLR benutzen sollte, damit die CLR Gültigkeit von Referenzen und Grenzen von Arrays prüfen kann (was in C nicht getan wird).seeba schrieb:Ich will mal meinen Wunsch äußern, wenn ich darf: Ich würd mir Funktionen wünschen der man den Buffer vorgeben kann.
z.B: daveGetU8(buffer, position)
und auch umgekehrt!
z.B.: daveGetBytesFromU16(buffer, position)
Das würde die Arbeit mit libnodave noch um einiges vereinfachen.
Wäre schön, wenn du sowas integrierst, aber kann auch sein das ich mal wieder blind bin.
Wir reden hier irgendwie aneinader vorbei? Wo willst du die 4 Bytes hernehmen? Wenn du in einem Programm in .NET eine float-Variable f hast, kannst du sie mit:seeba schrieb:Also ich benutze jetzt den BitConverter von .NET... Funtioniert auch gut soweit. Allerdings bekomm ich mit dem keinen Float aus 4 Bytes gewandet... Hast du eine Funktion der ich die 4 Bytes übergebe und die mir dann einen Float rausschmeißt?
(c#) (float)BitConverter.ToUInt32(buffer,index))
Zottel schrieb:Wir reden hier irgendwie aneinader vorbei? Wo willst du die 4 Bytes hernehmen? Wenn du in einem Programm in .NET eine float-Variable f hast, kannst du sie mit:seeba schrieb:Also ich benutze jetzt den BitConverter von .NET... Funtioniert auch gut soweit. Allerdings bekomm ich mit dem keinen Float aus 4 Bytes gewandet... Hast du eine Funktion der ich die 4 Bytes übergebe und die mir dann einen Float rausschmeißt?
d=libnodave.toPLCFloat(f)
oder
i=libnodave.daveToPLCFloat(f)
in eine float oder int-Variable konvertieren.
Die Ergebnis-Variable enthält das Bit-Muster so wie es auch in der SPS stehen würde. Für .NET oder einen i386-Prozessor ist dieses Bitmuster sinnlos.
Es kann aber mittels BitConverter die 32 Bit als eine Folge von 4 bytes an daveWriteBytes als Puffer übergeben werden. Das ist in testMPI.cs beispielhaft interpretiert und bewirkt, daß der Wert, der vorher aus dem MD12 gelesesen, ins PC-Format konvertiert und dann um 1.1 erhöht wurde, wieder so in die SPS ggeschrieben wird, daß in MD12 der erhöhte Wert steht.
Hast du dir das angesehen? Es ausprobiert?
testMPI -w COM1
Weitergehende Operationen mit Puffern sind sinnvoll, wenn mehrere aufeinaderfolgende Werte "in einem Rutsch" in den Merkerbereich oder einen DB geschrieben werden sollen.
Beispiel:
MD 0 INT
MD 4 REAL
MD 8 REAL
MD 12 INT
Sollen auf die Werte 42, 5.5, 6.123, 17 gesetzt werden:
byte[] buffer = new buffer[16];
int i,j=42;
i=libnodave.daveSwapIed_32(j);
Array.Copy(buffer,0,BitConverter(i),GetBytes,0,4);
i=libnodave.daveToPLCFloat(5.5);
Array.Copy(buffer,4,BitConverter(i),GetBytes,0,4);
i=libnodave.daveToPLCFloat(6.123);
Array.Copy(buffer,8,BitConverter(i),GetBytes,0,4);
i=libnodave.daveSwapIed_32(17);
Array.Copy(buffer,12,BitConverter(i),GetBytes,0,4);
dc.WriteBytes(...0,16,buffer);
Das ist kein getesteter Code, aber so oder so ähnlich geht es.
usw. muß natürlich richtiger heißen:Zottel schrieb:Array.Copy(buffer,12,BitConverter(i),GetBytes,0,4);
Das heißt, der Puffer ist mittels einer der Lesefunktionen, z.B. readBytes, mit Bytes aus der SPS gefüllt?seeba schrieb:Ich will die 4 Bytes aus meinem Buffer zum Float umwandeln. Und du bietest ja keine Funktion zum lesen aus einem bestimmten Buffer an einer bestimmten Stelle.
Dann habe ich in dieser Frage das Wort "zurück" mißverstanden? Oder sprechen wir inzwischen über eine neue Frage?seeba schrieb:folgende Frag: Gibt es auch eine Funktion um einen Floatwert wieder zurück zu wandel? Ähnlich daveGetFloat? Also sowas wie daveGetBytes(Floatwert)?
Zottel schrieb:Das heißt, der Puffer ist mittels einer der Lesefunktionen, z.B. readBytes, mit Bytes aus der SPS gefüllt?seeba schrieb:Ich will die 4 Bytes aus meinem Buffer zum Float umwandeln. Und du bietest ja keine Funktion zum lesen aus einem bestimmten Buffer an einer bestimmten Stelle.
Dann bräuchtest du ja dieselbe Funktion wie daveGetFloat, aber von einem eigenen Puffer?
Die Funktionen sind in der C-Version (und damit in libnodave.dll) enthalten, z.B.seeba schrieb:Zottel schrieb:Das heißt, der Puffer ist mittels einer der Lesefunktionen, z.B. readBytes, mit Bytes aus der SPS gefüllt?seeba schrieb:Ich will die 4 Bytes aus meinem Buffer zum Float umwandeln. Und du bietest ja keine Funktion zum lesen aus einem bestimmten Buffer an einer bestimmten Stelle.
Dann bräuchtest du ja dieselbe Funktion wie daveGetFloat, aber von einem eigenen Puffer?
Genau! Diese Funktionen fehlen mir
public static int getS16from(byte[] b, int pos) {
if (BitConverter.IsLittleEndian) {
byte[] b1=new byte[2];
b1[1]=b[pos+0];
b1[0]=b[pos+1];
return BitConverter.ToInt16(b1, 0);
}
else
return BitConverter.ToInt16(b, pos);
}
public static int getU16from(byte[] b, int pos) {
if (BitConverter.IsLittleEndian) {
byte[] b1=new byte[2];
b1[1]=b[pos+0];
b1[0]=b[pos+1];
return BitConverter.ToUInt16(b1, 0);
}
else
return BitConverter.ToUInt16(b, pos);
}
public static int getS32from(byte[] b, int pos) {
if (BitConverter.IsLittleEndian) {
byte[] b1=new byte[4];
b1[3]=b[pos];
b1[2]=b[pos+1];
b1[1]=b[pos+2];
b1[0]=b[pos+3];
return BitConverter.ToInt32(b1, 0);
}
else
return BitConverter.ToInt32(b, pos);
}
public static uint getU32from(byte[] b, int pos) {
if (BitConverter.IsLittleEndian) {
byte[] b1=new byte[4];
b1[3]=b[pos];
b1[2]=b[pos+1];
b1[1]=b[pos+2];
b1[0]=b[pos+3];
return BitConverter.ToUInt32(b1, 0);
}
else
return BitConverter.ToUInt32(b, pos);
}
public static float getFloatfrom(byte[] b, int pos) {
if (BitConverter.IsLittleEndian) {
byte[] b1=new byte[4];
b1[3]=b[pos];
b1[2]=b[pos+1];
b1[1]=b[pos+2];
b1[0]=b[pos+3];
return BitConverter.ToSingle(b1, 0);
}
else
return BitConverter.ToSingle(b, pos);
}
Zottel schrieb:Hier die Funktionen unter Verwendung von BitConverter.IsLittleEndian:
Code:public static int getS16from(byte[] b, int pos) { if (BitConverter.IsLittleEndian) { byte[] b1=new byte[2]; b1[1]=b[pos+0]; b1[0]=b[pos+1]; return BitConverter.ToInt16(b1, 0); } else return BitConverter.ToInt16(b, pos); } public static int getU16from(byte[] b, int pos) { if (BitConverter.IsLittleEndian) { byte[] b1=new byte[2]; b1[1]=b[pos+0]; b1[0]=b[pos+1]; return BitConverter.ToUInt16(b1, 0); } else return BitConverter.ToUInt16(b, pos); } public static int getS32from(byte[] b, int pos) { if (BitConverter.IsLittleEndian) { byte[] b1=new byte[4]; b1[3]=b[pos]; b1[2]=b[pos+1]; b1[1]=b[pos+2]; b1[0]=b[pos+3]; return BitConverter.ToInt32(b1, 0); } else return BitConverter.ToInt32(b, pos); } public static uint getU32from(byte[] b, int pos) { if (BitConverter.IsLittleEndian) { byte[] b1=new byte[4]; b1[3]=b[pos]; b1[2]=b[pos+1]; b1[1]=b[pos+2]; b1[0]=b[pos+3]; return BitConverter.ToUInt32(b1, 0); } else return BitConverter.ToUInt32(b, pos); } public static float getFloatfrom(byte[] b, int pos) { if (BitConverter.IsLittleEndian) { byte[] b1=new byte[4]; b1[3]=b[pos]; b1[2]=b[pos+1]; b1[1]=b[pos+2]; b1[0]=b[pos+3]; return BitConverter.ToSingle(b1, 0); } else return BitConverter.ToSingle(b, pos); }
Also kaum wirft Zottel euch ein Würstchen hin, willst Du gleich danach noch ein Steak.seeba schrieb:Und: getBitFrom() fehlt mir noch...
Anonymous schrieb:Hallo,
Mann seeba,
Also kaum wirft Zottel euch ein Würstchen hin, willst Du gleich danach noch ein Steak.seeba schrieb:Und: getBitFrom() fehlt mir noch...
Gruß
Question_mark
Habe ich das nicht voraer ausführlich erläutert?seeba schrieb:Und anderstrum?
Je nachdem, wie du das Bit bekommst ( 1. daveReadBits() oder 2. du hast per daveReadBytes() z.B. ein MB gelesen) vergleichst du auf ungleich 0 oder du vergleichst mit der Bit-Maske:seeba schrieb:Und: getBitFrom() fehlt mir noch...
MOV MeineVariableDieEineKopieVomMB_XIst,EAX
AND EAX,00000080h
JZ ok
MOV EAX,TRUE
ok: Nachfolgender Code
push buffer
push position
push bitNumber
call getBitfrom
//getBitfrom
enter ParameterGröße
MOV EAX,Buffer.Length
CMP EA, Position
JGT DoArrayBoundsException
MOV EDX,Buffer
XOR EDX,EDX
CMP EA, Position
JLE DoArrayBoundsException
ADD EDX,BUFFER
MOV EAX,[EDX]
PUSH EAX
MOV ECX,1
MOV EDX,BitNumber
SHL ECX,EDX
AND EAX,ECX
JZ ok
MOV EAX,TRUE
ok: leave ParameterGröße
ret
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?