【WinForm】C# Modbus RTU 通信学习过程-数据读取、写入

【WinForm】C# Modbus RTU 通信学习过程-通信连接

学习想法:前面进行了Modbus RTU通信连接的学习,现在就开始学习运用NModbus4进行数据读取和写入了;

第一步:在上一次学习通信连接的基础上添加控件;

GroupBox : GroupBox3-读写;

ComboBox : cbxPort-读写模式选择;

numericUpDown : nudSlaveID-从站地址、nudStartAdr-起始地址、nudLength-地址长度;

Button : btnRW-读写按钮;

TextBox : rbxRWMsg-读写信息;

第二步:ComboBox cbxPort-读写模式选择控件中添加相应选择信息

“读取输出线圈”、“读取离散输入”、“读取保持型寄存器”、“读取输入寄存器”、“写入单个线圈”、“写入多个线圈”、“写入单个寄存器”、“写入多个寄存器”;

第三步:对 cbxPort-读写模式选择、nudSlaveID-从站地址、nudStartAdr-起始地址、nudLength-地址长度这些控件添加Form1_Load事件进行默认选择和最小值限制;

//设置读写窗口默认选中项
cbxMode.SelectedIndex = 0;
nudSlaveID.Minimum = 1;
nudStartAdr.Minimum = 0;
nudLength.Minimum = 1;
//设置为默认输入法,即为英文半角
rbxRWMsg.ImeMode = ImeMode.Disable;

第四步:添加SetMsg方法,以便于在rbxRWMsg-读写信息显示读取结果

private void SetMsg<T>(List<T> result)//界面显示读取结果
{
    string msg = string.Empty;

    result.ForEach(m => msg += $"{m} ");

    rbxRWMsg.Text = msg.Trim();
}

第五步:添加rbxRWMsg_TextChanged事件,以便于后续做“读”事件更新写入长度计数

private void rbxRWMsg_TextChanged(object sender, EventArgs e)//更新写入值计数
{
    nudLength.Value = Regex.Matches(rbxRWMsg.Text, ",").Count + 1;
}

第六步:添加cbxMode_SelectedIndexChanged事件,当ComboBox : cbxPort-读写模式选择发生变化时切换Button : btnRW-读写按钮字样、TextBox : rbxRWMsg-读写信息控件是否有效;

private void cbxMode_SelectedIndexChanged(object sender, EventArgs e)// 模式切换事件
        {
            tbMessage.Clear();
            if (cbxMode.SelectedItem.ToString().Contains("读取"))
            {
                btnRW.Text = "读取";
                rbxRWMsg.Enabled = false;
            }
            else
            {
                btnRW.Text = "写入";
                rbxRWMsg.Enabled = true;
            }
        }

第七步:添加事件“写入单个线圈-WriteSingleCoil”、“写入多个线圈-WriteArrayCoil”、“写入单个寄存器-WriteSingleRegister”、“写入多个寄存器-WriteArrayRegister”、“读取输出线圈-ReadCoils”、“读取输入线圈-ReadInputs”、“读取保持型寄存器-ReadHoldingRegisters”、“读取输入寄存器-ReadInputRegisters”;

        /// <summary>
        /// 写入单个线圈
        /// </summary>
        private void WriteSingleCoil()
        {
            bool result = false;
            if (rbxRWMsg.Text.Equals("true", StringComparison.OrdinalIgnoreCase) || rbxRWMsg.Text.Equals("1", StringComparison.OrdinalIgnoreCase))
            {
                result = true;
            }
            master.WriteSingleCoil((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, result);
        }

        /// <summary>
        /// 批量写入线圈
        /// </summary>
        private void WriteArrayCoil()
        {
            List<string> strList = rbxRWMsg.Text.Split(',').ToList();

            List<bool> result = new List<bool>();

            strList.ForEach(m => result.Add(m.Equals("true", StringComparison.OrdinalIgnoreCase) || m.Equals("1", StringComparison.OrdinalIgnoreCase)));

            master.WriteMultipleCoils((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, result.ToArray());
        }

        /// <summary>
        /// 写入单个寄存器
        /// </summary>
        private void WriteSingleRegister()
        {
            ushort result = Convert.ToUInt16(rbxRWMsg.Text);

            master.WriteSingleRegister((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, result);
        }

        /// <summary>
        /// 批量写入寄存器
        /// </summary>
        private void WriteArrayRegister()
        {
            List<string> strList = rbxRWMsg.Text.Split(',').ToList();

            List<ushort> result = new List<ushort>();

            strList.ForEach(m => result.Add(Convert.ToUInt16(m)));

            master.WriteMultipleRegisters((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, result.ToArray());
        }

        /// <summary>
        /// 读取输出线圈
        /// </summary>
        /// <returns></returns>
        private bool[] ReadCoils()
        {
            return master.ReadCoils((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, (ushort)nudLength.Value);
        }

        /// <summary>
        /// 读取输入线圈
        /// </summary>
        /// <returns></returns>
        private bool[] ReadInputs()
        {
            return master.ReadInputs((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, (ushort)nudLength.Value);
        }

        /// <summary>
        /// 读取保持型寄存器
        /// </summary>
        /// <returns></returns>
        private ushort[] ReadHoldingRegisters()
        {
            return master.ReadHoldingRegisters((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, (ushort)nudLength.Value);
        }

        /// <summary>
        /// 读取输入寄存器
        /// </summary>
        /// <returns></returns>
        private ushort[] ReadInputRegisters()
        {
            return master.ReadInputRegisters((byte)nudSlaveID.Value, (ushort)nudStartAdr.Value, (ushort)nudLength.Value);
        }

第八步:添加Button : btnRW-读写按钮 btnRW_Click按钮读写事件;

    private void btnRW_Click(object sender, EventArgs e)//读写事件
        {
            if (serialPort.IsOpen)
            {
                //根据选择的模式进行读写
                switch (cbxMode.SelectedItem.ToString())
                {
                    case "读取输出线圈":
                        SetMsg(ReadCoils().ToList());
                        break;
                    case "读取离散输入":
                        SetMsg(ReadInputs().ToList());
                        break;
                    case "读取保持型寄存器":
                        SetMsg(ReadHoldingRegisters().ToList());
                        break;
                    case "读取输入寄存器":
                        SetMsg(ReadInputRegisters().ToList());
                        break;
                    case "写入单个线圈":
                        if (rbxRWMsg.Text.Contains(","))
                        {
                            MessageBox.Show("输入值过多");
                            return;
                        }
                        WriteSingleCoil();
                        break;
                    case "写入多个线圈":
                        WriteArrayCoil();
                        break;
                    case "写入单个寄存器":
                        if (rbxRWMsg.Text.Contains(","))
                        {
                            MessageBox.Show("输入值过多");
                            return;
                        }
                        WriteSingleRegister();
                        break;
                    case "写入多个寄存器":
                        WriteArrayRegister();
                        break;
                    default:
                        break;
                }

            }
        }

第九步:程序验证

首先完成通信连接

1)写入单个线圈

2)写入多个线圈(多个地址数据以“,”隔开,更新时会自动计算并更新地址长度)

3)写入单个寄存器

4)写入多个寄存器(多个地址数据以“,”隔开,更新时会自动计算并更新地址长度)

5)读取输出线圈

6)读取离散输入

7)读取保持型寄存器

8)读取输入寄存器

最终交互画面

以上就是这次【WinForm】C# Modbus RTU 通信学习过程之数据读取、写入了。

  • 12
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值