PLC通讯实现-C#实现西门子PLC串口通讯W95_S7(四)

本文档介绍了如何使用C#进行西门子PLC(W95_S7)的串口通讯。作者根据工业软件开发经验,提出了一种抽象设计方法,包括定义一个抽象基类BaseEquip,包含Open、Read、Write、Close等基本操作。通过这种方式,当更换PLC型号时,只需修改配置而无需改动业务代码。文中详细阐述了西门子串口通讯的具体实现,并提供了完整的C#代码示例。
摘要由CSDN通过智能技术生成

PLC通讯实现-C#实现西门子PLC串口通讯W95_S7(四)

背景

本人近十年的工作都与工业软件相关、其中工控系统开发过程中有一个必要环节就是跟各大厂商的PLC进行通讯,而对于从互联网行业跨入工业互联网行业的从业人员来说要实现各型号PLC通讯还是需要一个过程的,本人在此对主流型号PLC通讯实现进行总结以便大家参考。

抽象设计

首先我们要进行一下抽象设计,先设计一个抽象类(接口也可以,此处因为还有其他业务使用了抽象类)BaseEquip,对PLC的常规操作进行定义,即Open、Read、Write、Close,业务代码调用BaseEquip进行PLC的读写,然后在实现各型号的Equip类,对Open、Read、Write、Close进行实现,根据配置在业务代码中对BaseEquip进行实例化,这样后期更改PLC型号后,只需修改配置即可,不用修改业务代码。

西门子串口通讯实现W95_S7

实现语言C#

抽象基类BaseEquip

public class BaseEquip
{
   
	/// <summary>
    /// 打开设备
    /// </summary>
    /// <returns>成功返回true,失败返回false</returns>
	public abstract bool Open();
	/// <summary>
    /// 读取信息
    /// </summary>
    /// <param name="block">数据块</param>
    /// <param name="start">起始地址</param>
    /// <param name="len">长度</param>
    /// <param name="buff">读取返回信息</param>
    /// <returns>成功返回true,失败返回false</returns>
    public abstract bool Read(string block, int start, int len, out object[] buff);
    /// <summary>
    /// 写入信息
    /// </summary>
    /// <param name="block">数据块</param>
    /// <param name="start">起始地址</param>
    /// <param name="buff">要写入的数据</param>
    /// <returns>成功返回true,失败返回false</returns>
    public abstract bool Write(int block, int start, object[] buff);
    /// <summary>
    /// 关闭设备
    /// </summary>
    public abstract void Close();
}

设备实现类Equip实现

using System;
using Mesnac.Equips;
using Mesnac.Equips.BaseInfo;
using System.Runtime.InteropServices;

namespace Mesnac.Equip.Siemens.S7.Default
{
   
    /// <summary>
    /// 西门子S7-300PLC串口通讯设备类
    /// </summary>
    public class Equip : BaseEquip
    {
   
        private bool _isOpen = false;   //是否打开连接
        private IntPtr equipHandle = new IntPtr(Marshal.SizeOf(typeof(int)));

        private IntPtr structToIntPtr<T>(T s)
        {
   
            int nSizeOfT = Marshal.SizeOf(typeof(T));
            int nSizeOfIntPtr = Marshal.SizeOf(typeof(IntPtr));
            IntPtr Result = new IntPtr();
            Result = Marshal.AllocHGlobal(nSizeOfT);
            Marshal.StructureToPtr(s, (IntPtr)((UInt32)Result), true);
            return Result;
        }

        private T IntPtrTostruct<T>(IntPtr p)
        {
   
            return (T)Marshal.PtrToStructure(p, typeof(T));
        }
        private int Swap(int a)
        {
   
            return (a >> 8 & 0xFF) + (a << 8 & 0xFF00);
        }
        public override bool Open()
        {
   
            lock (this)
            {
   
                if (this._isOpen == true)
                {
   
                    return true;
                }
                this.State = false;
                //W95_S7.PLCConnParam adressType = new W95_S7.PLCConnParam();
                byte c1 = 1;
                byte[,] p3 = {
    {
    2, 0, 2, 0 }, {
    3, 0, 2, 0 }, {
    0, 0, 0, 0 } };


                int Result = W95_S7.load_tool(c1, "S7ONLINE", p3);
                if ((Result != 0) && (Result != 39))  // 39已经初始化
                {
   
                    Console.WriteLine("PLC连接失败:" + this.GetErrInfo(Result));
                    this.State = false;
                    return this.State;
                }
                else
                {
   
                    this.State = true;
                    this._isOpen = true;
                }
                return this.State;
            }
        }
        /// <summary>
        /// PLC数据读取方法
        /// </summary>
        /// <param name="block">要读取的块号</param>
        /// <param name="start">要读取的起始字</param>
        /// <param name="len">要读取的长度,最大255,超过255则不读取</param>
        /// <param name="buff"></param>
        /// <returns></returns>
        public override bool Read(string block, int start, int len, out object[] buff)
        {
   
            lock (this)
            {
   
                buff = new object[len];
                try
                {
   
                    if (len > 256)
                    {
   
                        for (int i = 0; i < len; i++)
                        {
   
                            buff[i] = 0;
                        }
                        base.State = false;
                        return 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值