admin管理员组

文章数量:1446760

今天要说的是,当使用 Snet.* 采集库读取PLC所有字节数组时,怎么通过简便的方法映射到结构体里面

如题,通过什么方式映射可以得到字节对应的数据对象呢?下面我们就来看看

但是要注意的是,你得明确知道你读到字节数据哪位到哪位是什么意思,什么类型,还需知道转换格式,这样才能使用如下方法

此方法针对于你有很多点位你觉得单点读取慢时,可以一次性读取 ByteArray,只需一次命令得到所有数据,这样就可以从几百毫秒甚至几秒的请求理论缩短到 ≤50 毫秒

1. 先定义特性

代码语言:javascript代码运行次数:0运行复制
/// <summary>
/// 定义一个解析特性
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class SensorAttribute : Attribute
{
    public SensorAttribute(int startBit, int length, DataType dataType)
    {
        this.StartBit = startBit;
        this.Length = length;
        this.DataType = dataType;
    }
    public SensorAttribute(int startBit, DataType dataType)
    {
        this.StartBit = startBit;
        this.DataType = dataType;
    }
    /// <summary>
    /// 开始位
    /// </summary>
    public int? StartBit { get; private set; } = null;
    /// <summary>
    /// 长度
    /// </summary>
    public int? Length { get; private set; } = null;
    /// <summary>
    /// 数据类型
    /// </summary>
    public DataType DataType { get; private set; } = DataType.None;
}

2. 定义结构体

代码语言:javascript代码运行次数:0运行复制
/// <summary>
/// 定义一个结构体
/// </summary>
public class Test
{
    /// <summary>
    /// 0-3,传感器1
    /// </summary>
    [Sensor(0, 4, DataType.Float)]
    public float sensor1 { get; set; }
    /// <summary>
    /// 4-7,传感器2
    /// </summary>
    [Sensor(4, 4, DataType.Int)]
    public int sensor2 { get; set; }
    /// <summary>
    /// 8-15,传感器3
    /// </summary>
    [Sensor(8, 8, DataType.Double)]
    public double sensor3 { get; set; }
    /// <summary>
    /// 16,传感器4
    /// </summary>
    [Sensor(16, DataType.Bool)]
    public bool sensor4 { get; set; }
}

3. 代码解析的实现

代码语言:javascript代码运行次数:0运行复制
static async Task Main(string[] args)
{
    //创建一个字节缓存
    List<byte> bytes = new List<byte>();
    //已知:0-3,传感器1
    byte[] bytes_float = BitConverter.GetBytes(1.1f);
    //添加到缓存
    bytes.AddRange(bytes_float);
    //已知:4-7,传感器2
    byte[] bytes_int = BitConverter.GetBytes(66);
    //添加到缓存
    bytes.AddRange(bytes_int);
    //已知:8-15,传感器3
    byte[] bytes_double = BitConverter.GetBytes(3.1415d);
    //添加到缓存
    bytes.AddRange(bytes_double);
    //已知:16,传感器4
    byte[] bytes_bool = BitConverter.GetBytes(true);
    //添加到缓存
    bytes.AddRange(bytes_bool);



    //模拟一次性读取所有字节
    byte[] new_bytes = bytes.ToArray();

    //打印缓存字节数据
    Console.WriteLine(new_bytes.HexToStr());

    //实例化对象
    Test test = new Test();

    //遍历结构体属性
    foreach (var item in test.GetType().GetProperties())
    {
        //取到特性定义
        var info = test.GetType().GetProperty(item.Name).GetCustomAttribute<SensorAttribute>();

        //判断类型
        switch (info.DataType)
        {
            case DataType.Bool:  //一个字节
                item.SetValue(test, BitConverter.ToBoolean(new_bytes, info.StartBit.Value));
                break;
            case DataType.Double: //八个字节
                //缓冲区
                bytes_double = new byte[info.Length.Value];
                //字节复制
                Array.Copy(new_bytes, info.StartBit.Value, bytes_double, 0, info.Length.Value);
                //设置值
                item.SetValue(test, BitConverter.ToDouble(bytes_double));
                break;
            case DataType.Float:  //四个字节
                bytes_float = new byte[info.Length.Value];
                Array.Copy(new_bytes, info.StartBit.Value, bytes_float, 0, info.Length.Value);
                item.SetValue(test, BitConverter.ToSingle(bytes_float));
                break;
            case DataType.Int:  //四个字节
                bytes_int = new byte[info.Length.Value];
                Array.Copy(new_bytes, info.StartBit.Value, bytes_int, 0, info.Length.Value);
                item.SetValue(test, BitConverter.ToInt32(bytes_int));
                break;
            default:
                Console.WriteLine($"{info.DataType}此类型不支持处理");
                break;
        }

    }

    //打印解析后的结果
    Console.WriteLine(test.ToJson(true));
}

4. 最终得到的数据结果图片

本文作者 :「 博主 」大顺

分享地址 : Shunnet.top/yvFuv 版权声明 : 转载注明出处

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-03-12,如有侵权请联系 cloudcommunity@tencent 删除summary数据数组缓存plc

本文标签: 今天要说的是,当使用 Snet* 采集库读取PLC所有字节数组时,怎么通过简便的方法映射到结构体里面