diff --git a/Main.Designer.cs b/Main.Designer.cs index 020a814..93f1e8b 100644 --- a/Main.Designer.cs +++ b/Main.Designer.cs @@ -33,14 +33,12 @@ this.TextBox_Log = new System.Windows.Forms.TextBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.panel6 = new System.Windows.Forms.Panel(); - this.UpDown_Value = new System.Windows.Forms.NumericUpDown(); this.label6 = new System.Windows.Forms.Label(); this.panel5 = new System.Windows.Forms.Panel(); this.UpDown_RegLength = new System.Windows.Forms.NumericUpDown(); this.label5 = new System.Windows.Forms.Label(); this.Button_SendCommand = new System.Windows.Forms.Button(); this.panel3 = new System.Windows.Forms.Panel(); - this.UpDown_RegAddress = new System.Windows.Forms.NumericUpDown(); this.label3 = new System.Windows.Forms.Label(); this.panel4 = new System.Windows.Forms.Panel(); this.CBox_Function = new System.Windows.Forms.ComboBox(); @@ -86,13 +84,13 @@ this.panel1 = new System.Windows.Forms.Panel(); this.CBox_Ports = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); + this.TBox_RegAddress = new System.Windows.Forms.TextBox(); + this.TBox_RegValue = new System.Windows.Forms.TextBox(); this.groupBox2.SuspendLayout(); this.panel6.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UpDown_Value)).BeginInit(); this.panel5.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.UpDown_RegLength)).BeginInit(); this.panel3.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UpDown_RegAddress)).BeginInit(); this.panel4.SuspendLayout(); this.groupBox1.SuspendLayout(); this.groupBox4.SuspendLayout(); @@ -149,20 +147,13 @@ // // panel6 // - this.panel6.Controls.Add(this.UpDown_Value); + this.panel6.Controls.Add(this.TBox_RegValue); this.panel6.Controls.Add(this.label6); - this.panel6.Location = new System.Drawing.Point(337, 20); + this.panel6.Location = new System.Drawing.Point(303, 20); this.panel6.Name = "panel6"; - this.panel6.Size = new System.Drawing.Size(75, 43); + this.panel6.Size = new System.Drawing.Size(104, 43); this.panel6.TabIndex = 4; // - // UpDown_Value - // - this.UpDown_Value.Location = new System.Drawing.Point(6, 17); - this.UpDown_Value.Name = "UpDown_Value"; - this.UpDown_Value.Size = new System.Drawing.Size(66, 20); - this.UpDown_Value.TabIndex = 1; - // // label6 // this.label6.AutoSize = true; @@ -176,7 +167,7 @@ // this.panel5.Controls.Add(this.UpDown_RegLength); this.panel5.Controls.Add(this.label5); - this.panel5.Location = new System.Drawing.Point(259, 20); + this.panel5.Location = new System.Drawing.Point(225, 20); this.panel5.Name = "panel5"; this.panel5.Size = new System.Drawing.Size(75, 43); this.panel5.TabIndex = 3; @@ -209,20 +200,13 @@ // // panel3 // - this.panel3.Controls.Add(this.UpDown_RegAddress); + this.panel3.Controls.Add(this.TBox_RegAddress); this.panel3.Controls.Add(this.label3); - this.panel3.Location = new System.Drawing.Point(162, 20); + this.panel3.Location = new System.Drawing.Point(159, 20); this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(91, 43); + this.panel3.Size = new System.Drawing.Size(63, 43); this.panel3.TabIndex = 2; // - // UpDown_RegAddress - // - this.UpDown_RegAddress.Location = new System.Drawing.Point(6, 17); - this.UpDown_RegAddress.Name = "UpDown_RegAddress"; - this.UpDown_RegAddress.Size = new System.Drawing.Size(82, 20); - this.UpDown_RegAddress.TabIndex = 1; - // // label3 // this.label3.AutoSize = true; @@ -645,6 +629,20 @@ this.label1.TabIndex = 0; this.label1.Text = "Порт"; // + // TBox_RegAddress + // + this.TBox_RegAddress.Location = new System.Drawing.Point(3, 18); + this.TBox_RegAddress.Name = "TBox_RegAddress"; + this.TBox_RegAddress.Size = new System.Drawing.Size(56, 20); + this.TBox_RegAddress.TabIndex = 1; + // + // TBox_RegValue + // + this.TBox_RegValue.Location = new System.Drawing.Point(3, 17); + this.TBox_RegValue.Name = "TBox_RegValue"; + this.TBox_RegValue.Size = new System.Drawing.Size(98, 20); + this.TBox_RegValue.TabIndex = 1; + // // App // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -669,13 +667,11 @@ this.groupBox2.ResumeLayout(false); this.panel6.ResumeLayout(false); this.panel6.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UpDown_Value)).EndInit(); this.panel5.ResumeLayout(false); this.panel5.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.UpDown_RegLength)).EndInit(); this.panel3.ResumeLayout(false); this.panel3.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.UpDown_RegAddress)).EndInit(); this.panel4.ResumeLayout(false); this.panel4.PerformLayout(); this.groupBox1.ResumeLayout(false); @@ -719,13 +715,11 @@ private System.Windows.Forms.Label label5; private System.Windows.Forms.Button Button_SendCommand; private System.Windows.Forms.Panel panel3; - private System.Windows.Forms.NumericUpDown UpDown_RegAddress; private System.Windows.Forms.Label label3; private System.Windows.Forms.Panel panel4; private System.Windows.Forms.ComboBox CBox_Function; private System.Windows.Forms.Label label4; private System.Windows.Forms.Panel panel6; - private System.Windows.Forms.NumericUpDown UpDown_Value; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label Label_ConfigTip; private System.Windows.Forms.Button Button_LoadConfig; @@ -768,6 +762,8 @@ private System.Windows.Forms.Panel panel1; private System.Windows.Forms.ComboBox CBox_Ports; private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox TBox_RegValue; + private System.Windows.Forms.TextBox TBox_RegAddress; } } diff --git a/Main.cs b/Main.cs index ae69584..f79202c 100644 --- a/Main.cs +++ b/Main.cs @@ -103,12 +103,7 @@ namespace Gidrolock_Modbus_Scanner CBox_Parity.Items.Add("Нечетн."); CBox_Parity.SelectedIndex = 0; - - UpDown_RegAddress.Minimum = 0; - UpDown_RegAddress.Maximum = 65535; - - UpDown_Value.Minimum = 0; - UpDown_Value.Maximum = 65535; // 2^16 + UpDown_RegLength.Value = 0; Radio_SerialPort.Checked = true; GBox_Ethernet.Enabled = false; @@ -156,7 +151,7 @@ namespace Gidrolock_Modbus_Scanner #endregion // Send a custom message - async Task SendMessageAsync(FunctionCode functionCode, ushort address, ushort length) + async Task ReadRegisterAsync(FunctionCode functionCode, ushort address, ushort length) { if (CBox_Ports.Text == "") MessageBox.Show("Необходимо выбрать COM порт.", "Ошибка", MessageBoxButtons.OK); @@ -204,33 +199,6 @@ namespace Gidrolock_Modbus_Scanner MessageBox.Show(err.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - - /* - Writing to Registers - */ - else - { - try - { - if (CBox_Function.SelectedIndex < 6) // Single Registers - { - byte[] request = new byte[8]; - Modbus.BuildMessage((byte)UpDown_ModbusID.Value, (byte)(1 + functionCode), address, length, ref request); - string messageParsed = Modbus.ByteArrayToString(request); - - var send = await Modbus.WriteSingle(port, functionCode, (byte)UpDown_ModbusID.Value, address, (ushort)UpDown_Value.Value); - } - else // Multiple Registers - { - byte[] request = new byte[(int)UpDown_RegLength.Value * 2 + 6]; - // TODO - } - } - catch (Exception err) - { - port.Close(); - MessageBox.Show(err.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } private async void ButtonConnect_Click(object sender, EventArgs e) @@ -345,7 +313,7 @@ namespace Gidrolock_Modbus_Scanner foreach (CheckEntry ce in juju.Keys) { - await SendMessageAsync((FunctionCode)ce.registerType, ce.address, ce.length); // send read request to device, + await ReadRegisterAsync((FunctionCode)ce.registerType, ce.address, ce.length); // send read request to device, while (message is null) // wait for response to arrive Thread.Sleep(10); @@ -441,7 +409,7 @@ namespace Gidrolock_Modbus_Scanner /* if (Radio_SerialPort.Checked) - await SendMessageAsync(FunctionCode.InputRegister, 200, 6); + await ReadRegisterAsync(FunctionCode.InputRegister, 200, 6); //else EthernetParse(); */ } @@ -493,25 +461,83 @@ namespace Gidrolock_Modbus_Scanner private async void Button_SendCommand_Click(object sender, EventArgs e) { - FunctionCode functionCode = (FunctionCode)CBox_Function.SelectedIndex + 1; - ushort address = (ushort)UpDown_RegAddress.Value; + int functionCode = CBox_Function.SelectedIndex + 1; + short address; ushort length = (ushort)UpDown_RegLength.Value; + if (Int16.TryParse(TBox_RegAddress.Text, out address)) + { + if (functionCode <= 4) + await ReadRegisterAsync((FunctionCode)functionCode, (ushort)address, length); + else + { + string valueLower = TBox_RegValue.Text.ToLower(); + switch ((FunctionCode)functionCode) + { + case (FunctionCode.WriteCoil): + if (valueLower == "true" || valueLower == "1") + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0xFF_00); + else if (valueLower == "false" || valueLower == "0") + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, 0x00_00); + else MessageBox.Show("Неподходящие значения для регистра типа Coil"); + break; + case (FunctionCode.WriteRegister): + short value; + if (IsHex(valueLower)) //assume this is hex + { + try + { + value = Convert.ToInt16(valueLower, 16); + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, + (ushort)value); + } + catch (Exception err) { MessageBox.Show(err.Message); } + break; + } + else if (IsDec(valueLower)) + { + try + { + value = Convert.ToInt16(valueLower); + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, + (ushort)value); + } + catch (Exception err) { MessageBox.Show(err.Message); } + break; + } + else if (valueLower == "true") + { + try + { + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, + 0x01); + } + catch (Exception err) { MessageBox.Show(err.Message); } + break; + } + else if (valueLower == "false") + { + try + { + await Modbus.WriteSingle(port, (FunctionCode)functionCode, (byte)UpDown_ModbusID.Value, (ushort)address, + 0x00); + } + catch (Exception err) { MessageBox.Show(err.Message); } + break; + } + break; + default: + break; - await SendMessageAsync(functionCode, address, length); + } + } + } } private void OnSelectedFunctionChanged(object sender, EventArgs e) { if (CBox_Function.SelectedIndex < 4) - UpDown_Value.Enabled = false; - else - { - if (CBox_Function.SelectedIndex == 4 || CBox_Function.SelectedIndex == 6) - UpDown_Value.Maximum = 1; - else UpDown_Value.Maximum = 65535; - - UpDown_Value.Enabled = true; - } + TBox_RegValue.Enabled = false; + else TBox_RegValue.Enabled = true; } private void Radio_SerialPort_CheckedChanged(object sender, EventArgs e) @@ -581,6 +607,30 @@ namespace Gidrolock_Modbus_Scanner { } + + public static bool IsHex(string str) + { + str = str.ToLower(); + for (int i = 0; i < str.Length; i++) + { + if (str[i] < '0' || str[i] > 'F') + { + if ((i == 0 || i == 1) && str[i] == 'x') + continue; + else return false; + } + } + return true; + } + public static bool IsDec(string str) + { + foreach (char c in str) + { + if (c < '0' || c > '9') + return false; + } + return true; + } } } diff --git a/Modbus.cs b/Modbus.cs index c0e4ff4..697e22e 100644 --- a/Modbus.cs +++ b/Modbus.cs @@ -80,23 +80,9 @@ namespace Gidrolock_Modbus_Scanner #endregion #region Write Single Coil/Register - public static async Task WriteSingle(SerialPort port, FunctionCode functionCode, byte address, ushort start, uint value) + public static async Task WriteSingle(SerialPort port, FunctionCode functionCode, byte slaveID, ushort address, uint value) { - MessageBox.Show("Not implemented"); - return false; - /* - if (port.IsOpen) - { - //Clear in/out buffers: - port.DiscardOutBuffer(); - port.DiscardInBuffer(); - } - else - { - MessageBox.Show("Порт не открыт"); - return false; - } - */ + } #endregion public static bool ParseResponse(byte[] res, ref string verbose)