Control Chart

Introduction

Nowadays the automobile industry is interested in automated measuring machines to ensure quality and to compete in the global industry. Control Charts take a major role in ensuring quality by measuring automobile components. The purpose of this article is to make a simple Control Bar Chart for measuring systems like Camshafts, Crankshafts and Master Settings and so on. A digital sensor is used for measuring a Camshaft and a Crankshaft. Then the measured data is analyzed using the Control Chart.

Control Chart (ref)

The Control Charts are graphs for checking the quality of a control of a process. In Control Charts UCL/LCL or USL/LSL will be used to check with the resultant data. If the measurement data is within the range of limits then the process is OK(GOOD). If the measurement data is above or below the limits then the process is NG (NOT GOOD).

  1. OK (GOOD) -> USL <= Measurement Data >= LSL
  2. NG (NOT GOOD) -> Upper Range -> Measurement Data > USL
  3. NG (NOT GOOD) -> Lower Range -> Measurement Data < LSL

    USL

In my simple Control Chart USL /LSL is used for verifying the data. USL is the Upper Specification Limit and LSL is the Lower Specification Limit. Note in this sample I have used USL/LSL.

Difference between USL/LSL and UCL/LCL

(The UCL or Upper Control Limit and LCL or Lower Control Limit are limits set by your process based on the actual amount of variation of your process. The USL or upper specification limit and LSL or lower specification limit are limits set by your customer's requirements. This is the variation that they will accept from your process. Ref)

I have been working on several automation projects. Instead of using third-party tools, I planned to create a simple program using .Net for creating a USL/LSL Control Bar chart for the master setting. The main purpose of this article is to share what I have developed to other members.

I have created a Control Chart as a User Control so that it can be used easily in all projects.

In this article I have attached a Zip file named SHANUControlChart_SRC.zip which contains:

  1. "SHANUControlChart_CNT" Folder (This folder contains the Control Chart User control Source code.)
  2. "SHANUControlChart_DEMO" Folder (This folder conains the Demo program that includes the Control Chart user control with Random Measurement sample using Timer control).

Using the code

1. First we will start with the User Control. To Create a user control:

  1. Create a new Windows Control Library project.
  2. Set the name of the project and click Ok (here my user control name is SHANUControlChart_CNT).
  3. Add all the controls that is needed.
  4. In the code behind declare all the public variables and Public property variables. Here USL/LSL/Nominal and Measurement Data Public property has been declared which will be used to pass the data from the Windows application.
    1. 'Public Property Declaration
    2. Public Property MasterData() As String
    3. Get
    4. Return lblMasterData.Text
    5. End Get
    6. Set(value As String)
    7. lblMasterData.Text = value
    8. End Set
    9. End Property
    10. Public Property USLData() As String
    11. Get
    12. Return lblUslData.Text
    13. End Get
    14. Set(value As String)
    15. lblUslData.Text = value
    16. End Set
    17. End Property
    18. Public Property LSLData() As String
    19. Get
    20. Return lblLslData.Text
    21. End Get
    22. Set(value As String)
    23. lblLslData.Text = value
    24. End Set
    25. End Property
    26. Public Property NominalData() As String
    27. Get
    28. Return lblNominalData.Text
    29. End Get
    30. Set(value As String)
    31. lblNominalData.Text = value
    32. End Set
    33. End Property
  5. In my User Control I used a Timer control to always check for the measurment data and produce the Bar Chart.in the user control load. I have enabled and started the timer. The timer Tick Event calls the function "LoadcontrolChart()". In this fucntion I set all the USL/LSL and measurement data and draw the Chart Control.
    1. Public Sub LoadcontrolChart()
    2. Try
    3. 'For Barand GageLoad
    4. upperLimitChk = False
    5. lowerLimitchk = False
    6. errLimtchk = False
    7. Dim pointVal As Integer
    8. Dim calcvalues As Double
    9. Dim calcvalues1 As Double
    10. ' Dim upperValue As Double
    11. Dim hasread As Integer
    12. Dim UpperRange As Double
    13. Dim err As String
    14. pointVal = 3
    15. Dim ival As Integer

    16. sensordata = Convert.ToDouble(lblMasterData.Text.Trim())
    17. frmMasteringPictuerBox.Refresh()
    18. upperValue = System.Convert.ToDouble(lblUslData.Text)
    19. lovervalue = System.Convert.ToDouble(lblLslData.Text)
    20. If upperValue = lovervalue Then
    21. lovervalue = lovervalue - 1
    22. End If
    23. inputValue = System.Convert.ToDouble(lblMasterData.Text)
    24. 'here we call the draw ractangle fucntion
    25. drawRectanles(barheight, barwidth, upperValue, lovervalue, loverInitialvalue, upperInititalvalue, xval, yval)

    26. Catch ex As Exception
    27. End Try
    28. End Sub
    In this method we check the measurement data with the USL and LSL limit values. If the measurement data is within the range of USL and LSL then the output will be Ok. I have used the if condition to check the values as below.
    1. ''This method is to draw the control chart
    2. 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)
    3. Try
    4. Dim limitsline As Double
    5. Dim lowerlimitline As Double
    6. Dim underrange As Double
    7. Dim upperrange As Double
    8. Dim differentpercentage As Double
    9. Dim totalheight As Double
    10. Dim inputvalueCal As Double
    11. Dim finaldisplayvalue As Double
    12. Dim backColors1 As Color
    13. Dim backColors2 As Color
    14. 'this is for the range persentage Calculation
    15. differentpercentage = uppervalue - lovervalue
    16. differentpercentage = differentpercentage * 0.2
    17. 'Upper range value
    18. upperrange = uppervalue + differentpercentage
    19. 'Lover range value
    20. underrange = lovervalue - differentpercentage
    21. totalheight = upperrange - underrange
    22. 'For Upper Limit
    23. ''limitsline = barheight * 0.2 - 10
    24. limitsline = lovervalue - underrange
    25. limitsline = limitsline / totalheight
    26. limitsline = barheight * limitsline + 10
    27. 'For Lower Limit
    28. lowerlimitline = uppervalue - underrange
    29. lowerlimitline = lowerlimitline / totalheight
    30. lowerlimitline = barheight * lowerlimitline + 10
    31. 'lowerlimitline = barheight - limitsline + 10
    32. 'for finding the rangedata
    33. inputvalueCal = inputValue - underrange
    34. finaldisplayvalue = inputvalueCal / totalheight
    35. finaldisplayvalue = barheight * finaldisplayvalue
    36. Dim g As Graphics = frmMasteringPictuerBox.CreateGraphics
    37. Dim f5 As Font
    38. f5 = New Font("arial", 22, FontStyle.Bold, GraphicsUnit.Pixel)
    39. ''If condition to check for the result and display the chart accordingly depend on limit values.
    40. If inputValue = "0.000" Then
    41. If zeroDisplay = 0 Then
    42. backColors1 = Color.Red
    43. backColors2 = Color.DarkRed
    44. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 90, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    45. g.DrawString("NG -> UnderRange", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    46. lblMasterData.ForeColor = Color.Red
    47. frmMasteringlblmsg.Text = "NG -> UnderRange"
    48. Else
    49. backColors1 = Color.GreenYellow
    50. backColors2 = Color.DarkGreen
    51. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 90, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    52. g.DrawString("OK -> Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    53. lblMasterData.ForeColor = Color.GreenYellow
    54. frmMasteringlblmsg.Text = "OK -> Good"
    55. End If
    56. ElseIf inputValue >= lovervalue And inputValue <= uppervalue Then
    57. backColors1 = Color.GreenYellow
    58. backColors2 = Color.DarkGreen
    59. If upperLimitChk = False Then
    60. backColors1 = Color.GreenYellow
    61. backColors2 = Color.DarkGreen
    62. lblMasterData.ForeColor = Color.GreenYellow
    63. Else
    64. backColors1 = Color.Red
    65. backColors2 = Color.DarkRed
    66. lblMasterData.ForeColor = Color.Red
    67. End If
    68. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    69. g.DrawString("OK -> Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    70. frmMasteringlblmsg.Text = "OK -> Good"
    71. 'frmMasteringlblOrignalData.ForeColor = Color.GreenYellow
    72. ElseIf inputValue < lovervalue Then
    73. backColors1 = Color.Red
    74. backColors2 = Color.DarkRed
    75. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    76. g.DrawString("NG -> UnderRange", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    77. lblMasterData.ForeColor = Color.Red
    78. 'frmMasteringlblOrignalData.ForeColor = Color.Red
    79. frmMasteringlblmsg.Text = "NG -> UnderRange"
    80. ElseIf inputValue > uppervalue Then
    81. backColors1 = Color.Red
    82. backColors2 = Color.DarkRed
    83. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    84. g.DrawString("NG -> UpperRange", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    85. lblMasterData.ForeColor = Color.Red
    86. 'frmMasteringlblOrignalData.ForeColor = Color.Red
    87. frmMasteringlblmsg.Text = "NG -> UpperRange"
    88. Else
    89. backColors1 = Color.Red
    90. backColors2 = Color.DarkRed
    91. Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    92. g.DrawString("Not Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)
    93. lblMasterData.ForeColor = Color.Red
    94. frmMasteringlblmsg.Text = "Not Good"
    95. End If
    96. Dim apen As New Pen(Color.Black, 2)
    97. g.DrawRectangle(Pens.Black, System.Convert.ToInt32(xval) - 2, System.Convert.ToInt32(yval) - 2, System.Convert.ToInt32(barwidth) + 3, System.Convert.ToInt32(barheight) + 3)
    98. g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, System.Convert.ToInt32(limitsline), System.Convert.ToInt32(xval), System.Convert.ToInt32(limitsline))
    99. g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, System.Convert.ToInt32(lowerlimitline), System.Convert.ToInt32(xval), System.Convert.ToInt32(lowerlimitline))
    100. Dim a1 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), Color.Blue, Color.Orange, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    101. Dim f As Font
    102. f = New Font("arial", 10, FontStyle.Bold, GraphicsUnit.Pixel)
    103. g.DrawString((String.Format("{0:N3}", CDbl(uppervalue.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, System.Convert.ToInt32(limitsline) + 1)
    104. g.DrawString((String.Format("{0:N3}", CDbl(lovervalue.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, System.Convert.ToInt32(lowerlimitline) + 1)
    105. g.DrawString((String.Format("{0:N3}", CDbl(upperrange.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, 9)
    106. g.DrawString((String.Format("{0:N3}", CDbl(underrange.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, barheight + 10)
    107. Dim a As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(xval, barheight + 10, barwidth, finaldisplayvalue + 1), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Vertical)
    108. Dim a2 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), Color.Black, Color.Black, Drawing.Drawing2D.LinearGradientMode.Horizontal)
    109. Dim f2 As Font
    110. f2 = New Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel)
    111. If inputValue >= upperrange Then
    112. g.FillRectangle(a, New RectangleF(xval, 10, barwidth, barheight))
    113. g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, yval - 8)
    114. ElseIf inputValue <= underrange Then
    115. g.FillRectangle(a, New RectangleF(xval, barheight + 10, barwidth, 4))
    116. g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, barheight + 10)
    117. Else
    118. g.FillRectangle(a, New RectangleF(xval, barheight - finaldisplayvalue + 10, barwidth, finaldisplayvalue))
    119. g.DrawString((String.Format("{0:N3}", CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, barheight - System.Convert.ToInt32(finaldisplayvalue))
    120. End If
    121. ' End If
    122. g.Dispose()
    123. Catch ex As Exception
    124. End Try
    125. End Sub
  6. After completion, save, build and run the project.

2. Now we create a Windows application and add and test our "SHANUControlChart_CNT" User Control.

  1. Create a new Windows project.
  2. Open your form and then from the Toolbox right-click then choose items > browse then select your User Control DLL and add it.
  3. Drag the User Control to your Windows form.
  4. Place all the USL/LSL and Measurement TextBox for input from the user. In the Manual check button click pass all the data to the User Control using the public property as below.
    1. private void btnDisplay_Click(object sender, EventArgs e)
    2. {
    3. shanuControlChart.USLData = txtusl.Text;
    4. shanuControlChart.LSLData = txtLSL.Text;
    5. shanuControlChart.NominalData = txtNominal.Text;
    6. shanuControlChart.MasterData = txtData.Text;
    7. }
  5. In my demo program I have used the timer for the randomly sampled measurement data result checking. I have used the "btnRealTime" as a toggle button. When the first time Enabled is clicked and start the timer and when the same button is clicked again the timer is stopped. When the timer is started I generated a random number and pass the various data to the User Control and check for the chart result.
    1. private void btnRealTime_Click(object sender, EventArgs e)
    2. {
    3. if (btnRealTime.Text == "Real Time Data ON")
    4. {
    5. btnRealTime.Text = "Real Time Data OFF";
    6. btnRealTime.ForeColor = Color.Red;
    7. timer1.Enabled = true;
    8. timer1.Start();
    9. }
    10. else
    11. {
    12. btnRealTime.Text = "Real Time Data ON";
    13. btnRealTime.ForeColor = Color.DarkGreen;
    14. timer1.Enabled = false;
    15. timer1.Stop();
    16. }
    17. }
    18. / Timer Tick Event to check for the different random sample Measurement test data.
    19. private void timer1_Tick(object sender, EventArgs e)
    20. {
    21. Random rnd =new Random();
    22. Double rndval = rnd.Next(1, 20);
    23. txtData.Text = rndval.ToString("0.000");//FormatNumber(rndval.ToString(), 3, , 0)
    24. shanuControlChart.USLData = txtusl.Text;
    25. shanuControlChart.LSLData = txtLSL.Text;
    26. shanuControlChart.NominalData = txtNominal.Text;
    27. shanuControlChart.MasterData = txtData.Text;
    28. }

Conclusion

The main purpose of this article is to create a simple and standard Control Bar Chart User Control for the automobile industry.