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

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 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀