使用 .NET 创建控制图






4.66/5 (20投票s)
使用 .NET 实现 USL/LSL 控制图进行质量控制
引言
如今,汽车行业对自动化测量设备非常感兴趣,以确保质量并在全球行业中竞争。控制图在通过测量汽车组件来确保质量方面发挥着重要作用。目的是为凸轮轴、曲轴和主设置等测量系统制作一个简单的控制条形图。数字传感器用于测量凸轮轴和曲轴。然后使用控制图分析测量数据。
控制图(参考)
控制图是用于检查过程质量的图形。在控制图中,将使用 UCL/LCL 或 USL/LSL 来与结果数据进行检查。如果测量数据在限值范围内,则过程为 OK(好)
。如果测量数据高于或低于限值,则过程为 NG(不好)
。
- OK (好) -> USL <= 测量数据 >= LSL
- NG (不好) -> 上限范围 -> 测量数据 > USL
- NG (不好) -> 下限范围 -> 测量数据 < LSL
在我简单的控制图中,**USL /LSL** 用于验证 data.USL
-> 上规格限和 LSL -> 下规格限。请注意,在此示例中,我使用了 USL/LSL。
USL/LSL 与 UCL/LCL 之间的区别。
(UCL 或上控制限和 LCL 或下控制限是由您的过程根据其实际变化量设定的限值。)
USL 或上规格限和 LSL 或下规格限是由客户要求设定的限值。这是他们将从您的流程中接受的变化。 (参考)
我一直在从事多个自动化项目。我计划使用 .NET 创建一个简单的程序来实现 USL/LSL 控制条形图用于主设置,而不是使用第三方工具。本文的主要目的是与大家分享我的开发成果。
我创建了一个作为用户控件的控制图,以便可以在所有项目中轻松使用。
在本文中,我附带了一个名为 SHANUControlChart_SRC.zip 的 zip 文件,其中包含
- "SHANUControlChart_CNT" 文件夹(该文件夹包含控制图用户控件的源代码。)
- "SHANUControlChart_DEMO" 文件夹(该文件夹包含演示程序,其中包括带有 Timer 控件的随机测量样本的控制图用户控件。)
Using the Code
- 首先,我们将从用户控件开始。要创建用户控件,
- 创建一个新的 Windows 控件库项目。
- 设置项目名称并单击“确定”(此处,我的用户控件名称为
SHANUControlChart_CNT
)。 - 添加所有需要的控件。
- 在代码隐藏中,声明所有
public
变量和Public
属性变量。此处声明了 USL/LSL/Nominal 和 Measurement DataPublic
属性,它们将用于从 Windows 应用程序传递数据。'Public Property Declaration Public Property MasterData() As String Get Return lblMasterData.Text End Get Set(value As String) lblMasterData.Text = value End Set End Property Public Property USLData() As String Get Return lblUslData.Text End Get Set(value As String) lblUslData.Text = value End Set End Property Public Property LSLData() As String Get Return lblLslData.Text End Get Set(value As String) lblLslData.Text = value End Set End Property Public Property NominalData() As String Get Return lblNominalData.Text End Get Set(value As String) lblNominalData.Text = value End Set End Property
- 在我的用户控件中,我使用了
Timer
控件来始终检查测量数据并生成条形图。在用户控件加载时,我启用了 Timer 并启动了它。在 Timer Tick 事件中,我调用了函数 "LoadcontrolChart()
"。在此函数中,我设置了所有 USL/LSL 和测量数据并绘制了图表控件。Public Sub LoadcontrolChart() Try 'For Bar and GageLoad upperLimitChk = False lowerLimitchk = False errLimtchk = False Dim pointVal As Integer Dim calcvalues As Double Dim calcvalues1 As Double ' Dim upperValue As Double Dim hasread As Integer Dim UpperRange As Double Dim err As String pointVal = 3 Dim ival As Integer sensordata = Convert.ToDouble(lblMasterData.Text.Trim()) frmMasteringPictuerBox.Refresh() upperValue = System.Convert.ToDouble(lblUslData.Text) lovervalue = System.Convert.ToDouble(lblLslData.Text) If upperValue = lovervalue Then lovervalue = lovervalue - 1 End If inputValue = System.Convert.ToDouble(lblMasterData.Text) 'here we call the draw rectangle function drawRectanles(barheight, barwidth, upperValue, lovervalue, loverInitialvalue, upperInititalvalue, xval, yval) Catch ex As Exception End Try End Sub
在此方法中,我们使用 USL 和 LSL 限值来检查测量数据。如果测量数据在 USL 和 LSL 的范围内,则结果输出为 OK。我使用了
if
条件来检查结果值,如下所示:''This method is to draw the control chart Public Sub drawRectanles(ByVal barheight As Double, ByVal barwidth As Double, _ ByVal uppervalue As Double, ByVal lovervalue As Double, _ ByVal loverinitialvalue As Double, ByVal upperinitialvalue As Double, _ ByVal xval As Double, ByVal yval As Double) Try Dim limitsline As Double Dim lowerlimitline As Double Dim underrange As Double Dim upperrange As Double Dim differentpercentage As Double Dim totalheight As Double Dim inputvalueCal As Double Dim finaldisplayvalue As Double Dim backColors1 As Color Dim backColors2 As Color 'this is for the range percentage Calculation differentpercentage = uppervalue - lovervalue differentpercentage = differentpercentage * 0.2 'Upper range value upperrange = uppervalue + differentpercentage 'Lover range value underrange = lovervalue - differentpercentage totalheight = upperrange - underrange 'For Upper Limit ''limitsline = barheight * 0.2 - 10 limitsline = lovervalue - underrange limitsline = limitsline / totalheight limitsline = barheight * limitsline + 10 'For Lower Limit lowerlimitline = uppervalue - underrange lowerlimitline = lowerlimitline / totalheight lowerlimitline = barheight * lowerlimitline + 10 'lowerlimitline = barheight - limitsline + 10 'for finding the rangedata inputvalueCal = inputValue - underrange finaldisplayvalue = inputvalueCal / totalheight finaldisplayvalue = barheight * finaldisplayvalue Dim g As Graphics = frmMasteringPictuerBox.CreateGraphics Dim f5 As Font f5 = New Font("arial", 22, FontStyle.Bold, GraphicsUnit.Pixel) ''If condition to check for the result and display ''the chart accordingly depend on limit values. If inputValue = "0.000" Then If zeroDisplay = 0 Then backColors1 = Color.Red backColors2 = Color.DarkRed Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 90, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("NG -> UnderRange", f5, a5, System.Convert.ToInt32(xval) - 40, _ barheight + 24) lblMasterData.ForeColor = Color.Red frmMasteringlblmsg.Text = "NG -> UnderRange" Else backColors1 = Color.GreenYellow backColors2 = Color.DarkGreen Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 90, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("OK -> Good", f5, a5, _ System.Convert.ToInt32(xval) - 40, barheight + 24) lblMasterData.ForeColor = Color.GreenYellow frmMasteringlblmsg.Text = "OK -> Good" End If ElseIf inputValue >= lovervalue And inputValue <= uppervalue Then backColors1 = Color.GreenYellow backColors2 = Color.DarkGreen If upperLimitChk = False Then backColors1 = Color.GreenYellow backColors2 = Color.DarkGreen lblMasterData.ForeColor = Color.GreenYellow Else backColors1 = Color.Red backColors2 = Color.DarkRed lblMasterData.ForeColor = Color.Red End If Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("OK -> Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24) frmMasteringlblmsg.Text = "OK -> Good" 'frmMasteringlblOrignalData.ForeColor = Color.GreenYellow ElseIf inputValue < lovervalue Then backColors1 = Color.Red backColors2 = Color.DarkRed Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("NG -> UnderRange", f5, a5, System.Convert.ToInt32(xval) - 40, _ barheight + 24) lblMasterData.ForeColor = Color.Red 'frmMasteringlblOrignalData.ForeColor = Color.Red frmMasteringlblmsg.Text = "NG -> UnderRange" ElseIf inputValue > uppervalue Then backColors1 = Color.Red backColors2 = Color.DarkRed Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("NG -> UpperRange", f5, a5, System.Convert.ToInt32(xval) - 40, _ barheight + 24) lblMasterData.ForeColor = Color.Red 'frmMasteringlblOrignalData.ForeColor = Color.Red frmMasteringlblmsg.Text = "NG -> UpperRange" Else backColors1 = Color.Red backColors2 = Color.DarkRed Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), backColors1, backColors2, _ Drawing.Drawing2D.LinearGradientMode.Horizontal) g.DrawString("Not Good", f5, a5, _ System.Convert.ToInt32(xval) - 40, barheight + 24) lblMasterData.ForeColor = Color.Red frmMasteringlblmsg.Text = "Not Good" End If Dim apen As New Pen(Color.Black, 2) g.DrawRectangle(Pens.Black, System.Convert.ToInt32(xval) - 2, _ System.Convert.ToInt32(yval) - 2, System.Convert.ToInt32(barwidth) + 3, _ System.Convert.ToInt32(barheight) + 3) g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, _ System.Convert.ToInt32(limitsline), _ System.Convert.ToInt32(xval), System.Convert.ToInt32(limitsline)) g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, _ System.Convert.ToInt32(lowerlimitline), _ System.Convert.ToInt32(xval), System.Convert.ToInt32(lowerlimitline)) Dim a1 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), _ Color.Blue, Color.Orange, Drawing.Drawing2D.LinearGradientMode.Horizontal) Dim f As Font f = New Font("arial", 10, FontStyle.Bold, GraphicsUnit.Pixel) g.DrawString((String.Format("{0:N3}", CDbl(uppervalue.ToString))), _ f, a1, System.Convert.ToInt32(xval) - 40, _ System.Convert.ToInt32(limitsline) + 1) g.DrawString((String.Format("{0:N3}", CDbl(lovervalue.ToString))), _ f, a1, System.Convert.ToInt32(xval) - 40, _ System.Convert.ToInt32(lowerlimitline) + 1) g.DrawString((String.Format("{0:N3}", CDbl(upperrange.ToString))), _ f, a1, System.Convert.ToInt32(xval) - 40, 9) g.DrawString((String.Format("{0:N3}", CDbl(underrange.ToString))), _ f, a1, System.Convert.ToInt32(xval) - 40, barheight + 10) Dim a As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF_ (xval, barheight + 10, barwidth, finaldisplayvalue + 1), backColors1, _ backColors2, Drawing.Drawing2D.LinearGradientMode.Vertical) Dim a2 As New System.Drawing.Drawing2D.LinearGradientBrush_ (New RectangleF(0, 0, 100, 19), _ Color.Black, Color.Black, Drawing.Drawing2D.LinearGradientMode.Horizontal) Dim f2 As Font f2 = New Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel) If inputValue >= upperrange Then g.FillRectangle(a, New RectangleF(xval, 10, barwidth, barheight)) g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), _ f2, a2, System.Convert.ToInt32(xval) + 40, yval - 8) ElseIf inputValue <= underrange Then g.FillRectangle(a, New RectangleF(xval, barheight + 10, barwidth, 4)) g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), _ f2, a2, System.Convert.ToInt32(xval) + 40, barheight + 10) Else g.FillRectangle(a, New RectangleF_ (xval, barheight - finaldisplayvalue + 10, barwidth, finaldisplayvalue)) g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), _ f2, a2, System.Convert.ToInt32(xval) + 40, _ barheight - System.Convert.ToInt32(finaldisplayvalue)) End If ' End If g.Dispose() Catch ex As Exception End Try End Sub
- 完成保存后,构建并运行项目。
- 现在我们创建一个 Windows 应用程序,并添加和测试我们的 "
SHANUControlChart_CNT
" 用户控件。- 创建一个新的 Windows 项目。
- 打开您的窗体,然后从工具箱 > 右键单击 > 选择项 > 浏览并选择您的用户控件 DLL 并添加。
- 将用户控件拖到您的 Windows 窗体上。
- 放置所有 USL/LSL 和测量文本框供用户输入。在手动检查按钮单击时,使用下面的
public
属性将所有数据传递给用户控件。private void btnDisplay_Click(object sender, EventArgs e) { shanuControlChart.USLData = txtusl.Text; shanuControlChart.LSLData = txtLSL.Text; shanuControlChart.NominalData = txtNominal.Text; shanuControlChart.MasterData = txtData.Text; }
- 在我的演示程序中,我使用了
Timer
来进行随机样本测量数据结果检查。我使用了 "btnRealTime
" 作为切换按钮。首次单击时,启用并启动 Timer;再次单击同一按钮时,停止 Timer。当 Timer 启动时,我生成了一个随机数,并将不同的数据传递给用户控件并检查图表结果。private void btnRealTime_Click(object sender, EventArgs e) { if (btnRealTime.Text == "Real Time Data ON") { btnRealTime.Text = "Real Time Data OFF"; btnRealTime.ForeColor = Color.Red; timer1.Enabled = true; timer1.Start(); } else { btnRealTime.Text = "Real Time Data ON"; btnRealTime.ForeColor = Color.DarkGreen; timer1.Enabled = false; timer1.Stop(); } } // Timer Tick Event to check for the different random sample Measurement test data. private void timer1_Tick(object sender, EventArgs e) { Random rnd =new Random(); Double rndval = rnd.Next(1, 20); txtData.Text = rndval.ToString("0.000");//FormatNumber(rndval.ToString(), 3, , 0) shanuControlChart.USLData = txtusl.Text; shanuControlChart.LSLData = txtLSL.Text; shanuControlChart.NominalData = txtNominal.Text; shanuControlChart.MasterData = txtData.Text; }
结论
本文的主要目的是为汽车行业创建一个简单标准的控制条形图用户控件。
历史
- 2014/07/14:初始发布