〇VB6 MSCommでシリアル通信

VB6でシリアル通信を行う場合には大抵、MSCommコントロールを使います。
他の方法、C言語みたいにAPIをゴリゴリ叩く方法も考えられますが見たことありません。
そこで、MSCommコントロールの使い方を調べて行きたいと思います。

まずは、通常コントロールが並んでいる場所にMSCommコントロールは無いと思いますので追加します。


メニューのプロジェクト→コンポーネントを選択します。


Microsoft Comm Control 6.0 のチェックボックスをONにして適用ボタンを押します。
そうすると、コントロールの場所に電話のコントロールが追加されたはずです。


▼受信イベントを拾う
コントロールをフォームに貼り付けてダブルクリックします、そうすると、Private Sub MSComm1_OnComm() というイベントが作成されたと思います。
そこで、次の様に書き換えてみましょう。

Private Sub MSComm1_OnComm()
    Select Case MSComm1.CommEvent
        Case comEvReceive
            MSComm1.InputLen = 0            '読み取るバイト数を指定 0は全て読み込む
            Label1.Caption = MSComm1.Input
        End Select
End Sub
これは、MSCommがデータを受信した時にLabelの文字を書き換えるコードです。


▼ポートへの接続
次にポートへの接続とイベントの閾値を設定します。

Private Sub Form_Load()
          MSComm1.CommPort = 4
          MSComm1.Settings = "9600,N,8,1"
          MSComm1.PortOpen = True
          MSComm1.RThreshold = 1
End Sub
COMポートは4番、ボーレート9600、パリティなし、データは8ビット、ストップビットは1にてポートを開けます。
後は、見ての通りですが、RThreshold を設定しないとイベントが発生しません。
RThreshold を 1 に設定すると、受信バッファに 1byte が格納されるたびにイベントが発生して値を受信できます。

▼文字の送信
MSComm1.OutBufferCount = 0      'バッファクリア
Do
    MSComm1.Output = "送信文字列" & vbCr & vbLf
Loop While MSComm1.OutBufferCount >= 1
上記コードを走らせると送信完了まで待機し、文字が送信されます。


■ポートをスキャンして通信機器を探す

通信機器に接続するときにポート番号を調べて設定し接続するのは面倒です。
そこで、ポートをスキャンする方法を考えます。

まず、なんらかの機器が接続されているポートを総当たりで調べます。
その後、開いているポートに対してコマンドを送信して機器を確認します。

しかし、接続する通信機器に特定のコマンドを送ったら、必ず決まったコマンドを返すという機能が無いと特定の機器であるのか識別できませんので、
私の場合には、t[cr][lf] と送った場合に、必ず NG[cr][lf] というコマンドを返す機能を通信機器に追加しました。

以下のコードは、 t[cr][lf] と送ったら、必ず NG[cr][lf] が返ってくるが前提になります。
Option Explicit
Private Declare Sub Sleep Lib "kernel32" ( _
    ByVal dwMilliseconds As Long)

Private Function connect(ByVal port As Integer) As Boolean
    connect = False
    If MSComm1.PortOpen Then MSComm1.PortOpen = False
On Error GoTo Err1
    MSComm1.CommPort = port
    MSComm1.Settings = "9600,E,8,1" '偶数パリティで設定しているため注意
    MSComm1.DTREnable = False
    MSComm1.PortOpen = True
    connect = True
Err1:
End Function

Private Function portScan() As Integer
    Dim portNo As Integer
    Dim str As String
    
    For portNo = 1 To 100
        If connect(portNo) Then
            MSComm1.OutBufferCount = 0      'バッファクリア
            Do
                MSComm1.Output = "t" & vbCr & vbLf
            Loop While MSComm1.OutBufferCount >= 1
            
            Dim i As Integer
            For i = 1 To 100
                Sleep 10
                If MSComm1.InBufferCount > 3 Then
                    str = MSComm1.Input
                    If str = ("NG" + vbCrLf) Then
                        '接続成功
                        portScan = portNo
                        Exit Function
                    End If
                End If
            Next i
        End If
    Next portNo
    portScan = -1 '接続先のポートが見つからなかった
End Function

Private Sub portScanReset()
    'ポート検索用に設定されているため、自分のアプリケーション用に設定しなおす
    MSComm1.InputLen = 1
    MSComm1.RThreshold = 1
End Sub

Private Sub Form_Load()
    Dim portNo As Integer
    portNo = portScan()
    
    If portNo <> -1 Then
        Form1.Caption = "接続先ポート番号 : " & portNo
    Else
        Form1.Caption = "接続エラー"
    End If
    portScanReset
End Sub
開いているポートを探すには、とりあえず開けてみてエラーが発生しないかどうかで判断できました。
その後は、開いたポートに対して特定のコマンドを送ってみて応答により判断しています。
アプリ起動後に接続されたポートに対しては検知できませんでした。


▲トップページ > Visual BASIC と C#