今回はBluetooth SPPの後編です。
この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。
投稿時の開発環境を記しておきます。
PC:
Windows10 OS
開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)
デバッガー(H/W):
FT2232D
デバッガー (S/W) :
Visual Studio Code + PlatformIO + ESP-IDF Framework
PC側の追加設定を行う
先にデバッガーを起動しておき、プログラムを動かしておきます。
(esp_bt_gap_set_pin()にブレークポイントを貼っておき、そこまで到達することを確認しておいた方が安心です)
PCのステータスバーの ^ 部分を押して、左上のBluetoothアイコンをクリックし「設定を開く」を選択します。

次にスクロールして降りていき、その他のBluetoothオプションを選択します。

Bluetooth設定のウィンドウが出たら、COMポートのタブを押し、追加ボタンを押します。

COMポートの追加 ウィンドウが出たら、発信の方をチェックして参照ボタンを押します。
ESP_SPP_ACCEPTOR を選択してOKボタンを押します。

これで Bluetooth とCOMポートのひもづけができたので Tera Term から Bluetooth を介してSPP通信を行うことができるようになりました。
私の環境では COM23 を使うことになります。

コーディングする
esp_spp_cb()関数を以下のようにコーディングします。
uint32_t clientHandle = 0;
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
static char buffer[256];
memset(buffer, 0, sizeof(buffer));
switch (event) {
case ESP_SPP_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
esp_bt_dev_set_device_name(EXAMPLE_DEVICE_NAME);
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
break;
case ESP_SPP_DISCOVERY_COMP_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT");
break;
case ESP_SPP_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
clientHandle = 0;
break;
case ESP_SPP_START_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
break;
case ESP_SPP_DATA_IND_EVT:
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
param->data_ind.len, param->data_ind.handle);
esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
// char *p = (char *)¶m->data_ind.data;
for (int i = 0; i < param->data_ind.len; i++)
{
// buffer[i] = p[i];
buffer[i] = (char)param->data_ind.data[i];
}
buffer[param->data_ind.len] = '\0';
ESP_LOGI(SPP_TAG, "Receive Data=%s\r\n", buffer);
char *msg = "Recv : Bluetooth SPP Data received.";
if (clientHandle)
{
ESP_LOGI(SPP_TAG, "Write to SPP.");
esp_spp_write(clientHandle, strlen(msg), (uint8_t *)msg);
}
#else
gettimeofday(&time_new, NULL);
data_num += param->data_ind.len;
if (time_new.tv_sec - time_old.tv_sec >= 3) {
print_speed();
}
#endif
break;
case ESP_SPP_CONG_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT");
break;
case ESP_SPP_WRITE_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT");
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
gettimeofday(&time_old, NULL);
clientHandle = param->srv_open.handle; // つながったらハンドルを取得する
break;
case ESP_SPP_SRV_STOP_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_STOP_EVT");
clientHandle = 0; // ハンドルを解放する
break;
case ESP_SPP_UNINIT_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_UNINIT_EVT");
break;
default:
break;
}
}
ビルドして実行する
ビルドしてエラーがないことを確認してプログラムを実行します。
しばらくは esp_bt_gap_set_pin() にブレークポイントを貼って、起動後ここにたどり着くことを確認しておいた方が安心します。
その後、再びプログラムを実行しモニターを起動しておきます。
ファイルを作成する
Tera Term 上で文字を送ると1キャラクタ毎に送られるので効率が悪いです。
あらかじめファイルを作成しておいて、それを送るようにしてみます。
私は以下の内容で send.txt というファイルをデスクトップに作成しました。
Send : Hello ESP32 Bluetooth SPP world.
Tera Termを起動してファイルを送ってみる
Tera Termを起動して 先ほどのCOMポートを選択します。
左上のタイトルが「未接続」から「接続中」になって消えます。
エラーのウィンドウが出なければ大丈夫です。
次に設定 - 端末から以下のように設定を行います。

これで送受信のデータが Tera Term 上で確認できるようになります。
それではファイル – ファイル送信から先ほどつくった send.txt を選択して送信してみましょう。
“Recv : Bluetooth SPP Data received.”の文字列は ESP32からBluetoothで送ったものになります。
こちらまで表示されれば送受信ができたことになります。

プログラムの概要
esp_spp_cb()という関数はコールバック関数で、SPPのイベントが発生するとここに来てお知らせしてくれます。
ESP_SPP_SRV_OPEN_EVT に来たところで param->srv_pen.handle を clientHandle に記憶しておきます。
ESP_SPP_SRV_STOP_EVT で clientHandle = 0 にして解放します。
Tera Term から電文が送られてくると ESP_SPP_DATA_IND_EVT に来るので buffer に取り込みます。
// 部にあるように char *p として、そこから buffer に取り込もうとするとなぜかうまくいきませんでした。
// 関数の同期が関連しているのかな?と思い、buffer[]をstaticの変数にかえてみたけれどかわらず。。
// 原因がおわかりの方がいらっしゃいましたら教えてください m(__)m
電文を受信できてかつ、clientHandle が有効なら、esp_spp_write()で送信するようにしました。
ESP32の方は、わざわざUARTを使う必要はなさそうなので、このようにコーディングしました。
いかがでしたか?
皆さんの環境では、うまく動きましたか?
ソースコードを github esp32e-bt-spp-acceptor におきました。
( 環境: VSCode + PlatformIO , Espressif IoT Development Framework )
ESP-IDE環境で Bluetooth SPP を試してみたい方は参考になさってください。
参考というほど、できの良いものではありませんけれど (^_^)