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所有字节数组时,怎么通过简便的方法映射到结构体里面
版权声明:本文标题:今天要说的是,当使用 Snet.* 采集库读取PLC所有字节数组时,怎么通过简便的方法映射到结构体里面 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1748236666a2830488.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论