赵玉~想要一个定所 2023-11-10 10:39 采纳率: 50%
浏览 151
已结题

C# S7.NetPlus 使用读取类的方式获取PLC DB块的Struct或Array数据类型的数据

C# S7.netPlus 使用类的方式读取PLC。
简单的类型使用类映射读取已经实现比如bool,int,real已经实现,但是现在遇到了DB块里面有Struct,和Array这种类型的数据,适应类映射该怎么读取。如何写?
使用的方法plc.ReadClass(t, db, startByteAdr);

数组类型报错 Received error from PLC: Address out of range.”
结构体类型报错 The size of the class is less than 1 byte and therefore cannot be read 和S7.Net.PlcException:“Received error from PLC: Address out of range.”

结构体DB块

img

结构体类声明

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PLCClass
{
    public class PlcEntity
    {
        public struct _6P101 
        {
            public   bool _local { get; set; }
            public   bool _Fail { get; set; }
            public   bool _Start_Cmd { get; set; }
            public   bool _Stop_Cmd { get; set; }
            public   bool _Km_Start { get; set; }
            public   bool _Km_Stop { get; set; }
            public   bool _I { get; set; }
            public   ushort _Sec { get; set; }
            public   ushort _min { get; set; }
            public   ushort _Hour { get; set; }
            public   bool _Clean { get; set; }
            public   bool _Sec_Plus { get; set; }
        }

        public struct _6P102
        {
            public bool _local { get; set; }
            public bool _Fail { get; set; }
            public bool _Start_Cmd { get; set; }
            public bool _Stop_Cmd { get; set; }
            public bool _Km_Start { get; set; }
            public bool _Km_Stop { get; set; }
            public bool _I { get; set; }
            public ushort _Sec { get; set; }
            public ushort _min { get; set; }
            public ushort _Hour { get; set; }
            public bool _Clean { get; set; }
            public bool _Sec_Plus { get; set; }
        }
      //public _6P101 _6P1017 { get; set; } = new _6P101();
      // public _6P102 _6P1028 { get; set; } = new _6P102();
        public _6P101 _6P1017 { get; set; }
        public _6P102 _6P1028 { get; set; }
        // 定义一个静态变量来保存类的实例
        private static PlcEntity uniqueInstance;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        // 定义私有构造函数,使外界不能创建该类实例
        private PlcEntity()
        {
          
        }
        /// <summary>2
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static PlcEntity GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new PlcEntity();
                    }
                }
            }
            return uniqueInstance;
        }
    }
}


数组DB块

img

数组类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PLCClass
{
    public class PLCDB10Entity
    {
        public bool[] data1 { get; set; } = new bool[11];

        // 定义一个静态变量来保存类的实例
        private static PLCDB10Entity uniqueInstance;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        // 定义私有构造函数,使外界不能创建该类实例
        private PLCDB10Entity()
        {

        }
        /// <summary>2
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static PLCDB10Entity GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new PLCDB10Entity();
                    }
                }
            }
            return uniqueInstance;
        }
    }
}


报错

img

  • 写回答

6条回答 默认 最新

  • 专家-司宇[在线] 2023-11-10 10:56
    关注

    引自强大而免费的微信小程序:皆我工具箱

    首先,对于数组类型的数据,可以使用S7.Net的ReadBytes方法读取。首先确定数组的起始字节地址和长度,然后使用ReadBytes方法将数据读取到字节数组中,最后使用BitConverter将字节数组转换为对应的数据类型。

    对于结构体类型的数据,可以使用类的方式进行映射读取。首先创建一个类来表示结构体,类的属性应该和结构体的字段一一对应。然后使用plc.ReadClass方法将数据从PLC读取到该类的实例中。

    下面是使用这种方法来读取PLC DB块的Struct和Array数据类型的示例代码:

    using S7.Net;
    using System;
    
    namespace PLCClass
    {
        class Program
        {
            static void Main(string[] args)
            {
                Plc plc = new Plc(CpuType.S71200, "192.168.0.1", 0, 1); // 这里根据实际情况初始化PLC对象
    
                // 读取结构体数据
                PlcEntity._6P101 structData = plc.ReadClass<PlcEntity._6P101>(10, 0); // 这里10表示DB块的号码,0表示结构体的起始字节地址
    
                // 读取数组数据
                byte[] arrayDataBytes = plc.ReadBytes(DataType.DataBlock, 10, 10, 11); // 这里10表示DB块的号码,10表示数组的起始字节地址,11表示数组的长度
                bool[] arrayData = new bool[11];
                for (int i = 0; i < arrayDataBytes.Length; i++)
                {
                    arrayData[i] = BitConverter.ToBoolean(arrayDataBytes, i);
                }
    
                // 输出结果
                Console.WriteLine("Struct Data:");
                Console.WriteLine("_local: " + structData._local);
                Console.WriteLine("_Fail: " + structData._Fail);
                // ...
    
                Console.WriteLine("\nArray Data:");
                for (int i = 0; i < arrayData.Length; i++)
                {
                    Console.WriteLine("data1[" + i + "]: " + arrayData[i]);
                }
            }
        }
    }
    

    注意要根据实际情况修改Plc的初始化参数和DB块的号码、起始地址、长度等参数。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 11月18日
  • 已采纳回答 11月10日
  • 赞助了问题酬金15元 11月10日
  • 创建了问题 11月10日

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看