- fix data type converting

- add new string string data type
This commit is contained in:
Thomas Ze
2018-03-18 21:26:22 +01:00
parent f6a2e11045
commit 7cedec5909
16 changed files with 133 additions and 265 deletions

View File

@@ -15,15 +15,11 @@ namespace S7.Net
/// <returns></returns>
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
/// <returns></returns>
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;
}

View File

@@ -163,6 +163,11 @@
/// </summary>
String,
/// <summary>
/// String variable type (variable)
/// </summary>
StringEx,
/// <summary>
/// Timer variable type
/// </summary>

View File

@@ -343,6 +343,8 @@ namespace S7.Net
return resultBytes.ToArray();
}
/// <summary>
/// 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:

View File

@@ -91,6 +91,7 @@
<Compile Include="Types\Double.cs" />
<Compile Include="Types\DWord.cs" />
<Compile Include="Types\Int.cs" />
<Compile Include="Types\StringEx.cs" />
<Compile Include="Types\String.cs" />
<Compile Include="Types\Struct.cs" />
<Compile Include="Types\Timer.cs" />

View File

@@ -13,8 +13,7 @@ namespace S7.Net.Types
/// </summary>
public static bool FromByte(byte v, byte bitAdr)
{
BitArray bitArr = new BitArray(new byte[] { v });
return bitArr[bitAdr];
return (((int)v & (1 << bitAdr)) != 0);
}
/// <summary>

View File

@@ -12,10 +12,7 @@ namespace S7.Net.Types
/// </summary>
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);
}
/// <summary>
@@ -23,7 +20,7 @@ namespace S7.Net.Types
/// </summary>
public static byte SetBit(byte value, int bit)
{
return (byte)(value | (byte)Math.Pow(2, bit));
return (byte)((value | (1 << bit)) & 0xFF);
}
/// <summary>
@@ -31,7 +28,7 @@ namespace S7.Net.Types
/// </summary>
public static byte ClearBit(byte value, int bit)
{
return (byte)(value & (byte)(~(byte)Math.Pow(2, bit)));
return (byte)((value | (~(1 << bit))) & 0xFF);
}
}

View File

@@ -12,8 +12,7 @@ namespace S7.Net.Types
/// </summary>
public static byte[] ToByteArray(byte value)
{
byte[] bytes = new byte[] { value};
return bytes;
return new byte[] { value }; ;
}
/// <summary>

View File

@@ -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]);
}
/// <summary>
/// Converts a Counter (2 bytes) to ushort (UInt16)
/// </summary>
public static UInt16 FromBytes(byte LoVal, byte HiVal)
{
return (UInt16)(HiVal * 256 + LoVal);
}
/// <summary>
/// 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;
}

View File

@@ -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];
}
/// <summary>
/// Converts a S7 DInt (4 bytes) to int (Int32)
/// </summary>
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));
}
/// <summary>
/// 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;
}
/// <summary>
/// Converts from C# long (Int64) to C# int (Int32)
/// </summary>
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;
}
}
}

View File

@@ -12,36 +12,39 @@ namespace S7.Net.Types
/// </summary>
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]);
}
/// <summary>
/// Converts a S7 DWord (4 bytes) to uint (UInt32)
/// Converts 4 bytes to DWord (UInt32)
/// </summary>
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);
}
/// <summary>
/// Converts a uint (UInt32) to S7 DWord (4 bytes)
/// </summary>
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;
}
/// <summary>
/// Converts an array of uint (UInt32) to an array of S7 DWord (4 bytes)
/// </summary>

View File

@@ -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);
}
/// <summary>
@@ -76,48 +53,13 @@ namespace S7.Net.Types
/// </summary>
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] };
}
/// <summary>
@@ -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;
}
}
}

View File

@@ -10,7 +10,7 @@ namespace S7.Net.Types
/// <summary>
/// Converts a S7 Int (2 bytes) to short (Int16)
/// </summary>
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));
}
/// <summary>
/// Converts a S7 Int (2 bytes) to short (Int16)
/// </summary>
public static Int16 FromBytes(byte LoVal, byte HiVal)
{
return (Int16)(HiVal * 256 + LoVal);
}
/// <summary>
/// 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
/// </summary>
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;
}
/// <summary>
@@ -64,10 +56,12 @@ namespace S7.Net.Types
/// </summary>
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;

View File

@@ -3,19 +3,14 @@
/// <summary>
/// Contains the methods to convert from S7 strings to C# strings
/// </summary>
public static class String
public class String
{
/// <summary>
/// Converts a string to S7 bytes
/// </summary>
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);
}
/// <summary>
@@ -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;
}
}
}

26
S7.Net/Types/StringEx.cs Normal file
View File

@@ -0,0 +1,26 @@
namespace S7.Net.Types
{
/// <summary>
/// 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
/// </summary>
public static class StringEx
{
/// <summary>
/// Converts S7 bytes to a string
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
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);
}
}
}

View File

@@ -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;
}

View File

@@ -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]);
}
/// <summary>
/// Converts a word (2 bytes) to ushort (UInt16)
/// Converts 2 bytes to ushort (UInt16)
/// </summary>
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);
}
/// <summary>
/// Converts a ushort (UInt16) to word (2 bytes)
/// </summary>
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;
}