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 System.Net.Sockets; using System.Threading; using NModbus; using System.Net; namespace ModbusTcp { public partial class Form1 : Form { private static ModbusFactory modbusFactory; //private static IModbusMaster master=null; private static IModbusMaster master; //寫線圈或寫寄存器數組 bool[] coilsBuffer; ushort[] registerBuffer; //參數(分別爲站號,起始地址,長度) byte slaveAddress; ushort startAddress; ushort numberOfPoints; string functionCode; public Form1() { InitializeComponent(); } /// <summary> /// 監聽狀態 /// </summary> // private bool isConnected = false; private void Form1_Load(object sender, EventArgs e) { //IPAddress address = new IPAddress(new byte[]{127,0,0,1}); //TcpClient client = new TcpClient(address.ToString(), 502); groupBox1.Enabled = false; groupBox2.Enabled = false; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox1.SelectedIndex >= 4) { groupBox2.Enabled = true; groupBox1.Enabled = false; } else { groupBox1.Enabled = true; groupBox2.Enabled = false; } comboBox1.Invoke(new Action(() => { functionCode = comboBox1.SelectedItem.ToString(); })); } /// <summary> /// 讀/寫 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //初始化modbusmaster modbusFactory = new ModbusFactory(); //在本地測試 因此使用迴環地址,modbus協議規定端口號 502 master = modbusFactory.CreateMaster(new TcpClient("127.0.0.1", 502)); //設置讀取超時時間 master.Transport.ReadTimeout = 2000; master.Transport.Retries = 2000; comboBox1_SelectedIndexChanged(sender,e); ExecuteFunction(); } private async void ExecuteFunction() { try { //master = modbusFactory.CreateMaster(new TcpClient("127.0.0.1", 502)); if (functionCode != null) { switch (functionCode) { case "01 Read Coils"://讀取單個線圈 SetReadParameters(); coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints); for (int i = 0; i < coilsBuffer.Length; i++) { SetMsg(coilsBuffer[i] + ""); } break; case "02 Read DisCrete Inputs"://讀取輸入線圈/離散量線圈 SetReadParameters(); coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints); for (int i = 0; i < coilsBuffer.Length; i++) { SetMsg(coilsBuffer[i] + ""); } break; case "03 Read Holding Registers"://讀取保持寄存器 SetReadParameters(); registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints); for (int i = 0; i < registerBuffer.Length; i++) { //SetMsg(registerBuffer[i]+""); } break; case "04 Read Input Registers"://讀取輸入寄存器 SetReadParameters(); registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints); for (int i = 0; i < registerBuffer.Length; i++) { SetMsg(registerBuffer[i] + ""); } break; case "05 Write Single Coil"://寫單個線圈 SetWriteParametes(); await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]); break; case "06 Write Single Registers"://寫單個輸入線圈/離散量線圈 SetWriteParametes(); await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]); break; case "0F Write Multiple Coils"://寫一組線圈 SetWriteParametes(); await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer); break; case "10 Write Multiple Registers"://寫一組保持寄存器 SetWriteParametes(); await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer); break; default: break; } } else { MessageBox.Show("請選擇功能碼!"); } master.Dispose(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// 初始化讀參數 /// </summary> private void SetReadParameters() { if (txt_startAddr1.Text == "" || txt_slave1.Text == "" || txt_length.Text == "") { MessageBox.Show("請填寫讀參數!"); } else { slaveAddress = byte.Parse(txt_slave1.Text); startAddress = ushort.Parse(txt_startAddr1.Text); numberOfPoints = ushort.Parse(txt_length.Text); } } /// <summary> /// 初始化寫參數 /// </summary> private void SetWriteParametes() { if (txt_slave2.Text == "" || txt_slave2.Text == "" || txt_data.Text == "") { MessageBox.Show("請填寫寫參數!"); } else { slaveAddress = byte.Parse(txt_slave2.Text); startAddress = ushort.Parse(txt_slave2.Text); //判斷是否寫線圈 if (comboBox1.SelectedIndex == 4 || comboBox1.SelectedIndex == 6) { string[] strarr = txt_data.Text.Split(' '); coilsBuffer = new bool[strarr.Length]; //轉化爲bool數組 for (int i = 0; i < strarr.Length; i++) { // strarr[i] == "0" ? coilsBuffer[i] = true : coilsBuffer[i] = false; if (strarr[i] == "0") { coilsBuffer[i] = false; } else { coilsBuffer[i] = true; } } } else { //轉化ushort數組 string[] strarr = txt_data.Text.Split(' '); registerBuffer = new ushort[strarr.Length]; for (int i = 0; i < strarr.Length; i++) { registerBuffer[i] = ushort.Parse(strarr[i]); } } } } /// <summary> /// SetMessage /// </summary> /// <param name="msg"></param> public void SetMsg(string msg) { richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(msg + "\r\n"); })); } /// <summary> /// 清除文本 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click_1(object sender, EventArgs e) { richTextBox1.Clear(); } } }
能夠讀取的ModbusTcp示例Demo數組