Excelからシリアル通信を実現してみようという連載の5回目です。前回の記事はこちらになります。
前回はExcelと通信モニターでデータを送受信してみました。実際に送受信できるようになると、面白くなってきますね。
今回はLoopBackTestToolのソースコードを解説します。
実際のコード
それでは実際のコードを見てみます。
入力対応
まずは入力対応です。Topシートに記述されていて、実行ボタンに割り当てられています。
'ループバックテスト実行 Public Sub Execute() Me.Range("Receive_Data").Value = _ LoopBackTest(Me.Range("Port_No").Value, Me.Range("Send_Data").Value) Me.Range("Send_Data").Value = "" End Sub
標準モジュールに記述されているファンクションプロシージャ「LoopBackTest」に、ポート番号と送信データを引数で渡しています。受信したデータが返り値になって、シート上に表示されます。
ループバックテスト(前半)
標準モジュールのファンクションプロシージャ「LoopBackTest」の内容前半です。指定されたポートの初期設定を実行します。コマンドの詳細については次回に説明します。
'ループバックテスト Public Function LoopBackTest(ByVal comPort As String, ByVal sendData As String) As String Dim lngResult As Long Dim lngHandle As Long 'ポートオープン処理 comPort = "\\.\" & comPort lngHandle = CreateFile(comPort, GENERIC_READ Or GENERIC_WRITE, _ 0&, 0&, OPEN_EXISTING, 0&, 0&) 'バッファの設定 lngResult = SetupComm(lngHandle, 2048, 2048) 'バッファのクリア lngResult = PurgeComm(lngHandle, PURGE_TXCLEAR) lngResult = PurgeComm(lngHandle, PURGE_RXCLEAR) '通信設定 fDCB.BaudRate = 9600 fDCB.Parity = 0 fDCB.ByteSize = 8 fDCB.StopBits = 1 lngResult = SetCommState(lngHandle, fDCB) 'タイムアウト1秒に設定 fCOMMTIMEOUTS.ReadIntervalTimeout = 1000 fCOMMTIMEOUTS.ReadTotalTimeoutMultiplier = 1000 fCOMMTIMEOUTS.ReadTotalTimeoutConstant = 1000 fCOMMTIMEOUTS.WriteTotalTimeoutMultiplier = 1000 fCOMMTIMEOUTS.WriteTotalTimeoutConstant = 1000 lngResult = SetCommTimeouts(lngHandle, fCOMMTIMEOUTS) Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 3)
ボートをオープンしてからバッファーの設定とクリア、通信条件の設定、タイムアウト時間の設定をしています。通信条件はArduino標準にあわせてあります。
ループバックテスト(後半)
続いて後半です。実際の送受信を実施します。
'送受信開始 'データ送信 If sendData <> "" Then Dim writeData() As Byte writeData = StrConv(sendData, vbFromUnicode) Dim writeBytes As Long writeBytes = UBound(writeData) + 1 '送信実行 Call WriteFile(lngHandle, writeData(0), writeBytes, lngResult, 0) End If Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 1) '返信データ受信 Call ClearCommError(lngHandle, lngResult, fCOMSTAT) If 0 < fCOMSTAT.cbInQue Then '受信データ確認 Dim readByte As Long readByte = fCOMSTAT.cbInQue ReDim readData(readByte - 1) As Byte Call ReadFile(lngHandle, readData(0), readByte, lngResult, 0) LoopBackTest = StrConv(readData, vbUnicode) End If 'ポートクローズ CloseHandle lngHandle End Function
送信データがある場合には、データを変換して送信を実施します。Unicodeの文字列データをバイト形式の配列にして送信しています。 続いて受信データを確認してデータがある場合には、受信を実施します。受信データは送信と逆に、バイト形式の配列で受信して、文字列データに変換します。 一連の動作が完了するとポートをクローズします。
次回もソースコード解説
如何でしょうか。今回は動作部分の解説を行いました。次回は使用しいるダイナミック リンク ライブラリ (DLL) の参照、その他の宣言について解説しようと思います。お楽しみに!!!