本文来源:C# ModBus Tcp客户端读取数据 完整Demo - 陈彦斌 - 博客园,感谢作者。看了作者的文章后,为了加深影响,做一个更加精细的说明。
1.建立一个程序,引用HslCommunication.dll和Newtonsoft.Json.dll
2.界面
3.界面代码
namespace ModbusDemo
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button5 = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.textBox2 = new System.Windows.Forms.TextBox();
this.button3 = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.txtIp = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.txtPort = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button5
//
this.button5.Location = new System.Drawing.Point(133, 318);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(164, 82);
this.button5.TabIndex = 4;
this.button5.Text = "开启连接";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.Button5_Click);
//
// button6
//
this.button6.Location = new System.Drawing.Point(355, 318);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(172, 82);
this.button6.TabIndex = 5;
this.button6.Text = "关闭连接";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.Button6_Click);
//
// textBox1
//
this.textBox1.Enabled = false;
this.textBox1.Location = new System.Drawing.Point(222, 39);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(272, 58);
this.textBox1.TabIndex = 6;
//
// label1
//
this.label1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label1.Location = new System.Drawing.Point(116, 52);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(100, 45);
this.label1.TabIndex = 7;
this.label1.Text = "返回值";
//
// label2
//
this.label2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label2.Location = new System.Drawing.Point(129, 153);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(72, 45);
this.label2.TabIndex = 8;
this.label2.Text = "地址";
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(222, 140);
this.textBox2.Multiline = true;
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(272, 58);
this.textBox2.TabIndex = 9;
//
// button3
//
this.button3.Location = new System.Drawing.Point(512, 148);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(108, 50);
this.button3.TabIndex = 10;
this.button3.Text = "监听";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.Button3_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label3.Location = new System.Drawing.Point(91, 263);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(31, 20);
this.label3.TabIndex = 11;
this.label3.Text = "IP";
//
// txtIp
//
this.txtIp.Location = new System.Drawing.Point(133, 255);
this.txtIp.Multiline = true;
this.txtIp.Name = "txtIp";
this.txtIp.Size = new System.Drawing.Size(164, 35);
this.txtIp.TabIndex = 12;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label4.Location = new System.Drawing.Point(338, 263);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(51, 20);
this.label4.TabIndex = 13;
this.label4.Text = "端口";
//
// txtPort
//
this.txtPort.Location = new System.Drawing.Point(418, 255);
this.txtPort.Multiline = true;
this.txtPort.Name = "txtPort";
this.txtPort.Size = new System.Drawing.Size(109, 35);
this.txtPort.TabIndex = 14;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(724, 477);
this.Controls.Add(this.txtPort);
this.Controls.Add(this.label4);
this.Controls.Add(this.txtIp);
this.Controls.Add(this.label3);
this.Controls.Add(this.button3);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button6);
this.Controls.Add(this.button5);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "ModBus Tcp客户端";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtIp;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtPort;
}
}
4.源代码
using System;
using System.Windows.Forms;
using HslCommunication.ModBus;
using HslCommunication;
namespace ModbusDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 初始化类
/// </summary>
private ModbusTcpNet busTcpClient =null;
/// <summary>
/// 监听状态
/// </summary>
private bool IsEnable = false;
private void Form1_Load(object sender, EventArgs e)
{
txtPort.Text = "502";
txtIp.Text = "172.30.16.220";
textBox2.Text = "00141";
}
/// <summary>
/// 开启服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button5_Click(object sender, EventArgs e)
{
try
{
if (IsEnable)
{
MessageBox.Show("请勿重复建立连接!");
return;
}
string ip = txtIp.Text.Trim();
int port = Convert.ToInt32(txtPort.Text);
if (ip==null || ip=="")
{
MessageBox.Show("ip不能为空!");
return;
}
busTcpClient = new ModbusTcpNet(ip, port, 0x01);
OperateResult res = busTcpClient.ConnectServer();
if (res.IsSuccess==true) //接收状态返回值
{
IsEnable = true;
MessageBox.Show("开启连接成功");
}
else
{
MessageBox.Show("开启连接失败");
}
}
catch (Exception ex)
{
MessageBox.Show("开启连接失败!", ex.Message.ToString());
}
}
private void Button6_Click(object sender, EventArgs e)
{
try
{
if (!IsEnable)
{
MessageBox.Show("尚未建立连接!");
return;
}
busTcpClient.ConnectClose();
IsEnable = false;
MessageBox.Show("关闭连接成功!");
}
catch (Exception ex)
{
MessageBox.Show("关闭连接失败!", ex.Message.ToString());
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void Button3_Click(object sender, EventArgs e)
{
try
{
if (!IsEnable)
{
MessageBox.Show("尚未建立连接!");
return;
}
if (busTcpClient == null)
{
MessageBox.Show("尚未初始化对象!");
return;
}
string txt = textBox2.Text.Trim();
if (txt=="")
{
MessageBox.Show("地址不能为空!");
return;
}
bool coil100 = busTcpClient.ReadCoil(txt).Content; // 读取线圈100的通断
textBox1.Text = "";
MessageBox.Show("监听成功!");
textBox1.Text = coil100 == true ? "true" : "false";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
}
}
5.对源码进行加注释和说明
在之前的文章中《modbus调试工具的使用》,并且根据IP进行模拟通信这个方法配置完成后,这是前提。
5.1打开Modbus Slave,按F8进入这个界面,函数选择线圈,数量选择20,点击ok
5.2 同理也打开Modbus Poll,按F8进入这个界面,函数选择线圈,数量选择20,点击ok
5.3这时他们可以进行通信了,修改其中一个参数,另一个软件也会进行变化
5.4源代码从上到下,注释说明
6.所有注释说明过的代码
using System;
using System.Windows.Forms;
using HslCommunication.ModBus;
using HslCommunication;
namespace ModbusDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 初始化类
/// </summary>
private ModbusTcpNet busTcpClient = null;
/// <summary>
/// 监听状态
/// </summary>
private bool IsEnable = false;
private void Form1_Load(object sender, EventArgs e)
{
txtPort.Text = "502";//这里是端口号
txtIp.Text = "127.0.0.1";//这里是本机的IP地址,原配置是172.30.16.220,修改成127.0.0.1
//这里的值,先看第二列,00000,第一列是别名,就和sql语句中的as是一样的。
//再看行0,1,2,3,4,5,6,7,8,9
//列值和行值组合在一起,就是我们要的地址。例如00001 00002 00003 00004 以此类推,第一列到00009,第二列到00019。
//所以,这里我们要读谁的值,或者写入谁的值,就写入谁的地址。
textBox2.Text = "00002";
}
/// <summary>
/// 开启服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button5_Click(object sender, EventArgs e)
{
try
{
if (IsEnable)
{
MessageBox.Show("请勿重复建立连接!");
return;
}
string ip = txtIp.Text.Trim();
int port = Convert.ToInt32(txtPort.Text);
if (ip == null || ip == "")
{
MessageBox.Show("ip不能为空!");
return;
}
busTcpClient = new ModbusTcpNet(ip, port, 0x01);
OperateResult res = busTcpClient.ConnectServer();
if (res.IsSuccess == true) //接收状态返回值
{
IsEnable = true;
MessageBox.Show("开启连接成功");
}
else
{
MessageBox.Show("开启连接失败");
}
}
catch (Exception ex)
{
MessageBox.Show("开启连接失败!", ex.Message.ToString());
}
}
private void Button6_Click(object sender, EventArgs e)
{
try
{
if (!IsEnable)
{
MessageBox.Show("尚未建立连接!");
return;
}
busTcpClient.ConnectClose();
IsEnable = false;
MessageBox.Show("关闭连接成功!");
}
catch (Exception ex)
{
MessageBox.Show("关闭连接失败!", ex.Message.ToString());
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void Button3_Click(object sender, EventArgs e)
{
try
{
if (!IsEnable)
{
MessageBox.Show("尚未建立连接!");
return;
}
if (busTcpClient == null)
{
MessageBox.Show("尚未初始化对象!");
return;
}
string txt = textBox2.Text.Trim();
if (txt == "")
{
MessageBox.Show("地址不能为空!");
return;
}
bool coil100 = busTcpClient.ReadCoil(txt).Content; // 这里写谁的地址,读的就是谁的值
textBox1.Text = "";
MessageBox.Show("监听成功!");
textBox1.Text = coil100 == true ? "true" : "false";
// 读取操作,以下txt写谁,读取的就是谁的值
bool coil1001 = busTcpClient.ReadCoil(txt).Content; // 读取线圈100的通断
short short100 = busTcpClient.ReadInt16(txt).Content; // 读取寄存器100的short值
ushort ushort100 = busTcpClient.ReadUInt16(txt).Content; // 读取寄存器100的ushort值
int int100 = busTcpClient.ReadInt32(txt).Content; // 读取寄存器100-101的int值
uint uint100 = busTcpClient.ReadUInt32(txt).Content; // 读取寄存器100-101的uint值
float float100 = busTcpClient.ReadFloat(txt).Content; // 读取寄存器100-101的float值
long long100 = busTcpClient.ReadInt64(txt).Content; // 读取寄存器100-103的long值
ulong ulong100 = busTcpClient.ReadUInt64(txt).Content; // 读取寄存器100-103的ulong值
string str100 = busTcpClient.ReadString(txt, 5).Content;// 读取100到104共10个字符的字符串
// 写入操作,以下txt写谁,就是写入谁的值
busTcpClient.WriteCoil(txt, true);// 写入线圈100为通
busTcpClient.Write(txt, (short)12345);// 写入寄存器100为12345
busTcpClient.Write(txt, (ushort)45678);// 写入寄存器100为45678
busTcpClient.Write(txt, 123456789);// 写入寄存器100-101为123456789
busTcpClient.Write(txt, (uint)123456778);// 写入寄存器100-101为123456778
busTcpClient.Write(txt, 123.456);// 写入寄存器100-101为123.456
busTcpClient.Write(txt, 12312312312414L);//写入寄存器100-103为一个大数据
busTcpClient.Write(txt, 12634534534543656UL);// 写入寄存器100-103为一个大数据
busTcpClient.Write(txt, 123.456d);// 写入寄存器100-103为一个双精度的数据
busTcpClient.Write(txt, "K123456789");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
}
}
7. 效果。最后我们进行读取和写入的验证
读取
读取00002地址的值,成功
写入
写入00001的值,还未写入的时候是0
写入后,0变成1