TPTブログ

テックポート株式会社のブログです。 技術情報や製品・サービス情報、 また未経験社員がデータサイエンティストを 目指す奮闘記など、更新していきます。

M5Stackとスマホを連携させよう!

こんにちは、えーちゃんです。
M5Stackでミニカーを作る最終回ということで、今回はミニカーを操作するためのリモコンを作ります。
また、スマホをリモコンとして使えたらかっこいいですよね??
ということでBlynkというサービスを使ってスマホからM5Stackを操作しちゃいましょう!

開発環境

使用するM5StackはM5GO、開発環境はPlatformIO IDEです。

Blynkとは?

Blynkとは、マイコンボードとスマートフォン連携アプリを作るためのサービスです。
M5StackのほかにもRaspberry Piなど色々なマイコンボードが対応しています。
Blynkは基本料金無料で使用でき、使い方も簡単なことが魅力です。
詳細は以下の公式サイトからご確認ください。
blynk.io

Blynkでは、スマホとマイコンボード両方からアクセスできる内部変数を使ってアプリを操作します。
たとえばですがミニカーを走らせるアプリを作るとします。
そのためにミニカーが前進するか止まるかを表す変数MOVEを用意します。
スマホアプリ画面上に操作のためのジョイスティックを配置します。

変数MOVEはジョイスティックの倒される向きによって変化するように設定します。
ジョイスティックが前に倒れているときTrue、中央か後ろに倒れているときFalseを変数MOVEに代入させます。

マイコンボード側では、アプリと通信して変数MOVEの値を取得します。
変数MOVE=Trueならモーターを回してミニカーを走らせます。MOVE=Falseならモーターを止めます。

上記のような仕組みでBlynkアプリは動きます。
私の説明だけだと分かりにくいと思うので、まず実際にBlynkのチュートリアルをやってみましょう。

Blynkチュートリアルをやってみる

①Blynkアカウントを作成しよう
こちらよりBlynkのアカウントを作成しましょう。

②スマホ版Blynkアプリをインストール
スマホ版のBlynkアプリをインストールします。
このアプリを通して操作用画面を作ったり、マイコンボードを操作します。

③チュートリアル(QuickStart)にアクセス
アカウントを作成するとチュートリアル(QuickStart)が始まります。
ここでは案内に沿ってお試し用アプリを作成します。
スマホからでもできますがコードコピーの都合上PCから作業していただくのがおすすめです。
キャンセルしても以下のリンクからQuickStartを見ることができます。
Quickstart - Blynk Documentation

また、QuickStart用のアプリは、サイドメニューからいつでも作ることができます。


④マイコンボードの設定をしよう
QuickStartをはじめるとマイコンボードの種類を聞かれます。
M5Stackないじゃん!?と思うかもしれませんが大丈夫です。「ESP32」を選択しましょう。
「ESP32」とはM5Stackに使われている基板の名前です。
マイコンボードを選択すると通信方法が自動で入力されますので次に進みましょう。

⑤開発環境を選ぼう
開発環境を聞かれるので好きなものを選びます。
今回はPlatformioIDEを選びます。
次に進むとなにやらライブラリを追加しろという画面がでてきます。

⑥PlatformIOプロジェクトの準備をしよう
PlatformIOを使ってM5Stack用プロジェクトを作ります。
PlatformIOを開き、Blynkチュートリアル用のプロジェクトを作成します。
ライブラリ管理画面から「M5Stack」と「Blynk」ライブラリを追加します。

⑦サンプルコードを生成しよう
再びPC版Blynkに戻ります。自宅WifiのSSIDとパスワード入力を求められます。
注意点としてはWifiは2.4GHz帯のものを使ってください。M5Stackの仕様上2.4GHz帯のWifiしか利用できません。
SSIDとパスワードを入力すると画面右側にQuickStartアプリを動かすためのサンプルコードが生成されます。
こちらをコピペしてPlatformIOプロジェクトのmain.cppにまるっとコピペしたら次にすすみます。

⑧動かしてみよう
PlatformIOに移動します。ビルドする前にplatform.ini(プロジェクトの設定ファイル)を開き、最後の行に以下の一文を追加します。
これは動作確認に使われるシリアルモニタのための設定です。M5Stackを使う場合は115200に設定します。

monitor_speed=115200

また、サンプルコードに2点追記します。
1点目は、サンプルコード16~18行目のライブラリをインクルードしている部分を以下のように変更します。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

2点目は、サンプルコード54行目からのsetup()関数の最初に以下のように変更します。
M5Stackの立ち上げを行います。

void setup(){
M5.begin();
// Debug console
Serial.begin(115200);

// 以下略

}

ここまできたらビルド&アップロードしてM5Stackにプログラムを送りましょう。

⑧動作確認してみよう
シリアルモニタを使ってアプリの動作確認をしてみましょう。
シリアルモニタはM5StackとUSBケーブルで繋いだPC同士でデータをやり取りする方法です。
pythonのprint文のような感覚で変数をPC画面上に表示できるため、マイコン開発ではデバッグ目的で使われることが多いです。
M5StackとPCをUSBケーブルで繋いだままの状態で、VSCodeのViewメニューから「コマンドパレット」を選びましょう。

コマンドパレットの検索ボックスにSerialと入力すると検索候補にシリアルモニタが出てきます。
クリックすると画面下部にターミナル(シリアルモニタ)が立ち上がります。

シリアルモニタが立ち上がった状態で、一度M5Stack本体側面のスイッチを押して再起動してみましょう。
アプリがうまく立ち上がっていれば以下のような画面が表示されます。


また、スマホのBlynkアプリを立ち上げて、QuickStartアプリを選ぶと以下のような画面が立ち上がっています。

⑨コード解説
軽くコード解説させていただきます。今回のアプリにはV0~V3という4つの内部変数が使われています。
アプリ内部には1つのボタンと2つのラベルが設置されています。
ボタンは自身のon/off状態を変数に代入します。
ラベルは指定された変数の値を表示します。

QuickStartで使われている、Blynkに関する処理は3つです。

  • BLYNK_CONNECTED : アプリが起動している間ずっと行われる処理
  • BLYNK_WRITE : アプリ内部変数が変更されたときに起こる処理
  • timer : 決まった時間ごとに起こる処理

使い方としては、上記の処理の内容を関数として決めておき、
Blynk.run();によって決めておいたBlynk関係の処理を呼び出します。

#define BLYNK_TEMPLATE_ID           "あなたのBlynk Template ID"
#define BLYNK_TEMPLATE_NAME         "あなたのBlynk Template Name"
#define BLYNK_AUTH_TOKEN            "あなたのBlynk Auth Token"

#define BLYNK_PRINT Serial

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

char ssid[] = "あなたのSSID";
char pass[] = "あなたのパスワード";

BlynkTimer timer;

BLYNK_WRITE(V0)    // 変数V0が変更されたときに実行される処理を決めます。
{
  int value = param.asInt();    // V0の値を取得します。
  Blynk.virtualWrite(V1, value);    // V1にV0の値を代入します。
}

BLYNK_CONNECTED()    // アプリが起動している間ずっと行う処理を設定します。
{
  Blynk.setProperty(V3, "offImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations.png");
  Blynk.setProperty(V3, "onImageUrl",  "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations_pressed.png");
  Blynk.setProperty(V3, "url", "https://docs.blynk.io/en/getting-started/what-do-i-need-to-blynk/how-quickstart-device-was-made");
}

void myTimerEvent()    // タイマー機能から呼び出す関数を設定します。
{
  Blynk.virtualWrite(V2, millis() / 1000);    // 変数V2にプログラムが開始してからの秒数を代入します。
}

void setup()
{
  M5.begin();
  Serial.begin(115200);

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);    // アプリを起動します。
  timer.setInterval(1000L, myTimerEvent);    // タイマー機能にて、myTimerEventを1秒ごとに実行することを設定します
}

void loop()
{
  Blynk.run();    // Blynk関係の関数(BLYNK_WRITE, BLYNK_CONNECTEDなど)を呼び出します。
  timer.run();    // タイマー機能を呼び出します。
  // loop関数内にdelay()を入れることは推奨されないようです。
}

ミニカーを走らせるアプリを作ろう

踏まえてミニカーを走らせるアプリを作っていきましょう!
①アプリテンプレートの作成
PC版Blynkにログインし、テンプレートというアプリのもとを作成しましょう。
サイドバーから四角形の「Template」をクリック、右上の「Create New Template」を選択しましょう。
ちなみに無料会員では、テンプレートは3つまで保存できます。

名前を求められますので適当に決めましょう。
M5Stacではdeviceは「esp32」、通信方法は「wifi」を選択します。

②内部変数を設定しよう
モーターの前進/停止を司るアプリ内部変数を作りましょう。
「DataStream」を設定することでアプリ内部変数を編集できます。
テンプレート編集画面が開くので、上部のタブから「DataStream」をクリックします。
画面中央の「New DataStream」をクリック、変数の種類は「Virtual Pin」を選びます。

以下のように設定します。
変数は文字列型(string)、整数型(integer)、小数型(float)から選べます。
変数にはデフォルト値と、数値の場合最大最小値を設定してあげる必要があります。
今回は整数(Integer)型の変数V0を作成します。
デフォルト値0, 最大値1、最小値-1とします。(前進/停止/後退を管理するため)

③デバイス(アプリ本体)を作成しよう
アプリ本体を作成します。Blynkではアプリ本体のことをデバイスと呼ぶようです。
サイドバーの虫眼鏡マークをクリックして、右上の「New Device」をクリック。

デバイスの作り方を聞かれるので、「Template」を選択

チェックボックスから先ほど作ったテンプレートを選びます。

上のタブから「Device info」を選ぶとPlatformIOにコピペする用のアプリのID一覧がコピーできます。

④アプリ画面を作ろう
スマホのBlynkアプリから操作画面を作ります。
まずBlynkアプリを開き、先ほど作ったデバイスを選択します。
右上のレンチのマークをクリックすることでDeveloper modeになり、アプリの編集ができるようになります。

まず、ラジコン操作のためのジョイスティックをレイアウトしましょう。
右上の+アイコンをタップして出てきたメニューから、「Joystick」をえらびます。
アプリ画面に配置されたジョイスティックは長押し+ドラッグで好きな位置に配置できます。

次にジョイスティックに割り当てる変数を設定します。
ジョイスティックをタップすると変数編集画面に移ります。
「Y DATASTREAM」変数V0を選択します。

ラジコン機能には不要ですが動作確認用にラベルを設置しましょう。
右上の+アイコンをタップして出てきたメニューから「Value Display」をえらびます。
アプリ画面上のラベルをタップし、表示する変数に「V0」を選択します。
一番上の入力ボックスにラベルの説明をつけられるので、「v0 value」とでも入れておくと分かりやすいです。

アプリ画面左上の×を押して編集モードを終了し、テスト運転してみましょう。
左上のラベルに、ジョイスティックを前に倒すと1、真ん中のとき0、後ろに倒すと-1が表示されます。
変数V0に、ジョイスティックの傾き具合に応じた数値が代入されるわけです。

⑤ミニカーを組み立てよう
ミニカーを用意します。お好きに組み立てていただければいいですが、紹介するサンプルコードは前の記事にて使ったもので動くよう作ってあります。
M5Stackとモータードライバ、モーターを繋ぎます。

使ったモータードライバはこちら
モーターは5VのDCモーターを使っています。
完成図イメージです。今回使用したモータードライバでは、1個のモーターを動かすだけなら外部電源不要です。


⑥M5Stackのプログラムを書こう
PlatFormIOを開き、新しくプログラムを作ります。
M5StackライブラリとBlynkライブラリを追加しましょう。
モータードライバを動かすためのライブラリも追加します。私の使ったモータードライバではこちらからライブラリをダウンロードできます。
「platformio.ini」に「monitor_speed=115200」と追記します。

以下をmain.cppにコピペしてビルド+書き込みしましょう。
Blynkアプリからラジコン操作できるようになっています。
ジョイスティックを前に倒して前進、中央で停止、後ろに倒して後退します。
速度調整?カーブ?そのような機能は残念ながらありません。

#define BLYNK_TEMPLATE_ID "あなたのTemplate ID"
#define BLYNK_TEMPLATE_NAME "あなたのTemplate Name"
#define BLYNK_AUTH_TOKEN "あなたのTemplate Token"

#define BLYNK_PRINT Serial

#define I2C_ADDRESS 0x0f // モータードライバのI2Cアドレス

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Grove_I2C_Motor_Driver.h> // モータードライバを動かすためのライブラリ

char ssid[] = "あなたのSSID";
char pass[] = "あなたのpassword";

BLYNK_WRITE(V0) // 変数V0が変更されるごとに以下を実行します
{
  int value = param.asInt(); // 変数V0を取得します。
  int speed = 50; // モーターのスピードを設定します。小さすぎると動かないので適宜調整してください
  Motor.speed(MOTOR1, speed * value); // モーターを動かします。
}

void setup()
{
  M5.begin();
  Motor.begin(I2C_ADDRESS);
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}

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

最後に

Blynkを使いこなせばM5Stack運用の幅がググッと広がるはずです。
ここまでお読みいただきありがとうございました。ミニカーを作る内容紹介は今回にて終了です。

今も少しずつ色々なものを作っています。
いいものができたらまたご紹介しますので、今後ともブログを見ていただけると幸いです。

宣伝!

弊社で開催しているデータサイエンティスト養成講座第七期が現在受講生募集中です。
こちらはAIってなんなの?使ってみたいけどよくわからないよ??という方向けの半年間の講座です。
わたしも前職まではAIよくわからん!って感じだったのですがこちらの講座を受けてなんとか仕事ができています。

機械学習やAIの基礎を勉強し、最終的には受講生のグループに分かれた開発演習を行います。
AIって何?という全くの初心者でも、自分でデータを集めてモデルを組めるようになれたと好評の講座です。
もし気になる!という方がいらっしゃいましたら下記講座HPからを詳しい内容を見てみてください!

www.tbtech.co.jp