2019年6月8日土曜日

ESP32のBluetoothでSPPを使ってみた

ESP-WROOM-32にはBluetoothも搭載されているけれど、実はBluetooth Classicにも対応しているみたいなので、SPPでHC-05やRN42みたいにBluetoothシリアル変換アダプタとして使ってみた。

とりあえずArduino core for the ESP32のサンプルプログラムとしてBluetoothSerial→SerialToSerialBTで事足りるんだけど、RN42みたいにPCから未接続時はLED点滅で接続後に点灯みたいなインジケータを追加してみた。
あとは開発ボードのデフォルトのシリアルポートはUSBシリアル変換ICに直結されていて起動時に情報などが流れてきてしまうので別なポートをシリアルポートとして設定してみた。

#include "BluetoothSerial.h"
#include "Ticker.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

Ticker ticker;

#define BUILTIN_LED 2

void setup() {
  //インジケータ用LEDピンの設定
  pinMode(BUILTIN_LED, OUTPUT);
  //BluetoothのMACアドレス取得
  uint8_t macBT[6];
  esp_read_mac(macBT, ESP_MAC_BT);
  //BluetoothのMACアドレスの下4桁を使用して固有のデバイス名作成
  char btname[11];
  sprintf(btname,"ESP32-%02X%02X",macBT[4],macBT[5]);
  //Bluetoothのcallback関数設定
  SerialBT.register_callback(callbackBT);
  //先ほど作成したデバイス名でBluetooth開始
  if(SerialBT.begin(btname)){
    //Bluetoothが開始できたらLED点滅開始(接続待ち)
    ticker.attach(0.5, ledBlink);
  }
  //Serial2(RX=GPIO16,TX=GPIO17)を開始
  Serial2.begin(115200);
}

void loop() {
  if (Serial2.available()) {
    SerialBT.write(Serial2.read());
  }
  if (SerialBT.available()) {
    Serial2.write(SerialBT.read());
  }
}

void callbackBT(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
  if (event == ESP_SPP_SRV_OPEN_EVT) {
    //接続後LEDを点滅→点灯
    ticker.detach();
    digitalWrite(BUILTIN_LED,HIGH);
  }else if (event == ESP_SPP_CLOSE_EVT) {
    //切断後LEDを点滅させる
    ticker.attach(0.5, ledBlink);
  }
}

void ledBlink() {
  volatile static int led = HIGH;
  digitalWrite(BUILTIN_LED, led);
  led = !led;
}

Bluetooth SPP用にBluetoothSerial.hと、LED点滅用にTicker.hを使用した。
デバイス名はRN42みたいにBluetoothのMACアドレスの下4桁を使用してデバイス固有のデバイス名にするようにしてみた。
LEDの方はBluetooth接続待ちになったらTickerで点滅させて、PC等にペアリングしてSPPの仮想COMポートをオープンするとLEDが点灯する感じ。切断すると点滅に戻る。
ここらへんもRN42ライクにしてみた。


Bluetoothデバイスを検索するとこんな感じに表示される。
あとはBluetoothとその他のデバイスからその他のBluetoothオプションを開くとどのCOMポートに繋がっているかがわかる。

例によってWindowsではSPPはなぜか仮想COMポートが2ポートできるんだけど、名前にESP32SPPがついてるほうが通信できるポート。この場合はCOM5なのでCOM3は削除しても問題なかった。

こんなに単純なプログラムなのにシリアルデバイスとは問題なく通信できてる。
RS-232CからBluetooth変換とか結構高級品だけど、これを使えばかなりお安く作れるんじゃないだろうか?RN42より安いし。ついでにESP32はWiFi搭載なので将来的にソフトウェア変更でWiFiシリアル変換にもできたり…

ちなみに例によってシリアルデバイス側のボーレートとESP32に書き込んだSerial2のボーレートは合わせておかないと通信できない。Bluetooth SPPは仮想COMポートのボーレート設定ではデバイス側のボーレートまでは変更できない仕様っぽいので…
なのであとはRN42みたいにコマンドモードでボーレートとかIOをいじれたら便利そうだなぁ
Bluetooth SPPとBLEは同時に使用できる。ただしデバイス名が一緒になってしまう…
ESP-WROOM-32はRN42より安いのにいろいろ盛りだくさんだなぁ。

RN42と違ってESP32は5Vトレラントじゃないので5Vで駆動しているマイコンとかに接続するときはi2c用とかのレベルコンバータ使ったほうがいいかも。


2 件のコメント:

  1. もっと早くこの記事を見つけていればよかったです。。。参考になります!

    返信削除
    返信
    1. 書き込みありがとうございます!
      少しでも参考になったのであれば幸いです

      削除