From 8ca15d3e2a58436a78a54c6343dc9f8fc9a28369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=A4=A7=E7=9F=B3=E5=A4=B4?= Date: Wed, 8 Dec 2021 23:22:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EModbusSlave=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=EF=BC=8C=E9=9A=8F=E6=9C=BA=E6=95=B0=E6=8D=AE=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XCoder/FrmMDI.cs | 2 + XCoder/XCoder.csproj | 10 + XCoder/XNet/FrmModbusSlave.cs | 177 +++++++++++++ XCoder/XNet/FrmModbusSlave.designer.cs | 329 +++++++++++++++++++++++++ XCoder/XNet/FrmModbusSlave.resx | 129 ++++++++++ XCoder/XNet/RegisterUnit.cs | 15 ++ XCoderWpf/XCoderWpf.csproj | 6 +- 7 files changed, 665 insertions(+), 3 deletions(-) create mode 100644 XCoder/XNet/FrmModbusSlave.cs create mode 100644 XCoder/XNet/FrmModbusSlave.designer.cs create mode 100644 XCoder/XNet/FrmModbusSlave.resx create mode 100644 XCoder/XNet/RegisterUnit.cs diff --git a/XCoder/FrmMDI.cs b/XCoder/FrmMDI.cs index 9413e16..3636f07 100644 --- a/XCoder/FrmMDI.cs +++ b/XCoder/FrmMDI.cs @@ -65,6 +65,8 @@ namespace XCoder } } + ts = ts.OrderBy(t => t.FullName).ToArray(); + this.Invoke(() => { var ms = new Dictionary(); diff --git a/XCoder/XCoder.csproj b/XCoder/XCoder.csproj index 18c9164..dae5113 100644 --- a/XCoder/XCoder.csproj +++ b/XCoder/XCoder.csproj @@ -150,6 +150,12 @@ FrmIp.cs + + Form + + + FrmModbusSlave.cs + Form @@ -165,6 +171,7 @@ + Form @@ -261,6 +268,9 @@ FrmIp.cs + + FrmModbusSlave.cs + FrmMqtt.cs diff --git a/XCoder/XNet/FrmModbusSlave.cs b/XCoder/XNet/FrmModbusSlave.cs new file mode 100644 index 0000000..261fbbd --- /dev/null +++ b/XCoder/XNet/FrmModbusSlave.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows.Forms; +using NewLife; +using NewLife.Log; +using NewLife.Net; +using NewLife.Security; +using NewLife.Threading; +using XCoder; +using XCoder.Common; +using XCoder.XNet; + +namespace XNet +{ + [Category("网络通信")] + [DisplayName("ModbusSlave")] + public partial class FrmModbusSlave : Form, IXForm + { + private ControlConfig _config; + private ILog _log; + private NetServer _Server; + private RegisterUnit[] _data; + + #region 窗体 + public FrmModbusSlave() + { + InitializeComponent(); + + // 动态调节宽度高度,兼容高DPI + this.FixDpi(); + + Icon = IcoHelper.GetIcon("Modbus"); + } + + private void FrmMain_Load(Object sender, EventArgs e) + { + _log = new TextControlLog { Control = txtReceive }; + + _config = new ControlConfig { Control = this, FileName = "ModbusSlave.json" }; + _config.Load(); + + if (cbMode.SelectedIndex < 0) cbMode.SelectedIndex = 0; + + txtReceive.SetDefaultStyle(12); + + // 加载保存的颜色 + UIConfig.Apply(txtReceive); + } + #endregion + + #region 收发数据 + private void btnConnect_Click(Object sender, EventArgs e) + { + var btn = sender as Button; + if (btn.Text == "开始") + { + var svr = new NetServer((Int32)numPort.Value) + { + Log = _log + }; + svr.Received += OnReceived; + svr.Start(); + + _Server = svr; + + ShowData(); + + pnlSetting.Enabled = false; + btn.Text = "停止"; + + _config.Save(); + } + else + { + _Server.TryDispose(); + _Server = null; + _timer.TryDispose(); + + pnlSetting.Enabled = true; + btn.Text = "开始"; + } + } + + private void ShowData() + { + var addr = (Int32)numAddress.Value; + var count = (Int32)numCount.Value; + var mode = cbMode.SelectedItem + ""; + + var list = new List(count); + + switch (mode) + { + case "0x0000": + for (var i = 0; i < count; i++) + { + list.Add(new RegisterUnit { Address = addr + i, Value = 0 }); + } + break; + case "0x7777": + for (var i = 0; i < count; i++) + { + list.Add(new RegisterUnit { Address = addr + i, Value = 0x7777 }); + } + break; + case "0xFFFF": + for (var i = 0; i < count; i++) + { + list.Add(new RegisterUnit { Address = addr + i, Value = 0xFFFF }); + } + break; + case "递增": + for (var i = 0; i < count; i++) + { + list.Add(new RegisterUnit { Address = addr + i, Value = (UInt16)i }); + } + break; + case "静态随机": + case "动态随机": + default: + for (var i = 0; i < count; i++) + { + list.Add(new RegisterUnit { Address = addr + i, Value = (UInt16)Rand.Next(UInt16.MaxValue) }); + } + break; + } + + if (mode == "动态随机") _timer = new TimerX(DoRefreshData, null, 1_000, 1_000); + + _data = list.ToArray(); + + dataGridView1.DataSource = _data; + } + + private TimerX _timer; + private void DoRefreshData(Object state) + { + if (_data == null) return; + + for (var i = 0; i < _data.Length; i++) + { + var x = (Rand.Next(20) - 10) / 100.0; + _data[i].Value = (UInt16)(_data[i].Value * (1 + x)); + } + //dataGridView1.DataSource = _data; + dataGridView1.Refresh(); + } + + private void OnReceived(Object sender, ReceivedEventArgs e) + { + var session = sender as ISocketSession; + if (session == null) + { + var ns = sender as INetSession; + if (ns == null) return; + session = ns.Session; + } + + if (NetConfig.Current.ShowReceiveString) + { + var line = e.Packet.ToStr(); + + _log.Info(line); + } + } + + private Int32 _pColor = 0; + private void timer1_Tick(Object sender, EventArgs e) + { + var cfg = NetConfig.Current; + if (cfg.ColorLog) txtReceive.ColourDefault(_pColor); + _pColor = txtReceive.TextLength; + } + #endregion + } +} \ No newline at end of file diff --git a/XCoder/XNet/FrmModbusSlave.designer.cs b/XCoder/XNet/FrmModbusSlave.designer.cs new file mode 100644 index 0000000..91f8c88 --- /dev/null +++ b/XCoder/XNet/FrmModbusSlave.designer.cs @@ -0,0 +1,329 @@ +namespace XNet +{ + partial class FrmModbusSlave + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.txtReceive = new System.Windows.Forms.RichTextBox(); + this.btnConnect = new System.Windows.Forms.Button(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.label1 = new System.Windows.Forms.Label(); + this.lbLocal = new System.Windows.Forms.Label(); + this.cbMode = new System.Windows.Forms.ComboBox(); + this.numPort = new System.Windows.Forms.NumericUpDown(); + this.pnlSetting = new System.Windows.Forms.Panel(); + this.numHost = new System.Windows.Forms.NumericUpDown(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.numCount = new System.Windows.Forms.NumericUpDown(); + this.numAddress = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + ((System.ComponentModel.ISupportInitialize)(this.numPort)).BeginInit(); + this.pnlSetting.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numHost)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numCount)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numAddress)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.SuspendLayout(); + // + // txtReceive + // + this.txtReceive.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtReceive.HideSelection = false; + this.txtReceive.Location = new System.Drawing.Point(468, 55); + this.txtReceive.Margin = new System.Windows.Forms.Padding(4); + this.txtReceive.Name = "txtReceive"; + this.txtReceive.Size = new System.Drawing.Size(404, 407); + this.txtReceive.TabIndex = 1; + this.txtReceive.Text = ""; + // + // btnConnect + // + this.btnConnect.Location = new System.Drawing.Point(783, 11); + this.btnConnect.Margin = new System.Windows.Forms.Padding(4); + this.btnConnect.Name = "btnConnect"; + this.btnConnect.Size = new System.Drawing.Size(89, 36); + this.btnConnect.TabIndex = 3; + this.btnConnect.Text = "开始"; + this.btnConnect.UseVisualStyleBackColor = true; + this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click); + // + // timer1 + // + this.timer1.Enabled = true; + this.timer1.Interval = 300; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(7, 11); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(37, 15); + this.label1.TabIndex = 6; + this.label1.Text = "模式"; + // + // lbLocal + // + this.lbLocal.AutoSize = true; + this.lbLocal.Location = new System.Drawing.Point(467, 11); + this.lbLocal.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.lbLocal.Name = "lbLocal"; + this.lbLocal.Size = new System.Drawing.Size(52, 15); + this.lbLocal.TabIndex = 7; + this.lbLocal.Text = "地址:"; + // + // cbMode + // + this.cbMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbMode.FormattingEnabled = true; + this.cbMode.Items.AddRange(new object[] { + "0x0000", + "0x7777", + "0xFFFF", + "递增", + "静态随机", + "动态随机"}); + this.cbMode.Location = new System.Drawing.Point(55, 7); + this.cbMode.Margin = new System.Windows.Forms.Padding(4); + this.cbMode.Name = "cbMode"; + this.cbMode.Size = new System.Drawing.Size(123, 23); + this.cbMode.TabIndex = 9; + // + // numPort + // + this.numPort.Location = new System.Drawing.Point(246, 6); + this.numPort.Margin = new System.Windows.Forms.Padding(4); + this.numPort.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numPort.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numPort.Name = "numPort"; + this.numPort.Size = new System.Drawing.Size(68, 25); + this.numPort.TabIndex = 11; + this.numPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.toolTip1.SetToolTip(this.numPort, "端口"); + this.numPort.Value = new decimal(new int[] { + 502, + 0, + 0, + 0}); + // + // pnlSetting + // + this.pnlSetting.Controls.Add(this.numHost); + this.pnlSetting.Controls.Add(this.label4); + this.pnlSetting.Controls.Add(this.label3); + this.pnlSetting.Controls.Add(this.numCount); + this.pnlSetting.Controls.Add(this.numPort); + this.pnlSetting.Controls.Add(this.numAddress); + this.pnlSetting.Controls.Add(this.label2); + this.pnlSetting.Controls.Add(this.label1); + this.pnlSetting.Controls.Add(this.lbLocal); + this.pnlSetting.Controls.Add(this.cbMode); + this.pnlSetting.Location = new System.Drawing.Point(12, 10); + this.pnlSetting.Margin = new System.Windows.Forms.Padding(4); + this.pnlSetting.Name = "pnlSetting"; + this.pnlSetting.Size = new System.Drawing.Size(763, 39); + this.pnlSetting.TabIndex = 13; + // + // numHost + // + this.numHost.Location = new System.Drawing.Point(381, 6); + this.numHost.Margin = new System.Windows.Forms.Padding(4); + this.numHost.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numHost.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numHost.Name = "numHost"; + this.numHost.Size = new System.Drawing.Size(68, 25); + this.numHost.TabIndex = 21; + this.numHost.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.toolTip1.SetToolTip(this.numHost, "端口"); + this.numHost.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(331, 11); + this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(52, 15); + this.label4.TabIndex = 22; + this.label4.Text = "站号:"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(616, 11); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(52, 15); + this.label3.TabIndex = 20; + this.label3.Text = "个数:"; + // + // numCount + // + this.numCount.Location = new System.Drawing.Point(676, 6); + this.numCount.Margin = new System.Windows.Forms.Padding(4); + this.numCount.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numCount.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numCount.Name = "numCount"; + this.numCount.Size = new System.Drawing.Size(68, 25); + this.numCount.TabIndex = 18; + this.numCount.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.toolTip1.SetToolTip(this.numCount, "端口"); + this.numCount.Value = new decimal(new int[] { + 2000, + 0, + 0, + 0}); + // + // numAddress + // + this.numAddress.Location = new System.Drawing.Point(520, 6); + this.numAddress.Margin = new System.Windows.Forms.Padding(4); + this.numAddress.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numAddress.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numAddress.Name = "numAddress"; + this.numAddress.Size = new System.Drawing.Size(85, 25); + this.numAddress.TabIndex = 17; + this.numAddress.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.toolTip1.SetToolTip(this.numAddress, "端口"); + this.numAddress.Value = new decimal(new int[] { + 40000, + 0, + 0, + 0}); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(199, 11); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(52, 15); + this.label2.TabIndex = 19; + this.label2.Text = "端口:"; + // + // dataGridView1 + // + this.dataGridView1.AllowUserToAddRows = false; + this.dataGridView1.AllowUserToDeleteRows = false; + this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Location = new System.Drawing.Point(12, 56); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.RowHeadersWidth = 51; + this.dataGridView1.RowTemplate.Height = 27; + this.dataGridView1.Size = new System.Drawing.Size(449, 406); + this.dataGridView1.TabIndex = 14; + // + // FrmModbusSlave + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(889, 474); + this.Controls.Add(this.txtReceive); + this.Controls.Add(this.dataGridView1); + this.Controls.Add(this.pnlSetting); + this.Controls.Add(this.btnConnect); + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "FrmModbusSlave"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "网络调试"; + this.Load += new System.EventHandler(this.FrmMain_Load); + ((System.ComponentModel.ISupportInitialize)(this.numPort)).EndInit(); + this.pnlSetting.ResumeLayout(false); + this.pnlSetting.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numHost)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numCount)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numAddress)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.Button btnConnect; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.RichTextBox txtReceive; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lbLocal; + private System.Windows.Forms.ComboBox cbMode; + private System.Windows.Forms.NumericUpDown numPort; + private System.Windows.Forms.Panel pnlSetting; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.NumericUpDown numCount; + private System.Windows.Forms.NumericUpDown numAddress; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.NumericUpDown numHost; + } +} + diff --git a/XCoder/XNet/FrmModbusSlave.resx b/XCoder/XNet/FrmModbusSlave.resx new file mode 100644 index 0000000..57fa2ec --- /dev/null +++ b/XCoder/XNet/FrmModbusSlave.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 601, 17 + + + 601, 17 + + \ No newline at end of file diff --git a/XCoder/XNet/RegisterUnit.cs b/XCoder/XNet/RegisterUnit.cs new file mode 100644 index 0000000..24c1632 --- /dev/null +++ b/XCoder/XNet/RegisterUnit.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace XCoder.XNet +{ + internal class RegisterUnit + { + public Int32 Address { get; set; } + + public UInt16 Value { get; set; } + } +} diff --git a/XCoderWpf/XCoderWpf.csproj b/XCoderWpf/XCoderWpf.csproj index a305321..02c07fd 100644 --- a/XCoderWpf/XCoderWpf.csproj +++ b/XCoderWpf/XCoderWpf.csproj @@ -29,9 +29,9 @@ - - - + + +