こちらの記事はケーシーエスキャロット Advent Calendar 2019の8日目の記事です。
昨日…、ではなく一昨日はaookiさんの自作キーボードを作りましたでした、自作キーボード、興味はあるのですが、手が出せていません。
さて、1年ほど前、VB.Net で Bluetooth を経由してロボットからログを取得・表示するツールを作成する記事を記載しました。
その記事の最後で
- 受信したログをファイルに保存
- ログにキーワードを紐付けて、絞り込みを行う
等を追加すると利便性が高まると記載したのですが、その部分を1年越しに追加してみたいと思います!
前提条件
VB.Net で Bluetooth を経由してロボットからログを取得・表示するツールの内容に沿って、既にロボットとbluetooth通信が行えていること。
フォームの配置
前回から新たに追加するコンポーネントは以下の通り。
コード(VB.Net)
コンポーネントを配置したら、コードを記載していきます。
データセットの追加
プロジェクト内に、新規にデータセットを追加します。
追加方法は以下の通りです。
- ソリューションエクスプローラー内のプロジェクト名を右クリック
- コンテキストメニューで
追加
->新しい項目
を選択 - 新しい項目の追加ダイアログで
データセット
を選択
また、追加したデータセットへ、下図のような名称で DataTable を追加、その DataTable 内に列(DataColumn)を2つ追加します。
更に、コードとして以下のクラス・メソッドを追加します。
Partial Class EtRoboData
Public Function AddBtRecvLogRow(ByVal recv As String) As String
Const DELIMITER As String = ")]"
Dim row As BtRecvLogRow = Me.BtRecvLog.NewBtRecvLogRow()
Dim index As Integer = recv.IndexOf(DELIMITER)
If index < 0 Then
row.Tag = "notag"
row.Log = recv
Else
row.Tag = recv.Substring(0, index)
row.Log = recv.Substring(index + DELIMITER.Length)
End If
Me.BtRecvLog.AddBtRecvLogRow(row)
Return row.Tag
End Function
End Class
追加したデータセットをフレーム内にメンバ変数として追加。
Private m_EtRoboData As New EtRoboData() '追加
Private Delegate Sub addRecvLogDataDelegate(recv As String)
前回追加したaddRecvLogData
メソッドを以下のように変更。
Private Sub addRecvLogData(recv As String)
Dim lines() As String = Split(recv.Replace(vbCr, String.Empty), vbLf)
If lines.Length <= 1 Then
Return
End If
For Each line As String In lines
If String.IsNullOrEmpty(line) Then
Continue For
End If
Console.WriteLine(line)
addCmbTag(m_EtRoboData.AddBtRecvLogRow(line))
Me.lstLog.SelectedIndex = Me.lstLog.Items.Count - 1
Next
End Sub
今回追加したコンポーネント群の初期化処理。
Private Sub initDataTable()
Me.lstLog.DataSource = m_EtRoboData.BtRecvLog
Me.lstLog.DisplayMember = m_EtRoboData.BtRecvLog.Columns(1).ColumnName
End Sub
Private Sub clearCmbTag()
Me.cmbTag.Items.Clear()
Me.cmbTag.Items.Add(String.Empty)
End Sub
Private Sub addCmbTag(ByVal tag As String)
If Me.cmbTag.Items.Contains(tag) Then
Return
End If
Me.cmbTag.Items.Add(tag)
End Sub
イベントハンドラ
追加した各初期化処理をロード部分へ追加、さらに新しく追加したコンポーネントのイベントハンドラを追加します。
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
initPortName()
initDataTable() '追加
clearCmbTag() '追加
End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim dialog As New SaveFileDialog()
With dialog
'ダイアログボックスで表示するファイル名
.FileName = DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log"
'ファイル種類
.Filter = "ログファイル(*.log)|*.log|すべてのファイル(*.*)|*.*"
'タイトル
.Title = "ログ保存先"
'前回保存先フォルダの保持
.RestoreDirectory = True
'既存ファイルのチェック
.OverwritePrompt = True
If .ShowDialog() = DialogResult.OK Then
Using sr As New StreamWriter(.FileName, False, System.Text.Encoding.UTF8)
For Each row As EtRoboData.BtRecvLogRow In m_EtRoboData.BtRecvLog.Rows()
sr.WriteLine(row.Tag + "," + row.Log)
Next
End Using
End If
End With
End Sub
Private Sub cmbTag_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbTag.SelectedIndexChanged
Dim search As String = Me.cmbTag.Text.TrimEnd()
If String.IsNullOrEmpty(search) Then
Me.lstLog.DataSource = m_EtRoboData.BtRecvLog
Else
Dim query = From row As EtRoboData.BtRecvLogRow In m_EtRoboData.BtRecvLog.AsEnumerable
Where row.Tag = search
Me.lstLog.DataSource = query.AsDataView()
End If
End Sub
コード (C)
続いて、ロボット側のログ送信部分を以下のように変更します。
const char *pTag1 = "hogehoge";
const char *pTag2 = "test";
const char *pMsg1 = "Hello EV3!";
const char *pMsg2 = "Good Bye EV3!";
FILE* sp;
sp = ev3_serial_open_file(EV3_SERIAL_DEFAULT)
fprintf(sp, "%s)],%s\r\n", pTag1, pMsg1);
fprintf(sp, "%s)],%s\r\n", pTag2, pMsg2);
fclose(sp);
動作確認
では、動作確認です。
ツールとロボットを起動すると、以下のようにログが表示されます。
さらにログを受信した状態でコンボボックスをクリックすると、ログに紐付けたタグが表示されます。
補足ですが、タグの部分を未指定(空文字)にするとnotag
として紐づきます。
試しにhogehoge
を選択すると、Hello EV3!
のみ絞り込まれて表示できます。
(この機能を使えば、PID部分だったり、難所部分のログといった感じで絞り込みが行えます)
あとは、保存ボタンを押下すると、ログ保存先ダイアログが表示されて保存ができます。
保存したログを開くと、タグと一緒に保存できています。
最後に
今年もETロボコンに参加しましたが、昨年同様、大変な半年でした。
そんな中、リンク情報システムさんが開催して頂いた非公式試走会のおかげで、本番に近い環境で色々と試せたことは非常に助かりました。
改めまして、ありがとうございました!
因みに、今回動確をしていて思ったのですが、bluetoothの接続状態等を表示すると、もっと使いやすいかもしれませんね。
※ 来年度の記事への布石ではありません(笑)