From 3211d1431baced52a1da4003db3739c1ede0684b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= Date: Wed, 15 Mar 2023 11:11:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SphygmomanometerTester.sln | 25 + SphygmomanometerTester/App.config | 6 + SphygmomanometerTester/FormMain.Designer.cs | 553 ++++++++++++++++++ SphygmomanometerTester/FormMain.cs | 436 ++++++++++++++ SphygmomanometerTester/FormMain.resx | 120 ++++ SphygmomanometerTester/Program.cs | 22 + .../Properties/AssemblyInfo.cs | 35 ++ .../Properties/Resources.Designer.cs | 71 +++ .../Properties/Resources.resx | 117 ++++ .../Properties/Settings.Designer.cs | 30 + .../Properties/Settings.settings | 7 + .../Sphygmomanometer/MaiBoBo/MaiBoBo.cs | 437 ++++++++++++++ .../Sphygmomanometer/MaiBoBo/RBP-9000c.cs | 6 + .../Sphygmomanometer/MaiBoBo/RBP-9001.cs | 6 + .../Sphygmomanometer/OMRON/Omron.cs | 177 ++++++ .../Sphygmomanometer/SerialControl.cs | 82 +++ .../Sphygmomanometer/Sphygmomanometer.cs | 74 +++ .../SphygmomanometerTester.csproj | 89 +++ .../SphygmomanometerTester.csproj.DotSettings | 2 + 19 files changed, 2295 insertions(+) create mode 100644 SphygmomanometerTester.sln create mode 100644 SphygmomanometerTester/App.config create mode 100644 SphygmomanometerTester/FormMain.Designer.cs create mode 100644 SphygmomanometerTester/FormMain.cs create mode 100644 SphygmomanometerTester/FormMain.resx create mode 100644 SphygmomanometerTester/Program.cs create mode 100644 SphygmomanometerTester/Properties/AssemblyInfo.cs create mode 100644 SphygmomanometerTester/Properties/Resources.Designer.cs create mode 100644 SphygmomanometerTester/Properties/Resources.resx create mode 100644 SphygmomanometerTester/Properties/Settings.Designer.cs create mode 100644 SphygmomanometerTester/Properties/Settings.settings create mode 100644 SphygmomanometerTester/Sphygmomanometer/MaiBoBo/MaiBoBo.cs create mode 100644 SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9000c.cs create mode 100644 SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9001.cs create mode 100644 SphygmomanometerTester/Sphygmomanometer/OMRON/Omron.cs create mode 100644 SphygmomanometerTester/Sphygmomanometer/SerialControl.cs create mode 100644 SphygmomanometerTester/Sphygmomanometer/Sphygmomanometer.cs create mode 100644 SphygmomanometerTester/SphygmomanometerTester.csproj create mode 100644 SphygmomanometerTester/SphygmomanometerTester.csproj.DotSettings diff --git a/SphygmomanometerTester.sln b/SphygmomanometerTester.sln new file mode 100644 index 0000000..308e3b1 --- /dev/null +++ b/SphygmomanometerTester.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SphygmomanometerTester", "SphygmomanometerTester\SphygmomanometerTester.csproj", "{8C5FDDD2-5EC5-4AD7-AB24-F87665872A95}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C5FDDD2-5EC5-4AD7-AB24-F87665872A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C5FDDD2-5EC5-4AD7-AB24-F87665872A95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C5FDDD2-5EC5-4AD7-AB24-F87665872A95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C5FDDD2-5EC5-4AD7-AB24-F87665872A95}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5E052F27-92AD-454F-9611-88871647070C} + EndGlobalSection +EndGlobal diff --git a/SphygmomanometerTester/App.config b/SphygmomanometerTester/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/SphygmomanometerTester/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SphygmomanometerTester/FormMain.Designer.cs b/SphygmomanometerTester/FormMain.Designer.cs new file mode 100644 index 0000000..3d6555c --- /dev/null +++ b/SphygmomanometerTester/FormMain.Designer.cs @@ -0,0 +1,553 @@ +namespace SphygmomanometerTester +{ + partial class FormMain + { + /// + /// 必需的设计器变量。 + /// + 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.GrpSerialPort = new System.Windows.Forms.GroupBox(); + this.CmbSerialPortName = new System.Windows.Forms.ComboBox(); + this.LblPortName = new System.Windows.Forms.Label(); + this.BtnUpdatePortNames = new System.Windows.Forms.Button(); + this.BtnOpenPort = new System.Windows.Forms.Button(); + this.BtnClosePort = new System.Windows.Forms.Button(); + this.GrpSphygmomanometer = new System.Windows.Forms.GroupBox(); + this.BtnConnect = new System.Windows.Forms.Button(); + this.BtnStartMeasure = new System.Windows.Forms.Button(); + this.BtnStopMeasure = new System.Windows.Forms.Button(); + this.LblSystolicPressure = new System.Windows.Forms.Label(); + this.GrpMeasureResult = new System.Windows.Forms.GroupBox(); + this.LblSystolicPressureValue = new System.Windows.Forms.Label(); + this.LblDiastolicPressure = new System.Windows.Forms.Label(); + this.LblDiastolicPressureValue = new System.Windows.Forms.Label(); + this.LblPulse = new System.Windows.Forms.Label(); + this.LblPulseValue = new System.Windows.Forms.Label(); + this.GrpPressure = new System.Windows.Forms.GroupBox(); + this.LblPressureValue = new System.Windows.Forms.Label(); + this.LblInterval = new System.Windows.Forms.Label(); + this.NudInterval = new System.Windows.Forms.NumericUpDown(); + this.ChkLoopTest = new System.Windows.Forms.CheckBox(); + this.LblLoopTestTip = new System.Windows.Forms.Label(); + this.PrbIntervalProgress = new System.Windows.Forms.ProgressBar(); + this.GrpLog = new System.Windows.Forms.GroupBox(); + this.TxtLog = new System.Windows.Forms.TextBox(); + this.GrpStat = new System.Windows.Forms.GroupBox(); + this.BtnResetStat = new System.Windows.Forms.Button(); + this.FlpStatLabels = new System.Windows.Forms.FlowLayoutPanel(); + this.LblTestStat = new System.Windows.Forms.Label(); + this.LblTestSuccessCount = new System.Windows.Forms.Label(); + this.LblTestStatSeparator1 = new System.Windows.Forms.Label(); + this.LblTestFailedCount = new System.Windows.Forms.Label(); + this.LblTestStatSeparator2 = new System.Windows.Forms.Label(); + this.LblTestCount = new System.Windows.Forms.Label(); + this.GrpSerialPort.SuspendLayout(); + this.GrpSphygmomanometer.SuspendLayout(); + this.GrpMeasureResult.SuspendLayout(); + this.GrpPressure.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.NudInterval)).BeginInit(); + this.GrpLog.SuspendLayout(); + this.GrpStat.SuspendLayout(); + this.FlpStatLabels.SuspendLayout(); + this.SuspendLayout(); + // + // GrpSerialPort + // + this.GrpSerialPort.Controls.Add(this.BtnClosePort); + this.GrpSerialPort.Controls.Add(this.BtnOpenPort); + this.GrpSerialPort.Controls.Add(this.BtnUpdatePortNames); + this.GrpSerialPort.Controls.Add(this.LblPortName); + this.GrpSerialPort.Controls.Add(this.CmbSerialPortName); + this.GrpSerialPort.Location = new System.Drawing.Point(13, 12); + this.GrpSerialPort.Name = "GrpSerialPort"; + this.GrpSerialPort.Size = new System.Drawing.Size(561, 60); + this.GrpSerialPort.TabIndex = 0; + this.GrpSerialPort.TabStop = false; + this.GrpSerialPort.Text = "串口设置"; + // + // CmbSerialPortName + // + this.CmbSerialPortName.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CmbSerialPortName.FormattingEnabled = true; + this.CmbSerialPortName.Location = new System.Drawing.Point(71, 22); + this.CmbSerialPortName.Name = "CmbSerialPortName"; + this.CmbSerialPortName.Size = new System.Drawing.Size(120, 25); + this.CmbSerialPortName.TabIndex = 1; + // + // LblPortName + // + this.LblPortName.AutoSize = true; + this.LblPortName.Location = new System.Drawing.Point(21, 25); + this.LblPortName.Name = "LblPortName"; + this.LblPortName.Size = new System.Drawing.Size(44, 17); + this.LblPortName.TabIndex = 0; + this.LblPortName.Text = "端口:"; + // + // BtnUpdatePortNames + // + this.BtnUpdatePortNames.Location = new System.Drawing.Point(197, 22); + this.BtnUpdatePortNames.Name = "BtnUpdatePortNames"; + this.BtnUpdatePortNames.Size = new System.Drawing.Size(75, 25); + this.BtnUpdatePortNames.TabIndex = 2; + this.BtnUpdatePortNames.Text = "刷新"; + this.BtnUpdatePortNames.UseVisualStyleBackColor = true; + this.BtnUpdatePortNames.Click += new System.EventHandler(this.BtnUpdatePortNames_Click); + // + // BtnOpenPort + // + this.BtnOpenPort.Location = new System.Drawing.Point(278, 22); + this.BtnOpenPort.Name = "BtnOpenPort"; + this.BtnOpenPort.Size = new System.Drawing.Size(75, 25); + this.BtnOpenPort.TabIndex = 3; + this.BtnOpenPort.Text = "打开"; + this.BtnOpenPort.UseVisualStyleBackColor = true; + this.BtnOpenPort.Click += new System.EventHandler(this.BtnOpenPort_Click); + // + // BtnClosePort + // + this.BtnClosePort.Location = new System.Drawing.Point(359, 22); + this.BtnClosePort.Name = "BtnClosePort"; + this.BtnClosePort.Size = new System.Drawing.Size(75, 25); + this.BtnClosePort.TabIndex = 4; + this.BtnClosePort.Text = "关闭"; + this.BtnClosePort.UseVisualStyleBackColor = true; + this.BtnClosePort.Click += new System.EventHandler(this.BtnClosePort_Click); + // + // GrpSphygmomanometer + // + this.GrpSphygmomanometer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.GrpSphygmomanometer.Controls.Add(this.PrbIntervalProgress); + this.GrpSphygmomanometer.Controls.Add(this.LblLoopTestTip); + this.GrpSphygmomanometer.Controls.Add(this.ChkLoopTest); + this.GrpSphygmomanometer.Controls.Add(this.NudInterval); + this.GrpSphygmomanometer.Controls.Add(this.LblInterval); + this.GrpSphygmomanometer.Controls.Add(this.BtnStopMeasure); + this.GrpSphygmomanometer.Controls.Add(this.BtnStartMeasure); + this.GrpSphygmomanometer.Controls.Add(this.BtnConnect); + this.GrpSphygmomanometer.Location = new System.Drawing.Point(13, 272); + this.GrpSphygmomanometer.Name = "GrpSphygmomanometer"; + this.GrpSphygmomanometer.Size = new System.Drawing.Size(560, 77); + this.GrpSphygmomanometer.TabIndex = 3; + this.GrpSphygmomanometer.TabStop = false; + this.GrpSphygmomanometer.Text = "血压计控制"; + // + // BtnConnect + // + this.BtnConnect.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.BtnConnect.Location = new System.Drawing.Point(24, 31); + this.BtnConnect.Name = "BtnConnect"; + this.BtnConnect.Size = new System.Drawing.Size(100, 30); + this.BtnConnect.TabIndex = 0; + this.BtnConnect.Text = "测试连接"; + this.BtnConnect.UseVisualStyleBackColor = true; + this.BtnConnect.Click += new System.EventHandler(this.BtnConnect_Click); + // + // BtnStartMeasure + // + this.BtnStartMeasure.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.BtnStartMeasure.Location = new System.Drawing.Point(132, 31); + this.BtnStartMeasure.Name = "BtnStartMeasure"; + this.BtnStartMeasure.Size = new System.Drawing.Size(100, 30); + this.BtnStartMeasure.TabIndex = 1; + this.BtnStartMeasure.Text = "开始测量"; + this.BtnStartMeasure.UseVisualStyleBackColor = true; + this.BtnStartMeasure.Click += new System.EventHandler(this.BtnStartMeasure_Click); + // + // BtnStopMeasure + // + this.BtnStopMeasure.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.BtnStopMeasure.Location = new System.Drawing.Point(238, 31); + this.BtnStopMeasure.Name = "BtnStopMeasure"; + this.BtnStopMeasure.Size = new System.Drawing.Size(100, 30); + this.BtnStopMeasure.TabIndex = 2; + this.BtnStopMeasure.Text = "中断测量"; + this.BtnStopMeasure.UseVisualStyleBackColor = true; + this.BtnStopMeasure.Click += new System.EventHandler(this.BtnStopMeasure_Click); + // + // LblSystolicPressure + // + this.LblSystolicPressure.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblSystolicPressure.AutoSize = true; + this.LblSystolicPressure.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblSystolicPressure.Location = new System.Drawing.Point(55, 33); + this.LblSystolicPressure.Name = "LblSystolicPressure"; + this.LblSystolicPressure.Size = new System.Drawing.Size(74, 25); + this.LblSystolicPressure.TabIndex = 1; + this.LblSystolicPressure.Text = "收缩压:"; + // + // GrpMeasureResult + // + this.GrpMeasureResult.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.GrpMeasureResult.Controls.Add(this.LblPulseValue); + this.GrpMeasureResult.Controls.Add(this.LblPulse); + this.GrpMeasureResult.Controls.Add(this.LblDiastolicPressureValue); + this.GrpMeasureResult.Controls.Add(this.LblDiastolicPressure); + this.GrpMeasureResult.Controls.Add(this.LblSystolicPressureValue); + this.GrpMeasureResult.Controls.Add(this.LblSystolicPressure); + this.GrpMeasureResult.Location = new System.Drawing.Point(13, 189); + this.GrpMeasureResult.Name = "GrpMeasureResult"; + this.GrpMeasureResult.Size = new System.Drawing.Size(560, 77); + this.GrpMeasureResult.TabIndex = 2; + this.GrpMeasureResult.TabStop = false; + this.GrpMeasureResult.Text = "测量结果"; + // + // LblSystolicPressureValue + // + this.LblSystolicPressureValue.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblSystolicPressureValue.AutoSize = true; + this.LblSystolicPressureValue.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblSystolicPressureValue.Location = new System.Drawing.Point(135, 33); + this.LblSystolicPressureValue.Name = "LblSystolicPressureValue"; + this.LblSystolicPressureValue.Size = new System.Drawing.Size(23, 25); + this.LblSystolicPressureValue.TabIndex = 2; + this.LblSystolicPressureValue.Text = "0"; + // + // LblDiastolicPressure + // + this.LblDiastolicPressure.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblDiastolicPressure.AutoSize = true; + this.LblDiastolicPressure.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblDiastolicPressure.Location = new System.Drawing.Point(230, 33); + this.LblDiastolicPressure.Name = "LblDiastolicPressure"; + this.LblDiastolicPressure.Size = new System.Drawing.Size(69, 25); + this.LblDiastolicPressure.TabIndex = 3; + this.LblDiastolicPressure.Text = "舒张压"; + // + // LblDiastolicPressureValue + // + this.LblDiastolicPressureValue.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblDiastolicPressureValue.AutoSize = true; + this.LblDiastolicPressureValue.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblDiastolicPressureValue.Location = new System.Drawing.Point(305, 33); + this.LblDiastolicPressureValue.Name = "LblDiastolicPressureValue"; + this.LblDiastolicPressureValue.Size = new System.Drawing.Size(23, 25); + this.LblDiastolicPressureValue.TabIndex = 4; + this.LblDiastolicPressureValue.Text = "0"; + // + // LblPulse + // + this.LblPulse.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblPulse.AutoSize = true; + this.LblPulse.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblPulse.Location = new System.Drawing.Point(399, 33); + this.LblPulse.Name = "LblPulse"; + this.LblPulse.Size = new System.Drawing.Size(55, 25); + this.LblPulse.TabIndex = 5; + this.LblPulse.Text = "脉搏:"; + // + // LblPulseValue + // + this.LblPulseValue.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.LblPulseValue.AutoSize = true; + this.LblPulseValue.Font = new System.Drawing.Font("微软雅黑", 14F); + this.LblPulseValue.Location = new System.Drawing.Point(460, 33); + this.LblPulseValue.Name = "LblPulseValue"; + this.LblPulseValue.Size = new System.Drawing.Size(23, 25); + this.LblPulseValue.TabIndex = 6; + this.LblPulseValue.Text = "0"; + // + // GrpPressure + // + this.GrpPressure.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.GrpPressure.Controls.Add(this.LblPressureValue); + this.GrpPressure.Location = new System.Drawing.Point(192, 78); + this.GrpPressure.Name = "GrpPressure"; + this.GrpPressure.Size = new System.Drawing.Size(200, 105); + this.GrpPressure.TabIndex = 1; + this.GrpPressure.TabStop = false; + this.GrpPressure.Text = "实时压力值(mmHg)"; + // + // LblPressureValue + // + this.LblPressureValue.Dock = System.Windows.Forms.DockStyle.Fill; + this.LblPressureValue.Font = new System.Drawing.Font("微软雅黑", 20F); + this.LblPressureValue.Location = new System.Drawing.Point(3, 19); + this.LblPressureValue.Name = "LblPressureValue"; + this.LblPressureValue.Size = new System.Drawing.Size(194, 83); + this.LblPressureValue.TabIndex = 0; + this.LblPressureValue.Text = "0"; + this.LblPressureValue.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // LblInterval + // + this.LblInterval.AutoSize = true; + this.LblInterval.Location = new System.Drawing.Point(357, 31); + this.LblInterval.Name = "LblInterval"; + this.LblInterval.Size = new System.Drawing.Size(50, 17); + this.LblInterval.TabIndex = 3; + this.LblInterval.Text = "间隔(S):"; + // + // NudInterval + // + this.NudInterval.Increment = new decimal(new int[] { + 30, + 0, + 0, + 0}); + this.NudInterval.Location = new System.Drawing.Point(413, 29); + this.NudInterval.Maximum = new decimal(new int[] { + 2147483647, + 0, + 0, + 0}); + this.NudInterval.Name = "NudInterval"; + this.NudInterval.Size = new System.Drawing.Size(60, 23); + this.NudInterval.TabIndex = 4; + this.NudInterval.Value = new decimal(new int[] { + 120, + 0, + 0, + 0}); + // + // ChkLoopTest + // + this.ChkLoopTest.AutoSize = true; + this.ChkLoopTest.Location = new System.Drawing.Point(479, 31); + this.ChkLoopTest.Name = "ChkLoopTest"; + this.ChkLoopTest.Size = new System.Drawing.Size(75, 21); + this.ChkLoopTest.TabIndex = 5; + this.ChkLoopTest.Text = "循环测试"; + this.ChkLoopTest.UseVisualStyleBackColor = true; + this.ChkLoopTest.CheckedChanged += new System.EventHandler(this.ChkLoopTest_CheckedChanged); + // + // LblLoopTestTip + // + this.LblLoopTestTip.AutoSize = true; + this.LblLoopTestTip.ForeColor = System.Drawing.SystemColors.GrayText; + this.LblLoopTestTip.Location = new System.Drawing.Point(360, 55); + this.LblLoopTestTip.Name = "LblLoopTestTip"; + this.LblLoopTestTip.Size = new System.Drawing.Size(188, 17); + this.LblLoopTestTip.TabIndex = 6; + this.LblLoopTestTip.Text = "收到测试结果指定时间后自动开始"; + // + // PrbIntervalProgress + // + this.PrbIntervalProgress.Location = new System.Drawing.Point(360, 14); + this.PrbIntervalProgress.Name = "PrbIntervalProgress"; + this.PrbIntervalProgress.Size = new System.Drawing.Size(188, 10); + this.PrbIntervalProgress.TabIndex = 7; + this.PrbIntervalProgress.Visible = false; + // + // GrpLog + // + this.GrpLog.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.GrpLog.Controls.Add(this.TxtLog); + this.GrpLog.Location = new System.Drawing.Point(579, 12); + this.GrpLog.Name = "GrpLog"; + this.GrpLog.Size = new System.Drawing.Size(233, 284); + this.GrpLog.TabIndex = 4; + this.GrpLog.TabStop = false; + this.GrpLog.Text = "日志"; + // + // TxtLog + // + this.TxtLog.BackColor = System.Drawing.Color.White; + this.TxtLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.TxtLog.Location = new System.Drawing.Point(3, 19); + this.TxtLog.Multiline = true; + this.TxtLog.Name = "TxtLog"; + this.TxtLog.ReadOnly = true; + this.TxtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.TxtLog.Size = new System.Drawing.Size(227, 262); + this.TxtLog.TabIndex = 0; + // + // GrpStat + // + this.GrpStat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.GrpStat.Controls.Add(this.FlpStatLabels); + this.GrpStat.Controls.Add(this.BtnResetStat); + this.GrpStat.Location = new System.Drawing.Point(579, 301); + this.GrpStat.Name = "GrpStat"; + this.GrpStat.Size = new System.Drawing.Size(230, 48); + this.GrpStat.TabIndex = 5; + this.GrpStat.TabStop = false; + this.GrpStat.Text = "统计"; + // + // BtnResetStat + // + this.BtnResetStat.Dock = System.Windows.Forms.DockStyle.Right; + this.BtnResetStat.Location = new System.Drawing.Point(177, 19); + this.BtnResetStat.Name = "BtnResetStat"; + this.BtnResetStat.Size = new System.Drawing.Size(50, 26); + this.BtnResetStat.TabIndex = 1; + this.BtnResetStat.Text = "重置"; + this.BtnResetStat.UseVisualStyleBackColor = true; + this.BtnResetStat.Click += new System.EventHandler(this.BtnResetStat_Click); + // + // FlpStatLabels + // + this.FlpStatLabels.Controls.Add(this.LblTestStat); + this.FlpStatLabels.Controls.Add(this.LblTestSuccessCount); + this.FlpStatLabels.Controls.Add(this.LblTestStatSeparator1); + this.FlpStatLabels.Controls.Add(this.LblTestFailedCount); + this.FlpStatLabels.Controls.Add(this.LblTestStatSeparator2); + this.FlpStatLabels.Controls.Add(this.LblTestCount); + this.FlpStatLabels.Dock = System.Windows.Forms.DockStyle.Fill; + this.FlpStatLabels.Location = new System.Drawing.Point(3, 19); + this.FlpStatLabels.Name = "FlpStatLabels"; + this.FlpStatLabels.Size = new System.Drawing.Size(174, 26); + this.FlpStatLabels.TabIndex = 2; + // + // LblTestStat + // + this.LblTestStat.AutoSize = true; + this.LblTestStat.Location = new System.Drawing.Point(0, 4); + this.LblTestStat.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestStat.Name = "LblTestStat"; + this.LblTestStat.Size = new System.Drawing.Size(59, 17); + this.LblTestStat.TabIndex = 0; + this.LblTestStat.Text = "测量次数:"; + // + // LblTestSuccessCount + // + this.LblTestSuccessCount.AutoSize = true; + this.LblTestSuccessCount.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.LblTestSuccessCount.ForeColor = System.Drawing.Color.Green; + this.LblTestSuccessCount.Location = new System.Drawing.Point(59, 4); + this.LblTestSuccessCount.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestSuccessCount.Name = "LblTestSuccessCount"; + this.LblTestSuccessCount.Size = new System.Drawing.Size(15, 17); + this.LblTestSuccessCount.TabIndex = 1; + this.LblTestSuccessCount.Text = "0"; + // + // LblTestStatSeparator1 + // + this.LblTestStatSeparator1.AutoSize = true; + this.LblTestStatSeparator1.Location = new System.Drawing.Point(74, 4); + this.LblTestStatSeparator1.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestStatSeparator1.Name = "LblTestStatSeparator1"; + this.LblTestStatSeparator1.Size = new System.Drawing.Size(13, 17); + this.LblTestStatSeparator1.TabIndex = 2; + this.LblTestStatSeparator1.Text = "/"; + // + // LblTestFailedCount + // + this.LblTestFailedCount.AutoSize = true; + this.LblTestFailedCount.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.LblTestFailedCount.ForeColor = System.Drawing.Color.Red; + this.LblTestFailedCount.Location = new System.Drawing.Point(87, 4); + this.LblTestFailedCount.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestFailedCount.Name = "LblTestFailedCount"; + this.LblTestFailedCount.Size = new System.Drawing.Size(15, 17); + this.LblTestFailedCount.TabIndex = 3; + this.LblTestFailedCount.Text = "0"; + // + // LblTestStatSeparator2 + // + this.LblTestStatSeparator2.AutoSize = true; + this.LblTestStatSeparator2.Location = new System.Drawing.Point(102, 4); + this.LblTestStatSeparator2.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestStatSeparator2.Name = "LblTestStatSeparator2"; + this.LblTestStatSeparator2.Size = new System.Drawing.Size(13, 17); + this.LblTestStatSeparator2.TabIndex = 4; + this.LblTestStatSeparator2.Text = "/"; + // + // LblTestCount + // + this.LblTestCount.AutoSize = true; + this.LblTestCount.Location = new System.Drawing.Point(115, 4); + this.LblTestCount.Margin = new System.Windows.Forms.Padding(0, 4, 0, 0); + this.LblTestCount.Name = "LblTestCount"; + this.LblTestCount.Size = new System.Drawing.Size(15, 17); + this.LblTestCount.TabIndex = 5; + this.LblTestCount.Text = "0"; + // + // FormMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(824, 361); + this.Controls.Add(this.GrpStat); + this.Controls.Add(this.GrpLog); + this.Controls.Add(this.GrpPressure); + this.Controls.Add(this.GrpMeasureResult); + this.Controls.Add(this.GrpSphygmomanometer); + this.Controls.Add(this.GrpSerialPort); + this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.MinimumSize = new System.Drawing.Size(840, 400); + this.Name = "FormMain"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "血压计通讯测试工具"; + this.GrpSerialPort.ResumeLayout(false); + this.GrpSerialPort.PerformLayout(); + this.GrpSphygmomanometer.ResumeLayout(false); + this.GrpSphygmomanometer.PerformLayout(); + this.GrpMeasureResult.ResumeLayout(false); + this.GrpMeasureResult.PerformLayout(); + this.GrpPressure.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.NudInterval)).EndInit(); + this.GrpLog.ResumeLayout(false); + this.GrpLog.PerformLayout(); + this.GrpStat.ResumeLayout(false); + this.FlpStatLabels.ResumeLayout(false); + this.FlpStatLabels.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox GrpSerialPort; + private System.Windows.Forms.Button BtnClosePort; + private System.Windows.Forms.Button BtnOpenPort; + private System.Windows.Forms.Button BtnUpdatePortNames; + private System.Windows.Forms.Label LblPortName; + private System.Windows.Forms.ComboBox CmbSerialPortName; + private System.Windows.Forms.GroupBox GrpSphygmomanometer; + private System.Windows.Forms.Button BtnConnect; + private System.Windows.Forms.Button BtnStopMeasure; + private System.Windows.Forms.Button BtnStartMeasure; + private System.Windows.Forms.Label LblSystolicPressure; + private System.Windows.Forms.GroupBox GrpMeasureResult; + private System.Windows.Forms.Label LblSystolicPressureValue; + private System.Windows.Forms.Label LblPulseValue; + private System.Windows.Forms.Label LblPulse; + private System.Windows.Forms.Label LblDiastolicPressureValue; + private System.Windows.Forms.Label LblDiastolicPressure; + private System.Windows.Forms.GroupBox GrpPressure; + private System.Windows.Forms.Label LblPressureValue; + private System.Windows.Forms.ProgressBar PrbIntervalProgress; + private System.Windows.Forms.Label LblLoopTestTip; + private System.Windows.Forms.CheckBox ChkLoopTest; + private System.Windows.Forms.NumericUpDown NudInterval; + private System.Windows.Forms.Label LblInterval; + private System.Windows.Forms.GroupBox GrpLog; + private System.Windows.Forms.TextBox TxtLog; + private System.Windows.Forms.GroupBox GrpStat; + private System.Windows.Forms.FlowLayoutPanel FlpStatLabels; + private System.Windows.Forms.Label LblTestStat; + private System.Windows.Forms.Label LblTestSuccessCount; + private System.Windows.Forms.Label LblTestStatSeparator1; + private System.Windows.Forms.Label LblTestFailedCount; + private System.Windows.Forms.Label LblTestStatSeparator2; + private System.Windows.Forms.Label LblTestCount; + private System.Windows.Forms.Button BtnResetStat; + } +} + diff --git a/SphygmomanometerTester/FormMain.cs b/SphygmomanometerTester/FormMain.cs new file mode 100644 index 0000000..3698c07 --- /dev/null +++ b/SphygmomanometerTester/FormMain.cs @@ -0,0 +1,436 @@ +using System; +using System.Drawing; +using System.IO; +using System.IO.Ports; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +using SphygmomanometerTester.Sphygmomanometer.MaiBoBo; +using SphygmomanometerTester.Sphygmomanometer.OMRON; + +namespace SphygmomanometerTester +{ + public partial class FormMain : Form + { + public static FormMain Instance { get; private set; } + + /// + /// 血压计实例 + /// + private readonly Sphygmomanometer.Sphygmomanometer sphygmomanometer = new Omron(); + + #region - 窗口构造与事件 - + + public FormMain() + { + Instance = this; + InitializeComponent(); + + if (sphygmomanometer is MaiBoBo maiBoBo) + maiBoBo.MeasuringPoll += Sphygmomanometer_MeasuringPoll; + sphygmomanometer.MeasureOver += Sphygmomanometer_MeasureOver; + } + + /// + /// 窗体加载时触发 + /// + /// + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + CmbSerialPortName.DataSource = SerialPort.GetPortNames(); + UpdateControlButtons(); + } + + /// + /// 窗口关闭时触发 + /// + protected override void OnFormClosed(FormClosedEventArgs e) + { + try + { + if (!string.IsNullOrEmpty(TxtLog.Text)) + { + // 保存日志文件 + File.WriteAllText(DateTime.Now.ToString("MMddHHmm") + ".log", TxtLog.Text); + } + } + catch + { + // ignored + } + + sphygmomanometer.CloseCom(); + + base.OnFormClosed(e); + } + + #endregion - 窗口构造与事件 - + + #region - 血压计事件 - + + /// + /// 测量过程压力上报事件 + /// + private void Sphygmomanometer_MeasuringPoll(object sender, MaiBoBo.MeasurePoll e) + { + BeginInvoke(new Action(() => + { + LblPressureValue.Text = e.Pressure.ToString(); + })); + } + + /// + /// 测量结束事件 + /// + private void Sphygmomanometer_MeasureOver(object sender, Sphygmomanometer.MeasureResult e) + { + BeginInvoke(new Action(() => + { + // 显示结果 + LblPressureValue.Text = "0"; + LblSystolicPressureValue.Text = e.SystolicPressure.ToString(); + LblDiastolicPressureValue.Text = e.DiastolicPressure.ToString(); + LblPulseValue.Text = e.Pulse.ToString(); + if (!string.IsNullOrEmpty(e.Message)) + { + StatEndTest(false); + Log("测量失败:" + e.Message); + if (!ChkLoopTest.Checked) + { + MessageBox.Show(e.Message, "测量出错", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + StatEndTest(true); + Log($"测量完成,结果:收缩压={e.SystolicPressure} 舒张压={e.DiastolicPressure} 脉搏={e.Pulse}"); + } + + // 检查并循环测量 + CheckAndLoop(); + })); + } + + #endregion - 血压计事件 - + + #region - 控制按钮 - + + /// + /// 更新控制按钮状态 + /// + private void UpdateControlButtons() + { + var isOpen = sphygmomanometer.IsOpen; + CmbSerialPortName.Enabled = !isOpen; + BtnUpdatePortNames.Enabled = !isOpen; + BtnOpenPort.Enabled = !isOpen; + BtnClosePort.Enabled = isOpen; + BtnConnect.Enabled = isOpen; + BtnStartMeasure.Enabled = isOpen; + BtnStopMeasure.Enabled = isOpen; + } + + /// + /// 刷新串口列表 + /// + private void BtnUpdatePortNames_Click(object sender, EventArgs e) + { + CmbSerialPortName.DataSource = SerialPort.GetPortNames(); + } + + /// + /// 点击打开串口 + /// + private void BtnOpenPort_Click(object sender, EventArgs e) + { + if (!string.IsNullOrEmpty(CmbSerialPortName.Text)) + { + Log("打开串口 " + CmbSerialPortName.Text); + try + { + sphygmomanometer.OpenCom(CmbSerialPortName.Text); + } + catch (Exception ex) + { + Log("打开串口异常", ex); + MessageBox.Show("串口打开失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else + { + MessageBox.Show("请选择端口", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + UpdateControlButtons(); + } + + /// + /// 点击关闭串口 + /// + private void BtnClosePort_Click(object sender, EventArgs e) + { + Log("关闭串口"); + sphygmomanometer.CloseCom(); + UpdateControlButtons(); + } + + /// + /// 点击测试连接按钮 + /// + private async void BtnConnect_Click(object sender, EventArgs e) + { + if (!(sphygmomanometer is MaiBoBo maiBoBo)) + { + MessageBox.Show("当前血压计不支持测试连接状态", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var btn = (Button)sender; + try + { + btn.Enabled = false; + LblPressureValue.Text = "0"; + Log("尝试连接血压计,发送连接测试"); + await maiBoBo.Connect(); + Log("正常响应"); + await ButtonOk(btn); + } + catch (Exception ex) + { + Log("连接测试异常", ex); + MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + btn.Enabled = true; + } + } + + /// + /// 点击开始测量按钮 + /// + private async void BtnStartMeasure_Click(object sender, EventArgs e) + { + var btn = (Button)sender; + try + { + btn.Enabled = false; + LblPressureValue.Text = "0"; + Log($"尝试开始第 {TestCount + 1} 次测量..."); + await sphygmomanometer.StartMeasure(); + StatBeginTest(); + await ButtonOk(btn); + } + catch (Exception ex) + { + Log("开始测量异常", ex); + MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + btn.Enabled = true; + } + } + + /// + /// 点击停止测量按钮 + /// + private async void BtnStopMeasure_Click(object sender, EventArgs e) + { + var btn = (Button)sender; + try + { + btn.Enabled = false; + LblPressureValue.Text = "0"; + Log("尝试取消测量"); + await sphygmomanometer.StopMeasure(); + await ButtonOk(btn); + } + catch (Exception ex) + { + Log("停止测量异常", ex); + MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + btn.Enabled = true; + } + } + + /// + /// 检查并启动循环 + /// + private void CheckAndLoop() + { + if (!ChkLoopTest.Checked) return; + var interval = (int)NudInterval.Value; + if (interval > 0) + { + PrbIntervalProgress.Maximum = interval; + PrbIntervalProgress.Value = 0; + PrbIntervalProgress.Visible = true; + CancellationTokenSource = new CancellationTokenSource(); + var cancellationToken = CancellationTokenSource.Token; + Log($"启动任务,等待 {interval} 秒后重新开始测试..."); + Task.Run(async () => + { + for (var i = 0; i < interval && !cancellationToken.IsCancellationRequested; i++) + { + await Task.Delay(1000, cancellationToken); + Invoke(new Action(() => + { + PrbIntervalProgress.Value += 1; + if (PrbIntervalProgress.Value == PrbIntervalProgress.Maximum) + PrbIntervalProgress.Visible = false; + })); + } + + if (!cancellationToken.IsCancellationRequested && sphygmomanometer.IsOpen) + { + BeginInvoke(new Action(() => BtnStartMeasure_Click(BtnStartMeasure, EventArgs.Empty))); + } + }, cancellationToken); + } + else + { + Log("无间隔循环测试继续"); + BtnStartMeasure_Click(BtnStartMeasure, EventArgs.Empty); + } + } + + private CancellationTokenSource CancellationTokenSource; + + /// + /// 循环测试复选框改变事件 + /// + private void ChkLoopTest_CheckedChanged(object sender, EventArgs e) + { + if (ChkLoopTest.Checked) return; + if (CancellationTokenSource != null && !CancellationTokenSource.IsCancellationRequested) + { + CancellationTokenSource.Cancel(); + PrbIntervalProgress.Visible = false; + Log("取消循环测试"); + } + } + + #endregion - 控制按钮 - + + #region - 日志 - + + /// + /// 写日志到文本框 + /// + /// + public void Log(string message) + { + if (InvokeRequired) + { + Invoke(new Action(Log), message); + return; + } + var scrollToEnd = TxtLog.SelectionStart == TxtLog.Text.Length; + TxtLog.AppendText(DateTime.Now.ToLongTimeString()); + TxtLog.AppendText(" "); + TxtLog.AppendText(message); + TxtLog.AppendText(Environment.NewLine); + if (!scrollToEnd) return; + TxtLog.SelectionStart = TxtLog.Text.Length; + TxtLog.SelectionLength = 0; + TxtLog.ScrollToCaret(); + } + + public void Log(string message, Exception ex) + { + Log(message + " " + ex); + } + + #endregion - 日志 - + + #region - 工具 - + + /// + /// 按钮OK动画 + /// + /// + /// + private static async Task ButtonOk(Control btn) + { + var text = btn.Text; + var color = btn.ForeColor; + btn.Text = "OK"; + btn.ForeColor = Color.LawnGreen; + await Task.Delay(1000); + btn.Text = text; + btn.ForeColor = color; + } + + #endregion - 工具 - + + #region - 重置统计 - + + /// + /// 测试次数 + /// + private int TestCount; + + /// + /// 测试成功次数 + /// + private int TestSuccessCount; + + /// + /// 测试失败次数 + /// + private int TestFailedCount; + + /// + /// 点击重置统计按钮 + /// + private void BtnResetStat_Click(object sender, EventArgs e) + { + TestCount = 0; + TestSuccessCount = 0; + TestFailedCount = 0; + UpdateStat(); + } + + /// + /// 更新统计 + /// + private void UpdateStat() + { + if (InvokeRequired) + Invoke(new Action(UpdateStat)); + else + { + LblTestCount.Text = TestCount.ToString(); + LblTestSuccessCount.Text = TestSuccessCount.ToString(); + LblTestFailedCount.Text = TestFailedCount.ToString(); + } + } + + /// + /// 统计开始测试 + /// + private void StatBeginTest() + { + TestCount += 1; + UpdateStat(); + } + + /// + /// 统计测试结束 + /// + /// 测试是否成功 + private void StatEndTest(bool isSuccess) + { + if (isSuccess) TestSuccessCount++; + else TestFailedCount++; + UpdateStat(); + } + + #endregion - 重置统计 - + } +} \ No newline at end of file diff --git a/SphygmomanometerTester/FormMain.resx b/SphygmomanometerTester/FormMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SphygmomanometerTester/FormMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/SphygmomanometerTester/Program.cs b/SphygmomanometerTester/Program.cs new file mode 100644 index 0000000..718a599 --- /dev/null +++ b/SphygmomanometerTester/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SphygmomanometerTester +{ + internal static class Program + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new FormMain()); + } + } +} diff --git a/SphygmomanometerTester/Properties/AssemblyInfo.cs b/SphygmomanometerTester/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a780f69 --- /dev/null +++ b/SphygmomanometerTester/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("SphygmomanometerTester")] +[assembly: AssemblyDescription("血压计测试工具")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SphygmomanometerTester")] +[assembly: AssemblyCopyright("Copyright © 2023 jie65535")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("8c5fddd2-5ec5-4ad7-ab24-f87665872a95")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SphygmomanometerTester/Properties/Resources.Designer.cs b/SphygmomanometerTester/Properties/Resources.Designer.cs new file mode 100644 index 0000000..28c48a4 --- /dev/null +++ b/SphygmomanometerTester/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 4.0.30319.42000 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + +namespace SphygmomanometerTester.Properties +{ + + + /// + /// 强类型资源类,用于查找本地化字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// 返回此类使用的缓存 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SphygmomanometerTester.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/SphygmomanometerTester/Properties/Resources.resx b/SphygmomanometerTester/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/SphygmomanometerTester/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SphygmomanometerTester/Properties/Settings.Designer.cs b/SphygmomanometerTester/Properties/Settings.Designer.cs new file mode 100644 index 0000000..bd5ff01 --- /dev/null +++ b/SphygmomanometerTester/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SphygmomanometerTester.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/SphygmomanometerTester/Properties/Settings.settings b/SphygmomanometerTester/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/SphygmomanometerTester/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/MaiBoBo.cs b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/MaiBoBo.cs new file mode 100644 index 0000000..7232480 --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/MaiBoBo.cs @@ -0,0 +1,437 @@ +using System; +using System.IO; +using System.IO.Ports; +using System.Threading; +using System.Threading.Tasks; + +namespace SphygmomanometerTester.Sphygmomanometer.MaiBoBo +{ + public class MaiBoBo : Sphygmomanometer + { + public MaiBoBo() + { + // 串口波特率为115200 + // 串口的其它参数保持默认即可 + SerialPort.BaudRate = 115200; + + SerialPort.DataReceived += SerialPort_DataReceived; + } + + /// + /// 通讯尝试超时时间(毫秒) + /// + private const int TryTimeoutMs = 200; + + /// + /// 最大重试次数 + /// + private const int RetryMax = 5; + + public Task Connect() => RequestAsync(PackageConnect, BloodPressureSubCode.Connect); + + public override Task StartMeasure() => RequestAsync(PackageStart, BloodPressureSubCode.Start); + + public override Task StopMeasure() => RequestAsync(PackageStop, BloodPressureSubCode.Stop); + + public override event EventHandler MeasureOver; + + /// + /// 测量中报告 + /// + public class MeasurePoll : EventArgs + { + /// + /// 当前压力值 + /// + public int Pressure; + + public MeasurePoll(int pressure) + { + Pressure = pressure; + } + } + + /// + /// 测量中压力上报 + /// + public event EventHandler MeasuringPoll; + + #region - 通讯协议 - + + /// + /// 协议包 + /// + /// 类型标识 + /// 类型子码 + /// 数据内容 + /// 包字节数组 + private static byte[] GetPackage(byte type, byte sub, byte data = 0) + { + var package = new byte[] + { + 0xCC, 0x80, // 前导码 + 0x03, // 设备版本 + 0x03, // 数据长度 + type, // 类型标识 + sub, // 类型子码 + data, // 数据内容 + 0x00 // 校验码(包头和校验除外的字节异或) + }; + + byte xorsum = 0; + for (var i = 2; i < package.Length - 1; i++) + xorsum ^= package[i]; + + package[package.Length - 1] = xorsum; + + return package; + } + + /// + /// 连接指令 + /// + private static readonly byte[] PackageConnect = GetPackage((byte)TypeCode.BloodPressure, (byte)BloodPressureSubCode.Connect); + + /// + /// 启动指令 + /// + private static readonly byte[] PackageStart = GetPackage((byte)TypeCode.BloodPressure, (byte)BloodPressureSubCode.Start); + + /// + /// 停止指令 + /// + private static readonly byte[] PackageStop = GetPackage((byte)TypeCode.BloodPressure, (byte)BloodPressureSubCode.Stop); + + /// + /// 请求信号量,控制请求并发数 + /// + private readonly SemaphoreSlim requestSemaphore = new SemaphoreSlim(1, 1); + + /// + /// 请求信号量集 + /// + private readonly SemaphoreSlim[] RequestMap = new SemaphoreSlim[4]; + + /// + /// 发送并等待响应,错误会以异常的方式抛出,需要捕获并处理异常! + /// + /// 通讯包 + /// 请求代码 + /// 串口未打开时抛出 + /// 若等待响应超时时抛出 + private async Task RequestAsync(byte[] package, BloodPressureSubCode code) + { + if (!IsOpen) + throw new IOException("通讯端口未连接,无法发送数据"); + + try + { + // 同时只能存在一个请求 + await requestSemaphore.WaitAsync(); + + var semaphore = new SemaphoreSlim(0); + RequestMap[(int)code] = semaphore; + + // 重试RetryMax次 + for (var tryCount = 1; tryCount <= RetryMax; tryCount++) + { + try + { + Write(package, 0, package.Length); + if (await semaphore.WaitAsync(TryTimeoutMs)) + { + // 正常响应,直接返回 + return; + } + else + { + // 超时,重试 + Console.WriteLine($"等待回复超时,正在重试第{tryCount}次"); + } + } + catch (TimeoutException) { } // 忽略超时异常 + catch (Exception ex) + { + // 发生异常时忽略,重试RetryMax次 + Console.WriteLine("等待响应时发生预期外的异常!" + ex); + } + } + + Console.WriteLine("等待响应超时"); + // 未收到回复,抛出超时异常,报告等待响应超时 + throw new TimeoutException("等待响应超时"); + } + finally + { + RequestMap[(int)code] = null; + requestSemaphore.Release(); + } + } + + /// + /// 包最小字节数,用以判断包是否完整 + /// + private const int PackageMinSize = 5; + + /// + /// 串口收到数据时触发 + /// + /// + /// + private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + var n = SerialPort.BytesToRead; + Thread.Sleep(15); + + // 等待接收剩余的数据 + while (n < SerialPort.BytesToRead) + { + n = SerialPort.BytesToRead; + Thread.Sleep(15); + } + + // 读取到缓冲区 + var buf = new byte[n]; + // buf 为本次收到的报文消息 + Read(buf, 0, n); + + Console.WriteLine("接收到数据:" + BitConverter.ToString(buf).Replace('-', ' ').ToUpper()); + + // 包头索引 + var i = 0; + + // 寻找包开始 + findPackage: + + // 找到包头 + while (i < n && (buf[i] != 0xAA || buf[i + 1] != 0x80)) + i++; + if (n - i >= PackageMinSize) // 是否至少包含一个包 + { + // 数据长度 + var dataLength = buf[i + 3]; + // 包长 = 数据长度 + 包头包尾长度 + var packageLength = dataLength + PackageMinSize; + + if (i == 0 && packageLength == n) + { + if (CheckPackage(buf)) + { + // 校验包完整后解析包内容 + OnReceivedPackage(buf); + } + else + { + // 包校验失败 + Console.WriteLine("数据包校验失败!"); + i++; // 尝试寻找下一包 + goto findPackage; + } + } + else + { + if (CheckPackage(buf, i, packageLength)) + { + // 校验包完整后解析包内容 + var package = new byte[packageLength]; + Array.Copy(buf, i, package, 0, packageLength); + OnReceivedPackage(package); + } + else + { + // 包校验失败 + Console.WriteLine("数据包校验失败!"); + i++; // 尝试寻找下一包 + goto findPackage; + } + } + } + else + { + // 未找到包头或者包不完整 + Console.WriteLine("不是有效的数据包!"); + } + } + + /// + /// 校验包是否正常 + /// + /// 数据包 + /// 是否正常 + private static bool CheckPackage(byte[] package) + => CheckPackage(package, 0, package.Length); + + /// + /// 校验包是否正常 + /// + /// 数据包 + /// 偏移 + /// 字节数 + /// 是否正常 + private static bool CheckPackage(byte[] package, int offset, int count) + { + var xorsum = 0; + for (var i = offset + 2; i < count - 1; i++) + xorsum ^= package[i]; + return xorsum == package[package.Length - 1]; + } + + /// + /// 接收到完整包时触发 + /// + /// 包内容 + private void OnReceivedPackage(byte[] package) + { + var index = 4; + var type = (TypeCode)package[index++]; + var subType = package[index++]; + + if (type != TypeCode.BloodPressure) + return; // 类型不是血压相关,忽略 + + // 根据子码做对应的处理 + switch ((BloodPressureSubCode)subType) + { + case BloodPressureSubCode.Connect: // 应答连接 + case BloodPressureSubCode.Start: // 应答启动 + case BloodPressureSubCode.Stop: // 应答停止 + RequestMap[subType]?.Release(); // 释放信号量 + break; + + case BloodPressureSubCode.Poll: // 实时压力 + var pressure = (package[index++] << 8) | package[index]; + Console.WriteLine($"实时压力值:{pressure}"); + OnMeasuringPoll(pressure); + break; + + case BloodPressureSubCode.Result: // 测量结果 + var userId = package[index++].ToString(); + var measureTime = DateTime.Now; + try + { + measureTime = + // 测量时间 年-2000,月,日,时,分,秒 + new DateTime(package[index++] + 2000, package[index++], package[index++], + package[index++], package[index++], package[index++]); + } + catch + { + // ignored + } + + // 转换测量结果 + var result = new MeasureResult( + // 用户标识 + userId, + // 测量时间 + measureTime, + // 收缩压 + (package[index++] << 8) | package[index++], + // 舒张压 + (package[index++] << 8) | package[index++], + // 脉搏数 + (package[index++] << 8) | package[index]); + Console.WriteLine($"接收到测量结果:{result.MeasureTime}\t收缩压:{result.SystolicPressure}\t舒张压:{result.DiastolicPressure}\t脉搏数:{result.Pulse}"); + OnMeasureOver(result); + break; + + case BloodPressureSubCode.Error: // 发生错误 + var message = "未知错误"; + switch (package[index]) // 错误代码 + { + case 1: + message = "臂筒内上游气囊压力超过安全压力"; + break; + + case 2: + message = "测量中手臂放置不正确或臂筒内上游气囊漏气"; + break; + + case 5: + message = "测量中手臂放置不正确或臂筒内下游气囊漏气"; + break; + + case 6: + message = "手臂放置方式不正确或脉搏传感器无信号"; + break; + + case 9: + message = "臂筒内气囊放气时间过长"; + break; + } + + Console.WriteLine("接收到测量报错信息:" + message); + OnMeasureOver(new MeasureResult(message)); + break; + + default: + // 未知的报文 + Console.WriteLine("未知的上报数据"); + break; + } + } + + /// + /// 测量结束时调用 + /// + /// 测量结果 + private void OnMeasureOver(MeasureResult result) + => MeasureOver?.Invoke(this, result); + + /// + /// 测量过程中上报压力时调用 + /// + /// 压力值 + private void OnMeasuringPoll(int pressure) + => MeasuringPoll?.Invoke(this, new MeasurePoll(pressure)); + + /// + /// 类型代码 + /// + private enum TypeCode : byte + { + /// + /// 血压相关 + /// + BloodPressure = 0x01, + } + + /// + /// 血压测量子码 + /// + private enum BloodPressureSubCode : byte + { + /// + /// 连接 + /// + Connect = 0x01, + + /// + /// 开始 + /// + Start = 0x02, + + /// + /// 停止 + /// + Stop = 0x03, + + /// + /// 测量过程上报 + /// + Poll = 0x05, + + /// + /// 测量结果 + /// + Result = 0x06, + + /// + /// 发生错误 + /// + Error = 0x07, + } + + #endregion - 通讯协议 - + } +} \ No newline at end of file diff --git a/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9000c.cs b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9000c.cs new file mode 100644 index 0000000..d60abc7 --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9000c.cs @@ -0,0 +1,6 @@ +namespace SphygmomanometerTester.Sphygmomanometer.MaiBoBo +{ + public class RBP_9000c : MaiBoBo + { + } +} diff --git a/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9001.cs b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9001.cs new file mode 100644 index 0000000..f49c9cb --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/MaiBoBo/RBP-9001.cs @@ -0,0 +1,6 @@ +namespace SphygmomanometerTester.Sphygmomanometer.MaiBoBo +{ + public class RBP_9001 : MaiBoBo + { + } +} diff --git a/SphygmomanometerTester/Sphygmomanometer/OMRON/Omron.cs b/SphygmomanometerTester/Sphygmomanometer/OMRON/Omron.cs new file mode 100644 index 0000000..0833a2f --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/OMRON/Omron.cs @@ -0,0 +1,177 @@ +using System; +using System.IO.Ports; +using System.Text; +using System.Threading.Tasks; + +namespace SphygmomanometerTester.Sphygmomanometer.OMRON +{ + public class Omron : Sphygmomanometer + { + public Omron() + { + SerialPort.BaudRate = 2400; + SerialPort.Parity = Parity.Even; + SerialPort.DataBits = 7; + SerialPort.StopBits = StopBits.One; + + SerialPort.DataReceived += SerialPort_DataReceived; + } + + public override Task StartMeasure() + { + Write(PackageStart, 0, PackageStart.Length); + return Task.CompletedTask; + } + + public Task RestartMeasure() + { + Write(PackageRestart, 0, PackageRestart.Length); + return Task.CompletedTask; + } + + public override Task StopMeasure() + { + Write(PackageStop, 0, PackageStop.Length); + return Task.CompletedTask; + } + + public override event EventHandler MeasureOver; + + #region 通讯协议 + + /// + /// 包起始标识 + /// + private const byte StartTx = 0x02; + + /// + /// 包结束标识 + /// + private const byte EndTx = 0x03; + + /// + /// 生成通讯报文 + /// + /// 数据内容 + /// 通讯包 + private static byte[] GetPackage(byte payload) => new[] { StartTx, payload, EndTx }; + + /// + /// 开始报文 + /// + private static readonly byte[] PackageStart = GetPackage((byte)'S'); + + /// + /// 结束报文 + /// + private static readonly byte[] PackageStop = GetPackage((byte)'R'); + + /// + /// 重新开始报文 + /// + private static readonly byte[] PackageRestart = GetPackage((byte)'B'); + + /// + /// 接受通讯缓冲区 + /// + private readonly byte[] buffer = new byte[384]; + + /// + /// 接收索引 + /// + private int index; + + /// + /// 最后收到数据的时间 + /// + private DateTime lastReceivedTime = DateTime.MinValue; + + /// + /// 串口收到数据时触发 + /// + private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + var now = DateTime.Now; + // 如果距离上次收到数据超过了300ms,清空输入缓冲区 + if ((now - lastReceivedTime).TotalMilliseconds > 300) + index = 0; + // 更新最后收到数据的时间 + lastReceivedTime = now; + + // 接收数据 + index += Read(buffer, index, buffer.Length - index); + + // 从收到的数据中找到合法的包 + var start = -1; + for (var i = 0; i < index; i++) + { + if (start == -1) + { + // 找到包头 + if (buffer[i] == StartTx) + { + start = i; + } + } + else + { + // 找到包尾 + if (buffer[i] == EndTx) + { + // 处理收到的数据 + var len = i - (start + 1); + var data = new byte[len]; + Array.Copy(buffer, start + 1, data, 0, len); + index = 0; + OnDataReceived(data); + } + } + } + } + + /// + /// 当测量完成时触发 + /// + /// 测量结果报文数据 + private void OnDataReceived(byte[] data) + { + // 返回的结果是一个ASCII字符串 + var msg = Encoding.ASCII.GetString(data); + // 按照通讯协议,收到的是38个字节,开头是固定的ID9999999 + if (msg.Length != 38 || !msg.StartsWith("ID99999999")) + return; + + var year = msg.Substring(11, 2); + var month = msg.Substring(14, 2); + var day = msg.Substring(17, 2); + var hour = msg.Substring(20, 2); + var minute = msg.Substring(23, 2); + if (!DateTime.TryParse($"20{year}/{month}/{day} {hour}:{minute}", out var time)) + time = DateTime.Now; + var message = ""; + if (!int.TryParse(msg.Substring(26, 3), out var systolicPressure) + | !int.TryParse(msg.Substring(31, 3), out var diastolicPressure) + | !int.TryParse(msg.Substring(35, 3), out var pulse)) + { + message = "没有数据,请调整姿势重新测量!"; + } + + var result = message != "" ? new MeasureResult(message) : new MeasureResult( + "99999999", + time, + systolicPressure, + diastolicPressure, + pulse); + OnMeasureOver(result); + } + + /// + /// 测量结束时调用 + /// + /// 测量结果 + private void OnMeasureOver(MeasureResult result) + => MeasureOver?.Invoke(this, result); + + #endregion 通讯协议 + } +} \ No newline at end of file diff --git a/SphygmomanometerTester/Sphygmomanometer/SerialControl.cs b/SphygmomanometerTester/Sphygmomanometer/SerialControl.cs new file mode 100644 index 0000000..75c2f90 --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/SerialControl.cs @@ -0,0 +1,82 @@ +using System; +using System.IO.Ports; +using System.Text; + +namespace SphygmomanometerTester.Sphygmomanometer +{ + public abstract class SerialControl + { + /// + /// 串口对象 + /// + protected readonly SerialPort SerialPort = new SerialPort(); + + public bool IsOpen => SerialPort.IsOpen; + + /// + /// 打开串口 + /// + /// 端口号 + /// + public void OpenCom(string portName) + { + if (SerialPort.IsOpen) return; + FormMain.Instance.Log("打开串口 " + portName); + SerialPort.PortName = portName; + SerialPort.Open(); + } + + /// + /// 关闭端口 + /// + public void CloseCom() + { + if (!SerialPort.IsOpen) return; + FormMain.Instance.Log("关闭串口"); + SerialPort.Close(); + } + + /// + /// 字节到Hex字符串 + /// + /// 缓冲区 + /// 偏移量 + /// 字节数 + /// Hex字符串 + public static string BytesToHex(byte[] buffer, int offset, int count) + { + var result = string.Empty; + for (var i = 0; i < count; i++) + result += Convert.ToString(buffer[i + offset], 16) + .ToUpper() + .PadLeft(2, '0') + " "; + return result; + } + + /// + /// 写入数据到串口 + /// + /// 缓冲区 + /// 偏移量 + /// 字节数 + public void Write(byte[] buffer, int offset, int count) + { + FormMain.Instance.Log("发送出:" + BytesToHex(buffer, offset, count) + " | " + Encoding.UTF8.GetString(buffer, offset, count)); + SerialPort.Write(buffer, offset, count); + } + + /// + /// 从串口读取数据 + /// + /// 缓冲区 + /// 偏移量 + /// 字节数 + /// 读取到的字节数 + public int Read(byte[] buffer, int offset, int count) + { + var n = SerialPort.Read(buffer, offset, count); + FormMain.Instance.Log("接收到:" + BytesToHex(buffer, offset, n) + " | " + Encoding.UTF8.GetString(buffer, offset, n)); + return n; + } + } +} \ No newline at end of file diff --git a/SphygmomanometerTester/Sphygmomanometer/Sphygmomanometer.cs b/SphygmomanometerTester/Sphygmomanometer/Sphygmomanometer.cs new file mode 100644 index 0000000..41e6fc1 --- /dev/null +++ b/SphygmomanometerTester/Sphygmomanometer/Sphygmomanometer.cs @@ -0,0 +1,74 @@ +using System; +using System.Threading.Tasks; + +namespace SphygmomanometerTester.Sphygmomanometer +{ + public abstract class Sphygmomanometer : SerialControl + { + /// + /// 开始测量 + /// + public abstract Task StartMeasure(); + + /// + /// 提前结束测量 + /// + public abstract Task StopMeasure(); + + /// + /// 测量结束事件 + /// + public abstract event EventHandler MeasureOver; + } + + /// + /// 测量结果 + /// + public class MeasureResult : EventArgs + { + /// + /// 用户标识 + /// + public string UserId; + + /// + /// 测量时间 + /// + public DateTime MeasureTime; + + /// + /// 收缩压 + /// + public int SystolicPressure; + + /// + /// 舒张压 + /// + public int DiastolicPressure; + + /// + /// 脉搏 + /// + public int Pulse; + + /// + /// 消息,如果存在异常时设置,正常情况下为空 + /// + public string Message; + + public MeasureResult(string message) + { + UserId = string.Empty; + Message = message; + } + + public MeasureResult(string userId, DateTime measureTime, int systolicPressure, int diastolicPressure, int pulse) + { + UserId = userId; + MeasureTime = measureTime; + SystolicPressure = systolicPressure; + DiastolicPressure = diastolicPressure; + Pulse = pulse; + } + } +} \ No newline at end of file diff --git a/SphygmomanometerTester/SphygmomanometerTester.csproj b/SphygmomanometerTester/SphygmomanometerTester.csproj new file mode 100644 index 0000000..515ba84 --- /dev/null +++ b/SphygmomanometerTester/SphygmomanometerTester.csproj @@ -0,0 +1,89 @@ + + + + + Debug + AnyCPU + {8C5FDDD2-5EC5-4AD7-AB24-F87665872A95} + WinExe + SphygmomanometerTester + SphygmomanometerTester + v4.8 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Form + + + FormMain.cs + + + + + + + + + + + FormMain.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file diff --git a/SphygmomanometerTester/SphygmomanometerTester.csproj.DotSettings b/SphygmomanometerTester/SphygmomanometerTester.csproj.DotSettings new file mode 100644 index 0000000..6e7fff8 --- /dev/null +++ b/SphygmomanometerTester/SphygmomanometerTester.csproj.DotSettings @@ -0,0 +1,2 @@ + + No \ No newline at end of file