现如今,ModBus协议可以说是工业控、现场数据采集邻域各种控制设备与传感器应用最为广泛的数据交互协议,不管是简单方便的串口,还是高速稳定的以太网,ModBus协议都有相应的适配其传输特点的协议。
虽然目前主流的ModBus人机交互主站是组态王或者各种工控厂家生产的触摸屏,但如果你想做一些带逻辑控制或者界面比较自由的上位机,那么该文章将在Visual Studio集成开发环境下,使用C#语言和Visual Studio的Winform框架,从环境安装、创建工程、ModBus库的安装、代码编写和程序调试等几个步骤,带你快速开发出一个Window平台环境下的ModBus主站上位机demo。(该文档以Visual Studio 2017为例)
搭建开发环境
Visual Studio 社区版下载地址:
在“工作负荷”菜单处勾选“.NET桌面开发”(已省略安装具体步骤)与你需要的其他组件。
安装完成后,我们进入下一步。
创建工程
1、打开Visual Studio依次点击“文件”->“新建”->“项目”
创建Visual C#的 Windows窗体应用,按如下步骤创建Windows窗体应用,下面第四步我们可以自定义工程名称,这里笔者将该工程命名成“ModBusMaster”,完成后点击“确定。
ModBus库的安装
工程创建完成后,中间红色部分窗体就是我们该工程默认生成的界面,默认程序运行起来后会加载该界面,但我们先不管界面,我们先为工程安装Easy ModBusTcp库。
EasyModBusTCP是基于.NET Framework和Java平台上的ModBus TCP/UDP/RTU通讯协议库。它主要用于工业自动化领域,帮助用户实现远程控制和数据采集。
EasyModBusTCP的特点如下:
(1)简单易用:EasyModBusTCP提供了简单易用的API,使得用户可以轻松地实现与ModBus设备的通信。
(2)支持多种编程语言:EasyModBusTCP支持多种编程语言,如C#、VB.NET、Java、C++以及更多C#的变体,如Unity、Mono、.NET Core等。
(3)支持多种ModBus协议:EasyModBusTCP不仅支持ModBus TCP协议,还支持ModBus UDP和ModBus RTU协议。
(4)支持点对点通信:EasyModBusTCP支持点对点通信,每个设备都有一个唯一的IP地址,使得用户可以直接与特定设备进行通信。
(5)支持ModBus报文两种类型:EasyModBusTCP支持ModBus报文的两种类型,包括读取请求和写入请求。读取请求用于获取服务器上的数据,写入请求用于向服务器写入数据。
(6)可靠的数据传输:EasyModBusTCP使用TCP连接来确保可靠的数据传输。在通信之前,需要建立TCP连接,并在通信结束后关闭连接。
在上图红色区域点击鼠标右键然后点击“查看代码”(或者键盘单机“F7”),进入工程代码文件,然后点击”项目”->“管理NuGet程序包”。
在“浏览”菜单栏的搜索框中输入“easy ModBusTCP”,找到如下图扩展库后点击“下载”;
安装成功后我们可以在解决方案资源管理器中,引用中找到该扩展库。
代码编写
(1)界面设计
(2)源码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EasyModBus;
namespace ModBusMaster
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Master = new ModBusClient();
this.slaveIP.Text = "192.168.3.7";
this.serverPort.Text = "502";
Master.UnitIdentifier = 2;
}
EasyModBus.ModBusClient Master = null;
private bool SlaveCoilWrite(int regaddr , bool status)
{
try
{
Master.WriteSingleCoil(regaddr, status);
}
catch
{
return false;
}
return true;
}
private void btn_connect_Click(object sender, EventArgs e)
{
if (Master.Connected) return;
Master.Connect(this.slaveIP.Text, int.Parse(this.serverPort.Text));
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Master.Disconnect();
}
private void btn_do1_on_Click(object sender, EventArgs e)
{
SlaveCoilWrite(0, true);
}
private void btn_do2_on_Click(object sender, EventArgs e)
{
SlaveCoilWrite(1, true);
}
private void btn_do3_on_Click(object sender, EventArgs e)
{
SlaveCoilWrite(2, true);
}
private void btn_do4_on_Click(object sender, EventArgs e)
{
SlaveCoilWrite(3, true);
}
private void btn_do1_4_on_Click(object sender, EventArgs e)
{
//for (int i = 0; i < 4; i++)
//{
// SlaveCoilWrite(i, true);
//}
bool[] sta = new bool[4] { true , true , true , true};
try
{
Master.WriteMultipleCoils(0, sta);
}
catch
{
}
}
private void btn_do1_off_Click(object sender, EventArgs e)
{
SlaveCoilWrite(0, false);
}
private void btn_do2_off_Click(object sender, EventArgs e)
{
SlaveCoilWrite(1, false);
}
private void btn_do3_off_Click(object sender, EventArgs e)
{
SlaveCoilWrite(2, false);
}
private void btn_do4_off_Click(object sender, EventArgs e)
{
SlaveCoilWrite(3, false);
}
private void btn_do1_4_off_Click(object sender, EventArgs e)
{
//for (int i = 0; i < 4; i++)
//{
// SlaveCoilWrite(i, false);
//}
bool[] sta = new bool[4] { false, false, false, false };
try
{
Master.WriteMultipleCoils(0, sta);
}
catch
{
}
}
}
}
全部0条评论
快来发表一下你的评论吧 !