Control Chart Using .Net

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.   
    11.     Public Property USLData() As String  
    12.         Get  
    13.             Return lblUslData.Text  
    14.         End Get  
    15.         Set(value As String)  
    16.             lblUslData.Text = value  
    17.         End Set  
    18.     End Property  
    19.   
    20.     Public Property LSLData() As String  
    21.         Get  
    22.             Return lblLslData.Text  
    23.         End Get  
    24.         Set(value As String)  
    25.             lblLslData.Text = value  
    26.         End Set  
    27.     End Property  
    28.   
    29.   
    30.     Public Property NominalData() As String  
    31.         Get  
    32.             Return lblNominalData.Text  
    33.         End Get  
    34.         Set(value As String)  
    35.             lblNominalData.Text = value  
    36.         End Set  
    37.     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.    
    17.             sensordata = Convert.ToDouble(lblMasterData.Text.Trim())   
    18.             frmMasteringPictuerBox.Refresh()   
    19.             upperValue = System.Convert.ToDouble(lblUslData.Text)  
    20.             lovervalue = System.Convert.ToDouble(lblLslData.Text)  
    21.             If upperValue = lovervalue Then  
    22.                 lovervalue = lovervalue - 1  
    23.             End If  
    24.   
    25.             inputValue = System.Convert.ToDouble(lblMasterData.Text)  
    26.             'here we call the draw ractangle fucntion   
    27.             drawRectanles(barheight, barwidth, upperValue, lovervalue, loverInitialvalue, upperInititalvalue, xval, yval)  
    28.              
    29.         Catch ex As Exception  
    30.         End Try  
    31.     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 DoubleByVal barwidth As DoubleByVal uppervalue As DoubleByVal lovervalue As DoubleByVal loverinitialvalue As DoubleByVal upperinitialvalue As DoubleByVal xval As DoubleByVal 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.   
    48.                     frmMasteringlblmsg.Text = "NG -> UnderRange"  
    49.                 Else  
    50.                     backColors1 = Color.GreenYellow  
    51.                     backColors2 = Color.DarkGreen  
    52.                     Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 90, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    53.                     g.DrawString("OK -> Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)  
    54.                     lblMasterData.ForeColor = Color.GreenYellow  
    55.   
    56.                     frmMasteringlblmsg.Text = "OK -> Good"  
    57.                 End If  
    58.             ElseIf inputValue >= lovervalue And inputValue <= uppervalue Then  
    59.                 backColors1 = Color.GreenYellow  
    60.                 backColors2 = Color.DarkGreen  
    61.                 If upperLimitChk = False Then  
    62.                     backColors1 = Color.GreenYellow  
    63.                     backColors2 = Color.DarkGreen  
    64.                     lblMasterData.ForeColor = Color.GreenYellow  
    65.                 Else  
    66.                     backColors1 = Color.Red  
    67.                     backColors2 = Color.DarkRed  
    68.                     lblMasterData.ForeColor = Color.Red  
    69.                 End If  
    70.                 Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    71.                 g.DrawString("OK -> Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)  
    72.   
    73.                 frmMasteringlblmsg.Text = "OK -> Good"  
    74.                 'frmMasteringlblOrignalData.ForeColor = Color.GreenYellow  
    75.             ElseIf inputValue < lovervalue Then  
    76.                 backColors1 = Color.Red  
    77.                 backColors2 = Color.DarkRed  
    78.                 Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    79.                 g.DrawString("NG -> UnderRange", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)  
    80.                 lblMasterData.ForeColor = Color.Red  
    81.                 'frmMasteringlblOrignalData.ForeColor = Color.Red  
    82.   
    83.                 frmMasteringlblmsg.Text = "NG -> UnderRange"  
    84.             ElseIf inputValue > uppervalue Then  
    85.                 backColors1 = Color.Red  
    86.                 backColors2 = Color.DarkRed  
    87.                 Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    88.                 g.DrawString("NG -> UpperRange", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)  
    89.                 lblMasterData.ForeColor = Color.Red  
    90.                 'frmMasteringlblOrignalData.ForeColor = Color.Red  
    91.   
    92.                 frmMasteringlblmsg.Text = "NG -> UpperRange"  
    93.             Else  
    94.                 backColors1 = Color.Red  
    95.                 backColors2 = Color.DarkRed  
    96.                 Dim a5 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    97.                 g.DrawString("Not Good", f5, a5, System.Convert.ToInt32(xval) - 40, barheight + 24)  
    98.                 lblMasterData.ForeColor = Color.Red  
    99.   
    100.                 frmMasteringlblmsg.Text = "Not Good"  
    101.             End If  
    102.           
    103.             Dim apen As New Pen(Color.Black, 2)  
    104.             g.DrawRectangle(Pens.Black, System.Convert.ToInt32(xval) - 2, System.Convert.ToInt32(yval) - 2, System.Convert.ToInt32(barwidth) + 3, System.Convert.ToInt32(barheight) + 3)  
    105.   
    106.             g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, System.Convert.ToInt32(limitsline), System.Convert.ToInt32(xval), System.Convert.ToInt32(limitsline))  
    107.             g.DrawLine(apen, System.Convert.ToInt32(xval) - 15, System.Convert.ToInt32(lowerlimitline), System.Convert.ToInt32(xval), System.Convert.ToInt32(lowerlimitline))  
    108.             Dim a1 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), Color.Blue, Color.Orange, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    109.             Dim f As Font  
    110.             f = New Font("arial", 10, FontStyle.Bold, GraphicsUnit.Pixel)  
    111.             g.DrawString((String.Format("{0:N3}"CDbl(uppervalue.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, System.Convert.ToInt32(limitsline) + 1)  
    112.             g.DrawString((String.Format("{0:N3}"CDbl(lovervalue.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, System.Convert.ToInt32(lowerlimitline) + 1)  
    113.             g.DrawString((String.Format("{0:N3}"CDbl(upperrange.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, 9)  
    114.             g.DrawString((String.Format("{0:N3}"CDbl(underrange.ToString))), f, a1, System.Convert.ToInt32(xval) - 40, barheight + 10)  
    115.             Dim a As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(xval, barheight + 10, barwidth, finaldisplayvalue + 1), backColors1, backColors2, Drawing.Drawing2D.LinearGradientMode.Vertical)  
    116.             
    117.             Dim a2 As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, 100, 19), Color.Black, Color.Black, Drawing.Drawing2D.LinearGradientMode.Horizontal)  
    118.             Dim f2 As Font  
    119.             f2 = New Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel)  
    120.             If inputValue >= upperrange Then  
    121.                 g.FillRectangle(a, New RectangleF(xval, 10, barwidth, barheight))  
    122.                 g.DrawString((String.Format("{0:N3}"CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, yval - 8)  
    123.             ElseIf inputValue <= underrange Then  
    124.                 g.FillRectangle(a, New RectangleF(xval, barheight + 10, barwidth, 4))  
    125.                 g.DrawString((String.Format("{0:N3}"CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, barheight + 10)  
    126.             Else  
    127.                 g.FillRectangle(a, New RectangleF(xval, barheight - finaldisplayvalue + 10, barwidth, finaldisplayvalue))  
    128.                 g.DrawString((String.Format("{0:N3}"CDbl(inputValue.ToString))), f2, a2, System.Convert.ToInt32(xval) + 40, barheight - System.Convert.ToInt32(finaldisplayvalue))  
    129.             End If  
    130.             ' End If  
    131.             g.Dispose()  
    132.         Catch ex As Exception  
    133.         End Try  
    134.     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.   
    19. / Timer Tick Event to check for the different random sample Measurement test data.  
    20.   
    21. private void timer1_Tick(object sender, EventArgs e)  
    22. {  
    23.     Random rnd =new Random();  
    24.   
    25.     Double rndval = rnd.Next(1, 20);    
    26.     txtData.Text = rndval.ToString("0.000");//FormatNumber(rndval.ToString(), 3, , 0)    
    27.     shanuControlChart.USLData = txtusl.Text;  
    28.     shanuControlChart.LSLData = txtLSL.Text;  
    29.     shanuControlChart.NominalData = txtNominal.Text;  
    30.     shanuControlChart.MasterData = txtData.Text;  
    31. }  

Conclusion

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