ESP32[14] Bluetooth Serial で通信相手を切り替える
ESP32のBluetooth Serialは非常に簡単に使えてよいのですが、複数の端末を切り替えて通信のが結構、情報がなくて苦労しました。
ネットで見つかる説明はPeer to Peer の説明が多く、途中で通信相手を切り替えようとする例はあまりありませんでした。とりあえず、2つのESP32と切り替えて通信できたので覚書として書いておきます。
まず、プログラムの中で切り替えるので、setup()の中で接続するわけにはいかないので、Serial.begin()はsetup()に記述しますが、loop()中にconnect と disconnect を記述します。
切り替えるために、2つのクライアントのMACアドレスを記述します。MACアドレスの知り方は多くの方が書いているので割愛します。こんな感じです。
uint8_t w1_address[6] = {0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇};
uint8_t w3_address[6] = {0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇};
loop()でぐるぐる回しているので、通信相手を切り替えたいタイミングで、
if (SerialBT.disconnect()) {
Serial.println("Disconnected Succesfully!");
}
を実行します。
普段は、
if (!SerialBT.connected(10000)) で切断を確認しておき、切断が確認ができたら、必要なMACアドレスを使用して接続します。こんな感じです。
if (!SerialBT.connected(10000)) {
Serial.printf("\n%d: Start Connecting! %d\n", ws, msec_100B);
connected = SerialBT.connect(w1_address);
if (connected) {
Serial.printf("\n%d: Connected Succesfully! %d\n", ws, msec_100B);
} else {
Serial.printf("\n%d: Not connected Succesfully! %d\n", ws, msec_100B);
}
}
w1_address と w3_address の切り替えは直接書いてもいいですし、一旦、メモリコピーして使用してもいいと思います。
memcpy(address, w1_address, sizeof(w1_address));
以下に全体のソースを挙げておきます。でえバッグ用のメッセージが残っていますが、気にしないでください。これはタイマーを使って、20秒で切り替えています。
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
uint8_t w1_address[6] = {0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇};
uint8_t w3_address[6] = {0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇, 0x⁇};
uint8_t address[6];
bool connected;
hw_timer_t * timer = NULL; //timer 初期化
int msec; //msec カウンター用グローバル変数
int msec_100; // 100msec カウンター
int msec_100B; // 100msec カウンター
void IRAM_ATTR msecond_100() {
msec_100++;
msec_100B++;
if (msec_100 < 0) msec_100 = 0;
}
int ws;
void setup() {
Serial.begin(115200);
memcpy(address, w3_address, sizeof(w1_address));
//SerialBT.setPin(pin);
SerialBT.begin("W3", true);
Serial.println("The device started in master mode, make sure remote BT device is on!");
// msec timer start
timer = timerBegin(0, 80, true); //timer=1us
timerAttachInterrupt(timer, &msecond_100, true);
timerAlarmWrite(timer, 100000, true); // 100ms
timerAlarmEnable(timer);
ws = 1;
}
void loop() {
if (msec_100 > 200) {
if (ws == 1) ws = 3;
else ws = 1;
Serial.printf("\nmsec_100 timer expired %d\n", ws, msec_100B);
msec_100 = 0;
if (SerialBT.disconnect()) {
Serial.println("Disconnected Succesfully!");
}
}
switch (ws) {
case 1:
if (!SerialBT.connected(10000)) {
Serial.printf("\n%d: Start Connecting! %d\n", ws, msec_100B);
connected = SerialBT.connect(w1_address);
if (connected) {
Serial.printf("\n%d: Connected Succesfully! %d\n", ws, msec_100B);
} else {
Serial.printf("\n%d: Not connected Succesfully! %d\n", ws, msec_100B);
}
}
break;
case 2:
case 3:
if (!SerialBT.connected(10000)) {
Serial.printf("\n%d: Start Connecting! %d\n", ws, msec_100B);
connected = SerialBT.connect(w3_address);
if (connected) {
Serial.printf("\n%d: Connected Succesfully! %d\n", ws, msec_100B);
} else {
Serial.printf("\n%d: Not connected Succesfully %d\n", ws, msec_100B);
}
}
break;
}
// Serial.printf("\nloop start\n");
SerialBT.write('S');
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
delay(100);
}
クライアント側は非常に簡単です。
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
void setup() {
Serial.begin(115200);
SerialBT.begin("WS"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
if (SerialBT.available()) {
Serial.write(SerialBT.read());
SerialBT.write('1');
}
delay(20);
}