1.BluetoothでLチカ制御
前回、Bluetoothでの双方向通信に成功しましたので、ついでに少しスケッチを修正してスマホからESP32のLチカを制御した様子が以下の動画です。
撮影が悪くて画面が良く見えませんが、"1"を送信してESP32上の青色LED(LED0)を点灯、"0"で消灯です。LEDの載ってないボードの場合は、適当なLチカ回路を組んでみましょう。
2.改良スケッチ
Lチカ用に改良したスケッチは以下の通りです。
Arduino IDEでESP32の動作テストの際と同様、基板上のLED0を点灯させています。
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
int outpin = 2;
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32");
pinMode(outpin, OUTPUT);
}
void loop() {
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
char SW = SerialBT.read();
if (SW == '1'){
Serial.print("input char is ");
Serial.print(SW);
Serial.println(" / LED ON.");
digitalWrite(outpin,HIGH);
}
else if (SW == '0'){
Serial.print("input char is ");
Serial.print(SW);
Serial.println(" / LED OFF.");
digitalWrite(outpin,LOW);
}
}
delay(20);
}
3.便利なシリアル通信コントローラアプリ
「Serial Bluetooth Terminal」もとても便利なのですが、ESP32へ定型のコマンドを送るには少々面倒です。そこで「ボタンを押したらLED ON」の様な操作が出来るようなアプリをつくろうかな・・・・と思っていたら、便利なアプリを見つけてしまったのでこちらを使います。(Android studioもインストールしてやる気まんまんだったのですが。。)
使用したのは「BlueTooth Serial Controler」です。
操作画面は次の通りで、CONNECTからESP32と接続し、PREFERENCEから各ボタンにコマンドを割り付けます。今回は左上のボタンの名前を「ON」にしてコマンドは"1"、一つ右のボタン名を「OFF」にして"0"を割り付けました。
それぞれのボタンでLEDの制御が出来ています。
まだ試していませんが、他にもたくさんの機能が実装されていますので、当面はこのアプリで事足りそうです。
4.ついでにPWMでLチカも
ロボット制御の事を考えると、PWM制御の事も確認しておきたいので、PWMを使ったLEDの照度コントロールも試しておきました。Arduinoでは、servo.hというライブラリを使用していましたが、ESP32ではledcWrite()と言う関数が使えます。
使うLEDはいつものLED0ですが、ledcWrite()を使う際はアナログ出力を使用するため、ピン番号は2では無くA12となります。下のESP-WROOM-32のピンアウト図を見るとGPIOのピン2がアナログのA12と共有されていることが判ります。
ledcWrite()の使い方だけ簡単に説明しておきます。
- ledcSetup(chan,freq,bit_num)でチャンネルのパラメータを定義。chanはPWM制御を使うチャンネル番号で、同時に16チャンネル、0~15が使用出来ます。freqはPWM周波数、最大312.5KHz。bit_numはデューティ比設定の分解能で最大8ビット(256段階)です。
- ledcAttachPin(pin,chan)でPWM制御するピンを指定。選択したpinにledcSetupで指定した設定が適用されます。
- ledcWrite(chan,duty)で明るさを指定して点灯。指定したchanをdutyに設定した値に対応したduty比で点灯させます。dutyはbit_numで指定した値しか取れませんので、bit_numが8の場合は0~255、bit_numが7であれば0-127・・・となります
詳細はこちらのサイトに詳しく載っています。
これを踏まえたうえで、BluetoothからONにするとPWM制御でLEDが点滅するスケッチを書いてみました。
//スマホからの通信でLEDをPWM点灯させる
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
const int outpin = A12
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32");
ledcSetup(0,12800,8);
ledcAttachPin(outpin,0);
}
void loop() {
static int brightness = 0;
static int diff = 1;
static char SW = 0;
ledcWrite(0, brightness);
if (SerialBT.available()) {
SW = SerialBT.read();
Serial.println(SW);
}
if (SW == '1'){
if (brightness == 0) {
diff = 1;
} else if (brightness == 255) {
diff = -1;
}
brightness += diff;
}
else if (SW == '0'){
brightness = 0;
}
delayMicroseconds(1000); //1000で点滅サイクル約0.5sec、100で0.05sec、10だと0.005secなので点滅に見えない。
}
6.ledcWriteの限界?
ledcWrite関数でサーボもコントロールできそうなのですが、気になったのがbit_numで定義するデューティ比の分解能です。最大値の8bitとした場合でも256段階にしかなりません。
一方、servo.hでは、周期20msecのPWM信号に対してµsec単位でパルス幅を設定できます。これは20000段階でのデューティ比制御に等しく、ledcWriteで同程度の制御を行う場合は、14bit(16384段階)もしくは15bit(32768段階)に相当します。
ここまで理解したところでledcWrite関数は使えないかなと思いかけたのですが、こちらのサイトで最大16bitの精度で制御を行う方法が紹介されていました。大変参考になります。これならサーボ制御にも問題は無いでしょう。
7.まとめ
ESP32の簡単な使い方は見えてきました。ついでにサーボ制御のテストもやっておこうか、四足ロボットの製作記録も更新したいし、プリメイドAIも3台ゲットしたのに手を付けられていない。。。。