WPF上位机 - S7.NETPlus批量读取数据

在编写上位机程序中,需要读取PLC数据。使用到了S7.NETPlus 这个库。
S7.NETPlus提供了很多读取和写入数据的方式。大批量读取数据的方式包括一下几个方法

  • Readbytes
  • ReadClass
  • ReadStruct
  • ReadMultipleVars

PLC侧的数据是一个Array的UDT数据,其中UDT中还包含了很多的UDT。在使用库的过程中,发现ReadClass 和 ReadStruct 面对UDT类型的数据时,有时候会报错。
试了很久放弃了ReadClass和Read Struct。 准备使用ReadMultipleVars需要一个VarList,对于使用过程中的变量映射不是很方面,最终还是使用了ReadBytes

var AxisInterface = SiemensPlc.Instance.AxisController.ReadBytes(DataType.DataBlock, SiemensPlc.Instance.InterfaceDB, SiemensPlc.instance.AxisId * 730, 730);
以上代码中使用ReadBytes 读取730个字节的数据到了AxisInterface中。接下来就需要将读取到的数据使用Coverter转换为需要的数据类型。
但是由于西门子PLC 和 PC的存储数据大小端不一致的问题,还要大小端调换一下。这样就非常的麻烦,需要先Reverse在Converter。一个变量需要操作两步。

解决

在阅读S7.NetPlus源码过程中,发现库中已经有了相关的操作。以LReal举例


using System;

namespace S7.Net.Types;

//
// 摘要:
//     Contains the conversion methods to convert Real from S7 plc to C# double.
public static class LReal
{
    //
    // 摘要:
    //     Converts a S7 LReal (8 bytes) to double
    public static double FromByteArray(byte[] bytes)
    {
        if (bytes.Length != 8)
        {
            throw new ArgumentException("Wrong number of bytes. Bytes array must contain 8 bytes.");
        }

        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(bytes);
        }

        return BitConverter.ToDouble(bytes, 0);
    }

    //
    // 摘要:
    //     Converts a double to S7 LReal (8 bytes)
    public static byte[] ToByteArray(double value)
    {
        byte[] bytes = BitConverter.GetBytes(value);
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(bytes);
        }

        return bytes;
    }

    //
    // 摘要:
    //     Converts an array of double to an array of bytes
    public static byte[] ToByteArray(double[] value)
    {
        return TypeHelper.ToByteArray(value, ToByteArray);
    }

    //
    // 摘要:
    //     Converts an array of S7 LReal to an array of double
    public static double[] ToArray(byte[] bytes)
    {
        return TypeHelper.ToArray(bytes, FromByteArray);
    }
}

在S7.NET.Type中 提供了一系列数据类型的相关操作。可以直接使用。
这样根据PLC中数据的变量地址可以快速的写出来。

#region ActualValues
SiemensPlc.instance.actualValus.ActualVelocity = LReal.FromByteArray(AxisInterface[0..8]);
SiemensPlc.instance.actualValus.ActualPosition = LReal.FromByteArray(AxisInterface[8..16]);
SiemensPlc.instance.actualValus.TargetPosition = LReal.FromByteArray(AxisInterface[16..24]);
SiemensPlc.instance.actualValus.IsHomed = Bit.FromByte(AxisInterface[24], 0);
SiemensPlc.instance.actualValus.BrakelsOpen = Bit.FromByte(AxisInterface[24], 1);
SiemensPlc.instance.actualValus.AxisAlarm =DInt.FromByteArray(AxisInterface[26..30]);
SiemensPlc.instance.actualValus.AxisError = Bit.FromByte(AxisInterface[30], 0);
SiemensPlc.instance.actualValus.ErrorDetailReaction = DInt.FromByteArray(AxisInterface[32..36]);

#endregion Actual Values
posted @ 2024-05-03 16:18  4LPH4_αX  阅读(595)  评论(1编辑  收藏  举报