前回の記事で、ドローンの電子部品選定を行いました。本記事ではこれに基づき、ブレッドボードによる試験を行っていきます。
ピン配置
ピンの役割等についてはこちらのサイトが参考になります。IMU, optical flow, ToF センサの 3 種類のセンサと 6 つのモータのピン配置を以下のように定めます。
PIN | ESP32 In/Out | デバイス | 説明 |
5V | – | DCDC converter | 5V に昇圧された電圧を印加 |
GPIO 21 | – | IMU (SDA) | I2C データ入出力 |
GPIO 22 | – | IMU (SCL) | I2C クロック |
GPIO 5 | – | optical flow (CS0) | SPI チップセレクト |
GPIO 18 | – | optical flow (SCK) | SPI クロック |
GPIO 23 | – | optical flow (MOSI) | SPI マスター → スレーブ(データ送信) |
GPIO 19 | – | optical flow (MISO) | SPI スレーブ → マスター(データ受信) |
GPIO 21 | – | ToF (SDA) | I2C データ入出力 |
GPIO 22 | – | ToF (SCL) | I2C クロック |
GPIO 32 | Out | motor | モータ 1 |
GPIO 33 | Out | motor | モータ 2 |
GPIO 25 | Out | motor | モータ 3 |
GPIO 26 | Out | motor | モータ 4 |
GPIO 27 | Out | motor | モータ 5 |
GPIO 14 | Out | motor | モータ 6 |
GPIO 36 | In | tactile switch | デバッグ用スイッチ |
GPIO 12 | Out | LED | デバッグ用 LED |
以下の記述により、GPIO 7, 8, 9, 10, 11 (D0, D1, D2, D3, CMD に対応するピン) の使用は避けた方がよさそうです。ESP32-WROVER を使う場合は、GPIO 16, 17 も使わない方がよいようです。
The pins D0, D1, D2, D3, CMD and CLK are used internally for communication between ESP32 and SPI flash memory. They are grouped on both sides near the USB connector. Avoid using these pins, as it may disrupt access to the SPI flash memory / SPI RAM.
ESP32-DevKitC V4 Getting Started Guide
The pins GPIO16 and GPIO17 are available for use only on the boards with the modules ESP32-WROOM and ESP32-SOLO-1. The boards with ESP32-WROVER modules have the pins reserved for internal use.
ESP32-DevKitC V4 Getting Started Guide
回路図
以下のように ESP32-DevKitC V4 ボードと各部品を接続します。

必要部品
ブレッドボードでの実験には、以下を用意します。
部品 | 個数 | 備考 |
ブレッドボード | 2 | ESP32-DevKitC V4 が幅広なため、2 つのブレッドボードを横につなげる必要がある |
ESP32-DevKitC V4 | 1 | |
5V 出力昇圧 DCDC コンバーター | 1 | ESP32-DevKitC V4 は 5V の入力電圧を必要とするため。 |
タクトスイッチ | 1 | デバッグ用 |
抵抗 5.1kΩ | 1 | タクトスイッチ用 pull down 抵抗 |
LED | 1 | デバッグ用 |
抵抗 220Ω | 1 | LED 用の抵抗 |
モータ | 6 | 8.5 x 20mm ブラシモータを使用 |
Nch MOSFET 2SK4017 | 6 | モータに大電流を流すため(ESP32 の GPIO は 40mA までしか流せない)。 |
ショットキーダイオード 1S4 | 7 | ・スイッチオフ時にモータに生じる逆起電力から MOSFET を守る(参考)。 ・逆流防止用に DCDC コンバータに接続。 |
抵抗 100Ω | 6 | ゲート抵抗(ゲートの入力容量への充放電電流の制限: 参考) |
抵抗 10kΩ | 6 | ゲート・ソース間抵抗(FET のゲートがフローティングして回路が誤動作してしまうことを避けるため: 参考) |
コンデンサ 22uF | 6 | モータ用のバイパスコンデンサ(ノイズや電圧変動を抑制して動作を安定化する: 参考) |
BNO055 モジュール | 1 | 9 軸 IMU センサ |
VL53L1X モジュール | 1 | ToF センサ |
PMW3901 モジュール | 1 | オプティカルフローセンサ |
ESP32
以下を接続します。
- モータ 6 つ
- デバッグ用 switch
- デバッグ用 LED
- IMU センサ
- ToF センサ
- オプティカルフローセンサ
DCDC converter
秋月電子で販売されている DCDC コンバータを使います。
+BATT は電池ボックスや 1s リポバッテリなどです。+BATT から DCDC converter を通して 5V の安定化された電圧を ESP32 に供給します。
逆流防止用に、順方向に 1.0A まで電流を流せて順方向電圧が 0.5V のショットキーダイオード 1S4 を導入しました。500mA 程度が推奨される power supply と書いてあるので最大電流が 1.0A のダイオードを接続しても問題なさそうです。
The operating voltage of ESP32 ranges from 2.3 V to 3.6 V. When using a single-power supply, the recommended voltage of the power supply is 3.3 V, and its recommended output current is 500 mA or more.
https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
DCDC コンバータ | ESP32 | 説明 |
OUT | 5V | ESP32 の電源入力 |
GND | GND | GND |
IN | – | +BATT から DCDC コンバータへの電源入力 |
IMU
秋月電子で販売されている BNO055 使用 9 軸センサーモジュールを使用します。
I2C 通信で ESP32 とデータを送受信します。Arduino ライブラリは Adafruit_BNO055
を使います。
BNO055 | ESP32 | 説明 |
SDA | GPIO 21 (SDA) | データ入出力 |
SCL | GPIO 22 (SCL) | クロック |
VIN | 3V3 | 電源 |
GND | GND | GND |
Motor
モータの選定については前回記事をご覧ください。8.5mm x 20mm のモータを使うことにしています。
それぞれの電子部品の役割については過去記事で詳解しています。前回ドローンを自作した際、市販のモータドライバだと最大出力電流が足りなかったという経緯があり、下図のように Nch MOSFET でモータドライバを自作しています。
ESP32 の GPIO ピンから PWM 入力をしてモータの回転量を制御します。
オプティカルフローセンサと ToF センサの再選定
前回の記事で、ATK-PMW3901 というオプティカルフローセンサと ToF センサが合わさったモジュールを紹介しましたが、以下の問題がありました。
- オプティカルフローセンサのデータが時々更新されない
- ToF センサを ESP32 が認識できない
なので、別のモジュールを選定することにしました。選定結果は以下で、marutsu が品質ランク S1 と定めているものを今回は購入しました。
製造元 | 内蔵センサ | 商品コード | 購入元 | 備考 |
Pimoroni | PMW3901 | PIM453 | marutsu | |
Pololu | VL53L1X | POLOLU-3415 | SWITCH SCIENCE | 動作確認記事 |
Adafruit のこのモジュールも購入しましたが、今回のブレッドボード試験では上記の 2 つを使用しました(Adafruit 公式動作確認記事)。
ToF センサ(VL53L1X)
以下の記事が非常にわかりやすかったので、配線や書き込み方法等でわからない点があれば参照してもらえればと思います。
配線を以下のようにつなぎます。VL53L1X
という Arduino のライブラリを使います。
POLOLU-3415 | ESP32 | 説明 |
SDA | GPIO 21 (SDA) | データ入出力 |
SCL | GPIO 22 (SCL) | クロック |
VIN | 5V | 電源 |
GND | GND | GND |
オプティカルフローセンサ(PMW3901)
このモジュールは SPI 通信でデータを送受信します。Arduino ライブラリは Bitcraze_PMW3901
を使います。
PIM453 | ESP32 (VSPI) | 説明 |
3V-5V | 5V | 電源 |
CS | GPIO 5 (VSPICS0) | チップセレクト |
SCK | GPIO 18 (VSPICLK) | SPI クロック |
MOSI | GPIO 23 (VSPID) | マスター → スレーブ(データ送信) |
MISO | GPIO 19 (VSPIQ) | スレーブ → マスター(データ受信) |
GND | GND | GND |
ソフトウェア
ライブラリ
以下の 3 つのライブラリをインストールする必要があります。
- Adafruit BNO055 by Adafruit
- Bitcraze PMW3901 by Bitcraze
- VL53L1X by Pololu
ソースコード
全体のソースコードは GitHub にてご覧ください。
setup()
関数の中で、モータと IMU, ToF, オプティカルフローセンサの準備を行います。
// motor
pinMode(MOTOR1_PWM_PIN, OUTPUT);
pinMode(MOTOR2_PWM_PIN, OUTPUT);
pinMode(MOTOR3_PWM_PIN, OUTPUT);
pinMode(MOTOR4_PWM_PIN, OUTPUT);
pinMode(MOTOR5_PWM_PIN, OUTPUT);
pinMode(MOTOR6_PWM_PIN, OUTPUT);
// initialize IMU sensor
while (!bno.begin())
{
Serial.println("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
}
// initialize ToF sensor
vl53l1x.setTimeout(500);
while (!vl53l1x.init()) {
Serial.println("Ooops, no VL53L1X detected ... Check your wiring or I2C ADDR!");
}
vl53l1x.setDistanceMode(VL53L1X::Long);
vl53l1x.setMeasurementTimingBudget(50000);
vl53l1x.startContinuous(50);
// initialize optical flow sensor
while (!pmw3901.begin())
{
Serial.println("Ooops, no PMW3901 detected ... Check the SPI connection!");
}
タクトスイッチが押されたら LED を点灯し、モータを回します。
// turn on motors when a switch is pressed
int motor_pwm = 255;
if (util.is_builtin_button_pressed()) {
util.on_led();
analogWrite(MOTOR1_PWM_PIN, motor_pwm);
analogWrite(MOTOR2_PWM_PIN, motor_pwm);
analogWrite(MOTOR3_PWM_PIN, motor_pwm);
analogWrite(MOTOR4_PWM_PIN, motor_pwm);
analogWrite(MOTOR5_PWM_PIN, motor_pwm);
analogWrite(MOTOR6_PWM_PIN, motor_pwm);
} else {
util.off_led();
analogWrite(MOTOR1_PWM_PIN, 0);
analogWrite(MOTOR2_PWM_PIN, 0);
analogWrite(MOTOR3_PWM_PIN, 0);
analogWrite(MOTOR4_PWM_PIN, 0);
analogWrite(MOTOR5_PWM_PIN, 0);
analogWrite(MOTOR6_PWM_PIN, 0);
}
以下のコードでセンサの出力を Serial monitor で表示できるようにします。
// ToF sensor
Serial.print("ToF sensor output: ");
Serial.print(vl53l1x.read());
Serial.println("mm");
// imu
sensors_event_t accelerometerData, angVelocityData;
bno.getEvent(&accelerometerData, Adafruit_BNO055::VECTOR_ACCELEROMETER);
bno.getEvent(&angVelocityData, Adafruit_BNO055::VECTOR_GYROSCOPE);
util.printIMUEvent(&angVelocityData);
util.printIMUEvent(&accelerometerData);
uint8_t system, gyro, accel, mag = 0;
bno.getCalibration(&system, &gyro, &accel, &mag);
// optical flow sensor
int16_t dx, dy;
pmw3901.readMotionCount(&dx, &dy);
Serial.print("Optical Flow sensor output: dx: ");
Serial.print(dx);
Serial.print(" dy: ");
Serial.println(dy);
実際に以下のように Serial monitor でセンサーデータの出力を確認できます。
ToF sensor output: 158mm
IMU data: Gyro: x= 0.00 | y= 0.00 | z= -0.00
IMU data: Accl: x= 0.02 | y= 0.21 | z= -0.01
Optical Flow sensor output: dx: 0 dy: 0
実験
今回の実験では、以下を確認しました。
- スイッチを押すと LED が光り、モータが回る
- 6 つモータを回すと電力が足りないのか、ESP32 の電源が突然切れることがある
- 5 つのモータであれば問題ない
- スイッチを押していないときはモータは回らない
- ブレッドボードを振ったときに、BNO055 で読み取った角速度・加速度の値が変化する
- オプティカルフローセンサで横移動を検出できる
- ToF センサによって計測された距離が大体あっている
- モータを回したときにセンサの出力が途切れないか
上記のそれぞれの項目が問題ないことを確認済みです。モータを回している動画は以下です。

まとめ
今回は、ブレッドボード上でドローンのプロトタイプを作成し、①モータが回ること②センサが意図通り機能することを確認しました。次回から PCB の制作に移っていきます!
コメント