BluetoothでM5Stackと通信

(BluetoothでwindowsPCのterminalアプリと通信も可能)

2022.4.11 2021.5.11 Coskx Lab  

1 はじめに

BluetoothでAndroidがM5Stackと通信
AndroidデバイスとM5StackGray間でBluetooth Classic通信(Bluetooth Low Energyではありません)を行います。
Bluetooth通信(SPP Service Port Profile)では,Master(initiator)とSlave(Acceptor)の間で通信が行われます。
ここでは,AndroidをMaster,M5StackをSlaveとして使うことにします。
Master側では毎回通信相手を捜さなくてもよいように,通信前にPairing(Bonding)をしておきます。
Slaveは常時Masterからの接続を受け付けられるように動作しています。
Masterは,通信相手を1つだけ指定して接続し,通信を始めます。

M5Stack開発環境では,arduino用のBluetooth通信のサンプルプログラム(Slave)が公開されています。
ここではBluetooth通信ひな型アプリ(Android側Master)(通信相手は1機器のみ)を作成します。


Bluetooth通信ひな型アプリ(Android側)
Bluetooth通信ひな型アプリでは,EditTextで作成された文字列を送り,受信した文字列をTextViewに表示します。 このアプリでは,アプリ起動前にシステム設定で通信相手とのペアリングが行われていることが前提になります。
通信部はできるだけ裏方のクラスに隠して,文字列送信のメソッドと,文字列受信時のコールバックメソッドを使うようにします。
ただし,次の2つは表に見えるところ(MainActivity)に出します。
(1)Bluetooth通信相手(ここではM5Stack)の接続・接続解除
(2)AndroidデバイスのBluetooth機能がOFFになっていたらONにしてもらう手続き
作成に当たっては
https://www.hiramine.com/programming/bluetoothcommunicator/index.html
https://android.keicode.com/basics/bluetooth-list-paired-devices.php
を参考にし,引用させていただきました。感謝申し上げます。


Bluetooth通信ひな型アプリ(Android側)はWindowsPCのterminalアプリと通信も可能
Bluetooth通信ひな型アプリ(Android側)はM5Stackとの通信を目指していましたが,WindowsPCのterminalアプリと通信も可能です。
WindowsPCのterminalアプリは例えばTeraTermのようなものです。TeraTermは受信表示と送信表示が混ざってしまうので,区別しているアプリの利用が便利です。
事前に,AndroidとWindowsPCのbluetoothをペアリングしておく必要があります。
また,事前にWindowsPCのBluetoothの設定で,COMポートを開いておく必要があります。
WindowsPCのterminalアプリにこのCOMポートを指定して起動させて,から接続します。
詳細はこのページの付録で紹介しています。


Android 12 (API 31)以降でBluetoothに関するPermissionの扱いが変更されています。

2 使用環境

3 プログラムソース

sourcefiles.zipのダウンロード
作成中のpackage名が異なる場合は変更してください。
このzipファイルにはM5Stack側のソースも含まれています。

3.1 AndroidManifest

sourcefiles.zip中にAndroidManifestが含まれています。
AndroidManifast.xmlにおいて,Bluetoothを使うことを宣言します。次のように6行追加になっています。

AndroidManifast.xml
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s" />

3.2 Activity_main.xml

sourcefiles.zip中にactivity_main.xmlが含まれています。
次のようなスクリーンをイメージしています。
上から順に次のように配置されています。
 ・接続ボタン,接続解除ボタン
 ・通信相手のデバイス名(まだ決まっていない場合はno device)
 ・送信したい文字列作成のためのEditText(黄色の領域)
 ・送信ボタン,表示文字列クリアボタン
 ・受信文字列表示領域


3.3 MainActivity.java

sourcefiles.zip中にMainActivity.javaが含まれています。
onResume()中でAndroid端末のBluetooth機能の状態を調べ,有効化されていないときは有効化を促します。
onClick()中でボタンタップへの対応を行っています。
 ・ペアリング済のBluetoothデバイスを選択して接続
 ・Bluetoothデバイスを切断
 ・文字列送信
 ・文字列消去
を行います。
各作業の結果はBluetoothWorkのOverrideされたコールバックメソッド(onBTConnected()など)となって戻ってきます。
各コールバックメソッドでは必要に応じてボタンの無効化や有効化を行っています。
受信文字列はコールバックメソッドonMessageReceived()で受け取ります。
文字列送信はsendtext()で行っています。

3.4 BluetoothWork.java

sourcefiles.zip中にBluetoothWork.javaが含まれています。
舞台裏でBluetooth通信を行っているクラスです。スクリーンに対する直接の作業は一切行っていないので,舞台裏に隠れます。
この中に
private final UUID UUID_SPP = UUID.fromString( "00001101-0000-1000-8000-00805f9b34fb" );
が出てきますが,これが,Bluetooth Classicでシリアル通信を行うことを示すプロファイル(合言葉のようなもの)になります。
SPP(シリアルポートプロファイル)と呼ばれています。
この値は変更することはできません。


4 M5Stack Gray側のプログラム

sourcefiles.zip中にM5Stack/BT03.inoが含まれています。
arduinoを作業フォルダ中にフォルダBT03を作りその中にBT03.inoを入れてください。
その後は最新のarduinoのコンパイルシステムでコンパイル&書き込みをしてください。
プログラム中の「SerialBT.begin("M5Stack");」でM5Stack Gray側のデバイス名を決定しています。
BTシリアル通信中はノイズが多いせいか手元のM5StackGrayでは, ボタン取得にM5.BtnX.wasPressed()を使用すると誤検出をしていましたので, ボタン押し下げを50msec検出した後,ボタンリリースで,ボタン押し下げを検出したことにしています。
M5Stack Grayだけで起こることかもしれませんが, USBを通じたSerial通信とM5ライブラリを同時に使用するとうまく動作できません。 そのため,Serial通信は初期化も含めて使わないようにしています。

5 実行の様子

5.1 M5Stackの電源を入れたところで,Androidデバイスの設定でBluetoothのペアリングをしておきます。(準備)



起動時の様子

5.2 M5Stackは起動していますが,まだ接続されていません。
ボタンConnectをタップすると,ペアリングされているデバイス名の一覧が表示されるので,M5Stackを選択します。



デバイス選択
ここに表示されるのはAndroidデバイスとペアリングが完了しているデバイスです。

5.3 デバイスが選択されると接続状態になります。



通信中の様子 接続先のデバイス名が表示されています。
Androidからは文字列「Hello」を送り,M5Stack側が受信し表示しています。
M5Stack側でボタンAを押したので,文字列「key A」が送られ,Androidが受信し,表示しています。
ただし,M5StackのSerialBT.println()では,行末に\rがついていますが,android側は行末コードの違いを吸収して動作しています。

6 まとめ

Bluetooth通信(Master)ひな型Android用アプリを作成しました。
通信部分だけを再利用可能なクラスにしました。
プログラム中で作成された文字列をSlaveに送信するアプリ作成が楽になりました。


付録 BluetoothでwindowsPCのterminalアプリと通信

1 概要

Bluetooth通信ひな型アプリ(Android側)はAndroidとM5Stack間で通信するアプリですが,そのままAndroidとWindowsPC間で通信するのに使えます。
AndroidとWindowsPC間で通信するためには,次のことが必要です。
(1)WindowsPCでBluetoothが使えることが前提です
(2)WindowsPCではシリアル通信を行うために,BluetoothをCOMポートとして動作するようにする作業が必要です。
(3)WindowsPCではシリアル通信アプリ(ここではTera Termを想定しています)を使用します。
(4))WindowsPC側のシリアル通信アプリが先に接続状態になって待ち受けているところに,Android側のBluetooth通信ひな型アプリから接続します。

2 通信のためにWindowsPCのBluetoothをシリアルポートに結びつける

WindowsPCでBluetoothが使える状態であることが必要です。(bluetoothカードが内蔵,またはbluetoothアダプタを利用する)

WindowsPCのBluetoothをシリアルポート(COMポート)に結びつける手順は次の通りです。
WindowsPCの設定 → Bluetooth設定でBluetooth ON



WindowsPCの設定 → Bluetooth設定 → その他のBluetooth設定 → Bluetooth設定 → オプション




「BluetoothデバイスによるこのPCの検出を許可する」にチェックマークを入れる




WindowsPCの設定 → Bluetooth設定 → その他のBluetooth設定 → Bluetooth設定 → COMポート → 追加ボタン




「着信(デバイスが接続を開始する)」にチェックマークを入れ,OK




ポートにCOMxが「着信」設定で作られる。(ここではCOM8が作られている)
ここで作られたCOM8を後でターミナルアプリに設定する。



3 AndroidとPCのペアリングを行う

ペアリングに関しては個々のandroidデバイスの説明をnet検索してペアリングを実現してください。

4 WindowsPCのシリアルターミナルアプリTeraTerm

WindowsPCのTeraTermは有名なアプリなので,ネット検索してダウンロードしてください。
WindowsPCのTeraTermが起動したら,シリアル接続し,COMx(先ほどの例ではCOM8)を選択してください。
先にTeraTermを起動させてから,Bluetooth通信ひな型アプリ(Android側)を起動します。
Bluetooth通信ひな型アプリ(Android側)が起動したら,「CONNECT」ボタンで,通信先のWindowsPCを選んで通信を開始することができます。

参考 WindowsPCのシリアルターミナルアプリSerial_Terminal_plus

WindowsPCのTeraTermは送信・受信が同一画面内で行われているため,使いにくい場合があります。
Serial_Terminal_plus(https://github.com/healthywalk/Serial_Terminal_plus
はmicro:bitとPCのシリアル通信を想定されていますが,一般的なシリアルターミナル(送信・受信が別々に表示される)としても使用できます。
TeraTermの代わりに使うことができます。
WindowsPCのSerial_Terminal_plusが起動したら,シリアル接続し,COMx(先ほどの例ではCOM8)を選択してください。
先にSerial_Terminal_plusを「CONNECT」ボタンで,起動させてから,Bluetooth通信ひな型アプリ(Android側)を起動します。
Bluetooth通信ひな型アプリ(Android側)が起動したら,「CONNECT」ボタンで,通信先のWindowsPCを選んで通信を開始することができます。

Serial_Terminal_plus は次からダウンロードできます。


Serial_Terminal_plus.zipのダウンロード