ESP32でBluetooth相互無線通信(Arduino互換機)
どーもJunです。
久しぶりにまともな技術ブログを書いていこうかなと思います。
土日月と学校が休みだったのでいろいろ作業できました。土曜はいつもは授業がるのにテスト後ということで、月曜は3年生のクラスマッチだったので休みでした。今日(火曜)は、クラスマッチで昼前には、学校が終わりました。明日もクラスマッチなので休みです。
なんかテスト後っていうことで休みが多くて最高です。
そんなこんなでESP32を色々試してみたので書いていきたいと思います。
概要
今回は、ESP32で相互無線通信することを目標に1つ1つ手順を追って説明していきたいなと思います。
試作していく回路&プログラムはこんな感じです。
1、ESP32単体でArduino互換として使ってみる
2、Bluetoothで一方向無線通信
3、Bluetoothで双方向無線通信
用意するもの
ESP32
ESP32-WROVER-Eって名前がついてる適当なやつを用意すれば大丈夫なはずです。ちなみに僕が使ったのは、ロボットに搭載するときのことも考えて開発ボードではなくチップだけのやつです。
これです↓
ちなみに、チップと変換基板を自分ではんだ付けするタイプだとピンヘッダを自由に変えれるのでピンソケットにしました。
まぁ、なんだかんだこれを買うのが一番楽かもしれませんが少し高いので高校生だとそう簡単には買えません…
シリアル変換モジュール
適当にこれを使いました。ロボットに実際搭載するときには、もっと安いやつがあるらしいのでそっちを搭載したいですね。
細かい部品たち
・ブレッドボード
・ジャンパ
・LED × 2
・タクトスイッチ × 6
・LED用抵抗(330Ω) × 2
・プルアップ用抵抗(2kΩ) × 4
ちなみに抵抗は超絶適当にあったやつを使っただけなので適切な値は違うかもしれません。まぁ動いてるのでので良いといことにしましょう。
まぁ多分このくらいあれば十分ですかね。
ESP32単体でArduino互換として使ってみる
じゃあやっていきましょう。
まずは、適当に回路をくんでいきます。
回路
IO13に抵抗をかましてLEDをつけて、IO15とGNDの間にそのままタクトスイッチをつけます。
プログラム
プログラムは、ArduinoIDEに入ってるサンプルスケッチのButtonをちょっと改造したやつを使います。
const int buttonPin = 15; const int ledPin = 13; int buttonState = 0; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); } void loop() { buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }
変更点は、ピン番号だけですかね。
ちなみに、タクトスイッチはプルアップされてるので通常時はIO15はHIGHになっています。なので、このプログラムだと通常はLEDをが光っていて、ボタンを押すとLEDが消えます。
書き込み
これがArduinoと違って難しいところです。開発ボードを買った人は、元から自動書き込み回路が入っているのですが、チップを買ってしまった人は手動回路をつくってプログラムを入れないといけません。これが意外とめんどくさいです。トランジスタを使って自動回路を作れるらしいのですがめんどくさくてまだやってません。
回路としては、IO0とENにプルアップしてタクトスイッチをつなげます。
あとは、適当にArduinoかなんかから3.3Vを取ってきて、シリアル変換モジュールのGNDをチップのGNDへ、TxDをRxDに、RxDをTxDに繋げばOKです。
IO0をGNDとショートさせながらEN(RESET)をGNDとショートさせて再起動すると書き込みモードになります。
なので、もうすこし具体的に書くと
IO0 押す EN 押さない
↓
IO0 押す EN 押す
↓
IO0 押す EN 押さない (再起動完了)
↓
(書き込みボタンを押す)
↓
(マイコンボードに書き込み開始しますって表示が出たら)
↓
IO0 押さない EN 押さない
みたいな感じです。そんで、プログラムが入ったらENを押して再起動してあげれば動き出します。
まぁこれでうまく行っていればこの動画みたいな感じになるはずです。
ESP32手動書き込みやってみた pic.twitter.com/Ej8727IGEa
— All_outlook (@All_outlook) 2021年6月29日
Bluetoothで一方向無線通信
じゃあ次行ってみましょう。
無線通信の第一歩ということで、まずはスマホとESP1台との通信やっていきましょう。
スマホやタブレットに「Serial Bluetooth Terminal」ってやつを入れれば通信できるようになります。
回路はさっきのままで大丈夫です。まぁLEDしか使いませんが。
プログラム
#include "BluetoothSerial.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; void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); Serial.println("device start"); pinMode(13, OUTPUT); } char databox; void loop() { if (SerialBT.available()) { databox = SerialBT.read(); Serial.println(databox); if (databox == 'L') { digitalWrite(13, LOW); } if (databox == 'T') { digitalWrite(13, HIGH); } } delay(20); }
これも、ほぼサンプルスケッチのままですがまぁいいことにしましょう。
そしたらさっきみたいな方法で書き込んだら大丈夫です。
うまく行ってたらこんな感じになるはずです。
いい感じ pic.twitter.com/op6w5zXjMb
— Jun (@jun_robot) 2021年6月26日
そしたら、スマホやタブレットをESP32にしていきましょう。まずは、受信側(今使ってた方)のMACアドレスを調べます。さっきのアプリでDeviceってとこをみると確認することが出来ます。
40:f5:20:53:**:**
みたいなのがわかったらOKです。ちなみにこのプログラムでも調べられます。
もちろん「**」のところは任意の文字列です。
void setup(void) { Serial.begin(115200); Serial.println("-----------------"); uint8_t macBT[6]; esp_read_mac(macBT, ESP_MAC_BT); Serial.printf("%02X:%02X:%02X:%02X:%02X:%02X\r\n", macBT[0], macBT[1], macBT[2], macBT[3], macBT[4], macBT[5]); } void loop() { delay(1000); }
そしたらそのMACアドレスを下記のプログラムに書いて送信側のESP32に書き込みます。
2箇所あるので気をつけてください。
#include "BluetoothSerial.h" BluetoothSerial SerialBT; String MACadd = "40:f5:20:53:**:**"; uint8_t address[6] = {0x40, 0xf5, 0x20, 0x53, 0x**, 0x**}; bool connected; void setup() { Serial.begin(115200); SerialBT.begin("ESP32test", true); Serial.println("device start"); connected = SerialBT.connect(address); if(connected) { Serial.println("Connect OK"); } else { while(!SerialBT.connected(10000)) { Serial.println("No connect"); } } if (SerialBT.disconnect()) { Serial.println("Disconnected Succesfully!"); } SerialBT.connect(); pinMode(15, INPUT_PULLUP); } void loop() { if (digitalRead(15) == LOW) { Serial.println("LED is ON."); SerialBT.write('T'); } if (digitalRead(15) == HIGH) { Serial.println("LED is OFF."); SerialBT.write('L'); } delay(20); }
これが出来たら、一方向通信は完成です。こんな感じになっていますかね?
昨日からやってたESP32でbluetooth 通信できた!
— Jun (@jun_robot) 2021年6月26日
次は相互通信
左:送信側 右:受信側 pic.twitter.com/iefGzvFbXG
Bluetoothで双方向無線通信
それでは、目標の双方向通信やっていきましょう。これは、大して難しくないです。
さっきまでのプログラムでペアリングするところが書かれているので、loop内のプログラムは、普通のシリアル通信と何ら変わりないかんじです。
まぁ一応プログラム書いておきます。
マスター側
#include "BluetoothSerial.h" BluetoothSerial SerialBT; String MACadd = "40:f5:20:53:61:9e"; uint8_t address[6] = {0x40, 0xf5, 0x20, 0x53, 0x61, 0x9e}; bool connected; void setup() { Serial.begin(115200); SerialBT.begin("ESP32test", true); Serial.println("device start"); connected = SerialBT.connect(address); if(connected) { Serial.println("Connect OK"); } else { while(!SerialBT.connected(10000)) { Serial.println("No connect"); } } if (SerialBT.disconnect()) { Serial.println("Disconnected Succesfully!"); } SerialBT.connect(); pinMode(13, OUTPUT); pinMode(15, INPUT_PULLUP); } char databox; void loop() { if (digitalRead(15) == LOW) { Serial.println("LED is ON."); SerialBT.write('T'); } if (digitalRead(15) == HIGH) { Serial.println("LED is OFF."); SerialBT.write('L'); } if (SerialBT.available()) { databox = SerialBT.read(); Serial.println(databox); if (databox == 'L') { digitalWrite(13, LOW); } if (databox == 'T') { digitalWrite(13, HIGH); } } delay(20); }
スレーブ側
#include "BluetoothSerial.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; void setup() { Serial.begin(115200); SerialBT.begin("ESP32test"); Serial.println("device start"); pinMode(13, OUTPUT); pinMode(15, INPUT_PULLUP); } char databox; void loop() { if (digitalRead(15) == LOW) { Serial.println("LED is ON."); SerialBT.write('T'); } if (digitalRead(15) == HIGH) { Serial.println("LED is OFF."); SerialBT.write('L'); } if (SerialBT.available()) { databox = SerialBT.read(); Serial.println(databox); if (databox == 'L') { digitalWrite(13, LOW); } if (databox == 'T') { digitalWrite(13, HIGH); } } delay(20); }
まぁこんなかんじです。これは、動画を撮ってないので動画はなしです。
まとめ
そんなこんなでBluetooth無線通信が出来ました。電源をつけたら2秒ほどでペアリングされ通信可能になるのでとてもいい感じです。
ESP32はArduinoより計算速度も早くてピン数も多いのでメインマイコンとしてありだなと思ったりしています。これだけすごくて400円で買えるってコスパ最高です。
今回の記事はこれで終わりです。何か質問などありましたら、コメントやTwitterのDM(@jun_robot か @All_outlook)までお願いします。
実は、この記事「アラバマ物語」っていう映画を見ながら書きました。なんか学校の課題で見て感想文をかいっていうのがあったのでみてました。
感想としては、あんまり良くわからなかったのですが、酷い人種差別があったんだなーぐらいのことはわかりました。まぁもう少し良く考えて感想文書いていきたいなと思ってます。
何度も言ってますがテストが終わったのでいろいろやっていきたいなーっと思ってます!
てか、11時頃に始めたのに気付いたら3時ですね。まぁ明日(今日かな?)は学校休みなので問題なしです。
では、また今度 。