C#上位机与三菱PLC的通信10---开发自己的通讯工具软件(Winform版)

本文介绍了如何利用已经封装的通讯库开发一个Winform程序,作为专业的PLC通讯工具,包括创建项目、界面设计、添加通讯库引用、配置PLC参数、连接与断开、读取和写入不同类型的数据以及错误处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、工具介绍

上节2篇文章已经完成了通讯库的开发,可以看到封装的通讯库还是蛮厉害的,通讯库封装好后就是一个dll文件,那么可以在项目中就可以直接拿来应用,这节要做的就是做一个工具软件,形成自己专业的通讯工具,也是对通讯库的直接利用,本节要写的工具软件是一个winform程序,因为控制台程序是单调的,不方便操作,不直观。

2、开始干

1、创建窗体程序项目

2、界面UI设计布局

这里的布局因为时间的原因,没有去做精心的设计布局,没有引用其他的winform ui控件,使用的是传统的自带控件,当然你可以利用第三方的winform窗体控件来设计,比如HZHControls,SunnyUI等,有很多,另外本工具只针对MC协议的Qna-3E模式应用。

3、引入通讯库dll文件

将上一节封装好的通讯库文件复制到本项目中,并添加引用

 4、引入PLC配置参数

我们将PLC的IP地址和端口号写在项目的配置文件中,即写入到app.config

在窗体加载时读取配置文件,初始化PLC参数

 

5、错误异常处理

6、启动MC服务器

7、读取数据

1、读取short数据,包括ushort

2、读取float,包括ushort,short

3、读取bool

8、写入数据

1、写入short类型数据

2、写入float类型数据

9、完整代码

using Mitsubishi.Communication.MC.Mitsubishi;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MitsubishiMcToolForm
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// mctcp对象
        /// </summary>
        A3E mctcp=null;
        /// plc的ip地址
        /// </summary>
        private static string plcipstr = ConfigurationManager.AppSettings["plcIp"].ToString(); 
        /// <summary>
        /// plc端口
        /// </summary>
        private static string plcportstr = ConfigurationManager.AppSettings["plcPort"].ToString(); 

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            txtIPAddress.Text = plcipstr;
            txtPort.Text = plcportstr;
        }

        /// <summary>
        /// 连接PLC
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            string ip = txtIPAddress.Text.Trim();
            string port = txtPort.Text.Trim();
            mctcp = new A3E(ip,short.Parse(port));// 创建连接 
            var result = mctcp.Connect();// 开始连接PLC
            if (!result.IsSuccessed)
            {
                MessageBox.Show(result.Message);
                return;
            }
            lblMessage.Text = "PLC连接成功";
            SetTextDisable(true);
            this.btnOpen.Enabled = false;
            this.btnClose.Enabled = true;
        } 
        private void SetTextDisable(bool v)
        {
            txtIPAddress.ReadOnly = v;
            txtPort.ReadOnly = v;
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void myread_Click(object sender, EventArgs e)
        {
            //读取M区100开始的5个float数据
            //    读取D区100开始的3个short数据
            //    读取X区100开始的2个bool数据
            if (mctcp == null)
            {
                MessageBox.Show("PLC未连接成功,不能读取数据","错误提示");
                return;
            }
            //内存地址
            string plcAddr = txtMemoryAddr.Text.Trim();
            //读取数量
            short readCount = short.Parse(txtRCount.Text.Trim());
            //数据类型
            string dataType = cbodatatype.Text.Trim();
            txtReadDatas2.Text = "";
            txtReadDatas3.Text = "";
            txtReadDatas4.Text = "";
            switch (dataType)
            { 
                case "short":
                    var datas2 = mctcp.Read<short>(plcAddr, readCount);
                    if (!datas2.IsSuccessed)
                    {
                        MessageBox.Show(datas2.Message);
                        return;
                    }
                    txtReadDatas2.Text = string.Join(",", datas2.Datas);
                    break;
                case "float":
                    var datas3 = mctcp.Read<float>(plcAddr, readCount);
                    if (!datas3.IsSuccessed)
                    {
                        MessageBox.Show(datas3.Message);
                        return;
                    }
                    txtReadDatas3.Text = string.Join(",", datas3.Datas);
                    break;
                case "bool":
                    var datas4 = mctcp.Read<bool>(plcAddr, readCount);
                    if (!datas4.IsSuccessed)
                    {
                        MessageBox.Show(datas4.Message);
                        return;
                    }
                    txtReadDatas4.Text = string.Join(",", datas4.Datas);
                    break;
            }
        }

        /// <summary>
        /// 断开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            if(mctcp == null)
            {
                MessageBox.Show("PLC没有连接,不必断开");
                return;
            }
            lblMessage.Text = "PLC已断开";
            SetTextDisable(false);
            this.btnOpen.Enabled = true;
            this.btnClose.Enabled = false;
        }

        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnWrite_Click(object sender, EventArgs e)
        {
            //    写入D区101开始的2个short数据
            //        写入M区104开始的3个float数据
            if (mctcp == null)
            {
                MessageBox.Show("PLC未连接成功,不能写入数据", "错误提示");
                return;
            }
            //PLC地址
            string plcAddr = txtWPLCAddr.Text.Trim();
            //数据类型
            string dataType = cmddatatype2.Text.Trim();
            //实际数量
            string objWriteVals = "";
            switch (dataType)
            { 
                case "short":
                    objWriteVals = txtWriteDatas2.Text.Trim();
                    break;
                case "float":
                    objWriteVals = txtWriteDatas3.Text.Trim();
                    break;
                case "bool":
                    objWriteVals = txtWriteDatas4.Text.Trim();
                    break;
            }
            //写入数量
            ushort writeCount = ushort.Parse(txtWPLCCount.Text.Trim());
            ushort objWCount = (ushort)objWriteVals.Split(',').Length;
            //实际数量与要求数量不一致,不允许操作
            if (writeCount != objWCount)
            {
                MessageBox.Show("写入值的数量不正确!");
                return;
            }
            List<string> vals = objWriteVals.Split(',').ToList();
            switch (dataType)
            { 
                case "short":
                    //实际数值转换成list集合 short类型
                    List<short> objshort = new List<short>();
                    vals.ForEach((x) =>
                    {
                        objshort.Add(short.Parse(x));
                    });
                    var finish2 = mctcp.Write<short>(objshort, plcAddr);
                    if (finish2.IsSuccessed)
                    {
                        MessageBox.Show(finish2.Message,"操作提示");
                    }
                    break;
                case "float":
                    //实际数值转换成list集合 float
                    List<float> objfloat = new List<float>();
                    vals.ForEach((x) =>
                    {
                        objfloat.Add(float.Parse(x));
                    });
                    var finish3 = mctcp.Write<float>(objfloat, plcAddr);
                    if (finish3.IsSuccessed)
                    {
                        MessageBox.Show(finish3.Message,"操作提示");
                    }
                    break;
                    //此功能暂时有问题
                //case "bool":
                //    //实际数值转换成list集合bool
                //    List<bool> objbool = new List<bool>();
                //    vals.ForEach((x) =>
                //    {
                //        if (x == "1")
                //        {
                //            objbool.Add(true);
                //        }
                //        else
                //        {
                //            objbool.Add(false);
                //        }
                //    });
                //    var finish4 = mctcp.Write<bool>(objbool, plcAddr);
                //    if (finish4.IsSuccessed)
                //    {
                //        MessageBox.Show(finish4.Message);
                //    }
                //    break;
            }
        }
    }
}

走过路过不要错过,点赞关注收藏又圈粉,共同致富。

欢迎抄袭,复制,分享,转载,学习,截图..............

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqwest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值