加速度センサーでモーターカーを無線操作|ESP-NOWで傾きを送信しよう
前回は、2台のKUMITATE-C3を使ってESP-NOWでモーターカーを無線操作しました。
リモコン側の4つのボタンに、
- 前進
- 後退
- 左旋回
- 右旋回
を割り当て、押したボタンの情報をモーターカー側へ送信する仕組みです。
今回はさらに発展させて、ボタンを使わず、コントローラーそのものを傾けてモーターカーを操作してみましょう。
リモコン側にはKUMITATE-SENSORを接続します。
KUMITATE-SENSORに搭載された加速度センサーでコントローラーの傾きを検出し、その情報をESP-NOWでモーターカーへ送信します。
たとえば、
前へ傾ける → 前進
後ろへ傾ける → 後退
左へ傾ける → 左旋回
右へ傾ける → 右旋回
という直感的な操作ができる無線コントローラーを作ります。
今回作るもの
システム全体は次のようになります。
【コントローラー側】
KUMITATE-C3
│
KUMITATE-SENSOR
│
加速度センサー
│
傾きを検出
│
│ ESP-NOW
▼
【モーターカー側】
KUMITATE-C3
│
KUMITATE-MOTOR
│
├─ 左DCモーター
└─ 右DCモーター
前回はボタンの状態をESP-NOWで送信しました。
今回は加速度センサーで取得した値から操作方向を判断し、その結果をESP-NOWで送信します。
つまり、
センサー入力 → 判定 → 無線通信 → モーター出力
までをひとつにつないだシステムになります。
ESP-NOWの基本はこちら
この記事ではESP-NOWそのものの初期設定については詳しく説明しません。
ESP-NOWを初めて使用する場合は、先にこちらの記事を確認してください。
ESP-NOWとは?ESP32同士で無線通信する方法を初心者向けに解説

ESP-NOWの基本的な送受信ができたら、今回の作例へ進みましょう。
ボタン操作版はこちら
ESP-NOWでモーターカーを操作する基本的な仕組みについては、ボタン操作版の記事でも紹介しています。
ESP-NOWでモーターカーを無線操作|KUMITATE-C3のボタンで前後左右に動かそう

最初にボタン操作版を作っておくと、
ボタン入力を加速度センサーへ置き換えた
と考えられるので、今回の仕組みが理解しやすくなります。
用意するもの
今回は主に次のものを使用します。
コントローラー側
- KUMITATE-C3 × 1
- KUMITATE-SENSOR × 1
モーターカー側
- KUMITATE-C3 × 1
- KUMITATE-MOTOR × 1
- DCモーター × 2
- 車体・タイヤ
- モーター用電源
合計2台のKUMITATE-C3を使用します。
加速度センサーで傾きが分かる
KUMITATE-SENSORには加速度センサーが搭載されています。
加速度センサーでは、X・Y・Zの各方向にかかる加速度を測定できます。
コントローラーを静止させている場合でも、地球の重力が加わっています。
そのため、コントローラーの向きを変えると、各軸で検出される重力加速度の割合が変化します。
この変化を利用すると、
どちらの方向へ傾けているのか
を判断できます。
今回は複雑な姿勢計算を行わず、X軸とY軸の値を使って操作方向を判定します。
傾きとモーターカーの動きを対応させる
まず操作方法を決めましょう。
たとえば、
| コントローラー | モーターカー |
|---|---|
| 水平 | 停止 |
| 前へ傾ける | 前進 |
| 後ろへ傾ける | 後退 |
| 左へ傾ける | 左旋回 |
| 右へ傾ける | 右旋回 |
とします。
考え方は前回の4ボタンとほぼ同じです。
違うのは、
どのボタンが押されたか
ではなく、
どちらへ傾いているか
から操作命令を決めるところです。
しきい値を決める
加速度センサーの値は常に完全な0になるわけではありません。
水平に置いていても多少値が変動します。
そこで、
少し傾いた程度 → 停止
一定以上傾いた → 動作
となるようにしきい値を設定します。
たとえば概念的には、
const float THRESHOLD = 0.3;
として、
Y > 0.3 → 前進
Y < -0.3 → 後退
X > 0.3 → 右旋回
X < -0.3 → 左旋回
のように判定します。
実際の符号や軸方向は、KUMITATE-SENSORの取り付け方向によって変わります。
最初にシリアルモニターへX・Y・Zの値を表示し、実際に前後左右へ傾けて確認しておきましょう。
停止する範囲を作る
傾き操作では、中央付近に何もしない範囲を作ることが重要です。
たとえばXとYが、
-0.3 ~ +0.3
の範囲に入っている場合は停止とします。
このような範囲は一般にデッドゾーンと呼ばれます。
デッドゾーンがないと、コントローラーを水平に持っているつもりでもセンサー値のわずかな変化によってモーターカーが勝手に動いてしまうことがあります。
今回は、
中央付近 → STOP
大きく傾ける → 動作
という構成にします。
操作命令を定義する
ボタン操作版と同じように、操作命令を定義します。
enum Command {
STOP = 0,
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
これによって、センサー値そのものではなく、
STOP
FORWARD
BACKWARD
LEFT
RIGHT
という操作命令をESP-NOWで送信できます。
この方法なら、モーターカー側は操作方法がボタンなのか加速度センサーなのかを意識する必要がありません。
ここは今回のシステムの重要なポイントです。
コントローラー側の処理
コントローラー側では次の処理を繰り返します。
加速度を取得
↓
X・Yの値を確認
↓
傾いている方向を判定
↓
Commandへ変換
↓
ESP-NOWで送信
たとえば、
Command getCommand(float x, float y) {
if (y > THRESHOLD) {
return FORWARD;
}
if (y < -THRESHOLD) {
return BACKWARD;
}
if (x < -THRESHOLD) {
return LEFT;
}
if (x > THRESHOLD) {
return RIGHT;
}
return STOP;
}
とすれば、X・Yの値から操作命令へ変換できます。
※実際の軸方向や符号はセンサーの向きに合わせて調整してください。
なぜセンサー値をそのまま送らないの?
もちろん、
X = 0.52
Y = -0.14
Z = 0.84
のような加速度センサーの値そのものをESP-NOWで送ることもできます。
しかし今回は、コントローラー側で、
センサー値 → 操作命令
へ変換してから送信します。
こうすると受信側は、
FORWARDが来た → 前進
LEFTが来た → 左旋回
と単純に処理できます。
さらに、操作方法を変更してもモーターカー側のプログラムをほとんど変更する必要がありません。
たとえば、
4ボタン
から
加速度センサー
へ変えても、最終的に同じCommandを送れば受信側はそのまま利用できます。
入力方法と出力方法を分けて設計することで、プログラムを再利用しやすくなります。
ESP-NOWで操作命令を送信する
操作命令が決まったら、ESP-NOWでモーターカー側へ送信します。
Command command = getCommand(x, y);
esp_now_send(
receiverAddress,
(uint8_t *)&command,
sizeof(command)
);
これを一定間隔で繰り返します。
たとえば50msごとに送信すれば、コントローラーの傾きに比較的素早く反応できます。
delay(50);
モーターカー側はボタン操作版とほぼ同じ
今回面白いところがここです。
モーターカー側のプログラムは、前回作ったボタン操作版からほとんど変更する必要がありません。
受信するデータが、
FORWARD
BACKWARD
LEFT
RIGHT
STOP
であることは同じだからです。
受信した命令を、
switch (command) {
case FORWARD:
forward();
break;
case BACKWARD:
backward();
break;
case LEFT:
turnLeft();
break;
case RIGHT:
turnRight();
break;
default:
stopAll();
break;
}
と処理します。
つまり、
【ボタン操作版】
ボタン
↓
Command
↓
ESP-NOW
【傾き操作版】
加速度センサー
↓
Command
↓
ESP-NOW
となり、その先は共通です。
通信が途切れたら停止する
今回も、無線通信が途切れた場合にはモーターを停止するようにしておきましょう。
モーターカー側で最後に受信した時刻を保存します。
unsigned long lastReceiveTime = 0;
データを受信したら、
lastReceiveTime = millis();
と更新します。
そして、
if (millis() - lastReceiveTime > 500) {
stopAll();
}
とすれば、500ms以上通信が途切れた場合に自動停止できます。
コントローラーの電源が切れたり、通信できなくなったりしたときにモーターが回り続けることを防げます。
傾きの大きさで速度を変えることもできる
ここまでは、
一定以上傾けたら前進
というON/OFF的な操作でした。
しかし加速度センサーからは、傾きの大きさも取得できます。
そこで、
少し傾ける → ゆっくり進む
大きく傾ける → 速く進む
という制御にも発展できます。
たとえば加速度の値をPWM値へ変換します。
概念的には、
傾き 小
↓
PWM 小
↓
低速
傾き 大
↓
PWM 大
↓
高速
という関係です。
これまで学習したPWMによるDCモーターの速度制御が、ここで再び使えます。
単に方向だけを操作するのではなく、コントローラーの傾け方によって速度まで変えられるようになります。
斜めに傾けたらどうする?
今回の単純なプログラムでは、X軸またはY軸のどちらかを使って、
- 前
- 後ろ
- 左
- 右
の4方向を判定しています。
さらに発展させるなら、X軸とY軸を同時に利用できます。
たとえば、
前+右へ傾ける
と、
前進しながら右へ曲がる
ようにできます。
その場合は左右のモーターのPWM値を個別に変えます。
コントローラーの傾きを、
左右モーターの速度
へ直接対応させるわけです。
ここまで行くと、単純な4方向リモコンからかなり滑らかな操作ができるコントローラーになります。
KUMITATE-SENSORとKUMITATE-MOTORを組み合わせる
今回の作例では、2種類のKUMITATE拡張基板を使用しています。
コントローラー側では、
KUMITATE-C3
+
KUMITATE-SENSOR
を使用して傾きを検出します。
モーターカー側では、
KUMITATE-C3
+
KUMITATE-MOTOR
を使用して左右のDCモーターを制御します。
そして2台のKUMITATE-C3をESP-NOWで接続します。
つまり、
センサー
↓
I²C
↓
マイコン
↓
ESP-NOW
↓
マイコン
↓
GPIO / PWM
↓
モータードライバ
↓
DCモーター
という一連の流れになります。
ひとつの作例の中で、
- I²C
- センサー
- 条件分岐
- ESP-NOW
- GPIO
- PWM
- モータードライバ
- DCモーター
といった複数の技術を組み合わせることができます。
「センサーで測る」から「センサーで動かす」へ
センサーの学習では、最初は取得した値をシリアルモニターへ表示することが多いと思います。
たとえば、
X = 0.12
Y = 0.74
Z = 0.65
と表示して、
「加速度を取得できた」
というところから始めます。
しかし今回の作例では、その値を実際の機械の動作につなげます。
傾きを測る
↓
意味を判断する
↓
無線で伝える
↓
モーターを動かす
センサーから取得した情報によって実世界の機械を制御する、組み込みシステムらしい作例になります。
KUMITATE-SENSOR
今回コントローラー側で使用するKUMITATE-SENSORには、温湿度・照度・3軸加速度の3種類のセンサーが搭載されています。
今回使用するのは、3軸加速度センサー「MSA3S02」です。
X・Y・Z方向の加速度を取得できるため、基板の傾きや動きを検出できます。
この記事では、KUMITATE-C3とKUMITATE-SENSORを組み合わせ、取得した傾きの情報をモーターカーの操作に利用します。
センサーの値を単に表示するだけではなく、
傾きを測る
↓
操作方向を判定する
↓
ESP-NOWで送信する
↓
モーターカーを動かす
というところまで発展させます。
▶ KUMITATE-SENSORの詳細はこちら
https://kumicla.tatepro.com/asp-products/kumitate-sensor/
KUMITATE-MOTOR
モーターカー側ではKUMITATE-MOTORを使用します。
KUMITATE-C3から左右のDCモーターを制御し、
- 正転・逆転
- 前進・後退
- 左右旋回
- PWMによる速度制御
などを試すことができます。
▶ KUMITATE-MOTORの詳細はこちら
https://kumicla.tatepro.com/asp-products/kumitate-motor/
まとめ
今回は加速度センサーとESP-NOWを組み合わせて、コントローラーを傾けることでモーターカーを無線操作する仕組みを紹介しました。
全体の流れは、
コントローラーを傾ける
↓
加速度センサーでX・Yを取得
↓
前後左右を判定
↓
ESP-NOWで操作命令を送信
↓
別のKUMITATE-C3で受信
↓
KUMITATE-MOTORを制御
↓
モーターカーが動く
となります。
今回のポイントは、
- 加速度センサーでコントローラーの傾きを検出する
- しきい値とデッドゾーンを使って誤動作を防ぐ
- センサー値を操作命令へ変換する
- ESP-NOWで別のKUMITATE-C3へ送信する
- ボタン操作版と同じ受信側プログラムを再利用できる
- 傾きの大きさをPWMへ変換すれば速度制御にも発展できる
というところです。
これまで個別に学んできたセンサー・I²C・無線通信・GPIO・PWM・モーター制御を組み合わせることで、ひとつのシステムとして動かせるようになりました。
マイコンでは、それぞれの機能を単独で動かすだけでなく、複数の技術を組み合わせることでできることが大きく広がります。

