西门子PLC通信

西门子DB

DB 为数据块,就是DATA BLOCK 的两个单词的简写。
DB100是数据块编号为100,DBX0.0:就是在数据块中,第一个字节的第一个位。
DB100.DBX0.0 完整的意思:在数据块100中,第一个字节的第一个位

1、DB100.DBB0 一个字节有8个位,分别为0---7!例:0.0----0.7共8位。
2、DB100.DBW0一个字有两个字节,分别为 DB100.DBB0和 DB100.DBB1
3、DB100.DBD0一个双字有两个字,分别为 DB100.DBW0和 DB100.DBW2
4、DB100.DBX0.0 一个位,这是最小单位。

数据块位表示用DBX 1位 1bit
数据块字节表示用DBB 8位 1byde
数据块字表示用DBW 16位
数据块双字表示用DBD 32位

Bit  	=> 	DB1.DBX0.0
Byte 	=> 	DB1.DBB0
word 	=> 	DB1.DBW0
DWord 	=> 	DB1.DBD0
Int 	=> 	DB1.DBW0
DInt 	=> 	DB1.DBD0
Real 	=> 	DB1.DBD0

西门子DB_西门子plc程序中db和dbx-CSDN博客

C#与西门子类型转换

Bit  	=> 	bool
    
Byte 	=> 	byte
//S7 Word (无符号短整型, 16位)
word 	=> 	ushort   
//S7 DWord (无符号长整型, 32位)
DWord 	=> 	uint
//S7 Int / Dec (有符号短整型, 16位)
Int 	=> 	short
//S7 Dint (有符号长整型, 32位)
DInt 	=> 	int
//S7 Real (浮点数, 32位IEEE 754格式)
Real 	=> 	float
LReal 	=> 	double
String 	=> 	string

S7.NET

//1、建立连接
CpuType cpuType = (CpuType)Enum.Parse(typeof(CpuType), XHText.Text, true);
//PLC类型、IP、rack、slot
myplc = new Plc(cpuType, IPText.Text, short.Parse(JTHText.Text.ToString()), short.Parse(CCHText.Text.ToString()));
myplc.Open();

//2、断开连接
myplc.Close();

//3、数据读取
var Value = myplc.Read(DZText1.Text.ToUpper());
//Bit  	=> 	bool
OutValue = ((bool)Value).ToString();
//Byte 	=> 	byte
OutValue = ((byte)Value).ToString();
//word 	=> 	ushort
OutValue = ((ushort)Value).ConvertToShort().ToString();
//DWord 	=> 	uint
OutValue = ((uint)Value).ConvertToInt().ToString();
//Int 	=> 	short
OutValue = ((ushort)Value).ConvertToShort().ToString();
//DInt 	=> 	int
OutValue = ((uint)Value).ConvertToInt().ToString();
//Real 	=> 	float
OutValue = ((uint)Value).ConvertToDouble().ToString();

//4、数据写入
//Bit  	=> 	bool
myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToBoolean(WriteText.Text.ToString().ToUpper()));
//Byte 	=> 	byte
 myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToByte(WriteText.Text.ToString().ToUpper()));
//word 	=> 	ushort
 myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToUInt16(WriteText.Text.ToString().ToUpper()));
//DWord 	=> 	uint
myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToUInt32(WriteText.Text.ToString().ToUpper()));
//Int 	=> 	short
myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToUInt16(WriteText.Text.ToString().ToUpper()));
//DInt 	=> 	int
myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToUInt32(WriteText.Text.ToString().ToUpper()));
//Real 	=> 	float
OutValue = ((uint)Value).ConvertToDouble().ToString();
myplc.Write(XRDZText1.Text.ToString().ToUpper(), Convert.ToUInt32(WriteText.Text.ToString().ToUpper()));



C#与西门子PLC的S7.net通信 - 知乎 (zhihu.com)

.net通过S7.net读写西门子PLC中,字符串,bool,整数,小数及byte型_西门子的数组类型地址位怎么读-CSDN博客

C#使用S7.net连接西门子S1200PLC,C#直接连接西门子PLC_c#与plc通讯-CSDN博客

c#使用s7netplus读取plc数据-CSDN博客

ReadBytes

类型转换

//byte
return bytes[0];
//ushort
return Word.FromByteArray(bytes);
//short
return Int.FromByteArray(bytes);
//uint
return DWord.FromByteArray(bytes);
//int
return DInt.FromByteArray(bytes);
//float
return S7.Net.Types.Single.FromByteArray(bytes);
//string  读取时需要往后移动两字节
S7.Net.Types.String.FromByteArray(bytes);
//bool
return Bit.FromByte(bytes[0], bitAdr);

读取方式

注意:西门子两个string之间需要最少预留1字节空间

//读取地址形式  DB1.DBX1.1
public object? Read(string variable)
{
    PLCAddress pLCAddress = new PLCAddress(variable);
    return Read(pLCAddress.DataType, pLCAddress.DbNumber, pLCAddress.StartByte, pLCAddress.VarType, 1, (byte)pLCAddress.BitNumber);
}

//地址解析  DB1.DBX
public PLCAddress(string address)
{
    Parse(address, out dataType, out dbNumber, out varType, out startByte, out bitNumber);
}

public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0)
{
    //根据数据类型获取长度
    int count = VarTypeToByteLength(varType, varCount);
    //读取字节数据
    byte[] bytes = ReadBytes(dataType, db, startByteAdr, count);
    
    return ParseBytes(varType, bytes, varCount, bitAdr);
}

//长度计算
private int VarTypeToByteLength(VarType varType, int varCount = 1)
{
    switch (varType)
    {
        case VarType.Bit:
            return varCount;
        case VarType.Byte:
            if (varCount >= 1)
            {
                return varCount;
            }

            return 1;
        case VarType.String:
            return varCount;
        case VarType.StringEx:
            return varCount + 2;
        case VarType.Word:
        case VarType.Int:
        case VarType.Timer:
        case VarType.Counter:
            return varCount * 2;
        case VarType.DWord:
        case VarType.DInt:
        case VarType.Real:
            return varCount * 4;
        case VarType.DateTime:
            return varCount * 8;
        case VarType.DateTimeLong:
            return varCount * 12;
        default:
            return 0;
    }
}


//读取数据
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
{
    byte[] array = new byte[count];
    int num = 0;
    while (count > 0)
    {
        int num2 = Math.Min(count, MaxPDUSize - 18);
        ReadBytesWithSingleRequest(dataType, db, startByteAdr + num, array, num, num2);
        count -= num2;
        num += num2;
    }

    return array;
}


//类型转换
private object? ParseBytes(VarType varType, byte[] bytes, int varCount, byte bitAdr = 0)
{
    if (bytes == null || bytes.Length == 0)
    {
        return null;
    }

    switch (varType)
    {
        case VarType.Byte:
            if (varCount == 1)
            {
                return bytes[0];
            }

            return bytes;
        case VarType.Word:
            if (varCount == 1)
            {
                return Word.FromByteArray(bytes);
            }

            return Word.ToArray(bytes);
        case VarType.Int:
            if (varCount == 1)
            {
                return Int.FromByteArray(bytes);
            }

            return Int.ToArray(bytes);
        case VarType.DWord:
            if (varCount == 1)
            {
                return DWord.FromByteArray(bytes);
            }

            return DWord.ToArray(bytes);
        case VarType.DInt:
            if (varCount == 1)
            {
                return DInt.FromByteArray(bytes);
            }

            return DInt.ToArray(bytes);
        case VarType.Real:
            if (varCount == 1)
            {
                return S7.Net.Types.Single.FromByteArray(bytes);
            }

            return S7.Net.Types.Single.ToArray(bytes);
        case VarType.String:
            return S7.Net.Types.String.FromByteArray(bytes);
        case VarType.StringEx:
            return StringEx.FromByteArray(bytes);
        case VarType.Timer:
            if (varCount == 1)
            {
                return Timer.FromByteArray(bytes);
            }

            return Timer.ToArray(bytes);
        case VarType.Counter:
            if (varCount == 1)
            {
                return Counter.FromByteArray(bytes);
            }

            return Counter.ToArray(bytes);
        case VarType.Bit:
            if (varCount == 1)
            {
                if (bitAdr > 7)
                {
                    return null;
                }

                return Bit.FromByte(bytes[0], bitAdr);
            }

            return Bit.ToBitArray(bytes, varCount);
        case VarType.DateTime:
            if (varCount == 1)
            {
                return S7.Net.Types.DateTime.FromByteArray(bytes);
            }

            return S7.Net.Types.DateTime.ToArray(bytes);
        case VarType.DateTimeLong:
            if (varCount == 1)
            {
                return DateTimeLong.FromByteArray(bytes);
            }

            return DateTimeLong.ToArray(bytes);
        default:
            return null;
    }
}

写入方式

//根据Value的类型转化为byte[]
Serialization.SerializeValue(value);

//写入数据byte[]
public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
{
    int num = 0;
    int num2 = value.Length;
    while (num2 > 0)
    {
        int num3 = Math.Min(num2, MaxPDUSize - 28);
        WriteBytesWithASingleRequest(dataType, db, startByteAdr + num, value, num, num3);
        num2 -= num3;
        num += num3;
    }
}
//Example
WriteBytes(dataType, db, startByteAdr, Serialization.SerializeValue(value));

//value转换为byte[]
public static byte[] SerializeValue(object value)
{
    switch (value.GetType().Name)
    {
        case "Boolean":
            return new byte[1] { (byte)(((bool)value) ? 1u : 0u) };
        case "Byte":
            return S7.Net.Types.Byte.ToByteArray((byte)value);
        case "Int16":
            return Int.ToByteArray((short)value);
        case "UInt16":
            return Word.ToByteArray((ushort)value);
        case "Int32":
            return DInt.ToByteArray((int)value);
        case "UInt32":
            return DWord.ToByteArray((uint)value);
        case "Double":
            return S7.Net.Types.Double.ToByteArray((double)value);
        case "Single":
            return S7.Net.Types.Single.ToByteArray((float)value);
        case "DateTime":
            return S7.Net.Types.DateTime.ToByteArray((System.DateTime)value);
        case "Byte[]":
            return (byte[])value;
        case "Int16[]":
            return Int.ToByteArray((short[])value);
        case "UInt16[]":
            return Word.ToByteArray((ushort[])value);
        case "Int32[]":
            return DInt.ToByteArray((int[])value);
        case "UInt32[]":
            return DWord.ToByteArray((uint[])value);
        case "Double[]":
            return S7.Net.Types.Double.ToByteArray((double[])value);
        case "Single[]":
            return S7.Net.Types.Single.ToByteArray((float[])value);
        case "String":
            {
                string obj = (string)value;
                return S7.Net.Types.String.ToByteArray(obj, obj.Length);
            }
        case "DateTime[]":
            return S7.Net.Types.DateTime.ToByteArray((System.DateTime[])value);
        case "DateTimeLong[]":
            return DateTimeLong.ToByteArray((System.DateTime[])value);
        default:
            throw new InvalidVariableTypeException();
    }
}


//写入Bit
public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
{
    if (bitAdr < 0 || bitAdr > 7)
    {
        throw new InvalidAddressException($"Addressing Error: You can only reference bitwise locations 0-7. Address {bitAdr} is invalid");
    }

    WriteBitWithASingleRequest(dataType, db, startByteAdr, bitAdr, value);
}

//写入Bit
public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, int value)
{
    if (value < 0 || value > 1)
    {
        throw new ArgumentException("Value must be 0 or 1", "value");
    }

    WriteBit(dataType, db, startByteAdr, bitAdr, value == 1);
}


//写入S7String
var temp = Encoding.ASCII.GetBytes(val);
var bytes = S7.Net.Types.S7String.ToByteArray(val, temp.Length);
_plc.WriteBytes(dataType, dbNumber, address, bytes);


public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
{
    int num = 0;
    int num2 = value.Length;
    while (num2 > 0)
    {
        int num3 = Math.Min(num2, MaxPDUSize - 28);
        WriteBytesWithASingleRequest(dataType, db, startByteAdr + num, value, num, num3);
        num2 -= num3;
        num += num3;
    }
}

private void WriteBytesWithASingleRequest(DataType dataType, int db, int startByteAdr, byte[] value, int dataOffset, int count)
{
    try
    {
        Stream streamIfAvailable = GetStreamIfAvailable();
        byte[] array = BuildWriteBytesPackage(dataType, db, startByteAdr, value, dataOffset, count);
        streamIfAvailable.Write(array, 0, array.Length);
        ValidateResponseCode((ReadWriteErrorCode)COTP.TSDU.Read(streamIfAvailable)[14]);
    }
    catch (Exception innerException)
    {
        throw new PlcException(ErrorCode.WriteData, innerException);
    }
}


private static object GetVariableValue(VarType varType, string text)
{
    switch (varType)
    {
        case VarType.Bit:
            return bool.Parse(text);
        case VarType.Byte:
            return byte.Parse(text);
        case VarType.Word:
            return ushort.Parse(text);
        case VarType.DWord:
            return uint.Parse(text);
        case VarType.Int:
            return short.Parse(text);
        case VarType.DInt:
            return int.Parse(text);
        case VarType.Real:
            return float.Parse(text);
        case VarType.LReal:
            return double.Parse(text);
        default:
            return null;
    }
}


//bool
WriteBit(dataType, db, startByteAdr, bitAdr, value2);
WriteBytes(dataType, db, startByteAdr, Serialization.SerializeValue(value));

异常

S7PlcDataManager封装的String读取PLC时字节长度+1,S7String读取PLC时字节长度+2,都是在头部添加字符串长度.

采用S7Sstring类型读取和写入PLC中字符串

posted @ 2025-03-25 10:05  AWT-Stephen  阅读(395)  评论(0)    收藏  举报