摘要
本文详细描述了如安在在C#的Winform应用步伐中利用NModbus库实现Modbus通讯,包罗读取保持寄存器、以及相应的UI界面筹划和变乱处置惩罚。
媒介
应用场景
Modbus 从站广泛应用于工业自动化领域:
1、传感器数据采集(如温度、压力等)
2、执行器控制(如电机、阀门等)
3、设备监控与故障诊断。
Modbus 从站(Slave)是 Modbus 通讯协议中的响应设备,负责接收并执行来自主站(Master)的请求。
Modbus 从站是被动设备,它不能自动发起通讯,只能响应主站的请求。从站的主要功能包罗:
1、接收主站的指令(如读取数据或执行操作)。
2、执行相应的操作(如读取寄存器值或设置参数)。
3、返反响应数据或错误码给主站。
通讯模式
Modbus 从站支持多种通讯模式:
1、Modbus RTU/ASCII:通过串口(如 RS485)举行通讯,从站监听串口链路并响应主站指令。
2、Modbus TCP:通过以太网举行通讯,从站作为服务器监听 TCP 端口(默认 502 端口)并处置惩罚客户端请求。
寄存器范例
Modbus 从站通常管理四种范例的寄存器:
1、线圈(Coils):可读写的二进制状态(如开关状态)。
2、离散输入(Discrete Inputs):只读的二进制状态。
3、保持寄存器(Holding Registers):可读写的16位数据。
4、输入寄存器(Input Registers):只读的16位数据。
实现步骤
1、创建TcpListener并启动 侦听
2、创建Modbus从站数据存储
3、初始化数据
4、创建Modbus从站
5、创建Modbus TCP从站网络
6、添加从站到网络
7、异步侦听网络
运行结果
代码
Frm_ModbusService
- public partial class Frm_ModbusService : Form
- {
- #region 字段
- //定时器
- Timer timer = null;
- ModbusService modbusService = null;
- #endregion
- #region 构造函数、初始化
- public Frm_ModbusService()
- {
- InitializeComponent();
- CenterToParent();
- CenterToScreen();
- }
- private void ModbusService_Load(object sender, EventArgs e)
- {
- Initialize();
- }
- private void ModbusService_FormClosing(object sender, FormClosingEventArgs e)
- {
- modbusService.Stop();
- }
- #endregion
- /// <summary>
- /// 初始化控件状态
- /// </summary>
- public void InitializeControlsState()
- {
- tbx_IPAddress.Text = modbusService.IpAddress.ToString();
- tbx_OpenPort.Text = modbusService.Port.ToString();
- tbx_StartAddress.Text = modbusService.StartAddress.ToString();
- tbx_SlaveID.Text = modbusService.SlaveId.ToString();
- }
- /// <summary>
- /// 初始化
- /// </summary>
- public void Initialize()
- {
- modbusService = new ModbusService();
- modbusService.MessageUpdateHandler += OnUpdataMessage;
- InitializeControlsState();
- UpdataControlsState(modbusService.IsRunning);
- timer = new Timer();
- timer.Interval = 100;
- timer.Tick += Timer_Tick;
- dataGridView.Columns[0].Width = 100;
- dataGridView.Columns[1].Width = 100;
- dataGridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
- dataGridView.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
- dataGridView.RowHeadersVisible = false;
-
- //10行
- dataGridView.Rows.Add(new object[] { 0, 0});
- dataGridView.Rows.Add(new object[] { 1, 0 });
- dataGridView.Rows.Add(new object[] { 2, 0 });
- dataGridView.Rows.Add(new object[] { 3, 0 });
- dataGridView.Rows.Add(new object[] { 4, 0 });
- dataGridView.Rows.Add(new object[] { 5, 0 });
- dataGridView.Rows.Add(new object[] { 6, 0 });
- dataGridView.Rows.Add(new object[] { 7, 0 });
- dataGridView.Rows.Add(new object[] { 8, 0 });
- dataGridView.Rows.Add(new object[] { 9, 0 });
- }
- /// <summary>
- /// 定时器方法
- /// </summary>
- private void Timer_Tick(object sender, EventArgs e)
- {
- var array = modbusService.DataStore.HoldingRegisters.ReadPoints(modbusService.StartAddress, 10);
- for (int i = 0; i < array.Length; i++)
- {
- dataGridView.Rows[i].Cells[0].Value = (modbusService.StartAddress+ i);
- dataGridView.Rows[i].Cells[1].Value = array[i];
- }
- }
- /// <summary>
- /// 启动按钮
- /// </summary>
- private void btn_Start_Click(object sender, EventArgs e)
- {
- try
- {
- if (!modbusService.IsRunning)
- {
- modbusService.Start();
- timer.Start();
- UpdataControlsState(modbusService.IsRunning);
- }
- else
- {
- modbusService.Stop();
- timer.Stop();
- UpdataControlsState(modbusService.IsRunning);
- UpdataMessage("Modbus服务停止");
- }
- }
- catch (Exception ex)
- {
- modbusService.Stop();
- timer.Stop();
- UpdataControlsState(modbusService.IsRunning);
- UpdataMessage($"Modbus服务异常停止:{ex.Message}");
- }
- }
- /// <summary>
- /// 更新消息
- /// </summary>
- private void UpdataMessage(string message)
- {
- tbx_Output.BeginInvoke(new Action(() =>
- {
- if (tbx_Output.Lines.Length>100)
- {
- tbx_Output.Clear();
- }
- tbx_Output.AppendText($"{DateTime.Now.ToString()}】{message}\r\n");
- }));
- }
- /// <summary>
- /// 更新消息
- /// </summary>
- private void OnUpdataMessage(object sender, string message)
- {
- UpdataMessage(message);
- }
- /// <summary>
- /// 更新控件状态
- /// </summary>
- private void UpdataControlsState(bool isRunning)
- {
- if (isRunning)
- {
- tbx_IPAddress.Enabled = false;
- tbx_OpenPort.Enabled = false;
- tbx_SlaveID.Enabled = false;
- btn_Start.Text = "关闭";
- }
- else
- {
- tbx_IPAddress.Enabled = true;
- tbx_OpenPort.Enabled = true;
- tbx_SlaveID.Enabled = true;
- btn_Start.Text = "启动";
- }
- }
- #region 参数变更
- /// <summary>
- /// IP地址变更
- /// </summary>
- private void tbxIPAddress_TextChanged(object sender, EventArgs e)
- {
- if (IPAddress.TryParse(tbx_IPAddress.Text,out IPAddress result))
- {
- modbusService.IpAddress = result;
- }
- else
- {
- tbx_IPAddress.Text = modbusService.IpAddress.ToString();
- }
- }
- /// <summary>
- /// 端口变更
- /// </summary>
- private void tbxOpenPort_TextChanged(object sender, EventArgs e)
- {
- if (ushort.TryParse(tbx_OpenPort.Text, out ushort result))
- {
- modbusService.Port = result;
- }
- else
- {
- tbx_OpenPort.Text = modbusService.Port.ToString();
- }
- }
- /// <summary>
- /// 起始地址变更
- /// </summary>
- private void tbx_StartAddress_TextChanged(object sender, EventArgs e)
- {
- if (ushort.TryParse(tbx_StartAddress.Text, out ushort result))
- {
- modbusService.StartAddress = result;
- }
- else
- {
- tbx_StartAddress.Text = modbusService.StartAddress.ToString();
- }
- }
- /// <summary>
- /// 站ID变更
- /// </summary>
- private void tbx_SlaveID_TextChanged(object sender, EventArgs e)
- {
- if (byte.TryParse(tbx_SlaveID.Text, out byte result))
- {
- modbusService.SlaveId = result;
- }
- else
- {
- tbx_SlaveID.Text = modbusService.SlaveId.ToString();
- }
- }
- #endregion
- }
- }
复制代码 ModbusService
- public class ModbusService
- {
- #region 字段、属性
- public event EventHandler<string> MessageUpdateHandler;
- private IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
- private int port = 502; //端口
- private byte slaveId = 1; // 从站地址
- private ushort startAddress = 0; //起始地址
- private bool isRunning = false; //运行状态
- private TcpListener tcpListener = null; //创建Modbus服务器
- private DefaultSlaveDataStore dataStore = null; //默认从站数据存储
- private ModbusFactory factory = null; //Bodbus工厂
- private IModbusSlave slave = null; //modbus从站
- IModbusTcpSlaveNetwork slaveNetwork = null; //ModbusTcp从站网络
- public IPAddress IpAddress { get => ipAddress; set => ipAddress = value; }
- public int Port { get => port; set => port = value; }
- public byte SlaveId { get => slaveId; set => slaveId = value; }
- public ushort StartAddress { get => startAddress; set => startAddress = value; }
- public bool IsRunning { get => isRunning; set => isRunning = value; }
- public TcpListener TcpListener { get => tcpListener; set => tcpListener = value; }
- public DefaultSlaveDataStore DataStore { get => dataStore; set => dataStore = value; }
- public ModbusFactory Factory { get => factory; set => factory = value; }
- public IModbusSlave Slave { get => slave; set => slave = value; }
- public IModbusTcpSlaveNetwork SlaveNetwork { get => slaveNetwork; set => slaveNetwork = value; }
- #endregion
- public ModbusService() {}
- /// <summary>
- /// 初始化从站数据存储
- /// </summary>
- private void InitializeDataStore(DefaultSlaveDataStore dataStore)
- {
- // 初始化保持寄存器
- dataStore.HoldingRegisters.WritePoints(0, new ushort[] { 0 });
- // 初始化输入寄存器
- dataStore.InputRegisters.WritePoints(0, new ushort[] { 0 });
- // 初始化线圈
- dataStore.CoilDiscretes.WritePoints(0, new bool[] { false });
- // 初始化离散输入
- dataStore.CoilInputs.WritePoints(0, new bool[] { false });
- }
- /// <summary>
- /// 启动按钮
- /// </summary>
- public void Start()
- {
- try
- {
- if (!IsRunning)
- {
- // 创建TcpListener并启动
- TcpListener = new TcpListener(IpAddress, Port);
- //启动侦听
- TcpListener.Start();
- // 创建Modbus从站数据存储
- DataStore = new DefaultSlaveDataStore();
- // 初始化数据
- InitializeDataStore(DataStore);
- // 创建Modbus从站
- Factory = new ModbusFactory();
- Slave = Factory.CreateSlave(1, DataStore);
- // 创建Modbus TCP从站网络
- SlaveNetwork = Factory.CreateSlaveNetwork(TcpListener);
- // 添加从站到网络
- SlaveNetwork.AddSlave(Slave);
- //异步侦听网络
- SlaveNetwork.ListenAsync();
- IsRunning = true;
- OnUpdataMessage("Modbus服务启动");
- }
- }
- catch (Exception ex)
- {
- Stop();
- OnUpdataMessage($"Modbus服务异常停止:{ex.Message}");
- }
- }
- public void Stop()
- {
- TcpListener?.Stop();
- SlaveNetwork?.Dispose();
- DataStore = null;
- Factory = null;
- Slave = null;
- IsRunning = false;
- }
- /// <summary>
- /// 消息更新
- /// </summary>
- private void OnUpdataMessage(string message)
- {
- MessageUpdateHandler?.Invoke(this,message);
- }
- }
复制代码 结语
总结来说,Modbus 从站是 Modbus 网络中的关键构成部分,负责响应主站指令并执行相应操作。广泛应用于工业自动化和设备控制。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |