NonSoft

COMポート(シリアル)で電文の送受信をするサンプル
(VC6/VB6/VBA)


 サンプル(ソース/コード)
<このサンプルの概要>
COMポート(RS232C/シリアル)を使用して電文の送受信をするVC6(C++)のサンプルソースです。

COMポート(RS232C/シリアル)のオープン手順は以下の通りです。
1.COMポートのオープン
2.COMポートのセットアップ
3.COMポートの設定取得
4.COMポートの設定変更

COMポート(RS232C/シリアル)の送信手順は以下の通りです。
1.送信電文作成
2.COMポートにデータ送信

COMポート(RS232C/シリアル)の受信手順は以下の通りです。
1.COMポートの受信イベント作成
2.COMポートの受信イベントマスク
3.COMポートの受信待ち
4.COMポートの受信イベントチェック
5.COMポートの受信データチェック
6.COMポートからデータ受信

ちなみにCOMポートのCTSやDSRを確認したい時はGetCommModemStatusを使用します。
DWORD sts;GetCommModemStatus(hRs232c,&sts);
if ((sts & MS_CTS_ON)  != 0) // CTSがON
if ((sts & MS_DSR_ON)  != 0) // DSRがON

また、COMポートのDTRやRTSを設定したい時はEscapeCommFunctionを使用します。
EscapeCommFunction(hRs232c,SETDTR); // DTRをON
EscapeCommFunction(hRs232c,CLRDTR); // DTRをOFF
EscapeCommFunction(hRs232c,SETRTS); // RTSをON
EscapeCommFunction(hRs232c,CLRRTS); // RTSをOFF

このサンプルは仮想COMポート(com0com)で使用出来るように、
COMポート名を"\\.\COM11"としています。

(感想)
VCでのCOM通信は面倒ですね。VCに比べればVBは簡単でしょう。
ついでなのでVB6のサンプルも書いて置きます。
ついでなのでVBAのサンプルも書いて置きます。

RS232C関係のその他のツールやサンプルソースはこちらです。
このサンプルの通信テストでもこちらのツールを使用しました。
通信サンプルやツール(RS232C TCP/IP UDP/IP)

// VC6のRS232C通信サンプル
#include "stdafx.h"
#include <afxwin.h>

int main(int argc, char* argv[])
{
    // 送受信バッファ初期化
    char SndBuf[32];
    char RcvBuf[32];
    memset(SndBuf,0,sizeof(SndBuf));
    memset(RcvBuf,0,sizeof(RcvBuf));

    // COMポートのオープン
    HANDLE hRs232c = CreateFile(
        "\\\\.\\COM11",GENERIC_READ|GENERIC_WRITE,0,NULL,
        OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
    if ( hRs232c == INVALID_HANDLE_VALUE ) {
        printf("RS232C CreateFile Error\n");
        return -1;
    }

    // COMポートのセットアップ
    if (SetupComm(hRs232c,sizeof(RcvBuf),sizeof(SndBuf)) == FALSE){
        printf("RS232C SetupComm Error\n");
        return -1;
    }

    // COMポートの設定取得
    DCB dcb;
    memset(&dcb, NULL, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB);
    GetCommState(hRs232c, &dcb );

    // COMポートの設定変更
    dcb.BaudRate = 9600;
    dcb.Parity   = 0;    // 0,1,2,3,4 = no,odd,even,mark,space 
    dcb.StopBits = 0;    // 0,1,2     = 1bits,1.5bits,2bits
    dcb.ByteSize = 8;    // 4,5,6,7,8 = 4bits,5bits,6bits,7bits,8bits
    if (SetCommState(hRs232c,&dcb) == FALSE){
        printf("RS232C SetCommState Error\n");
        return -1;
    }

    // 送信電文作成
    sprintf(SndBuf,"abcあいう");

    // COMポートにデータ送信
    DWORD dwSize;
    OVERLAPPED ovWrite;
    memset(&ovWrite,0,sizeof(ovWrite));
    if (WriteFile(hRs232c,SndBuf,strlen(SndBuf),&dwSize,&ovWrite) == FALSE){
        printf("RS232C WriteFile Error\n");
        return -1;
    }else{
        // 送信成功
        printf("RS232C WriteFile Success\n");
    }

    // COMポートの受信イベント作成
    OVERLAPPED ovRead;
    memset(&ovRead,0,sizeof(ovRead));
    ovRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    if (ovRead.hEvent == NULL){
        printf("RS232C CreateEvent Error\n");
        return -1;
    }

    // COMポートの受信イベントマスク
    if (SetCommMask(hRs232c,EV_RXCHAR) == FALSE){
        printf("RS232C SetCommMask Error\n");
        return -1;
    }

    // COMポートの受信待ち
    DWORD dwEvtMask = 0;
    DWORD dwTransfer = 0;
    if (WaitCommEvent(hRs232c,&dwEvtMask,&ovRead) == FALSE){
        if (GetLastError() == ERROR_IO_PENDING) {
            GetOverlappedResult(hRs232c,&ovRead,&dwTransfer,TRUE);
        }else{
            printf("RS232C WaitCommEvent Error\n");
            return -1;
        }
    }

    // COMポートの受信イベントチェック
    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR){
        // COMポートの受信データチェック
        COMSTAT comst;
        DWORD dwErr;
        ClearCommError(hRs232c,&dwErr,&comst);

        // COMポートからデータ受信
        if(ReadFile(hRs232c,RcvBuf,comst.cbInQue,&dwSize,&ovRead) == FALSE){
            printf("RS232C ReadFile Error\n");
            return -1;
        }else{
            // 受信成功
            printf("%s\n",RcvBuf);
            printf("RS232C ReadFile Success\n");
        }
    }

    // OMポートの受信イベントクローズ
    CloseHandle(ovRead.hEvent);

    // COMポートのクローズ
    CloseHandle(hRs232c);

    return 0;
}

' VB6のRS232C通信サンプル
' MSCommコントロールをフォームに追加しています
Private Sub Form_Load()
    ' COMポートのオープン
    MSComm1.Settings = "9600,n,8,1"
    MSComm1.CommPort = 11
    MSComm1.PortOpen = True
    
    ' COMポート受信イベント作成
    MSComm1.RThreshold = 1
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ' COMポートのクローズ
    MSComm1.PortOpen = False
End Sub

Private Sub Command1_Click()
    ' COMポートにデータ送信
    MSComm1.Output = "abcあいう"
End Sub

Private Sub MSComm1_OnComm()
    ' COMポートからデータ受信
    If MSComm1.CommEvent = comEvReceive Then
        MsgBox MSComm1.Input
    End If
End Sub

' EXCEL VBAのRS232C通信サンプル(ACCESS VBAでも動きます)
' MSCOMM32.OCXを参照設定しています(MSCOMM32.OCXが入っているVB6ランタイムが必要)
Private WithEvents MSComm1 As MSComm

Private Sub CommandButton1_Click()
    ' COMポートのオープン
    Set MSComm1 = New MSComm
    MSComm1.Settings = "9600,n,8,1"
    MSComm1.CommPort = 11
    MSComm1.PortOpen = True

    ' COMポート受信イベント作成
    MSComm1.RThreshold = 1
End Sub

Private Sub CommandButton2_Click()
    ' COMポートのクローズ
    MSComm1.PortOpen = False
End Sub

Private Sub CommandButton3_Click()
    ' COMポートにデータ送信
    MSComm1.Output = "abcあいう"
End Sub

Private Sub MSComm1_OnComm()
    ' COMポートからデータ受信
    If MSComm1.CommEvent = comEvReceive Then
        MsgBox MSComm1.Input
    End If
End Sub