445 lines
16 KiB
VB.net
Raw Normal View History

Imports System.IO.Ports
Imports System.Windows.Forms
2025-05-12 09:13:11 +09:00
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 weightResult2 As Double = 0
2025-05-12 09:13:11 +09:00
Private zeroSet As Boolean = True
Private weightBuffer As New List(Of Double) ' 무게 버퍼
Private Const BUFFER_SIZE As Integer = 3 ' 버퍼 크기 (3개로 축소)
Private Const STABILITY_THRESHOLD As Double = 5.0 ' 안정성 임계값 (5g로 완화)
2025-05-12 09:13:11 +09:00
Private weight(2)
Private weight2(1) As String
2025-05-12 09:13:11 +09:00
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 & ")"
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
ElseIf mainForm.rdbWeightQW.Checked = True Then
If weightResult2 > 5 Then ' 5g 이상이면 측정 시작
' 실시간 무게 표시
lbNowWeight.Text = Math.Round(weightResult2, 0).ToString()
lbWeight.BackColor = Color.Yellow
lbWeight.Text = "측정중 (" & Math.Round(weightResult2, 0).ToString() & "g)"
' 무게 버퍼에 추가 (안정성 확인용)
AddToWeightBuffer(weightResult2)
' 버퍼가 충분히 쌓이면 안정성 검사
If weightBuffer.Count >= 3 AndAlso IsWeightStable() Then
statusTimer.Enabled = False
playTimer.Enabled = False
Dim stableWeight As Double = GetStableWeight()
lbNowWeight.Text = Math.Round(stableWeight, 0).ToString()
If weight_compare_improved(stableWeight) 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
End If
End If
2025-05-12 09:13:11 +09:00
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 AddToWeightBuffer(weight As Double)
weightBuffer.Add(weight)
' 버퍼 크기 초과 시 가장 오래된 값 제거
If weightBuffer.Count > BUFFER_SIZE Then
weightBuffer.RemoveAt(0)
End If
End Sub
' 무게가 안정한지 확인하는 함수
Private Function IsWeightStable() As Boolean
If weightBuffer.Count < BUFFER_SIZE Then
Return False
End If
Dim maxWeight As Double = weightBuffer.Max()
Dim minWeight As Double = weightBuffer.Min()
' 최대값과 최소값의 차이가 임계값보다 작으면 안정
Return (maxWeight - minWeight) <= STABILITY_THRESHOLD
End Function
' 안정된 무게값을 얻는 함수 (평균값 사용)
Private Function GetStableWeight() As Double
If weightBuffer.Count = 0 Then
Return 0
End If
Return weightBuffer.Average()
End Function
' 개선된 무게 비교 함수
Private Function weight_compare_improved(currentWeight As Double) As Boolean
Dim targetWeight As Double = weightSum
Dim upperLimit As Double = targetWeight + weightErrorPlus
Dim lowerLimit As Double = targetWeight - weightErrorMinus
Return currentWeight >= lowerLimit And currentWeight <= upperLimit
End Function
2025-05-12 09:13:11 +09:00
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
ElseIf mainForm.rdbWeightQW.Checked = True Then
lbNowWeight.Text = Math.Round(weightResult2, 0).ToString()
' 무게 불일치 후 재측정 모드를 먼저 체크
If zeroSet = False Then
' 무게가 변경되었는지 확인 (이전 측정값과 5g 이상 차이나면 재측정 시작)
Static previousWeight As Double = 0
If Math.Abs(weightResult2 - previousWeight) >= 5 Then
' 무게 변화 감지 - 재측정 시작
statusTimer.Enabled = True
playTimer.Enabled = True
ZeroTimer.Enabled = False
lbWeightEX.Text = weightSum
lbWeight.Text = "재측정 중..."
lbWeight.BackColor = Color.Yellow
' 버퍼 초기화
weightBuffer.Clear()
previousWeight = weightResult2
Else
' 무게 변화 없음 - 계속 대기
lbWeight.Text = "무게를 조정해주세요"
lbWeight.BackColor = Color.Orange
ZeroTimer.Enabled = True
previousWeight = weightResult2
End If
ElseIf weightResult2 <= 0 Then
statusTimer.Enabled = True
playTimer.Enabled = True
ZeroTimer.Enabled = False
lbWeightEX.Text = weightSum
lbWeight.Text = "저울에 올려주세요"
lbWeight.BackColor = Color.White
Else
ZeroTimer.Enabled = False
lbWeight.Text = "저울을 비워주세요."
lbWeight.BackColor = Color.Red
ZeroTimer.Enabled = True
End If
2025-05-12 09:13:11 +09:00
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 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
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 MeasureScale2(timeout As Integer) As String
'Return "US,GS, " & weightResult2.ToString("F3") & " kg"
Return "US,GS, " & (weightResult2 * 1000).ToString("F0") & " g"
End Function
2025-05-12 09:13:11 +09:00
Private Function AutoMeasureScale() As Boolean
Try
If mainForm.rdbWeightQW.Checked = True Then
' 2번 측정해서 무게가 거의 같으면 OK
For i = 0 To 1
weight2(i) = MeasureScale2(200) ' 예: "US,GS, 0.901 kg"
Next
Dim w0 As Double = ParseWeightData(weight2(0))
Dim w1 As Double = ParseWeightData(weight2(1))
If Math.Abs(w0 - w1) < 10 Then ' 10g 이내 차이 (kg 단위면 0.01)
Return True
Else
Return False
End If
End If
2025-05-12 09:13:11 +09:00
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
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 Function ParseWeightData(data As String) As Double
Try
Dim m = System.Text.RegularExpressions.Regex.Match(data, "([-+]?\d+\.\d+|\d+)\s*(kg|g)")
If m.Success Then
Dim value As Double = Convert.ToDouble(m.Groups(1).Value)
Dim unit As String = m.Groups(2).Value.ToLower()
If unit = "kg" Then
value = value * 1000 ' kg → g 변환
End If
Return value ' g 단위로 반환
End If
Catch ex As Exception
Debug.Print("파싱 오류: " & ex.Message)
End Try
Return 0
End Function
Private Sub QWSerialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles QWSerialPort.DataReceived
Try
System.Threading.Thread.Sleep(300) '딜레이
Dim incoming As String = QWSerialPort.ReadExisting()
'Debug.Print("수신 데이터: " & incoming)
' 여러 줄이 들어올 수 있으니, 줄 단위로 분리
Dim lines() As String = incoming.Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
Dim maxWeight As Double = 0
For Each line As String In lines
Dim w As Double = ParseWeightData(line)
If w > maxWeight Then maxWeight = w
Next
weightResult2 = maxWeight
'Debug.Print(maxWeight)
'Debug.Print(weightResult2)
If weightResult2 = 0 Then
zeroSet = True
Else
zeroSet = False
End If
Catch ex As Exception
Debug.Print("수신 오류: " & ex.Message)
End Try
End Sub
2025-05-12 09:13:11 +09:00
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