LEGOとM5StickCとBlynkでラジコン作った。


はじめに

前回、M5StickC Plusで、サーボモータを制御してLEGOで作った車を動かした。
モータへの給電もM5StickCを使うことで、とってもすっきりしていい感じやった。

LEGOとM5StickCで動く車作った。 - Qiita

ただ、せっかくBluetoothとWi-Fi使えるM5Stick使ったので、ラジコン化することにした。
あと、せっかくディファレンシャルギア(まがるときに右左でいい感じに回転数変わる)使ったので、ステアリング用のサーボモータ追加して曲がれるようにした。

なにより、息子くんの尊敬を得るために、がんばることにした。


完成したやつの写真。息子くんアレンジ。

まがらせる

前後に動かすモータには360度まわるサーボモーターを使ってた。
今回、ステアリングのモータは270度角度を変えられるサーボモータを使った。
GeekServoの灰色のやつ。360度まわるサーボと同じようにPWMでかんたんに制御できる。いい感じ。

GeekServo 9G Servo-Gray - SWITCH-SCIENCE

M5StickCにサーボを2つつけるのどうしよか考える必要があった。5VとGNDを共有しないといけないので。
方法いくつかありそうやけど、よくあるピンからケーブル分岐させることにした。はんだ付けちょいむずやった。ピンをブレッドボードにさした状態ではんだすればよかった。プラスチック部分がとけて金属部分が傾いて、なおすのに時間かかった。ミスった。すこし格闘したあと、写真にある感じで落ち着いた。5VとGNDの部分。

あんまり安定してないけど、こんな感じで接続。

LEGOはこんな感じで固定した。ちょうどよいのがないので、無駄に灰色のギアの部品を使った。
車体の前につけたほうがいい感じに曲がれる気がするけど、息子くんアレンジ的に後ろにつけることにした。

これで、まがらせる準備できた。

ラジコン化

技術選定

ラジコン化も、選択肢多いけど、気軽にやりたかったので、Blynkってアプリつかった。昔、触ったことあったのと友人が使ってるの見ていい感じやったので。

Blynk IoT platform: for businesses and developers

ラズパイとかArduinoとかいろんなプラットフォームに対応してる、お気軽にマイコンとスマホをつなぐことができるサービス。制限ありで無料。
クラウドとアプリと各プラットフォームのライブラリで構成されてる。スマホ側でインターフェースをGUIで良い感じに設定して、マイコン側でライブラリ使っていい感じにデータを送ったり受けたりする。トークンを使ってスマホとマイコンを接続する。Wi-Fiも使えるけど、今回はBLEでつなぐことにした。

スマホ側

こんな感じで、部品を並べる。今回は、JOYSTICKとBLEのパーツ。

Joystickの設定はこんな感じ。outputは2つあって、M5Stick側の実装にあわせてる。
レンジを決めれるのがすごく便利。モーターの回転の向きもここであわせられるから、M5Stick側を気にしなくて良い。何回も書き込みしなくてすむのですごく楽。

AutoreturnはJoystickから手をはなしたときに真ん中に戻るやつで、Rotate on tiltはスマホの向きでx, yかわるやつ。

BLEのセッティングは特に不要。おくだけ。つなぐとき、Connect BLE deviceする。

こんな画面になる。

M5StickC側

M5StickCがわはこんな感じ。トークンをちゃんとしたやつに変えたら動く。
ExampleにあるESP32_BLE.inoを真似して書いた。

PWMは前回と同様、ledcWriteを使った。

ledcAttachPinのチャンネルはなぜか、2からしか動かない。0とか1だと動かない。M5StickCPlus.hを使うとそうなった。M5StickC.hだと0を指定しても動く。謎。中身読んだらわかるかもやけど、諦めた。イシューとしてあげといたほうがよいのか。気が向いたときにするか。

V1ってのが、アプリ側とそろえる必要のある変数。

#define BLYNK_PRINT Serial
#define BLYNK_USE_DIRECT_CONNECT

#include <BlynkSimpleEsp32_BLE.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include "esp32-hal-ledc.h"
#include <M5StickCPlus.h>

char auth[] = "YourAuthToken";

const int WIDTH_BIT = 10;
const int FREQ = 50;
const int SPEED_PIN = 26;
const int SPEED_CH = 2;
const int STEERING_PIN = 25;
const int STEERING_CH = 3;

void setup()
{
  Serial.begin(115200);
  Serial.println("Waiting for connections...");
  Blynk.setDeviceName("Blynk");
  Blynk.begin(auth);

  ledcSetup(SPEED_CH, FREQ, WIDTH_BIT);
  ledcAttachPin(SPEED_PIN, SPEED_CH);
  ledcSetup(STEERING_CH, FREQ, WIDTH_BIT);
  ledcAttachPin(STEERING_PIN, STEERING_CH);

  M5.begin();
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE);
  M5.Lcd.setCursor(20, 40, 2);
  M5.Lcd.print("SERVO");
}

void loop()
{
  Blynk.run();
}

BLYNK_WRITE(V1) {
  int16_t steering = param[0].asInt();
  int16_t speed = param[1].asInt();
  ledcWrite(SPEED_CH, speed);
  ledcWrite(STEERING_CH, steering);
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setCursor(20, 80, 2);
  M5.Lcd.print(speed);
  M5.Lcd.setCursor(20, 120, 2);
  M5.Lcd.print(steering);
  Serial.println(speed);
  Serial.println(steering);
}

完成

いい感じに操作できるようになった。

おわりに

Blynk使って、いい感じにスマホから操作できるようになった。いい感じ。
ただ、息子くん、あまり興味持たず。息子くんの尊敬得られず、失敗。
先日買ったLEGO BOOSTが完成度高すぎて、目が肥えてしまってる模様。ぐぬぬ。