前回、AE-RN42というBluetoothモジュールを使いました。PCとマイコンをSPPというプロファイルを使用して、無線化することができました。記事はこちらです。
RN42-Bluetoothモジュールを使ってみた | ぼくのマイコン開発のメモ (tekuteku-embedded.xyz)
その時は、信号をTera Termからキーボード入力から手動で送信していましたが、今回は、Windowアプリケーションから信号を自動で出したいと思います。
実現したい機能は以下のような感じです。
- アプリがランダムな数字をBluetoothで送信する
- マイコン側はその数字を受信する
- 数字が3倍数の時だけ、LEDの色を赤くする(通常は白)
3の倍数だけバカになる芸人いましたよね…それをふと思いだしました。
C#ファームウェアを作成
C#では、SerialPortクラスというのが実装されているので、これを利用すれば、COMポートから信号の送受信が簡単に行えます。
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-3.1
下記のサイトも参考にしました。
https://qiita.com/mag2/items/d15bc3c9d66ce0c8f6b1
UIはこんなイメージです。
コンボBOXからBluetooth用のポート番号を選択して、接続、Sendボタンで信号だすという処理をします。超シンプルですが、一応コードの説明をしておきます。
SerialPortオブジェクトを作成する
SerialPortはVisual Studioのツールボックスに用意されているので、ドラッグアンドドロップでオブジェクトを作成できます。
今回、使用したSerialPortクラスのメソッドは以下のとおりです。
- public static string[] GetPortNames ()
システムレジストリから現在有効なCOMポート番号を取得します
- public void Open()
- public void Close()
シリアルポートを接続/切断します
- public void DiscardInBuffer()
- public void DiscardOutBuffer()
送受信用のバッファをクリアします。
- public bool IsOpen{ get; }
ポートの接続状況を確認、1なら接続中、0なら切断。
- public void Write( byte[] buffer, int offset, int count)
重要!ポートに信号を送信するメソッド、バイト配列で書き込み。offsetが配列の書き込み 開始のインデックス、0始まり。countが書き込むバイトサイズ
接続可能なCOMポートをコンボBOXへ反映
GetPortNamesというメソッドで、PCで認識されているCOMポートのString配列を取得します。その結果を、フォームのLoadイベントで、コンボBoxにリストを反映させています。
private void SerialSend_Load(object sender, EventArgs e)
{
// 使用できるシリアルポート名を取得
string[] PortList = SerialPort.GetPortNames();
// 使用できるシリアルポート名をコンボボックスの選択肢に追加
cmbSerialPort.Items.Clear();
foreach (string PortName in PortList)
{
cmbSerialPort.Items.Add(PortName);
}
if (cmbSerialPort.Items.Count > 0)
{
cmbSerialPort.SelectedIndex = 0;
}
}
COMポートを接続/切断
Connectボタンのクリックイベントで、選択したCOMポートに接続/切断します。あとは、ボーレートとかデータビット、ストップビットなどの通信設定をプロパティに反映させます。
private void btnConnection_Click(object sender, EventArgs e)
{
// シリアルポートに接続中の場合は切断する
if (serialPortCtrl.IsOpen == true)
{
return;
}
else
{
// シリアルポートに接続する
serialPortCtrl.PortName = cmbSerialPort.SelectedItem.ToString(); // Comboボックスで選択したシリアルポート番号をポート名に設定
serialPortCtrl.BaudRate = 9600; // ボーレートを設定
serialPortCtrl.DataBits = 8; // データビットを設定
serialPortCtrl.Parity = Parity.None; // パリティビットを設定
serialPortCtrl.StopBits = StopBits.One; // ストップビットを設定
serialPortCtrl.Handshake = Handshake.None; // フロー制御を設定
serialPortCtrl.Encoding = Encoding.ASCII; // 文字コードを設定
serialPortCtrl.WriteTimeout = 100000;
serialPortCtrl.ReadTimeout = 100000;
}
}
COMポートへ信号を送信
0~255の整数値をランダムに出力します。Sendボタンが押されたら、タイマーを動作させ、1sec間隔でWriteメソッドをよびだし、COMに信号を送信してます。
private void btnSend_Click(object sender, EventArgs e)
{
if (serialPortCtrl.IsOpen == true)
{
SendTimer.Start();
}
}
private void SendTimer_Tick(object sender, EventArgs e)
{
senddata[0] =(byte) sig.Next(0, 255);
serialPortCtrl.Write(senddata,0,1);
}
アプリ側の作業は以上です。つぎにマイコン側で受信して、LEDを光らすようにします。