#概要
仕事で温度センサーの精度検証を行っており、その際に活用できるかなと思いEXCEL VBA で行うシリアル通信モニタを作成しました。
今までは記録用の資料を作成し、ArduinoIDEのツールの「シリアルモニタ」で表示された温度を転記、計器で実測した値を入力して精度の確認の資料としてきました。
またArduinoIDEのツール「シリアルプロッタ」でグラフを見て推移を確認していました。ですが、このグラフでは細かい数値を確認することが出来ず困っていました。
そこで何とかできないかとモニタリングの方法を調べました。いくつかの方法がありましたが、シリアルデータをEXCELで出力する方法を用意しておけば今後、別データのモニタリングが必要になった場合にも応用が利くのではないかとこの方法を採用しました。
今回は5分置きに計測した温度がEXCELに出力されるようにしました。また出力シートに実測した値を計測中にも入力できるようにと考え作成しました。
#参考にしたサイト
下記のサイトでArduino + EXCEL VBA については書かれておりましたので、参考にさせていただきました。
https://blogs.yahoo.co.jp/nobita_rx7/28090650.html
Arduino側の設定
精度検証を行いたいセンサーの値をカンマ区切りで取得させています。
使用するセンサー:
atlas-scientific RTD Temperature
防水型 温度センサー DS18B20
取得するシリアルデータフォーマット
温度1(atlasの温度データ),温度2(DS18B20の温度データ)
例
28.021,28.22
EXCEL VBA シリアル通信モニタ
シリアル通信について
シリアル通信をするために参考にしたサイトで紹介されていたEasycCmmのモジュールを使用します。
仕様:
メインシートにてポート番号を指定可能。
開始ボタンを押すとモニタリングが開始される。
モニタリングが開始されるとテンプレートシートを元に新規ブックが作成され、モニタリングされた値が出力される。
モニタリング中もデータシートを編集が可能(実測値の入力などを平行して行えるようにする)
終了ボタンを押すとモニタリングが終了される。
##EXCEL VBAコード
メインシートのプログラム:
開始ボタン、停止ボタンがあり、ポート番号を設定できるメインシートです。
※プログラムの中で使われているshtMain.Range("ポート番号")は「名前の管理」で定義されているセルから参照しています。
※Worksheetのオブジェクト名を下記のように変更して参照しています。
Option Explicit
Enum E_COL
C_時刻 = 1
C_AtlasRTDCircuit
C_DS18B20
End Enum
Private WithEvents m_monitoring As clsMonitoring
'-------------------------------
' モニタリングを開始します
'-------------------------------
Sub MonitoringStart()
Dim bk As Workbook
Dim sht As Worksheet
Dim r As Long
Set m_monitoring = New clsMonitoring
'テンプレートシートを元に新しいブックを作成
shtTemp.Copy
Set bk = ActiveWorkbook
Set sht = bk.Sheets(1)
'カーソルを初期位置に設定
r = 3
sht.Cells(r, C_時刻).Select
ActiveCell.Offset(0, 0).Activate
'5分間隔でモニタリング開始
Call m_monitoring.MonitoringStart(CInt(shtMain.Range("ポート番号")), 5, sht, r)
End Sub
'-------------------------------
' モニタリングを終了します
'-------------------------------
Sub MonitoringEnd()
If m_monitoring Is Nothing Then
Exit Sub
End If
Call m_monitoring.MonitoringEnd
Set m_monitoring = Nothing
MsgBox "モニタリングを停止しました。"
End Sub
'-------------------------------
' モニタリングイベント:モニタリング結果をシートに反映
'-------------------------------
Private Sub m_monitoring_DisplaySerialData(sht As Worksheet, r As Long, value As String)
Dim vals As Variant
vals = Split(value, ",")
sht.Cells(r, C_時刻) = Format(Now(), "yyyy/mm/dd hh:mm:ss")
sht.Cells(r, C_AtlasRTDCircuit) = vals(0)
sht.Cells(r, C_DS18B20) = vals(1)
End Sub
モニタリングクラス:
モニタリングの開始、終了を行います。
シリアルデータ書き込み時に出力イベントを発生させています。
Option Explicit
' 取得したシリアルデータを表示するイベント
Public Event DisplaySerialData(sht As Worksheet, r As Long, value As String)
' モニタリング終了フラグ
Private m_endFlg As Boolean
'-------------------------------
' モニタリングを開始します
'
' ※spanMinute: 10 の場合は(10:10,10:20,10:30~)という10分ごとの区切りで実行されます。
'-------------------------------
Function MonitoringStart(portNo As Integer, spanMinute As Integer, sht As Worksheet, stRow As Long)
ec.COMn = portNo 'COM3を指定します
ec.Setting = "9600,n,8,2" '通信条件(ボーレート,パリティビット数,データビット数,ストップビット数)の設定
ec.HandShaking = ec.HANDSHAKEs.RTSCTS '通信ハンドシェークの設定
ec.Delimiter = ec.DELIMs.CrLf 'データの区切りを示す文字列を設定します
ec.OutBuffer = 100& * 1024& '現在処理の対象になっているポートの送信バッファを100kBに設定します
Dim value As String
Dim r As Long
Dim nextTime As Date
r = stRow
Do While Not m_endFlg
' 指定分ごとに実行
nextTime = GetNextTimeMinute(spanMinute)
' 指定分たつまでの間、EXCELが編集できないのは困るので、DoEventでイベントを処理しながら待機
Do While nextTime > Now()
DoEvents
Sleep (100)
If m_endFlg Then
Exit Do
End If
value = Replace(ec.AsciiLine, vbCr, "")
ec.InBufferClear '受信バッファをクリア
Loop
' 時間が経過した場合、取得したシリアルデータを表示
RaiseEvent DisplaySerialData(sht, r, value)
r = r + 1
DoEvents
Loop
'ポートを閉じる
ec.COMn = -1 '終了処理
End Function
'-------------------------------
' モニタリングを終了します
'-------------------------------
Function MonitoringEnd()
m_endFlg = True
End Function
'-------------------------------
' 次の計測時間を取得します
'-------------------------------
Function GetNextTimeMinute(mi As Integer) As Variant
Dim t As Date
Dim ms As String
Dim m As Integer
t = Now()
m = Mid(Format(t, "HH:MM:SS"), 4, 2)
m = m - m Mod mi + mi
ms = "00:" & Right(Format(t, "HH:MM:SS"), 5)
GetNextTimeMinute = t - TimeValue(ms) + TimeValue(WorksheetFunction.RoundDown(m / 60, 0) & ":" & m Mod 60 & ":00")
End Function
#まとめ
メインシート側でデータフォーマットを判断するようにプログラムを作成したので、今回とは違うフォーマットデータのモニタリングが必要になった場合も最小限の修正で対応が可能になったと思います。
グラフデータは出来上がったデータを元に、グラフツールを使って作成する形でしばらく様子を見たいと思います。