diff --git a/S7.Net/Conversion.cs b/S7.Net/Conversion.cs
index 246ed00..af0a05c 100644
--- a/S7.Net/Conversion.cs
+++ b/S7.Net/Conversion.cs
@@ -15,15 +15,11 @@ namespace S7.Net
///
public static int BinStringToInt32(this string txt)
{
- int cnt = 0;
int ret = 0;
- for (cnt = txt.Length - 1; cnt >= 0; cnt += -1)
+ for (int i = 0; i < txt.Length; i++)
{
- if (int.Parse(txt.Substring(cnt, 1)) == 1)
- {
- ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
- }
+ ret = (ret << 1) | ((txt[i] == '1') ? 1 : 0);
}
return ret;
}
@@ -35,20 +31,7 @@ namespace S7.Net
///
public static byte? BinStringToByte(this string txt)
{
- int cnt = 0;
- int ret = 0;
-
- if (txt.Length == 8)
- {
- for (cnt = 7; cnt >= 0; cnt += -1)
- {
- if (int.Parse(txt.Substring(cnt, 1)) == 1)
- {
- ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
- }
- }
- return (byte)ret;
- }
+ if (txt.Length == 8) return (byte)BinStringToInt32(txt);
return null;
}
diff --git a/S7.Net/Enums.cs b/S7.Net/Enums.cs
index b128285..ccb8941 100644
--- a/S7.Net/Enums.cs
+++ b/S7.Net/Enums.cs
@@ -163,6 +163,11 @@
///
String,
+ ///
+ /// String variable type (variable)
+ ///
+ StringEx,
+
///
/// Timer variable type
///
diff --git a/S7.Net/PLC.cs b/S7.Net/PLC.cs
index c5b9676..e1a5b8e 100644
--- a/S7.Net/PLC.cs
+++ b/S7.Net/PLC.cs
@@ -343,6 +343,8 @@ namespace S7.Net
return resultBytes.ToArray();
}
+
+
///
/// Read and decode a certain number of bytes of the "VarType" provided.
/// This can be used to read multiple consecutive variables of the same type (Word, DWord, Int, etc).
@@ -1208,8 +1210,12 @@ namespace S7.Net
return Types.Double.FromByteArray(bytes);
else
return Types.Double.ToArray(bytes);
+
case VarType.String:
return Types.String.FromByteArray(bytes);
+ case VarType.StringEx:
+ return Types.StringEx.FromByteArray(bytes);
+
case VarType.Timer:
if (varCount == 1)
return Types.Timer.FromByteArray(bytes);
@@ -1252,6 +1258,8 @@ namespace S7.Net
case VarType.Word:
case VarType.Timer:
case VarType.Int:
+ case VarType.StringEx:
+ return varCount + 2;
case VarType.Counter:
return varCount * 2;
case VarType.DWord:
diff --git a/S7.Net/S7.Net.csproj b/S7.Net/S7.Net.csproj
index 5356672..ac2ac19 100644
--- a/S7.Net/S7.Net.csproj
+++ b/S7.Net/S7.Net.csproj
@@ -91,6 +91,7 @@
+
diff --git a/S7.Net/Types/Bit.cs b/S7.Net/Types/Bit.cs
index 8523cb5..cd36118 100644
--- a/S7.Net/Types/Bit.cs
+++ b/S7.Net/Types/Bit.cs
@@ -13,8 +13,7 @@ namespace S7.Net.Types
///
public static bool FromByte(byte v, byte bitAdr)
{
- BitArray bitArr = new BitArray(new byte[] { v });
- return bitArr[bitAdr];
+ return (((int)v & (1 << bitAdr)) != 0);
}
///
diff --git a/S7.Net/Types/Boolean.cs b/S7.Net/Types/Boolean.cs
index cd9149a..4c93895 100644
--- a/S7.Net/Types/Boolean.cs
+++ b/S7.Net/Types/Boolean.cs
@@ -12,10 +12,7 @@ namespace S7.Net.Types
///
public static bool GetValue(byte value, int bit)
{
- if ((value & (int)Math.Pow(2, bit)) != 0)
- return true;
- else
- return false;
+ return (((int)value & (1 << bit)) != 0);
}
///
@@ -23,7 +20,7 @@ namespace S7.Net.Types
///
public static byte SetBit(byte value, int bit)
{
- return (byte)(value | (byte)Math.Pow(2, bit));
+ return (byte)((value | (1 << bit)) & 0xFF);
}
///
@@ -31,7 +28,7 @@ namespace S7.Net.Types
///
public static byte ClearBit(byte value, int bit)
{
- return (byte)(value & (byte)(~(byte)Math.Pow(2, bit)));
+ return (byte)((value | (~(1 << bit))) & 0xFF);
}
}
diff --git a/S7.Net/Types/Byte.cs b/S7.Net/Types/Byte.cs
index 2727ef6..d52bb45 100644
--- a/S7.Net/Types/Byte.cs
+++ b/S7.Net/Types/Byte.cs
@@ -12,8 +12,7 @@ namespace S7.Net.Types
///
public static byte[] ToByteArray(byte value)
{
- byte[] bytes = new byte[] { value};
- return bytes;
+ return new byte[] { value }; ;
}
///
diff --git a/S7.Net/Types/Counter.cs b/S7.Net/Types/Counter.cs
index dfbc6f5..7a56cf7 100644
--- a/S7.Net/Types/Counter.cs
+++ b/S7.Net/Types/Counter.cs
@@ -18,16 +18,9 @@ namespace S7.Net.Types
}
// bytes[0] -> HighByte
// bytes[1] -> LowByte
- return FromBytes(bytes[1], bytes[0]);
+ return (UInt16)((bytes[0] << 8) | bytes[1]);
}
- ///
- /// Converts a Counter (2 bytes) to ushort (UInt16)
- ///
- public static UInt16 FromBytes(byte LoVal, byte HiVal)
- {
- return (UInt16)(HiVal * 256 + LoVal);
- }
///
/// Converts a ushort (UInt16) to word (2 bytes)
@@ -35,16 +28,10 @@ namespace S7.Net.Types
public static byte[] ToByteArray(UInt16 value)
{
byte[] bytes = new byte[2];
- int x = 2;
- long valLong = (long)((UInt16)value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64)Math.Pow(256, (cnt));
- Int64 x3 = (Int64)(valLong / x1);
- bytes[x - cnt - 1] = (byte)(x3 & 255);
- valLong -= bytes[x - cnt - 1] * x1;
- }
+ bytes[0] = (byte)((value << 8) & 0xFF);
+ bytes[1] = (byte)((value) & 0xFF);
+
return bytes;
}
diff --git a/S7.Net/Types/DInt.cs b/S7.Net/Types/DInt.cs
index fc3b523..a5b5caa 100644
--- a/S7.Net/Types/DInt.cs
+++ b/S7.Net/Types/DInt.cs
@@ -16,16 +16,9 @@ namespace S7.Net.Types
{
throw new ArgumentException("Wrong number of bytes. Bytes array must contain 4 bytes.");
}
- return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]);
+ return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
}
- ///
- /// Converts a S7 DInt (4 bytes) to int (Int32)
- ///
- public static Int32 FromBytes(byte v1, byte v2, byte v3, byte v4)
- {
- return (Int32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24));
- }
///
/// Converts a int (Int32) to S7 DInt (4 bytes)
@@ -33,16 +26,12 @@ namespace S7.Net.Types
public static byte[] ToByteArray(Int32 value)
{
byte[] bytes = new byte[4];
- int x = 4;
- long valLong = (long)((Int32)value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64)Math.Pow(256, (cnt));
- Int64 x3 = (Int64)(valLong / x1);
- bytes[x - cnt - 1] = (byte)(x3 & 255);
- valLong -= bytes[x - cnt - 1] * x1;
- }
+ bytes[0] = (byte)((value >> 24) & 0xFF);
+ bytes[1] = (byte)((value >> 16) & 0xFF);
+ bytes[2] = (byte)((value >> 8) & 0xFF);
+ bytes[3] = (byte)((value) & 0xFF);
+
return bytes;
}
@@ -71,18 +60,6 @@ namespace S7.Net.Types
return values;
}
- ///
- /// Converts from C# long (Int64) to C# int (Int32)
- ///
- public static Int32 CDWord(Int64 value)
- {
- if (value > Int32.MaxValue)
- {
- value -= (long)Int32.MaxValue + 1;
- value = (long)Int32.MaxValue + 1 - value;
- value *= -1;
- }
- return (int)value;
- }
+
}
}
diff --git a/S7.Net/Types/DWord.cs b/S7.Net/Types/DWord.cs
index c735ad1..14bc2a4 100644
--- a/S7.Net/Types/DWord.cs
+++ b/S7.Net/Types/DWord.cs
@@ -12,36 +12,39 @@ namespace S7.Net.Types
///
public static UInt32 FromByteArray(byte[] bytes)
{
- return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]);
+ return (UInt32)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]);
}
+
///
- /// Converts a S7 DWord (4 bytes) to uint (UInt32)
+ /// Converts 4 bytes to DWord (UInt32)
///
- public static UInt32 FromBytes(byte v1, byte v2, byte v3, byte v4)
+ public static UInt32 FromBytes(byte b1, byte b2, byte b3, byte b4)
{
- return (UInt32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24));
+ return (UInt32)((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
}
+
///
/// Converts a uint (UInt32) to S7 DWord (4 bytes)
///
public static byte[] ToByteArray(UInt32 value)
{
byte[] bytes = new byte[4];
- int x = 4;
- long valLong = (long)((UInt32)value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64)Math.Pow(256, (cnt));
- Int64 x3 = (Int64)(valLong / x1);
- bytes[x - cnt - 1] = (byte)(x3 & 255);
- valLong -= bytes[x - cnt - 1] * x1;
- }
+ bytes[0] = (byte)((value >> 24) & 0xFF);
+ bytes[1] = (byte)((value >> 16) & 0xFF);
+ bytes[2] = (byte)((value >> 8) & 0xFF);
+ bytes[3] = (byte)((value) & 0xFF);
+
return bytes;
}
+
+
+
+
+
///
/// Converts an array of uint (UInt32) to an array of S7 DWord (4 bytes)
///
diff --git a/S7.Net/Types/Double.cs b/S7.Net/Types/Double.cs
index 85bcbbd..f06385b 100644
--- a/S7.Net/Types/Double.cs
+++ b/S7.Net/Types/Double.cs
@@ -16,38 +16,15 @@ namespace S7.Net.Types
{
throw new ArgumentException("Wrong number of bytes. Bytes array must contain 4 bytes.");
}
- byte v1 = bytes[0];
- byte v2 = bytes[1];
- byte v3 = bytes[2];
- byte v4 = bytes[3];
- if ((int)v1 + v2 + v3 + v4 == 0)
+ // sps uses bigending so we have to reverse if platform needs
+ if (BitConverter.IsLittleEndian)
{
- return 0.0;
+ // create deep copy of the array and reverse
+ bytes = new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
}
- else
- {
- // nun String bilden
- string txt = ValToBinString(v1) + ValToBinString(v2) + ValToBinString(v3) + ValToBinString(v4);
- // erstmal das Vorzeichen
- int vz = int.Parse(txt.Substring(0, 1));
- int exd = Conversion.BinStringToInt32(txt.Substring(1, 8));
- string ma = txt.Substring(9, 23);
- double mantisse = 1;
- double faktor = 1.0;
- //das ist die Anzahl der restlichen bit's
- for (int cnt = 0; cnt <= 22; cnt++)
- {
- faktor = faktor / 2.0;
- //entspricht 2^-y
- if (ma.Substring(cnt, 1) == "1")
- {
- mantisse = mantisse + faktor;
- }
- }
- return Math.Pow((-1), vz) * Math.Pow(2, (exd - 127)) * mantisse;
- }
+ return BitConverter.ToSingle(bytes, 0);
}
///
@@ -76,48 +53,13 @@ namespace S7.Net.Types
///
public static byte[] ToByteArray(double value)
{
- double wert = (double)value;
- string binString = "";
- byte[] bytes = new byte[4];
- if (wert != 0f)
- {
- if (wert < 0)
- {
- wert *= -1;
- binString = "1";
- }
- else
- {
- binString = "0";
- }
- int exponent = (int)Math.Floor((double)Math.Log(wert) / Math.Log(2.0));
- wert = wert / (Math.Pow(2, exponent)) - 1;
+ byte[] bytes = BitConverter.GetBytes((float)(value));
- binString += ValToBinString((byte)(exponent + 127));
- for (int cnt = 1; cnt <= 23; cnt++)
- {
- if (!(wert - System.Math.Pow(2, -cnt) < 0))
- {
- wert = wert - System.Math.Pow(2, -cnt);
- binString += "1";
- }
- else
- binString += "0";
- }
- bytes[0] = (byte)BinStringToByte(binString.Substring(0, 8));
- bytes[1] = (byte)BinStringToByte(binString.Substring(8, 8));
- bytes[2] = (byte)BinStringToByte(binString.Substring(16, 8));
- bytes[3] = (byte)BinStringToByte(binString.Substring(24, 8));
-
- }
- else
- {
- bytes[0] = 0;
- bytes[1] = 0;
- bytes[2] = 0;
- bytes[3] = 0;
- }
- return bytes;
+ // sps uses bigending so we have to check if platform is same
+ if (!BitConverter.IsLittleEndian) return bytes;
+
+ // create deep copy of the array and reverse
+ return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
}
///
@@ -145,38 +87,5 @@ namespace S7.Net.Types
return values;
}
-
- private static string ValToBinString(byte value)
- {
- string txt = "";
-
- for (int cnt = 7; cnt >= 0; cnt += -1)
- {
- if ((value & (byte)Math.Pow(2, cnt)) > 0)
- txt += "1";
- else
- txt += "0";
- }
- return txt;
- }
-
- private static byte? BinStringToByte(string txt)
- {
- int cnt = 0;
- int ret = 0;
-
- if (txt.Length == 8)
- {
- for (cnt = 7; cnt >= 0; cnt += -1)
- {
- if (int.Parse(txt.Substring(cnt, 1)) == 1)
- {
- ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
- }
- }
- return (byte)ret;
- }
- return null;
- }
}
}
diff --git a/S7.Net/Types/Int.cs b/S7.Net/Types/Int.cs
index f2d7124..468e8b3 100644
--- a/S7.Net/Types/Int.cs
+++ b/S7.Net/Types/Int.cs
@@ -10,7 +10,7 @@ namespace S7.Net.Types
///
/// Converts a S7 Int (2 bytes) to short (Int16)
///
- public static Int16 FromByteArray(byte[] bytes)
+ public static short FromByteArray(byte[] bytes)
{
if (bytes.Length != 2)
{
@@ -18,16 +18,9 @@ namespace S7.Net.Types
}
// bytes[0] -> HighByte
// bytes[1] -> LowByte
- return FromBytes(bytes[1], bytes[0]);
+ return (short)((int)(bytes[1]) | ((int)(bytes[0]) << 8));
}
- ///
- /// Converts a S7 Int (2 bytes) to short (Int16)
- ///
- public static Int16 FromBytes(byte LoVal, byte HiVal)
- {
- return (Int16)(HiVal * 256 + LoVal);
- }
///
/// Converts a short (Int16) to a S7 Int byte array (2 bytes)
@@ -35,16 +28,10 @@ namespace S7.Net.Types
public static byte[] ToByteArray(Int16 value)
{
byte[] bytes = new byte[2];
- int x = 2;
- long valLong = (long)((Int16)value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64)Math.Pow(256, (cnt));
- Int64 x3 = (Int64)(valLong / x1);
- bytes[x - cnt - 1] = (byte)(x3 & 255);
- valLong -= bytes[x - cnt - 1] * x1;
- }
+ bytes[1] = (byte)((int)value & 0xFF);
+ bytes[0] = (byte)((int)value >> 8 & 0xFF);
+
return bytes;
}
@@ -53,10 +40,15 @@ namespace S7.Net.Types
///
public static byte[] ToByteArray(Int16[] value)
{
- ByteArray arr = new ByteArray();
- foreach (Int16 val in value)
- arr.Add(ToByteArray(val));
- return arr.array;
+ byte[] bytes = new byte[value.Length * 2];
+ int bytesPos = 0;
+
+ for(int i=0; i< value.Length; i++)
+ {
+ bytes[bytesPos++] = (byte)((int)value[i] & 0xFF);
+ bytes[bytesPos++] = (byte)(((int)value[i] >> 8) & 0xFF);
+ }
+ return bytes;
}
///
@@ -64,10 +56,12 @@ namespace S7.Net.Types
///
public static Int16[] ToArray(byte[] bytes)
{
- Int16[] values = new Int16[bytes.Length / 2];
+ int shortsCount = bytes.Length / 2;
+
+ Int16[] values = new Int16[shortsCount];
int counter = 0;
- for (int cnt = 0; cnt < bytes.Length / 2; cnt++)
+ for (int cnt = 0; cnt < shortsCount; cnt++)
values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] });
return values;
diff --git a/S7.Net/Types/String.cs b/S7.Net/Types/String.cs
index d2a1d50..d1ca263 100644
--- a/S7.Net/Types/String.cs
+++ b/S7.Net/Types/String.cs
@@ -3,19 +3,14 @@
///
/// Contains the methods to convert from S7 strings to C# strings
///
- public static class String
+ public class String
{
///
/// Converts a string to S7 bytes
///
public static byte[] ToByteArray(string value)
{
- string txt = (string)value;
- char[] ca = txt.ToCharArray();
- byte[] bytes = new byte[txt.Length];
- for (int cnt = 0; cnt <= ca.Length - 1; cnt++)
- bytes[cnt] = (byte)Asc(ca[cnt].ToString());
- return bytes;
+ return System.Text.Encoding.ASCII.GetBytes(value);
}
///
@@ -27,13 +22,6 @@
{
return System.Text.Encoding.ASCII.GetString(bytes);
}
-
- private static int Asc(string s)
- {
- byte[] b = System.Text.Encoding.ASCII.GetBytes(s);
- if (b.Length > 0)
- return b[0];
- return 0;
- }
+
}
}
diff --git a/S7.Net/Types/StringEx.cs b/S7.Net/Types/StringEx.cs
new file mode 100644
index 0000000..e22282b
--- /dev/null
+++ b/S7.Net/Types/StringEx.cs
@@ -0,0 +1,26 @@
+namespace S7.Net.Types
+{
+ ///
+ /// Contains the methods to convert from S7 strings to C# strings
+ /// there are two kinds how strings a send. This one is with a pre of two bytes
+ /// they contain the length of the string
+ ///
+ public static class StringEx
+ {
+ ///
+ /// Converts S7 bytes to a string
+ ///
+ ///
+ ///
+ public static string FromByteArray(byte[] bytes)
+ {
+ if (bytes.Length < 2) return "";
+
+ int size = bytes[0];
+ int length = bytes[1];
+
+ return System.Text.Encoding.ASCII.GetString(bytes, 2, length);
+ }
+
+ }
+}
diff --git a/S7.Net/Types/Timer.cs b/S7.Net/Types/Timer.cs
index 167c12f..a95253b 100644
--- a/S7.Net/Types/Timer.cs
+++ b/S7.Net/Types/Timer.cs
@@ -13,26 +13,30 @@ namespace S7.Net.Types
public static double FromByteArray(byte[] bytes)
{
double wert = 0;
- Int16 value = (Int16)Types.Word.FromBytes(bytes[1], bytes[0]);
- string txt = Conversion.ValToBinString(value);
- wert = Conversion.BinStringToInt32(txt.Substring(4, 4)) * 100.0;
- wert += Conversion.BinStringToInt32(txt.Substring(8, 4)) * 10.0;
- wert += Conversion.BinStringToInt32(txt.Substring(12, 4));
- switch (txt.Substring(2, 2))
+
+ wert = ((bytes[0]) & 0x0F) * 100.0;
+ wert += ((bytes[1] >> 4) & 0x0F) * 10.0;
+ wert += ((bytes[1]) & 0x0F) * 1.0;
+
+ /// this value is not used... may for a nother exponation
+ ///int unknown = (bytes[0] >> 6) & 0x03;
+
+ switch ((bytes[0] >> 4) & 0x03)
{
- case "00":
+ case 0:
wert *= 0.01;
break;
- case "01":
+ case 1:
wert *= 0.1;
break;
- case "10":
+ case 2:
wert *= 1.0;
break;
- case "11":
+ case 3:
wert *= 10.0;
break;
}
+
return wert;
}
@@ -42,16 +46,9 @@ namespace S7.Net.Types
public static byte[] ToByteArray(UInt16 value)
{
byte[] bytes = new byte[2];
- int x = 2;
- long valLong = (long)((UInt16)value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64)Math.Pow(256, (cnt));
+ bytes[1] = (byte)((int)value & 0xFF);
+ bytes[0] = (byte)((int)value >> 8 & 0xFF);
- Int64 x3 = (Int64)(valLong / x1);
- bytes[x - cnt - 1] = (byte)(x3 & 255);
- valLong -= bytes[x - cnt - 1] * x1;
- }
return bytes;
}
diff --git a/S7.Net/Types/Word.cs b/S7.Net/Types/Word.cs
index f0f4347..1631fae 100644
--- a/S7.Net/Types/Word.cs
+++ b/S7.Net/Types/Word.cs
@@ -16,35 +16,30 @@ namespace S7.Net.Types
{
throw new ArgumentException("Wrong number of bytes. Bytes array must contain 2 bytes.");
}
- // bytes[0] -> HighByte
- // bytes[1] -> LowByte
- return FromBytes(bytes[1], bytes[0]);
+
+ return (UInt16)((bytes[0] << 8) | bytes[1]);
}
+
///
- /// Converts a word (2 bytes) to ushort (UInt16)
+ /// Converts 2 bytes to ushort (UInt16)
///
- public static UInt16 FromBytes(byte LoVal, byte HiVal)
+ public static UInt16 FromBytes(byte b1, byte b2)
{
- return (UInt16) (HiVal*256 + LoVal);
+ return (UInt16)((b2 << 8) | b1);
}
+
///
/// Converts a ushort (UInt16) to word (2 bytes)
///
public static byte[] ToByteArray(UInt16 value)
{
byte[] bytes = new byte[2];
- int x = 2;
- long valLong = (long) ((UInt16) value);
- for (int cnt = 0; cnt < x; cnt++)
- {
- Int64 x1 = (Int64) Math.Pow(256, (cnt));
- Int64 x3 = (Int64) (valLong/x1);
- bytes[x - cnt - 1] = (byte) (x3 & 255);
- valLong -= bytes[x - cnt - 1]*x1;
- }
+ bytes[1] = (byte)(value & 0xFF);
+ bytes[0] = (byte)((value>>8) & 0xFF);
+
return bytes;
}