ESP32をBluetoothに繋げる
ESP32をBluetoothに繋げる
Bluetoothシリアルを試してみます。
Bluetoothのシリアル接続は SPP (Serial Port Protocol) と呼ばれます。
ESP32にはSPPのホストになってもらい、スマートフォンから接続してみます。
SPPはBluetooth Classicに属します。
Classicとは別にBluetooth BLE (Bluetooth Low Energy) と呼ばれる規格があるのですが、こちらは新しい規格でBluetoothでお馴染みのペアリング操作などが不要且つ低電力で動作することを目的とした規格です。
Classicはヘッドフォンやキーボードなど基本的に同じみのものです。SPPはClassicにカテゴライズされます。
プログラム
単純にSPPサーバーとして起動、接続されたら送信されてきたデータをエコーバックするだけの単純なものです。
最初からやります。
VSCode起動後にF1 (またはCtrl+Shift+P) でコマンドパレットを開き、ESP-IDF: New Project を入力/選択します。
以下の画面になるのでProject NameとProject directory (保存先にプロジェクト名でディレクトリが作成されます) を入力します。
他の項目は特に弄らなくてよいです。
Choose Templete ボタンで作成です。
テンプレートを選択する画面になるので template-app を選択して Create project using template template-app をクリックします。
次にBluetoothを使うために設定があります。
VSCodeの画面下のツールバーから歯車マークをクリックしてmenuconfigを起動します。
Bluetooth を探してチェックします。
次に Bluedroid Options を探して以下をチェックします。
次に Controller Options を探して以下のように変更します。
最後に Sava ボタンで保存です。
プログラムソースは以下になります。
/**
* Bluetooth Classic SPP (Blutoothシリアル) のサンプル
* クライアントから接続されたら入力内容をエコーバックするだけです。
*/
#include <stdio.h>
#include <string.h>
#include "nvs_flash.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_bt_api.h"
#include "esp_spp_api.h"
#define SPPTEST "SPPTest"
#define SPPTEST_DEVICE_NAME "SPPTestDev"
// Bluetoothコントローライベントコールバック
void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
// ここでペアリング完了などのイベント取れますが、必要がなければ応答しなくても大丈夫
switch (event) {
default:
break;
}
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
char *pszStr;
switch (event) {
case ESP_SPP_INIT_EVT: // SPP初期化
if (param->init.status == ESP_SPP_SUCCESS) {
// SPPサーバー作成/接続待機
esp_spp_start_srv(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_SLAVE, 0, SPPTEST);
}
break;
case ESP_SPP_START_EVT: // SPPサーバー起動
if (param->start.status == ESP_SPP_SUCCESS) {
// デバイス名登録
esp_bt_dev_set_device_name(SPPTEST_DEVICE_NAME);
// SPPサーバー状態変更 (ESP_BT_CONNECTABLE=接続可、ESP_BT_GENERAL_DISCOVERABLE=発見可)
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
}
break;
case ESP_SPP_DATA_IND_EVT: // SPPデータ受信
pszStr = malloc(param->data_ind.len + 1);
strncpy(pszStr, (char*)param->data_ind.data, param->data_ind.len);
pszStr[param->data_ind.len] = '\0';
// エコーバックする
esp_spp_write(param->cl_init.handle, strlen(pszStr), (uint8_t *)pszStr);
free(pszStr);
break;
default:
break;
}
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init()); // Flash初期化 (お約束のようなもの)
// BluetoothがBLEモードだったら初期化 (念のため)
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
// Bluetoothコントローラ初期化、他のesp_bt関数を呼び出す前に1回呼び出しが必要
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
// BluetoothコントローラをClassicモードに設定
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT));
// Bluetooth初期化、他のesp_bluedroid関数を呼び出す前に1回呼び出しが必要
ESP_ERROR_CHECK(esp_bluedroid_init());
// Bluetooth有効
ESP_ERROR_CHECK(esp_bluedroid_enable());
// Bluetoothコントローライベントコールバック登録
ESP_ERROR_CHECK(esp_bt_gap_register_callback(esp_bt_gap_cb));
// Bluetoothイベントコールバック登録
ESP_ERROR_CHECK(esp_spp_register_callback(esp_spp_cb));
// SPP (Serial Port Protocol) モジュールを初期化/有効
esp_spp_cfg_t bt_spp_cfg = {
.mode = ESP_SPP_MODE_CB,
.enable_l2cap_ertm = true,
.tx_buffer_size = 0
};
ESP_ERROR_CHECK(esp_spp_enhanced_init(&bt_spp_cfg));
}
余計なイベントとか省けるだけ省くとこんな感じになります。
Androidから接続
Androidのスマホから接続してみます。
Serial Blutooth Terminal というソフトがあるのでこちらをインストールします。
最初にAndroidの設定でペアリングします。
デバイス名を SPPTestDev にしているのでそちらを選択します。
Serial Blutooth Terminal を起動して Bluetooth Classic を選択します。
ペアリングした SPPTestDev が一覧に出てきますのでタップします。
正常に接続できれば Connect と表示されます。
適当に何か入力して(青文字)、エコーバック(緑文字)が返ってくればOKです。
BluetoothでSPPはこんな感じです。
最初にmenuconfigで設定変更が必要なのに気が付かずビルドできなくて困りましたが、それ以外は特に問題なかったです。
コメント
コメントを投稿