スマホからサーボモータをPWM制御してみた!!

2023-01-02 · Tomoki Ikegami

"スマホアプリを自作して、ラジコン用サーボモータを無線操縦してみた"

~ 目次 ~


1. 今回やりたいこと

 いやぁ~(※)新年(2023)一発目の投稿ですね!!(※いやぁ~は東北とか北海道の人が使いがちみたいで、私もその一人です笑。特に深い意味はないです笑)

 今回はスマホからラジコン用サーボモータを操作します!

 スマホでスライダを操作し、その操作量に応じてサーボモータの角度をコントロールしました。

 これを作るにあたって、PWM制御シリアル通信という技術を使ったので、まずはその説明から始めます(^^)/

スマホからRCサーボを操作したい
☝ スマホからRCサーボを操作したい

2. 使った技術

2.1. PWM制御

 PWMというのは Pulse Width Modulation の頭文字を取ったものです。日本語に直すとパルス(Pulse)(Width)変調(Modulation)となります。と言われてもあんまりしっくり来ないと思うので、図を使って説明します!

 下の図がPWM制御のイメージ図です。このカクカクした波形をパルス波といいます。このパルス幅を変える(図中ではTonの幅を変える)ことで、サーボモータの角度を制御するのがPWM制御です。

 具体的には、ONになってるところのパルス幅を1000~2000[μs]の間(メーカによって異なる1が大体一緒)で変えて制御します。

 例えば、パルス幅が1000[μs]のときは右回転(角度:0°)、1500[μs]のときはニュートラル(角度:90°)、2000[μs]のときは左回転(角度:180°)となります。

RCサーボのPWM制御
☝ RCサーボのPWM制御

2.2. シリアル通信

 1本の(伝送)経路上にデータを順番に流して通信する方法です。送れるデータの種類やビット数など細かい話はあるのですが、ここではイメージのみを説明します。

 例えば、“ラジコン"という文字を送りたければ、まず"ラ"を送ってから、“ジ”、“コ”、“ン"と順番に送ります(同時に送らない)。一見効率が悪そうですが、高速通信が可能です。身近な場面では、USBやBluetoothの通信に使われています。

シリアル通信のイメージ
☝ シリアル通信のイメージ

3. 使ったもの

 作業にあたって使用したソフトとハードウェア(装置)を整理しておきます。

3.1. ソフトウェア

  1. MIT App Inventor(スマホアプリ作成)
  2. Arduino IDE(マイコン用のプログラム開発)
  3. KiCAD(回路図の作成)

3.2. ハードウェア

  1. 操縦用スマホ(送信機):Moto g pro(Android 12)
  2. マイコン(受信機):ESP32-WROOM-32E
  3. サーボモータ:Hitec DB777WP

(参考:以下の装置は、今回の話題でそこまで重要ではないです。)

4. 回路図

 ESP32(マイコンボード)とサーボモータの接続です。

 サーボモータには線が3本あります。サーボモータの電源(+)端子に6[V]、PWM信号線に5[V]が入るように自由に回路を組み立ててください。GND(-)は共通にしてください。

 サーボモータのPWM信号線は、ESP32の(PWMが使える)好きな端子に繋げてください。このとき、ESP32の端子番号は確認しておきます(プログラム書くときに使う)。

 ここでは例としてラジコン用のスピードコントローラー(ESC)から、サーボモータ用の6[V]電源を取る回路を載せておきます(‘ω’)/

サーボモータ&ESC制御用回路
☝ サーボモータ&ESC制御用回路(サーボモータの電源はESCから)

5. スマホアプリ

 MIT App Inventor を使って作ったスマホアプリです。

 スライダの位置によって、ラジコンカー側に送信するパルス幅を変化させます。パルス幅の値はBluetoothで無線送信します。

アプリ外観(デザイン編集タブ)
☝ アプリ外観(デザイン編集タブ)
アプリの中身(ブロック編集タブ)
☝ アプリの中身(ブロック編集タブ)

6. プログラム(ソースコード)

 Arduino IDEで作ったプログラムです。ラジコン側のESP32に書き込んで動かします。

 スマホから送られてきたパルス幅に応じて、サーボモータの角度をPWM制御で変化させます。スマホから送られてくるのは文字なので、数値に変換して制御に使ってます。

 プログラムの大まかな動きを説明すると、

  1. シリアル通信で、パルス幅を文字としてスマホから受信(パルス幅"1000"なら⇒'1’と'0’と'0’と'0’という文字として取得)
  2. 区切り文字(ここではセミコロン;)が来るまで文字を受信して、文字列に変換(‘1’と'0’と'0’と'0'⇒"1000”)
  3. 文字列を整数値に変換(“1000"⇒1000)
  4. 変換された数値でサーボモータをPWM制御

 シングルコーテーション(')は文字、ダブルコーテーション(")は文字列の意味です。

 PWM制御の方法2、文字列として受信して整数に変換する方法3 について紹介してくれている方に非常に感謝しています。ありがとうございます。


⇩⇩⇩ ソースコード ⇩⇩⇩
/**** アプリから受け取ったパルス幅でサーボを制御(サーボモータをPWM制御で動かしてみる。スマホアプリからサーボモータを操作)****/

/*ハードウェアの接続ピンの設定*/
#define SERVO_PWM_PIN 4    //サーボモータのPWMピン(信号入力ピン)をESP32の4番ピンに接続 ★回路と対応した番号にする

/*ライブラリ*/
#include "BluetoothSerial.h"  //ESP32のBluetooth通信に使用

/*変数の定義*/
int PWM_period = 20000;  //PWM周期をT=20000[μs]に設定
int CH1 = 1500;          //パルス幅Tonを1500[μs](中立)に設定。データシートにはLeft=900[μs]、Neutral=1500[μs]、Right=2100[μs]と記載されていた。(HiTEC DB777WP)

/*Bluetooth通信に必要*/
BluetoothSerial ESP_BT;  //ESP_BTという名前でオブジェクトを定義

void setup() {
  pinMode(SERVO_PWM_PIN, OUTPUT);     //サーボモータのピンへ、Arduinoから出力するように設定
  Serial.begin(115200);               //シリアルモニタで確認用。伝送速度を115200[bps]に設定
  ESP_BT.begin("ESP32_RC_Receiver");  //接続画面で表示される名前を設定 ★好きな名前にしてよい
}

/*PWM制御でサーボモータの角度を制御する関数*/
void change_ST_pos(int goal_pos) {
  /*20000[μs]周期で幅CH1[μs]のパルス波生成*/
  digitalWrite(SERVO_PWM_PIN, HIGH);  //PWMピンの電圧を5[V]に
  delayMicroseconds(goal_pos);        //パルス幅(goal_pos=900~2100[μs]:DB777WPの場合)
  digitalWrite(SERVO_PWM_PIN, LOW);   //PWMピンの電圧を0[V]に
  delayMicroseconds(PWM_period);      //制御周期(T=20000[μs])
}

void loop() {

  if (ESP_BT.available()) { //available()で受信した文字があるか確認。あればif文内の処理を実行。
    String input = ESP_BT.readStringUntil(';');  //文字をセミコロン(;)まで読んで、文字列として変数inputに保存。
    CH1 = input.toInt();  //文字列を整数値(int)に変換
    Serial.println(input); //数値をシリアルモニタに表示
  }

  change_ST_pos(CH1); //受信したパルス幅でサーボモータの角度を制御
}

7. 動作確認

 スマホのスライダを操作すると、それに応じてステア(ハンドル)が動いてます!

 スロットル(アクセル)も同時に操作できるようなれば、本格的なコントローラができそうです!!

8. サンプルファイル

 作成したアプリのデータはこちらになります。色々改良して遊んでみてください!

~ MIT App Inventorプロジェクトのファイル(.aia) ~

~ Androidアプリのファイル(.apk) ~

9. 参考文献


  1. Hori’s Library「サーボの動作原理」、(https://berry.sakura.ne.jp/technics/servo_control_p3.html↩︎

  2. ぶらり@web走り書き「【Arduino入門編⑧】サーボモーターを動かしてみる。PWM制御についていの解説です!」、(https://burariweb.info/electronic-work/arduino-learning/aruduino-servomotor-control.html↩︎

  3. メカトロDIYチャレンジ(Mechatro DIY Challenge)「スマホからBluetooth通信でArduinoを操作する②基本設計」、(https://mechadiy.com/bluetooth_phone_arduino_cont02/↩︎