当前位置: 首页 > news >正文

C#简易Modbus从站仿真器

       C#使用NModbus库,编写从站仿真器,支持Modbus TCP访问,支持多个从站地址和动态启用/停用从站(模拟离线),支持数据变化,可以很方便实现,最终效果如图所示。

项目采用.net framework 4.7的Windows窗体模式快速实现,NuGet包和版本如下:

界面设计如下:

窗体设计部分Form1.Designer.cs代码如下:

namespace ModbusSlaveSimulatorTest
{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.components = new System.ComponentModel.Container();this.checkBox1 = new System.Windows.Forms.CheckBox();this.checkBox2 = new System.Windows.Forms.CheckBox();this.checkBox3 = new System.Windows.Forms.CheckBox();this.checkBox4 = new System.Windows.Forms.CheckBox();this.checkBox5 = new System.Windows.Forms.CheckBox();this.checkBox6 = new System.Windows.Forms.CheckBox();this.checkBox7 = new System.Windows.Forms.CheckBox();this.checkBox8 = new System.Windows.Forms.CheckBox();this.checkBox9 = new System.Windows.Forms.CheckBox();this.checkBox10 = new System.Windows.Forms.CheckBox();this.timer1 = new System.Windows.Forms.Timer(this.components);this.label1 = new System.Windows.Forms.Label();this.comboBox1 = new System.Windows.Forms.ComboBox();this.SuspendLayout();// // checkBox1// this.checkBox1.AutoSize = true;this.checkBox1.Checked = true;this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox1.Location = new System.Drawing.Point(12, 12);this.checkBox1.Name = "checkBox1";this.checkBox1.Size = new System.Drawing.Size(66, 16);this.checkBox1.TabIndex = 0;this.checkBox1.Text = "Slave 1";this.checkBox1.UseVisualStyleBackColor = true;this.checkBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox2// this.checkBox2.AutoSize = true;this.checkBox2.Checked = true;this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox2.Location = new System.Drawing.Point(84, 12);this.checkBox2.Name = "checkBox2";this.checkBox2.Size = new System.Drawing.Size(66, 16);this.checkBox2.TabIndex = 1;this.checkBox2.Text = "Slave 2";this.checkBox2.UseVisualStyleBackColor = true;this.checkBox2.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox3// this.checkBox3.AutoSize = true;this.checkBox3.Checked = true;this.checkBox3.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox3.Location = new System.Drawing.Point(167, 12);this.checkBox3.Name = "checkBox3";this.checkBox3.Size = new System.Drawing.Size(66, 16);this.checkBox3.TabIndex = 2;this.checkBox3.Text = "Slave 3";this.checkBox3.UseVisualStyleBackColor = true;this.checkBox3.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox4// this.checkBox4.AutoSize = true;this.checkBox4.Checked = true;this.checkBox4.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox4.Location = new System.Drawing.Point(251, 12);this.checkBox4.Name = "checkBox4";this.checkBox4.Size = new System.Drawing.Size(66, 16);this.checkBox4.TabIndex = 3;this.checkBox4.Text = "Slave 4";this.checkBox4.UseVisualStyleBackColor = true;this.checkBox4.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox5// this.checkBox5.AutoSize = true;this.checkBox5.Checked = true;this.checkBox5.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox5.Location = new System.Drawing.Point(342, 12);this.checkBox5.Name = "checkBox5";this.checkBox5.Size = new System.Drawing.Size(66, 16);this.checkBox5.TabIndex = 4;this.checkBox5.Text = "Slave 5";this.checkBox5.UseVisualStyleBackColor = true;this.checkBox5.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox6// this.checkBox6.AutoSize = true;this.checkBox6.Checked = true;this.checkBox6.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox6.Location = new System.Drawing.Point(432, 12);this.checkBox6.Name = "checkBox6";this.checkBox6.Size = new System.Drawing.Size(66, 16);this.checkBox6.TabIndex = 5;this.checkBox6.Text = "Slave 6";this.checkBox6.UseVisualStyleBackColor = true;this.checkBox6.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox7// this.checkBox7.AutoSize = true;this.checkBox7.Checked = true;this.checkBox7.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox7.Location = new System.Drawing.Point(516, 12);this.checkBox7.Name = "checkBox7";this.checkBox7.Size = new System.Drawing.Size(66, 16);this.checkBox7.TabIndex = 6;this.checkBox7.Text = "Slave 7";this.checkBox7.UseVisualStyleBackColor = true;this.checkBox7.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox8// this.checkBox8.AutoSize = true;this.checkBox8.Checked = true;this.checkBox8.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox8.Location = new System.Drawing.Point(588, 12);this.checkBox8.Name = "checkBox8";this.checkBox8.Size = new System.Drawing.Size(66, 16);this.checkBox8.TabIndex = 7;this.checkBox8.Text = "Slave 8";this.checkBox8.UseVisualStyleBackColor = true;this.checkBox8.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox9// this.checkBox9.AutoSize = true;this.checkBox9.Checked = true;this.checkBox9.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox9.Location = new System.Drawing.Point(660, 12);this.checkBox9.Name = "checkBox9";this.checkBox9.Size = new System.Drawing.Size(66, 16);this.checkBox9.TabIndex = 8;this.checkBox9.Text = "Slave 9";this.checkBox9.UseVisualStyleBackColor = true;this.checkBox9.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox10// this.checkBox10.AutoSize = true;this.checkBox10.Checked = true;this.checkBox10.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox10.Location = new System.Drawing.Point(12, 57);this.checkBox10.Name = "checkBox10";this.checkBox10.Size = new System.Drawing.Size(96, 16);this.checkBox10.TabIndex = 9;this.checkBox10.Text = "数据随机变化";this.checkBox10.UseVisualStyleBackColor = true;this.checkBox10.CheckedChanged += new System.EventHandler(this.checkBox10_CheckedChanged);// // timer1// this.timer1.Enabled = true;this.timer1.Interval = 2000;this.timer1.Tick += new System.EventHandler(this.timer1_Tick);// // label1// this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(148, 58);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(101, 12);this.label1.TabIndex = 10;this.label1.Text = "仿真频率(ms):";// // comboBox1// this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;this.comboBox1.FormattingEnabled = true;this.comboBox1.Items.AddRange(new object[] {"100","200","500","1000","2000","5000","10000"});this.comboBox1.Location = new System.Drawing.Point(247, 56);this.comboBox1.Name = "comboBox1";this.comboBox1.Size = new System.Drawing.Size(70, 20);this.comboBox1.TabIndex = 11;this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(802, 125);this.Controls.Add(this.comboBox1);this.Controls.Add(this.label1);this.Controls.Add(this.checkBox10);this.Controls.Add(this.checkBox9);this.Controls.Add(this.checkBox8);this.Controls.Add(this.checkBox7);this.Controls.Add(this.checkBox6);this.Controls.Add(this.checkBox5);this.Controls.Add(this.checkBox4);this.Controls.Add(this.checkBox3);this.Controls.Add(this.checkBox2);this.Controls.Add(this.checkBox1);this.Name = "Form1";this.Text = "Modbus从站仿真";this.Load += new System.EventHandler(this.Form1_Load);this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.CheckBox checkBox1;private System.Windows.Forms.CheckBox checkBox2;private System.Windows.Forms.CheckBox checkBox3;private System.Windows.Forms.CheckBox checkBox4;private System.Windows.Forms.CheckBox checkBox5;private System.Windows.Forms.CheckBox checkBox6;private System.Windows.Forms.CheckBox checkBox7;private System.Windows.Forms.CheckBox checkBox8;private System.Windows.Forms.CheckBox checkBox9;private System.Windows.Forms.CheckBox checkBox10;private System.Windows.Forms.Timer timer1;private System.Windows.Forms.Label label1;private System.Windows.Forms.ComboBox comboBox1;}
}

窗体实现部分代码如下:

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;
using System.Windows.Forms;
using NModbus;namespace ModbusSlaveSimulatorTest
{public partial class Form1 : Form{class AppData{public string BindIp = "0.0.0.0";public ushort BindPort = 502;public byte SlaveCount = 9;public bool SimulationEnable = true;public int SimulationFreq = 1000;public string SimulationUnitId = "1,2,3,4,5,6,7,8,9";public ushort SimulationRegisterMax = 1000;public ushort SimulationStep = 1;}TcpListener modbusListener;List<IModbusSlave> listSlave = new List<IModbusSlave>();IModbusSlaveNetwork modbusSlaveNetwork = null;Dictionary<ushort, bool> dictSlaves = new Dictionary<ushort, bool>();//数据仿真ushort uValue = 0;ushort uStep = 1;AppData appData = new AppData();IModbusFactory factory = new ModbusFactory();public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//创建通讯绑定端口modbusListener = new TcpListener(IPAddress.Parse(appData.BindIp), appData.BindPort);modbusListener.Start();modbusSlaveNetwork = factory.CreateSlaveNetwork(modbusListener);//创建Slave设备for (byte i = 0; i < appData.SlaveCount; i++){IModbusSlave slave = factory.CreateSlave((byte)(i + 1));listSlave.Add(slave);modbusSlaveNetwork.AddSlave(slave);dictSlaves[(ushort)(i + 1)] = true;}//接受连接modbusSlaveNetwork.ListenAsync();comboBox1.SelectedIndex = 4;}private void checkBox9_MouseClick(object sender, MouseEventArgs e){CheckBox cb = sender as CheckBox;byte slaveId = byte.Parse(cb.Text.Replace("Slave", ""));if (cb.Checked){modbusSlaveNetwork.AddSlave(listSlave[slaveId - 1]);dictSlaves[slaveId] = true;}else{modbusSlaveNetwork.RemoveSlave(slaveId);dictSlaves.Remove(slaveId);}}private void checkBox10_CheckedChanged(object sender, EventArgs e){timer1.Enabled = checkBox10.Checked;}private void timer1_Tick(object sender, EventArgs e){bool[] vb = new bool[appData.SimulationRegisterMax];ushort[] vu = new ushort[appData.SimulationRegisterMax];for (int i = 0; i < appData.SimulationRegisterMax; i++){vu[i] = uValue;vb[i] = (uValue % 2 == 1) ? true : false;}foreach (var slave in listSlave){if (!dictSlaves.ContainsKey(slave.UnitId))continue;slave.DataStore.CoilDiscretes.WritePoints(0, vb);slave.DataStore.CoilInputs.WritePoints(0, vb);slave.DataStore.InputRegisters.WritePoints(0, vu);slave.DataStore.HoldingRegisters.WritePoints(0, vu);}uValue += uStep;}private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){timer1.Interval = int.Parse(comboBox1.Text);}}
}

代码托管地址:PascalMing/ModbusSlaveSimulatorTest: Modbus从站仿真
编译后的程序下载:https://github.com/PascalMing/ModbusSlaveSimulatorTest/releases/tag/v20250508

相关文章:

  • 2025年排名前十进销存软件大测评
  • Coding Practice,48天强训(32)
  • 【嵌入式开发-IIC】
  • OptiStruct动力分析超单元卡片说明(2)
  • 【嵌入式开发-xxxxx】
  • 计算机网络笔记(十五)——3.2点对点协议PPP
  • MySQL数据库创建、删除、修改
  • 2.4 点云数据存储格式——轻量文本型存储格式
  • 20250508在WIN10下使用移远的4G模块EC200A-CN直接上网
  • WEB UI自动化测试之Pytest框架学习
  • 前端取经路——框架修行:React与Vue的双修之路
  • 稳定性_李雅普诺夫——Lyapunov直接法
  • 数据结构-非线性结构-二叉树
  • Qt开发经验 --- 避坑指南(8)
  • 10. CSS通配符与选择器权重深度解析:以《悯农》古诗为例
  • 新能源汽车CAN通信深度解析:MCU、VCU、ECU协同工作原理
  • 图漾相机——Sample_V2示例程序(待补充)
  • 人工智能在网络安全中的重要性
  • 湖北理元理律师事务所的企业债务重组实践:挽救实体经济的法律处方
  • Android7 Input(六)InputChannel
  • 复旦发文缅怀文科杰出教授裘锡圭:曾提出治学需具备三种精神
  • 盖茨:20年内将捐出几乎全部财富,盖茨基金会2045年关闭
  • 复旦设立新文科发展基金,校友曹国伟、王长田联合捐赠1亿助力人文学科与社会科学创新
  • 洗衣机无法有效杀菌
  • 视觉周刊|劳动开创未来
  • 2类药物别乱吃,严重可致肝肾衰竭!多人已中招