エクセルVBA to ARDUINO |
次の記事を参考にさせて頂き、エクセルVBAからARDUINOへのシリアル通信を行ってみます。WindowsAPIを使ってシリアル通信を行います。
【Excel VBAでRS-232C通信】
https://qiita.com/pbjpkas/items/f81947ce38941356ebe4
先日、ARDUINOとCNC‐SHIELD を用いたステッピングモーター駆動について書きました。パソコンからシリアル通信でARDUINOにGコード送信し、モーターを動かすというものでした。途中経路を考慮しない位置決めの場合、エクセルシートのセルに入力された座標に基づき “G90G0X***.**Y***.**” のフォーマットでシリアル送信することで、連続的位置決めが出来そうです。先ずエクセルVBAからシリアル通信する方法について調べました。
プログラム概要 |
動作は次の図の通り、エクセルシート上の送信データ欄に文字を入力し、右側の“送信ボタン”をクリックするとUSB(RS232C)を介して ARDUINO にシリアルデータ送信します。ARDUINOは受信したデータの先頭に [RECEIVED] という文字を付与し返送します。エクセル側では受信データをエクセルシートに表示します。(赤線枠内)
エクセルVBA プログラム |
次はエクセルVBAのシリアル通信を行うプログラムです。
Public Function StartSerialComm(str_TX As String, com_port As String) に送信データとポート番号を指定して、呼び出すとデータを送信し、返信データを受信することが出来ます。
Option Explicit
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Sub CloseHandle Lib "kernel32" (ByVal hObject As Long)
Private Declare Sub ReadFile Lib "kernel32" _
(ByVal hFile As Long, _
ByVal lpBuffer As String, _
ByVal nNumberOfBytesToRead As Long, _
lpNumberOfBytesRead As Long, _
ByVal lpOverlapped As Long)
Private Declare Sub WriteFile Lib "kernel32" _
(ByVal hFile As Long, _
ByVal lpBuffer As String, _
ByVal nNumberOfBytesToWrite As Long, _
lpNumberOfBytesWritten As Long, _
ByVal lpOverlapped As Long)
Private Declare Function SetCommState Lib "kernel32" (ByVal hFile As Long, ByRef lpDCB As DCB) As Long
Private Declare Sub SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS)
'SetCommState
Private Type DCB
DCBlength As Long
BaudRate As Long
Fields As Long
wReserved As Integer
XonLim As Integer
XoffLim As Integer
ByteSize As Byte
Parity As Byte
StopBits As Byte
XonChar As Byte
XoffChar As Byte
ErrorChar As Byte
EofChar As Byte
EvtChar As Byte
wReserved1 As Integer
End Type
'SetCommTimeouts
Private Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
'CreateFileパラメータ用定数
Private Const GENERIC_READ = (&H80000000)
Private Const GENERIC_WRITE = (&H40000000)
Private Const OPEN_EXISTING = 3
Public Function StartSerialComm(str_TX As String, com_port As String)
Dim comPort As String
Dim hFile As Long
Dim cs As DCB 'CommState
Dim ct As COMMTIMEOUTS 'CommTimeouts
Dim length As Long
Dim buf As String
comPort = com_port
'COMポートオープン
hFile = CreateFile(comPort, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If hFile = -1 Then
StartSerialComm = "ERR_COM_OPEN"
Exit Function
End If
'RS232C通信設定
cs.BaudRate = 9600
cs.ByteSize = 8
cs.Parity = 0
cs.StopBits = 0
cs.Fields = &H3001
SetCommState hFile, cs
'RS232Cタイムアウト設定
ct.ReadIntervalTimeout = 1000
ct.ReadTotalTimeoutMultiplier = 1
ct.ReadTotalTimeoutConstant = 500
ct.WriteTotalTimeoutMultiplier = 1
ct.WriteTotalTimeoutConstant = 500
SetCommTimeouts hFile, ct
'送信
buf = str_TX + Chr(10)
WriteFile hFile, buf, Len(buf), length, 0
'受信
buf = String(1024, vbNullChar)
ReadFile hFile, buf, Len(buf), length, 0
'COMポートクローズ
CloseHandle hFile
'受信データのパース
buf = Replace(buf, vbNullChar, "")
buf = Replace(buf, Chr(10), "")
buf = Replace(buf, Chr(13), "")
StartSerialComm = buf
End Function
呼び出しは次の様な感じです。シートに貼り付けたコマンドボタンのクリックイベントで実行します。
Option Explicit
Private Sub CommandButton1_Click()
Dim sht
Dim res
sht = ActiveSheet.Name
Worksheets(sht).Cells(3, 3).Value = ""
res = StartSerialComm(Trim(Worksheets(sht).Cells(2, 3).Value), "COM5")
Worksheets(sht).Cells(3, 3).Value = res
End Sub
ARDUINO プログラム |
ARDUINO 側のプログラムです。
void setup() {
Serial.begin(9600);
Serial.setTimeout(15000UL);
Serial.println("Start!");
}
void loop() {
// put your main code here, to run repeatedly:
if( Serial.available() > 0 ){
// \r:CR, \r\n:CRLF, \n:LF
String str = Serial.readStringUntil('\n');
Serial.println((String)"[RECEIVED] " + str);
}
}
まとめ |
バージョンアップしたWordPressに不慣れで疲れました。
「エクセルVBAでARDUINOにシリアル通信する」への1件のフィードバック