본문 바로가기
VB

[VB6.0] Serial포트를 통해 Spread에 데이터 뿌려주기

by 엘딘 2022. 5. 24.

1. Serial Port 연결을 위해 Virtual Serial Ports Emulator를 통해 COM1 <=> COM2간 Pair를 해줍니다

 

2. Serial Port연결을 해준 후 데이터를 넘겨줄 COMM Virtual Machine을 켜준 후 Port Open 연결을 해줍니다 

 

Form의 경우 Spread와 Serial만 생성해줍니다.

 

Module

시리얼 포트 연결을 위해 모듈 작성(시리얼포트 연결할때마다 동일하게 작성)

Option Explicit

Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Public Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

' File: MSCOMM.BAS
'
' Copyright (C) 1996 Microsoft Technologies.
' All rights reserved.
'
'----------------------------------------------------------
'--- MSComm event constants
Public Const MSCOMM_EV_SEND = 1     ' There are SThreshold number of characters in the transmit buffer.
Public Const MSCOMM_EV_RECEIVE = 2  ' Received RThreshold # of chars.
Public Const MSCOMM_EV_CTS = 3      ' Change in the CTS line.
Public Const MSCOMM_EV_DSR = 4      ' Change in the DSR line.
Public Const MSCOMM_EV_CD = 5       ' Change in the CD line.
Public Const MSCOMM_EV_RING = 6     ' Change in the Ring Indicator.
Public Const MSCOMM_EV_EOF = 7      ' An EOF character was found in the input stream.
                            

'--- MSComm error code constants
Public Const MSCOMM_ER_BREAK = 1001     ' A Break was received.
Public Const MSCOMM_ER_CTSTO = 1002     ' CTS Timeout.
Public Const MSCOMM_ER_DSRTO = 1003     ' DSR Timeout.
Public Const MSCOMM_ER_FRAME = 1004     ' Framing Error.
Public Const MSCOMM_ER_OVERRUN = 1006   ' Data Lost.
Public Const MSCOMM_ER_CDTO = 1007      ' CD (RLSD) Timeout.
Public Const MSCOMM_ER_RXOVER = 1008    ' Receive buffer overflow.
Public Const MSCOMM_ER_RXPARITY = 1009  ' Parity Error.
Public Const MSCOMM_ER_TXFULL = 1010    ' Transmit buffer full.
Public Const MSCOMM_ER_DCB = 1011       ' Unexpected error retrieving DCB]

Public Function LeftH(ByVal anystr As String, ByVal nPos As Integer) As String
    LeftH = StrConv(LeftB(StrConv(anystr, vbFromUnicode), nPos), vbUnicode)
End Function

 

Form_Load()
Private Sub Form_Load()
    Dim sBuf$
    Dim RetVal$
    Dim a$
    Dim rsPort$
    Dim rsBaudRate$
    Dim rsParity$
    Dim rsDataBit$
    Dim rsStopBIt$

    '' 초기 행 값은 0으로 시작
    spread.MaxRows = 0
    
    '' Serial Port연결
    With MSComm1
        sBuf = String(255, 0)
        '' RetVal : GetPrivateProfileString을 통해 가져올 Port의 자릿수를 저장 
        '' sBuf에 값을 저장
        '' App.Path & "\Test.ini"를 통해 Port, BaudRate, Parity, DataBit, StipBIt값을 가져옴
        RetVal = GetPrivateProfileString("MSCOMM", "Port", "", sBuf, 255, App.Path & "\Test.ini")
        
        If RetVal = 0 Then
        Else
            '' sBuf에서 왼쪽(처음)에서 RetVal(자릿수)만큼을 a에 저장
            a = LeftH(sBuf, RetVal)
        End If
        
        rsPort = a
        
        
        sBuf = String(255, 0)
        RetVal = GetPrivateProfileString("MSCOMM", "BaudRate", "", sBuf, 255, App.Path & "\Test.ini")
        
        If RetVal = 0 Then
        Else
            a = LeftH(sBuf, RetVal)
        End If
        
        rsBaudRate = a
        
        
        sBuf = String(255, 0)
        RetVal = GetPrivateProfileString("MSCOMM", "Parity", "", sBuf, 255, App.Path & "\Test.ini")
        
        If RetVal = 0 Then
        Else
            a = LeftH(sBuf, RetVal)
        End If
        
        rsParity$ = a
              
              
        sBuf = String(255, 0)
        RetVal = GetPrivateProfileString("MSCOMM", "DataBit", "", sBuf, 255, App.Path & "\Test.ini")
        
        If RetVal = 0 Then
        Else
            a = LeftH(sBuf, RetVal)
        End If
        
        rsDataBit$ = a
        
        
        sBuf = String(255, 0)
        RetVal = GetPrivateProfileString("MSCOMM", "StopBIt", "", sBuf, 255, App.Path & "\Test.ini")
        
        If RetVal = 0 Then
        Else
            a = LeftH(sBuf, RetVal)
        End If
        
        rsStopBIt = a
              
              
        .CommPort = rsPort
        .Settings = rsBaudRate & "," & rsParity & "," & rsDataBit & "," & rsStopBIt
        .RTSEnable = True
        .RThreshold = 1
        .PortOpen = True
        
    End With
End Sub

 

MSCOMM
Private Sub MSComm1_OnComm()
    Dim sTemp As String
    
    '' COMM Virtual Machine에서 전송받은 데이터를 sTemp에 저장
    sTemp = MSComm1.Input

    '' Data함수를 통해 Spread에 뿌려줄 계산식 가져옴
    '' sTemp를 매개변수로 사용 > Data에서는 이게 sVal로 사용됨(Private Sub Data(ByVal sVal As String와 같이 사용하였음)
    Call Data(sTemp)
    
    Select Case MSComm1.CommEvent '장비내의 이벤트가 발생할 시 결과에 따라 각 케이스로 움직인다. 이때, 이벤트 결과값을 확인할수 있는 방법은 모듈안에 있다.
       ' Events
        Case MSCOMM_EV_SEND     ' There are SThreshold number of
                                ' character in the transmit buffer.
        Case MSCOMM_EV_RECEIVE  ' Received RThreshold # of chars.
            
        Case MSCOMM_EV_CTS      'j
        Case MSCOMM_EV_DSR      ' Change in the DSR line.
        Case MSCOMM_EV_CD       ' Change in the CD line.
        Case MSCOMM_EV_RING     ' Change in the Ring Indicator.
        ' Errors
        Case MSCOMM_ER_BREAK    ' A Break was received.
        ' Code to handle a BREAK goes here, and so on.
        Case MSCOMM_ER_CTSTO    ' CTS Timeout.
        Case MSCOMM_ER_DSRTO    ' DSR Timeout.
        Case MSCOMM_ER_FRAME    ' Framing Error.
        Case MSCOMM_ER_OVERRUN  ' Data Lost.
        Case MSCOMM_ER_CDTO     ' CD (RLSD) Timeout.
        Case MSCOMM_ER_RXOVER   ' Receive buffer overflow.
        Case MSCOMM_ER_RXPARITY ' Parity Error.
        Case MSCOMM_ER_TXFULL   ' Transmit buffer full.
    End Select
End Sub

 

Data함수
' Serial Port로 받아온 데이터를 스프레드에 뿌려주는 역할
' sVal은 파라미터를 통해 MSComm1_OnComm()에 있는 sTemp으로부터 데이터를 받아오는 역할
Private Sub Data(ByVal sVal As String)

    ' On Error GoTo err

    Dim sprTest() As String
    Dim sprPN As String
    Dim sprRack As String
    Dim sprPos As String
    Dim sprWSN As String
    Dim sprResult As String
    Dim vPN, vPN2
    Dim iRow As Integer
    Dim jRow As Integer
    
    sprPN = Mid(sVal, 5, 15)
    
    With spread
        'STX가 Q일때
        If Mid(sVal, 2, 1) = "Q" Then
            sprPN = Mid(sVal, 5, 15)
            sprWSN = Mid(sVal, 3, 2)
            sprResult = Mid(sVal, 20, 4)
            
            '' SearchCol(열 지정, 구할 값의 시작 행, 끝 행, 찾을 값, ?)를 통해 찾을 값의 행 번호를 구함
            iRow = .SearchCol(.GetColFromID("PN"), 0, .MaxRows, sprPN, SearchFlagsNone)
            '' vPN은 String값이 아님!
            '' PN열의 iRow행의 값을 vPN에 저장
            Call .GetText(.GetColFromID("PN"), iRow, vPN)
            
            
            '' 전송받은 데이터가 중복일 경우 입력되지 않도록 설정
            If sprPN = vPN Then
                .MaxRows = .MaxRows
                
                Call .SetText(.GetColFromID("PN"), iRow, sprPN)
                Call .SetText(.GetColFromID("Rack"), iRow, "")
                Call .SetText(.GetColFromID("Pos"), iRow, "")
                Call .SetText(.GetColFromID("WSN"), iRow, sprWSN)
                Call .SetText(.GetColFromID("Result"), iRow, sprResult)
            '' 중복이 아닐경우 입력
            Else
                .MaxRows = .MaxRows + 1
            
                Call .SetText(.GetColFromID("PN"), .MaxRows, sprPN)
                Call .SetText(.GetColFromID("Rack"), .MaxRows, "")
                Call .SetText(.GetColFromID("Pos"), .MaxRows, "")
                Call .SetText(.GetColFromID("WSN"), .MaxRows, sprWSN)
                Call .SetText(.GetColFromID("Result"), .MaxRows, sprResult)
            End If
    
            
        'STX가 T일때
        ElseIf Mid(sVal, 2, 1) = "T" Then
        
            sprPN = Mid(sVal, 5, 15)
            sprWSN = Mid(sVal, 3, 2)
            sprResult = Mid(sVal, 20, 4)
            
            iRow = .SearchCol(.GetColFromID("PN"), 0, .MaxRows, sprPN, SearchFlagsNone)
            ' vPN은 String값이 아님!
            Call .GetText(.GetColFromID("PN"), iRow, vPN)
            
            If sprPN = vPN Then
                .MaxRows = .MaxRows
                
                Call .SetText(.GetColFromID("PN"), iRow, sprPN)
                Call .SetText(.GetColFromID("Rack"), iRow, "")
                Call .SetText(.GetColFromID("Pos"), iRow, "")
                Call .SetText(.GetColFromID("WSN"), iRow, sprWSN)
                Call .SetText(.GetColFromID("Result"), iRow, sprResult)
            Else
                .MaxRows = .MaxRows + 1
            
                Call .SetText(.GetColFromID("PN"), .MaxRows, sprPN)
                Call .SetText(.GetColFromID("Rack"), .MaxRows, "")
                Call .SetText(.GetColFromID("Pos"), .MaxRows, "")
                Call .SetText(.GetColFromID("WSN"), .MaxRows, sprWSN)
                Call .SetText(.GetColFromID("Result"), .MaxRows, sprResult)
            End If
        
        'STX가 R일때
        Else
        
            sprPN = Mid(sVal, 5, 15)
            sprRack = Mid(sVal, 20, 2)
            sprPos = Mid(sVal, 23, 2)
            sprWSN = Mid(sVal, 3, 2)
            sprResult = Mid(sVal, 26, 4)
            
                '' searchCol (열에서 같은 값을 찾아주는 명령어)
                jRow = .SearchCol(.GetColFromID("PN"), 0, .MaxRows, sprPN, SearchFlagsNone)
                Call .GetText(.GetColFromID("PN"), jRow, vPN2)
                 
                If sprPN = vPN2 Then
                    .MaxRows = .MaxRows
                    
                    Call .SetText(.GetColFromID("PN"), jRow, sprPN)
                    Call .SetText(.GetColFromID("Rack"), jRow, sprRack)
                    Call .SetText(.GetColFromID("Pos"), jRow, sprPos)
                    Call .SetText(.GetColFromID("WSN"), jRow, sprWSN)
                    Call .SetText(.GetColFromID("Result"), jRow, sprResult)
                End If
           
        End If
    End With

'err:
'    If err <> 0 Then
'        Call msg(err.Description)
'    End If
    
End Sub

 

 

 시리얼 포트를 통해 전송해준 문자

Q01I114A0018      0000j
Q01I478A0061      0000j
Q01I234A0077      0000j
R01I114A0018      0701450082b
R01I478A0061      0101010132b
R01I234A0077      1418010643b

 

     R코드인 경우

    '첫번째 = STX(1char)
    '두번째 = R(1char)
    '세번째 = Workstation Number(2char)
    '네번째 = Patient ID Number(15char)
    '다섯번째 = Rack.no(2char)
    '여섯번째 = Position(2char)
    '일곱번째 = Cycle/Bayer(2char)
    '여덟번째 = Result(4char)
    '아홉번째 = Checksum(1char)
    '열번째 = ETX(1char)

댓글