292 lines
10 KiB
VB.net

Imports System.Windows.Forms
Public Class weightForm
Private weightSum As Integer
Private switchMotion As Boolean = False
'Private weightErrorPlus As Integer
'Private weightErrorMinus As Integer
Private weightMode As Boolean
Private weightStart As Boolean
Private Delegate Sub serialDelegate()
Private updateDelegate As serialDelegate
Private weightResult As Integer
Private zeroSet As Boolean = True
Private weight(2)
Dim weights As New List(Of Double)() ' 실측 측정값 저장용
Dim avg As Double = 0.0 ' 평균
Dim stdDev As Double = 0.0 ' 표준편차
Dim k As Double = 2.0 ' 오차 계수
Dim errorRate As Double = 0.0 ' 허용 오차 비율
Dim weightErrorPlus As Double = 0.0 ' 허용 오차 상한
Dim weightErrorMinus As Double = 0.0 ' 허용 오차 하한
Private Sub weightForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ZeroTimer.Enabled = True
lbNowWeight.Text = Nothing
lbWeightEX.Text = Nothing
weightSum = mainForm.weightSum
lbNowWeight.Refresh()
lbWeightEX.Refresh()
'weightErrorPlus = Val(mainForm.txbWeightPlus.Text)
'weightErrorMinus = Val(mainForm.txbWeightMinus.Text)
'lbError.Text = "(오차: +" & weightErrorPlus & ", -" & weightErrorMinus & ")"
lbError.Text = "(자동 오차 계산 중...)"
weightResult = 0
zeroSet = True
weightMode = mainForm.rdbWeightAuto.Checked
weightStart = mainForm.weightStart
End Sub
Private Sub playTimer_Tick(sender As Object, e As EventArgs) Handles playTimer.Tick
Dim scaleData As String
If mainForm.rdbWeightAuto.Checked = True Then
If weightResult > 0 Then
statusTimer.Enabled = False
playTimer.Enabled = False
lbNowWeight.Text = weightResult
If weight_compare() Then
lbWeight.BackColor = Color.Green
lbWeight.Text = "무게 일치"
delay(2000)
mainForm.weightResult = lbNowWeight.Text
mainForm.weightOkNg = True
Me.DialogResult = DialogResult.OK
Else
lbWeight.BackColor = Color.Red
lbWeight.Text = "무게 불일치"
delay(2000)
mainForm.weightOkNg = False
Me.DialogResult = DialogResult.No
End If
End If
Else
scaleData = Mid(MeasureScale(200), 2, weight.Length)
If scaleData > 5 Then
statusTimer.Enabled = False
lbWeight.BackColor = Color.Yellow
lbWeight.Text = "측정중"
playTimer.Enabled = False
If AutoMeasureScale() Then
lbNowWeight.Text = Val(weight(1))
If weight_compare() Then
lbWeight.BackColor = Color.Green
lbWeight.Text = "무게 일치"
delay(2000)
mainForm.weightResult = lbNowWeight.Text
mainForm.txbCheckWeight.Text = lbNowWeight.Text
mainForm.weightOkNg = True
Me.DialogResult = DialogResult.OK
Else
zeroSet = False
lbWeight.BackColor = Color.Red
lbWeight.Text = "무게 불일치"
ZeroTimer.Enabled = True
End If
Else
lbWeight.Text = "무게 측정 불안정"
lbWeight.BackColor = Color.Red
End If
End If
End If
End Sub
Private Sub Status_timer_Tick(sender As Object, e As EventArgs) Handles statusTimer.Tick
If switchMotion = True Then
lbWeight.BackColor = Color.MediumSlateBlue
switchMotion = False
Else
lbWeight.BackColor = Color.Gold
switchMotion = True
End If
End Sub
Private Sub Zero_Timer_Tick(sender As Object, e As EventArgs) Handles ZeroTimer.Tick
Dim scaledata As String
Try
If mainForm.rdbWeightAuto.Checked = True Then
If zeroSet = True Then
statusTimer.Enabled = True
playTimer.Enabled = True
ZeroTimer.Enabled = False
lbWeightEX.Text = weightSum
lbWeight.Text = "저울에 올려주세요"
End If
Else
scaledata = Mid(MeasureScale(200), 2, weight.Length)
If scaledata = 0 Then
statusTimer.Enabled = True
playTimer.Enabled = True
ZeroTimer.Enabled = False
lbWeightEX.Text = weightSum
lbWeight.Text = "저울에 올려주세요"
Else
ZeroTimer.Enabled = False
lbWeight.Text = " 저울을 비워주세요"
lbWeight.BackColor = Color.Red
ZeroTimer.Enabled = True
End If
End If
Catch ex As Exception
ZeroTimer.Enabled = False
mainForm.errorGen(Err.Description & "Zero_Timer_Tick_Scale_Error")
End Try
End Sub
Private Sub UpdateErrorRange()
If weights.Count >= 2 Then
avg = weights.Average()
stdDev = Math.Sqrt(weights.Select(Function(x) (x - avg) ^ 2).Average())
errorRate = (k * stdDev) / avg
weightErrorPlus = weightSum * errorRate
weightErrorMinus = weightSum * errorRate
' 폼에 오차 범위 표시
lbError.Text = "(오차: +" & weightErrorPlus.ToString() & ", -" & weightErrorMinus.ToString() & ")"
End If
End Sub
'Private Function weight_compare() As Boolean
' If lbNowWeight.Text >= weightSum - weightErrorMinus And lbNowWeight.Text <= weightSum + weightErrorPlus Then
' Return True
' Else
' Return False
' End If
'End Function
Private Function weight_compare() As Boolean
Dim nowWeight As Double = Double.Parse(lbNowWeight.Text)
' 기준 무게 기반 허용 오차 범위 계산 완료된 상태에서 비교
Dim upperBound As Double = weightSum + weightErrorPlus
Dim lowerBound As Double = weightSum - weightErrorMinus
Return (nowWeight >= lowerBound) AndAlso (nowWeight <= upperBound)
End Function
Public Sub delay(ByVal milliSecond As Double)
Dim delayTime As Date = Now.AddSeconds(milliSecond / 1000)
Do Until Now > delayTime
Application.DoEvents()
Loop
End Sub
Private Function AutoMeasureScale() As Boolean
Try
Do
For i = 0 To 1
weight(i) = MeasureScale(200)
If Mid(weight(i), 1, 1) = "U" Then
Exit For
ElseIf Mid(weight(i), 1, 1) = "S" Then
weight(i) = Mid(weight(i), InStr(1, weight(i), "S") + 1, weight(i).Length)
If weight(i) = weight(1) Then
Exit Do
End If
End If
Next
Loop
weights.Add(Double.Parse(weight(0)))
weights.Add(Double.Parse(weight(1)))
UpdateErrorRange()
If weight(0) - weight(1) < 10 And weight(0) - weight(1) > -10 Then
Return True
Else
Return False
End If
Catch ex As Exception
MsgBox("자동 무게 측정 에러 : " & Err.Description)
Return False
End Try
End Function
Private Sub Weight_Count_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
ZeroTimer.Enabled = False
statusTimer.Enabled = False
playTimer.Enabled = False
End Sub
Private Sub cmdSerialPort_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles cmdSerialPort.DataReceived
Try
If weightMode = True Then
If weightStart = True Then
Dim RecBuffer() As Byte
Dim weightUse As Single = 0
Dim dataSet As String = ""
Dim n As Integer = cmdSerialPort.BytesToRead
RecBuffer = New Byte(n - 1) {}
cmdSerialPort.Read(RecBuffer, 0, n)
For cnt = 0 To RecBuffer.Length - 1
dataSet = dataSet & Chr(RecBuffer(cnt))
Next
Dim dataCount As Int32 = UBound(Split(dataSet, vbCr)) - 1
For i = 0 To dataCount
Dim weightData As Single = Mid(dataSet, 1, InStr(dataSet, vbCr) - 1)
If weightData > weightUse Then
weightUse = weightData
End If
If i <> dataCount Then
dataSet = Mid(dataSet, InStr(dataSet, vbCr) + 1, dataSet.Length)
End If
Next
weightResult = weightUse * 1000
If weightResult = 0 Then
zeroSet = True
Else
zeroSet = False
End If
cmdSerialPort.DiscardInBuffer()
cmdSerialPort.DiscardOutBuffer()
Else
cmdSerialPort.DiscardInBuffer()
cmdSerialPort.DiscardOutBuffer()
End If
End If
Catch ex As Exception
MsgBox("데이터를 읽어올 수 없습니다. 통신을 확인하여 주십시오.", vbExclamation)
End Try
End Sub
End Class