M5Stack|はやぶさの技術ノート https://cpp-learning.com 理系に役立つ情報 Sun, 26 Jan 2020 07:48:09 +0000 ja hourly 1 https://wordpress.org/?v=6.8.5 https://cpp-learning.com/wp-content/uploads/2018/07/cropped-halogo-32x32.png M5Stack|はやぶさの技術ノート https://cpp-learning.com 32 32 148340536 深層学習×画像処理×M5Stackでアバターアプリを作る -AIアプリ開発チュートリアル- https://cpp-learning.com/mxnet_m5stack/ https://cpp-learning.com/mxnet_m5stack/#respond Mon, 16 Sep 2019 21:30:04 +0000 https://cpp-learning.com/?p=3436 こんにちは。

フクロウ大好きエンジニアの”はやぶさ”@Cpp_Learningです。

最近、M5Stack入門したので、色々なアプリを作って楽しんでいます。

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...

また、『深層学習 × 画像処理』も大好きなので、本ブログ(はやぶさの技術ノート)で情報発信しています。

ソーベルフィルタ
【深層学習入門】画像処理の基礎(画素操作)からCNN設計まで画像処理の基礎(画素操作)から深層学習のCNN設計までカバーした記事です。画像処理にはOpenCVとPythonを使用しました。画像処理入門、深層学習入門、どちらも取り組みたい人におすすめの記事です。...
ONNX RuntimeとSSDでリアルタイム物体検出
TensorFlowの学習済みモデルを変換してONNXRuntimeで物体検出こんにちは。 コンピュータビジョン(『ロボットの眼』開発)が専門の”はやぶさ”@Cpp_Learningです。 前回『ONN...

など

今回は、自分の大好きなものを組み合わて…

『深層学習 × 画像処理 × M5Stack』でアバターアプリを作りました。

https://twitter.com/Cpp_Learning/status/1172485484183900161

アバターアプリを作るモチベーション

我が家には、フクロウの”くるる”ちゃん@kururu_owlが住んでいます。

駆け出しエンジニアのフクロウ

好奇心旺盛な3歳児の行動は、休日ずーーっと見ていても飽きない(*・ω・)ノ♪

あっちへ行ったり、こっちへ飛んだり…普段は大人しいけどスイッチが入るとアクティブに!

はやぶさ
はやぶさ
どっちに向かって移動した?隣の部屋かな?

予測不可能な”くるる”ちゃんの行動が可愛らしい!

カメラで撮影した動物の動きに合わせてアバター(イラスト)が動いたら可愛らしいし、ちょっとした行動監視にも使えそうです。

アバターアプリのイメージ
【M5Stack】深層学習による物体検出を用いたアバターアプリ

…面白そうなので作ることにしました!以降から開発手順を解説します。

アバターアプリの要素技術

最初に「アバターアプリ」の要素技術を検討します。

「アバターアプリ」の要素技術
  1. カメラ画像からフクロウを検出する技術
  2. フクロウの座標データを送信する技術
  3. アバター(イラスト)を動かす画像処理技術

深層学習による物体検出

❶フクロウ検出については、深層学習による物体検出が使えそうです。

PytorchとMobileNet SSDでリアルタイム物体検出
PytorchでMobileNet SSDによるリアルタイム物体検出
PyTorchでMobileNet SSDによるリアルタイム物体検出深層学習フレームワークPytorchを使い、ディープラーニングによる物体検出の記事を書きました。物体検出手法にはいくつか種類がありますが、今回はMobileNetベースSSDによる『リアルタイム物体検出』を行いました。...
ChainerCVとYoloでリアルタイム物体検出
ChainerCVとYoloでリアルタイム物体検出
ChainerCVとYoloで『カメラ・動画対応!リアルタイム物体検出ソフト』を作るChainerファミリ一つChainerCVのYoloサンプルソースをカメラ・動画に対応できるよう改造した「リアルタイム物体検出ソフト」を開発した。その開発手順を紹介します。...
MXNetで物体検出 -Yolo, SSD, Faster-RCNNモデル対応-
MXnetとGluonで物体検出ソフトを作る
MXNetで『カメラ・動画対応!物体検出ソフト』を作った -Yolo, SSD, Faster-RCNNモデル対応-こんにちは。 コンピュータビジョン(『ロボットの眼』開発)が専門の”はやぶさ”@Cpp_Learningです。 『深層学習に...

自分の好きな深層学習フレームワークを使えば良いです。

今回は、実験などで扱いやすい易いコードに仕上げた『MXNetの物体検出ソフト』を採用します。

M5StackとPCのUDP通信

❷フクロウの座標データ送信については、以前トライしたUDP通信が使えそうです。

M5StackとスマホのUDP通信
M5Stackでスマホのセンサ値を取得
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-M5Stackとスマートフォン(iPhone/Android)を無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)を取得する汎用的なアプリを作りました。アプリの使い方やソースコードを公開するので、自由な発想で楽しんでほしいです。...
M5StackとPCのUDP通信
M5Stack(Arduino)とPC(Python)でUDP通信
M5Stack(Arduino)とPC(Python)でUDP通信する方法 -雛形ソースコードあり-M5Stack(Arduino)とPC(Python)でUDP通信する雛形ソースコードを公開しました。「深層学習などの負荷が大きい演算はPythonにやらせて、演算結果をM5Stackに送信して、何かを制御する」などの応用アプリを作るときの参考になれば嬉しいです。...

通信環境などを考慮して、通信方式を決めても良いと思います。

今回は「ノートPC + Webカメラで物体検出」⇒「座標データをM5Stackに送信」を実践します。

画像処理によるアニメーション

➌アバター(イラスト)を動かす画像処理については、私の専門分野です。本ブログで「画像処理チュートリアル」をいくつか公開しています。

pyxelでレトロゲームを作ろう Day1 -画像の扱い方-
Pyxelでレトロゲームを作る
【Pyxel】Pythonでレトロゲームを作ろう! Day 1 -画像の扱い方-こんにちは! 前回こんな記事を書きました↓ https://cpp-learning.com/object-...
Processingでオリジナルビデオを作ろう
Processing
【Processing入門】画像処理プログラミングでプロモーションビデオ作成教育用途やデジタルアートなど様々な用途があるプログラミング言語Processingの入門チュートリアルを作りました。オリジナル動画を作るためのサンプルコードも公開しています。...
M5Stackで画像処理 -静止画の表示から動画作成まで-
M5Stackで画像処理 -静止画表示から動画作成まで-
M5Stackで画像処理 -静止画の表示から動画作成まで-M5Stackで画像処理をするためのチュートリアル記事を書きました。静止画の表示からオリジナル動画(アニメーション)作成まで説明します。初心者にも優しいソースコード付きの解説です。ご参考までに...

『M5Stackでアニメーションを作成するチュートリアル』も公開しています。

つまり、『深層学習 × 画像処理 × M5Stack』によるアバターアプリを開発するための要素技術は全て、本ブログ(はやぶさの技術ノート)で公開しています(*・ω・)ノ♪

開発したいアプリが決まったら、まず最初に”そのアプリ”を実現するための要素技術を検討します。

  • 習得済みの技術で実現できるか?
  • どの技術を組み合わせれば良いか?
  • どんな技術を新規に習得する必要があるか?

など、自分のやりたいことを実現するために、多くの技術を習得しましょう!

実践!深層学習×画像処理×M5Stackでアバターアプリ開発

開発するアプリのイメージを再確認します。

アバターアプリのイメージ
【M5Stack】深層学習による物体検出を用いたアバターアプリ

『深層学習でフクロウ検出して座標データを送信する”AIアプリ”』

『座標データを受信してアバター(イラスト)を動かす”画像処理アプリ”』

以上の二つのアプリを開発する必要があります。

また、座標データ通信用のネットワークも構築する必要があります。

本記事では、以下のネットワークを構築してアプリの動作確認を行いました。

ネットワークやIPアドレス

ホームルータやスマホ(テザリング)などをアクセスポイントとしたネットワークを構築し、UDP通信で座標データをやり取りします。

深層学習で物体検出して座標データを送信する”AIアプリ”

最初に『深層学習でフクロウ検出して座標データ送信する”AIアプリ”』のソースコードを紹介します。

import argparse
import matplotlib.pyplot as plt
from timeit import default_timer as timer
import cv2

import gluoncv as gcv
import mxnet as mx

import json
from socket import socket, AF_INET, SOCK_DGRAM

 # M5Stack address
ADDRESS = "192.168.2.3"
PORT = 5555

# M5Stack window size
WINDOW_W = 320
WINDOW_H = 240

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-model', default='ssd_512_mobilenet1.0_voc')
    parser.add_argument('-threshold', type=float, default=0.5)
    parser.add_argument('video')
    args = parser.parse_args()

    # Set threshold
    th = args.threshold

    # Load the webcam handler
    if args.video == "0":
        cap = cv2.VideoCapture(0)
    else:
        cap = cv2.VideoCapture(args.video)
    if not cap.isOpened():
        raise ImportError("Couldn't open video file or webcam.")

    # For UDP
    s = socket(AF_INET, SOCK_DGRAM)

    # Compute aspect ratio of video
    vidw = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    vidh = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    vidw = int(vidw)
    vidh = int(vidh)
    print(vidw)
    print(vidh)

    # Load the model
    net = gcv.model_zoo.get_model(args.model, pretrained=True)
    # net = gcv.model_zoo.get_model('yolo3_mobilenet1.0_coco', pretrained=True)
    # net = gcv.model_zoo.get_model('ssd_512_mobilenet1.0_voc', pretrained=True)

    # Time parameter
    accum_time = 0
    curr_fps = 0
    fps = "FPS: ??"
    prev_time = timer()

    frame_count = 1
    while True:
        # Load frame from the camera
        ret, frame = cap.read()
        if ret == False:
            print("Done!")
            return

        # Result image
        result_img = frame.copy()

        # Image pre-processing
        frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
        rgb_nd, scaled_frame = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)

        # Run frame through network
        class_IDs, scores, bounding_boxes = net(rgb_nd)

        # Convert NDArray to numpy.ndarray
        bounding_boxes = bounding_boxes.asnumpy()
        scores = scores.asnumpy()
        class_IDs = class_IDs.asnumpy()

        # Class name list
        class_names = net.classes

        # Display the result
        for i, bbox in enumerate(bounding_boxes[0]):
            if th < scores[0][i]:
                score = scores[0][i]
                class_id = class_IDs[0][i]
                class_name = class_names[int(class_id)]

                xmin = int(bbox[0])
                ymin = int(bbox[1])
                xmax = int(bbox[2])
                ymax = int(bbox[3])

                # Draw box
                cv2.rectangle(result_img, (xmin, ymin), (xmax, ymax), (0,255,0), 2)

                text = class_name + " " + ('%.2f' % score)
                print(text)

                text_top = (xmin, ymin - 10)
                text_bot = (xmin + 80, ymin + 5)
                text_pos = (xmin + 5, ymin)

                # Draw class and score
                cv2.rectangle(result_img, text_top, text_bot, (255,255,255), -1)
                cv2.putText(result_img, text, text_pos, 
                cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 0), 1)

                # Detected target(bird)
                if class_name == "bird":
                    # M5Stack scale x,y
                    x = str(xmin*WINDOW_W/vidw)
                    y = str(ymin*WINDOW_H/vidh)

                    # JSON
                    data = {'class_name': class_name,
                            'x': x,
                            'y': y}
                    dic = json.dumps(data)
                    print(dic)

                    # Send JSON (class_name, x, y)
                    s.sendto(dic.encode(), (ADDRESS, PORT))
                    # s.sendto(x.encode('utf-8'), (ADDRESS, PORT))
                    # s.sendto(y.encode('utf-8'), (ADDRESS, PORT))
                    # time.sleep(1)
            else:
                # Cut low score
                break

        # Calculate FPS
        curr_time = timer()
        exec_time = curr_time - prev_time
        prev_time = curr_time
        accum_time = accum_time + exec_time
        curr_fps = curr_fps + 1
        if accum_time > 1:
            accum_time = accum_time - 1
            fps = "FPS: " + str(curr_fps)
            curr_fps = 0

        # Draw FPS in top right corner
        cv2.rectangle(result_img, (vidw-50, 0), (vidw, 17), (0, 0, 0), -1)
        cv2.putText(result_img, fps, (vidw-45, 10), 
        cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

        # Draw Frame Number in top left corner
        cv2.rectangle(result_img, (0, 0), (50, 17), (0, 0, 0), -1)
        cv2.putText(result_img, str(frame_count), (0, 10), 
        cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1)

        # Output Result
        title = args.model + " Result"
        cv2.imshow(title, result_img)

        # Stop Processing
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        frame_count += 1

if __name__ == '__main__':
    main()

既に説明した通りですが、以下の2つの記事で紹介したソースコードを組み合わせて、AIアプリを作成しました。

MXNetで物体検出 -Yolo, SSD, Faster-RCNNモデル対応-
MXnetとGluonで物体検出ソフトを作る
MXNetで『カメラ・動画対応!物体検出ソフト』を作った -Yolo, SSD, Faster-RCNNモデル対応-こんにちは。 コンピュータビジョン(『ロボットの眼』開発)が専門の”はやぶさ”@Cpp_Learningです。 『深層学習に...
M5StackとPCのUDP通信
M5Stack(Arduino)とPC(Python)でUDP通信
M5Stack(Arduino)とPC(Python)でUDP通信する方法 -雛形ソースコードあり-M5Stack(Arduino)とPC(Python)でUDP通信する雛形ソースコードを公開しました。「深層学習などの負荷が大きい演算はPythonにやらせて、演算結果をM5Stackに送信して、何かを制御する」などの応用アプリを作るときの参考になれば嬉しいです。...

「MXNetの物体検出ソフト」をベースに「UDP通信(送信用)コード」を追記しています。

ポイントは以下の通りです。

113~127行目の追記コード

  • ”bird”を検出したときのみM5Stackにx,y座標を送信
  • M5Stackの画面サイズに合わせてx,y座標をリサイズ
  • 送信データ(クラス名とx,y座標)をJSONフォーマットにひとまとめ
  • M5Stackのアドレスとポートを指定して送信

座標データを受信してアバター(イラスト)を動かす”画像処理アプリ”

次に『座標データを受信してアバター(イラスト)を動かす”画像処理アプリ”』のソースコードを紹介します。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>

#define N 1024

const char* ssid     = "yourssid";
const char* password = "yourpassword";
const int port = 5555;

// The udp library class
WiFiUDP udp;

// M5Stack window size
#define WINDOW_W 320
#define WINDOW_H 240

void print_wifi_state(){
	M5.Lcd.clear(BLACK);
  	M5.Lcd.setTextColor(YELLOW);
  	M5.Lcd.setCursor(3, 3);
	M5.Lcd.println("");
	M5.Lcd.println("WiFi connected.");
	M5.Lcd.print("IP address: ");
	M5.Lcd.println(WiFi.localIP());
	M5.Lcd.print("Port: ");
	M5.Lcd.println(port);
}

void setup_wifi(){
	M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    M5.Lcd.print("Connecting to ");
    M5.Lcd.println(ssid);

	// setup wifi
    WiFi.mode(WIFI_STA);  // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
    WiFi.begin(ssid, password);
	// WiFi.begin();

	// Connecting ..
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        M5.Lcd.print(".");
    }

	// print state
    print_wifi_state();

    udp.begin(port);
}

void setup() {
	M5.begin();

	M5.Lcd.clear(BLACK);
    M5.Lcd.setTextColor(YELLOW);
	M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    setup_wifi();
	M5.Lcd.println("");
	M5.Lcd.setTextColor(GREENYELLOW);
    M5.Lcd.setTextSize(3);
	M5.Lcd.println("Bird Detection.");
}

void loop() {
	char packetBuffer[N];
	int packetSize = udp.parsePacket();
	DynamicJsonDocument doc(N);

	// get packet
	if (packetSize){
		int len = udp.read(packetBuffer, packetSize);
		if (len > 0){
			packetBuffer[len] = '\0'; // end
		}
		// for JSON
		deserializeJson(doc, packetBuffer);
  		JsonObject obj = doc.as<JsonObject>();

		// get param
		String class_name = obj["class_name"];
		uint16_t x = obj["x"];
    	uint16_t y = obj["y"];

		if (x < 0 || WINDOW_W < x){
			x = WINDOW_W/2;
		}
		if (y < 0 || WINDOW_H < y){
			y = WINDOW_H/2;
		}

		// Draw image
		M5.Lcd.clear(BLACK);
		M5.Lcd.drawJpgFile(SD, "/img/kururu.jpg", x, y);
		// Draw info
		M5.Lcd.setTextColor(GREENYELLOW);
		M5.Lcd.setTextSize(2);
		M5.Lcd.setCursor(3, 220);
		M5.Lcd.print("class:");
		M5.Lcd.print(class_name);
		M5.Lcd.print(" x:");
		M5.Lcd.print(x);
		M5.Lcd.print(" y:");
		M5.Lcd.print(y);
	}
}

既に説明した通りですが、以下の2つの記事で紹介したソースコードを組み合わせて、画像処理アプリを作成しました。

M5Stackで画像処理 -静止画の表示から動画作成まで-
M5Stackで画像処理 -静止画表示から動画作成まで-
M5Stackで画像処理 -静止画の表示から動画作成まで-M5Stackで画像処理をするためのチュートリアル記事を書きました。静止画の表示からオリジナル動画(アニメーション)作成まで説明します。初心者にも優しいソースコード付きの解説です。ご参考までに...
M5StackとスマホのUDP通信
M5Stackでスマホのセンサ値を取得
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-M5Stackとスマートフォン(iPhone/Android)を無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)を取得する汎用的なアプリを作りました。アプリの使い方やソースコードを公開するので、自由な発想で楽しんでほしいです。...

「M5Stackで画像処理(動画編)のコード」をベースに「UDP通信(JSONフォーマット受信用)コード」を追記しています。

ポイントは以下の通りです。

UDP/JSON/画像処理(アバター描画)について

  • UDP通信で座標データ(JSONフォーマット)を受信
  • ArduinoJSONでJSONフォーマットを扱う
  • 受信したx,y座標がM5StackのWindowサイズ(320×240)に収まらない場合は画面の中心座標をx,yに代入
  • drawJpgFile関数でSDカードに保存したアバター(JPGファイル)をx,y座標を指定して描画
  • 受信データ(クラス名とx,y座標)を画面左下に表示

深層学習×画像処理×M5Stackによるアバターアプリ動作手順

以下の手順で『深層学習×画像処理×M5Stackによるアバターアプリ』を楽しめます。

【アバターアプリ動作手順】

  1. 「画像処理アプリ」をインストールしたM5Stackの電源ON
  2. M5Stackが自動でネットワークに接続され、座標データ受信待ちになる
  3. 「AIアプリ」をPCから起動する
  4. ”くるる”ちゃん(bird)をWebカメラで撮影する
  5. M5Stackに表示されたアバター(イラスト)が”くるる”ちゃんの座標に合わせて移動

実際に”くるる”ちゃんの映像を使い『アバターアプリ』で遊んでみました。

現実世界の”くるる”ちゃんに合わせてアバター(イラスト)が動くの面白し、可愛い!

深層学習×画像処理×M5Stackによるアバターアプリの改良ポイント

本アプリをベースに自分好みのアプリを作ってみましょう!改良ポイント紹介しますね。

ハードウェア選定

今回は「AIアプリ」をノートPC、「画像処理アプリ」をM5Stackで動かしましたが…

「AIアプリ」Jetson Nano「画像処理アプリ」Raspberry Pi(ラズパイ)で動かすなど、自分のやりたいことに合わせて、好きなディバイスを使ってください。

組込みAI向けエッジディバイスJetsonシリーズ
名刺サイズの汎用PCラズパイのスターターセット
ABOX Raspberry Pi 3 Model b+ ラズベリーパイ 3 b+ MicroSDHCカード32G/NOOBSシステムプリインストール/カードリーダ /5V/3A スイッチ付電源/高品質HDMIケーブルライン/ヒートシンク /簡単に取り付けケース /日本語取扱説明書/24ヶ月保証
ABOX

AIアプリ(深層学習による物体検出アプリ)改良

今回は『MXNetの物体検出ソフト』をベースにしました。

本記事で公開している動画では「MobileNetV1-SSDモデル」を使って、物体検出(フクロウ検出)を実現しています。

Model Zoo(モデルの動物園)のObject Detectionカテゴリーで公開しているモデル(Faster-RCNN, YOLO-v3など)も使えるので、処理速度や検出精度を考慮して、目的に合うモデルを使ってください。

また、’bird’以外に‘person’, ‘car’, ‘cat’, ‘dog’なども検出できます。ソースコードの以下の部分を書き換えて、好きな対象の座標データを抽出してください。

# Detected target(bird)
if class_name == "bird":

もし、Model Zooのモデルで満足できない場合は、独自モデルを作成する必要があります。

検出したい対象の画像を大量に用意して、MXNet・Tensorflow・Pytorch・Chainerなどの深層学習フレームワークを使い、学習(モデル作成)に挑戦してみて下さい。

画像処理アプリ(M5Stackアプリ)改良

今回はフクロウの”くるる”ちゃん@kururu_owlを対象としたアバターアプリなので、以下のイラストをSDカードに保存して、LCDに描画させました。

サイズ90×70ピクセルのJPGファイル
くるる

 

 

 

イラストを変更して、自分好みのアバターアプリにして下さい。

また、以下の記事で紹介した通り、M5Stack用の拡張モジュールGroveセンサがあります。

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...

モーターを駆動させたり、LEDを光らせたり…アバターの動きに合わせて何かを制御するのも楽しいと思いますよ(*・ω・)ノ♪

本記事で公開しているソースコード(アプリ)は改良OKです。自由な発想でAIアプリ開発を楽しんで頂けたら、とても嬉しいです。

AIアプリ開発チュートリアルまとめ

本記事で「AIアプリ開発チュートリアル」を書きました。本記事を読むことで以下のことを学べたと思います。

【本記事で学べる内容】

  • 【AI】深層学習による物体検出を利用したアプリの例
  • 【IoT】UDP通信でデータをやり取りする方法
  • 【画像処理】好きなイラストを自由に移動させる画像処理
  • 【VR】リアルな動物とバーチャルなアバターをリンクさせる方法
  • 【マイコン】M5Stack(Arduino)アプリ開発
  • 【プログラミング】自分のやりたいことを実現するためのヒント
  • インターネット未使用なので、正確には【IoT】一歩手前
  • 動物(人含む)の動きに合わせてアバターが動くので、【VR】ではなく【インターフェース】という表現の方が適切かもしれません
はやぶさ
はやぶさ
自分が思いつく限りの面白い技術を、本記事に”ギュッ”と凝縮しました!

Webアプリ以外の「AIアプリ開発チュートリアル」ってあまり無い気がするので、参考になれば嬉しいです。

くるる
くるる
すごーーーく楽しく勉強できました♪

”くるる”ちゃんのように本記事で楽しく勉強してくれる人が一人でもいたら嬉しいです!

はやぶさ
はやぶさ
理系応援ブロガー”はやぶさ”@Cpp_Learningは頑張る理系を応援します!

おまけ -AIアプリ開発のヒントとメッセージ-

時間がある人は、以下の”おまけ”も読んでみてね。

”くるる”ちゃんが考えたAIアプリのアイデア

こんにちは。

くるる
くるる
駆け出しエンジニアの”くるる”だよー

本記事は面白い内容が”ギュッ”と凝縮されてて、しかもアプリを改良するときのポイントまで書いてある!

ノートPCとM5Stackで手軽に試せるので、初期投資も少ない!

くるる
くるる
AIアプリ開発ってもっと敷居の高いものだと思ってたけど…

本記事を参考にすれば”くるる”でもAIアプリ作れそう!!

”くるる”は暑いの苦手だから室温によって行動が違うと思うけど…あまり意識したことないからアバターで自分の行動を客観視してみたい!

M5Stackに温度センサ取り付けて、室温とアバターの座標から相関関係を~♪

くるる

 

はやぶさ
はやぶさ
スイッチ入った”くるる”ちゃんが黙々と作業してる姿が可愛い

実用的なアプリ・面白いアプリ…作りたいアプリは人それぞれだと思います。

”くるる”ちゃんのように自由な発想で『AIアプリ開発』を楽しんでくれたら嬉しいです!

メッセージ -本ブログのサポートについて-

本記事は、もし自分が技術書典(技術同人誌即売会)などで本を出すなら『深層学習×画像処理×M5Stack -AIアプリ開発チュートリアル-』というタイトルで書きたい!と想った内容を具現化したものです。

ただ、お金のない学生さんも含め、多くの人に『AIアプリ開発』を楽しんでもらいたい!という想いから、無料公開にしました。

(本は無理でも有料noteで公開したら、Jetson Nanoの購入資金くらい稼げたかな?とか考えたりもするけど…)

もし、本チュートリアルが参考になり、ブログ『はやぶさの技術ノート』をサポートしたいという人がいれば、以下の方法でサポートして頂けると嬉しいです!

【本ブログのサポート方法】

  • 本ブログの記事をSNS(Twitterやfacebookなど)でシェア
  • 本記事を参考に『アプリ開発』を実践したら、参考資料で本記事を紹介

記事に対して反応があると、次も良い記事書きたいな!というモチベーションに繋がります。気軽にシェアして頂けると嬉しいです。

また、本記事が拡散することで、以下のような『技術で繋がる輪』ができたら、最高に嬉しいと考えています。

  1. 本記事をシェア
  2. 多くの人が『AIアプリ開発』に興味をもつ
  3. 各自が『AIアプリ』に関するアイデアやソースコードを公開(シェア)
  4. 誰かの『AIアプリ』が新たなアイデアやソースコードの創出に繋がる

多くの人が『AIアプリ』の情報を公開することで、ひとりの人間では思いつかなかった素晴らしい『AIアプリ』が誕生するかもしれません。

名も知らない人同士が『技術で繋がり』イノベーションが起こるかもしれません。

想像するだけでワクワクしますね!もし『AIアプリ』を作ったら、是非”はやぶさ”@Cpp_Learningに自慢してくださいね。

皆様が楽しく『AIアプリ開発』を実践してくれたら、最高に嬉しいです。

(完)

]]>
https://cpp-learning.com/mxnet_m5stack/feed/ 0 3436
M5Stackで画像処理 -静止画の表示から動画作成まで- https://cpp-learning.com/m5stack_image/ https://cpp-learning.com/m5stack_image/#respond Mon, 02 Sep 2019 09:34:54 +0000 https://cpp-learning.com/?p=3460 こんにちは。

くるる
くるる
人気フクロウの”くるる”@kururu_owl だよー

コンピュータビジョン(『ロボットの眼』開発)が専門の”はやぶさ”先生@Cpp_Learning一番弟子です!

くるる

はやぶさ先生は、画像処理や機械学習などの技術を分かりやすく説明してくれる”変な…優しいお兄さん”です!

本サイト:はやぶさの技術ノートで はやぶさ先生が書いた記事がタダで読めるよー

ソーベルフィルタ
【深層学習入門】画像処理の基礎(画素操作)からCNN設計まで画像処理の基礎(画素操作)から深層学習のCNN設計までカバーした記事です。画像処理にはOpenCVとPythonを使用しました。画像処理入門、深層学習入門、どちらも取り組みたい人におすすめの記事です。...
MXnetとGluonで物体検出ソフトを作る
MXNetで『カメラ・動画対応!物体検出ソフト』を作った -Yolo, SSD, Faster-RCNNモデル対応-こんにちは。 コンピュータビジョン(『ロボットの眼』開発)が専門の”はやぶさ”@Cpp_Learningです。 『深層学習に...
ONNX RuntimeとYoloV3でリアルタイム物体検出
ONNX RuntimeとYoloV3でリアルタイム物体検出Microsoft社製OSS”ONNX Runtime”の入門から実践まで学べる記事です。ONNXおよびONNX Runtimeの概要から、YoloV3モデルによる物体検出(ソースコード付)まで説明します。深層学習や画像処理に興味のある人にオススメの内容です。...

など

くるる
くるる
多すぎて紹介しきれないけど、他にも沢山の記事を書いてるよ!

くるるは先生と一緒に勉強しながら、ゲームやオリジナルビデオを作ったことがあるよー

Pyxelでレトロゲームを作る 総集編
【Pyxel】Pythonでレトロゲームを作ろう! 総集編 -まるっと1週間でゲーム開発入門-Python向けのレトロゲームエンジン:pyxelを用いたゲーム開発入門チュートリアル(ソースコード付き)を書きました。画像処理・数学・物理・制御について学び、実践としてゲームプログラミングまで行います。...
Processing
【Processing入門】画像処理プログラミングでプロモーションビデオ作成教育用途やデジタルアートなど様々な用途があるプログラミング言語Processingの入門チュートリアルを作りました。オリジナル動画を作るためのサンプルコードも公開しています。...
pyxelで物理シミュレーション
【Pyxel】Pythonで物理シミュレーションをしよう! 総集編 -まるっと1週間チュートリアル-こんにちは! 本記事は『Pythonで物理シミュレーションをしよう!』シリーズの総集編です! 本シリーズは、...
くるる
くるる
勉強楽しい!プログラミング最高!!

最近、先生が遊んでるM5Stackってやつが楽しそうなので…

先生が留守の間に、こっそり画像処理で遊ぶことにした!本記事も勝手に書いちゃうよー

本記事は「静止画編」と「動画編」の二部構成で説明します。目次からジャンプできるので、好きなところから読み始めてくださな

M5Stackの始め方

M5Stack初心者のくるるでも以下の記事を読んだら、すぐにプログラミングを始められたよ!はやぶさ先生イイ記事書いてる~♪

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...

M5StackちっちゃいBodyに画面まで付いてるから、つい画像処理とかしたくなっちゃうよね♪

くるる

M5Stackで画像処理 -静止画編-

M5StackのLCDにjpg画像を表示する場合、以下のソースコードのやり方が最も簡単です。

#include <M5Stack.h>

void setup() {
	M5.begin();
}

void loop() {
	M5.Lcd.drawJpgFile(SD, "/kururu.jpg");
}

このコードでSDカード直下に保存した”kururu.jpg”という画像を表示できます。

もし、SDカード直下ではなく、imgフォルダなどに画像を保存している場合は、以下のように書きます。

void loop() {
	M5.Lcd.drawJpgFile(SD, "/img/kururu.jpg");
}

M5StackのWindowサイズが320×240なので、画面いっぱいに表示させたいときは、同じ320×240pixelのjpg画像を使うのがオススメです。

M5StackのWindowサイズ

座標を指定して画像表示

画像処理では画面左上を原点として扱うことが多く、M5Stackも左上が原点でした。

最初に紹介した画像表示のやり方は、M5Stack(Window)の原点とjpg画像の原点を揃えて表示する方法です。

以下のコードを使えば、座標指定で画像表示ができます。

void loop() {
    uint16_t x = 50;
    uint16_t y = 40;

	M5.Lcd.drawJpgFile(SD, "/kururu.jpg", x, y);
}

以下のような画像表示になります。

【M5Stack】x,y座標指定で画像表示

画像の幅と高さを指定して表示

jpg画像の幅と高さを指定して表示することもできます。

void loop() {
    uint16_t x = 50;
    uint16_t y = 40;
    uint16_t width = 160;
    uint16_t height = 80;

    M5.Lcd.drawJpgFile(SD, "/kururu.jpg", x, y, width, height);
}

以下のような画像表示になります。

【M5Stack】幅と高さ指定で画像表示

オフセットを指定して画像表示

オフセットも指定できるよー

void loop() {
    uint16_t x = 50;
    uint16_t y = 40;
    uint16_t width = 0;
    uint16_t height = 0;
    uint16_t offset_x = 80;
    uint16_t offset_y = 20;

    M5.Lcd.drawJpgFile(SD, "/kururu.jpg",
                        x, y, width, height,
                        offset_x, offset_y);
}

以下のような画像表示になります。

【M5Stack】オフセット指定で画像表示

クリッピング(画像の指定範囲を表示)

今までの説明したやつを応用すれば、目の部分だけ表示(クリッピング)ができます。

void loop() {
    uint16_t x = 50;
    uint16_t y = 40;
    uint16_t width = 100;
    uint16_t height = 18;
    uint16_t offset_x = 80;
    uint16_t offset_y = 20;

    M5.Lcd.drawJpgFile(SD, "/kururu.jpg",
                        x, y, width, height,
                        offset_x, offset_y);
}

以下のような画像表示になります。

【M5Stack】画像表示(応用)
くるる
くるる
必殺技が出せそう!

スケールを指定して画像表示

サイズの大きいjpg画像を表示させるなら、スケールを変更すると良いです。

void loop() {
    uint16_t x = 0;
    uint16_t y = 0;
    uint16_t width = 0;
    uint16_t height = 0;
    uint16_t offset_x = 0;
    uint16_t offset_y = 0;
    jpeg_div_t scale = JPEG_DIV_2; // JPEG_DIV_NONE, JPEG_DIV_2, JPEG_DIV_4, JPEG_DIV_8

    M5.Lcd.drawJpgFile(SD, "/kururu.jpg",
                        x, y, width, height,
                        offset_x, offset_y,
                        scale);
}

このコードで以下のような1/2スケールの表示ができます。

【M5Stack】スケール指定で画像表示

スケールは整数値でも指定できますが、用意してある列挙型を使う方が直感的にスケールを理解できるのでオススメです。

jpeg_div_tという列挙型が用意してあります。

  • JPEG_DIV_NONE:スケール指定なし
  • JPEG_DIV_2:1/2スケール
  • JPEG_DIV_4:1/4スケール
  • JPEG_DIV_8:1/8スケール
  • JPEG_DIV_MAX:存在するけど使わない

列挙型なので、JPEG_DIV_NONE=0, JPEG_DIV_NONE2=1,… を表現しています。

そのため、scale=JPEG_DIV_NONE2ではなく、scale=1を指定してもスケールは1/2になります。

また、JPEG_DIV_NONEは省略してもOKです。

ただし、JPEG_DIV_〇を書いたり/書かなかったすると読み手が混乱するので…

一箇所でもJPEG_DIV_〇でスケール指定するなら、JPEG_DIV_NONEも省略せずに書く方が親切です。

くるる

補足 -良いソースコードとは?-

くるる
くるる
『読み手や使い手のことを想ってソースコードを書くのが正解』って、はやぶさ先生が教えてくれたよ♪

ケースバイケースだけど、変数を使わずに引数を書くと何の処理をしているか分かりにくいので…

M5.Lcd.drawJpgFile(SD, "/kururu.jpg", 50, 40, 100, 18, 30, 20);

コメントで引数の定義を補足するか、直感的に理解しやすい名前の変数を使うと良いです。

M5.Lcd.drawJpgFile(SD, "/kururu.jpg",
                        x, y, width, height,
                        offset_x, offset_y,
                        scale);

また、「悪い例」・「良い例」で引数の数が異なります。これは、省略可能なスケールを書いたり・書かなかったりした差です。

エラーは出ませんが、統一感のないコードは読み手が混乱します。

『読み手や使い手のことを想ってソースコードを書くのが正解』

思想や好みもありますが、統一感のあるコードの方が「読み手を想ったコード」になると考えています。

くるる

(静止画編 完)

M5Stackで画像処理 -動画編-

静止画だけじゃなくて、M5Stackで動画(アニメーション)も作成するよー!

簡単なアニメーションなら、パラパラ漫画…つまり、静止画を重ねるだけで実現できます。

単純に1枚の画像のx,y座標を少しずつ動かすだけでも面白い動画になります。

Processing

この図はProcessingでオリジナルビデオを作る』のブログ記事で使った図解です。なので、ソースコードの言語は異なりますが、画像処理の基礎は同じです!

Processingでオリジナルビデオを作る
Processing
【Processing入門】画像処理プログラミングでプロモーションビデオ作成教育用途やデジタルアートなど様々な用途があるプログラミング言語Processingの入門チュートリアルを作りました。オリジナル動画を作るためのサンプルコードも公開しています。...

オリジナルビデオ作成に興味のある人は、この記事も読んでほしいな~

くるる
くるる
今回はM5Stack(Arduino)でアニメーションを作成するよ♪
くるる

実践!M5Stackでアニメーション表示

静止画編でjpg画像の一部を切り取ったり、スケールを変更する方法を説明しました。

静止画を表示させるだけなら、処理速度を気にする必要はありませんが、できるだけ実行する処理を減らした方が滑らかなアニメーションになります。

そのため、SDカードに保存した小さなjpg画像を読み込み、x,y座標を動かすソースコードを作成しました。

#include <M5Stack.h>

uint16_t x = 0;
uint16_t y = 40;

void setup() {
	M5.begin();
}

void loop() {
    int dx = 10, dy = 10;

    x = x + dx;
    y = y + dy;
	M5.Lcd.drawJpgFile(SD, "/kururu.jpg", x, y);
}

このコードでjpg画像のx,y座標が10pixelずつ移動するアニメーションを生成できます。

あとは以下の仕様を検討すれば、オリジナルアニメーションが作成できます。

  • 更新速度(画像を移動させる時間)を調整
  • 移動量(dx=〇pixel移動させるか)を調整
  • ある座標(画面の端など)に行ったときの処理
  • ボタンが押されたらときの処理
  • 移動軌跡(sin・cosを使って滑らかに移動など)の処理

など、自由な発想でオリジナルアニメーションを作ってみよう♪

実践!M5Stackでオリジナルアニメーション作成

最後に簡単なオリジナルアニメーションのソースコードを紹介します。

#include <M5Stack.h>

// M5Stack window size
#define WINDOW_W 320
#define WINDOW_H 240

// jpg image param
uint16_t x = 0;
uint16_t y = 0;
uint16_t width = 120;
uint16_t height = 120;
// uint16_t offset_x = 30;
// uint16_t offset_y = 50;
// // JPEG_DIV_NONE, JPEG_DIV_2, JPEG_DIV_4, JPEG_DIV_8, JPEG_DIV_MAX
// jpeg_div_t scale = JPEG_DIV_NONE;

void setup() {
	M5.begin();

	M5.Lcd.clear(BLACK);
	M5.Lcd.setTextColor(YELLOW);
	M5.Lcd.setTextSize(2);
	M5.Lcd.setCursor(3, 10);
	M5.Lcd.println("");
	M5.Lcd.println("Read image form SD.");
}

void loop() {
	M5.update();

	int dx = 10, dy = 10;

	// move image
	if (M5.BtnA.wasReleased()) {
		M5.Lcd.clear(BLACK);
		if (x + width < WINDOW_W - dx){
			x = x + dx;
		}else{
			x = 0;
			y = 0;
		}
		if (y + height < WINDOW_H - dy){
			y = y + dy;
		}else{
			x = 0;
			y = 0;
		}
		M5.Lcd.drawJpgFile(SD, "/guruguru.jpg", x, y);
	}

	// display image
	if (M5.BtnB.wasReleased()) {
		M5.Lcd.drawJpgFile(SD, "/kururu.jpg");
	}

	// animation
	if (M5.BtnC.wasReleased()) {
		y = 60;
		while (true){
			M5.Lcd.clear(BLACK);
			if (x + width < WINDOW_W - dx){
				x = x + dx;
			}else{
				x = 0;
				y = 0;
				break;
			}
			M5.Lcd.drawJpgFile(SD, "/kururu_go.jpg", x, y);
			delay(100);
		}
	}
}

3つの画像を用意して、ボタン毎に処理を変えてみました。このコードを動かしたときの様子は以下の通りです。

https://twitter.com/Cpp_Learning/status/1167999615200718848

自分の好きな画像を使ってオリジナルアニメーションが動くの楽しい!M5Stackの小さな画面で動くのが可愛らしい♪

くるる

(動画編 完)

M5Stackで画像処理まとめ

M5Stackに画面が付いてたから、画像処理で遊んでみました。

画像表示の方法について説明し、最終的にはアニメーション作成まで実践しました。

くるる
くるる
楽しかった~

みんなもオリジナルアニメーション作成に挑戦してみてね♪

おまけ -本ブログのサポートについて-

はやぶさ
はやぶさ
この記事くるるちゃんが書いたの!?すごいよ!
くるる
くるる
”はやぶさ先生”@Cpp_Learningが色々教えてくれたから、楽しく自力でオリジナルアニメを作れたよ!
くるる
はやぶさ
はやぶさ
画像処理の基礎がしっかり習得できてるから、言語が変わっても自分のやりたいことを実現できたね
くるる
くるる
言語も違ったし、PCじゃなくてマイコンモジュールだったけど、画像処理できたよー

くるるちゃんは着実にレベルアップしています。教える立場としては、とても誇らしいです!

はやぶさ
はやぶさ
本記事は、子供も大人も楽しめる良い記事だと感じたよ!頑張ったご褒美に何かプレゼントしようか?
くるる
くるる
くるる
じゃあ【くるるの野望ショップ】でフクロウグッズ買って!

本ブログのサポート方法

本記事が参考になり、くるるちゃんに投げ銭(ごはん代をサポート)したいという人がいれば LINEスタンプ【くるるの野望ショップ】でフクロウグッズを購入して頂けると嬉しいです。

また、ブログ『はやぶさの技術ノート』では、本記事も含め多くのチュートリアル記事を無料で公開しています。SNSなどで友達にも教えてあげてほしいです!

【本ブログのサポート方法】

くるる
くるる
最後まで読んでくれてありがとね!また一緒に勉強しようねー♪
M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
Processing
【Processing入門】画像処理プログラミングでプロモーションビデオ作成教育用途やデジタルアートなど様々な用途があるプログラミング言語Processingの入門チュートリアルを作りました。オリジナル動画を作るためのサンプルコードも公開しています。...
Pyxelでレトロゲームを作る 総集編
【Pyxel】Pythonでレトロゲームを作ろう! 総集編 -まるっと1週間でゲーム開発入門-Python向けのレトロゲームエンジン:pyxelを用いたゲーム開発入門チュートリアル(ソースコード付き)を書きました。画像処理・数学・物理・制御について学び、実践としてゲームプログラミングまで行います。...
]]>
https://cpp-learning.com/m5stack_image/feed/ 0 3460
M5Stack(Arduino)とPC(Python)でUDP通信する方法 -雛形ソースコードあり- https://cpp-learning.com/m5stack_udp/ https://cpp-learning.com/m5stack_udp/#respond Thu, 29 Aug 2019 09:53:23 +0000 https://cpp-learning.com/?p=3437 こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

前回、M5StackとスマホをUDP通信するアプリの作り方・使い方の記事を書きました。

M5Stackでスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-
M5Stackでスマホのセンサ値を取得
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-M5Stackとスマートフォン(iPhone/Android)を無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)を取得する汎用的なアプリを作りました。アプリの使い方やソースコードを公開するので、自由な発想で楽しんでほしいです。...

今回は、スマホではなくPCとUDP通信するM5Stackアプリを作りました。

深層学習などの負荷が大きい演算はPC(Python)にやらせて、演算結果をM5Stackに送信して、ごにょごにょ…

みたいなことが出来ると面白そうなので、送信側のソースコードはPythonで作成しました。

本記事で、受信側(Arduino)と送信側(Python)の両ソースコードを紹介します。

UDP通信用ネットワーク

今回、通信テストのために構築したネットワークの概要は以下の通りです。

ネットワークやIPアドレス

ホームルータやスマホなどをアクセスポイントとしたネットワークを構築し、UDPで通信します。

【ネットワーク概要】

  • アクセスポイント:ホームルータまたはスマホ(※1)
  • UDPデータ送信側:Python環境構築済みPC
  • UDPデータ受信側:M5Stack(※2)

(※1)ホームルータおよびiPhoneXのテザリングでテストしました
(※2)M5Stack Grayを使いました

M5Stackアプリのソースコード -UDPデータ受信-

M5StackでUDPデータを受信するアプリについては、以下の記事で説明しています。

M5Stackでスマホのセンサ値を取得
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-M5Stackとスマートフォン(iPhone/Android)を無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)を取得する汎用的なアプリを作りました。アプリの使い方やソースコードを公開するので、自由な発想で楽しんでほしいです。...

この記事のソースコードをシンプルに通信のみを行うコードに改良します。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>

#define N 1024

const char* ssid     = "yourssid";
const char* password = "yourpassword";
const int port = ****;

// The udp library class
WiFiUDP udp;

void print_wifi_state(){
	M5.Lcd.clear(BLACK);  // clear LCD
  	M5.Lcd.setTextColor(YELLOW);
  	M5.Lcd.setCursor(3, 3);
	M5.Lcd.println("");
	M5.Lcd.println("WiFi connected.");
	M5.Lcd.print("IP address: ");
	M5.Lcd.println(WiFi.localIP());
	M5.Lcd.print("Port: ");
	M5.Lcd.println(port);
}

void setup_wifi(){
	M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    M5.Lcd.print("Connecting to ");
    M5.Lcd.println(ssid);

	// setup wifi
    WiFi.mode(WIFI_STA);  // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
    WiFi.begin(ssid, password);
	// WiFi.begin();

	// Connecting ..
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        M5.Lcd.print(".");
    }

	// print state
    print_wifi_state();

    udp.begin(port);
}

void setup() {
	M5.begin();

	// setup wifi
	setup_wifi();
}

void loop() {
	char packetBuffer[N];
	int packetSize = udp.parsePacket();

	// get packet
	if (packetSize){
		int len = udp.read(packetBuffer, packetSize);
		if (len > 0){
			packetBuffer[len] = '\0'; // end
		}

		// print param
		M5.Lcd.clear(BLACK);
  		M5.Lcd.setCursor(3, 3);
		M5.Lcd.setTextColor(GREEN);
		M5.Lcd.println(packetBuffer);
	}
}

これが『M5StackでUDPデータを受信ときの雛形コード』になります。

シンプルな雛形コードは、様々なアプリに組み込み易いので、とても便利です。

Pythonソースコード -UDPデータ送信-

PythonでUDP通信するソースコードについては、以下の記事のコードがそのまま使えました。

この記事で送受信のコードを紹介していますが、今回使うのは送信側のコードのみです。

from socket import socket, AF_INET, SOCK_DGRAM

ADDRESS = "192.168.2.3" # M5Stack address
PORT = 5555

s = socket(AF_INET, SOCK_DGRAM)

while True:
    msg = input("> ")
    s.sendto(msg.encode(), (ADDRESS, PORT))

s.close()

このコードを”udpy.py”というファイル名で保存しました。

M5StackとPCのUDP通信テスト

以下の手順でM5StackとPCの通信が行えます。

【M5Stack-PCのUDP通信の手順】

  1. 「UDP通信アプリ」をインストールしたM5Stackの電源ON
  2. PCのターミナルからudpy.pyを起動
  3. ターミナルにキーボードから文字入力

私が通信テストしたときの様子が以下です。

https://twitter.com/Cpp_Learning/status/1166698632436805632

【応用】おしゃべり代行アプリ(UDP版)を作る

雛形コードの紹介だけだと、あまり面白くないので…ちょっとだけ応用を考えてみます。

以前、Telnet通信を使った「おしゃべり代行アプリ」を作りました。

M5Stackアバターにキーボード入力した文字を読んでもらう
M5Stackおしゃべり代行アプリ
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作るM5Stack(Wifiサーバ)とPC(クライアント)をTelnetで無線通信して、PCのキーボードから入力した文字をM5Stackアバターが読み上げる「おしゃべり代行アプリ」を作りました。アプリの使い方はもちろんソースコードも公開しています。遊んでくれたら嬉しいです。...

今回は、TelnetではなくUDPで「おしゃべり代行」を実現してみます。

#include <M5Stack.h>
#include <AquesTalkTTS.h>
#include <Avatar.h>
#include <tasks/LipSync.h>
#include <WiFi.h>
#include <WiFiUdp.h>

#define N 30

using namespace m5avatar;

// AquesTalk License Key
// NULL or wrong value is just ignored
const char* AQUESTALK_KEY = "XXXX-XXXX-XXXX-XXXX";

// for wifi setup
const char* ssid     = "yourssid";
const char* password = "yourpassword";
const int port = ****;

Avatar avatar;
WiFiUDP udp;

void setup_wifi(){
	M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    M5.Lcd.print("Connecting to ");
    M5.Lcd.println(ssid);

	// wifi setup
    WiFi.mode(WIFI_STA);  // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
    WiFi.begin(ssid, password);
	// WiFi.begin();

	// Connecting ..
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        M5.Lcd.print(".");
    }

	udp.begin(port);
}

void setup() {
    int iret;
    M5.begin();

	// setup wifi
	setup_wifi();

    // For Kanji-to-speech mode (requires dictionary file saved on microSD)
    // See http://blog-yama.a-quest.com/?eid=970195
    // iret = TTS.createK(AQUESTALK_KEY);
	iret = TTS.create(AQUESTALK_KEY);
    M5.Lcd.setBrightness(30);
    M5.Lcd.clear();
    avatar.init();
    avatar.addTask(lipSync, "lipSync");
}

void loop() {
	char packetBuffer[N];
	int packetSize = udp.parsePacket();

	// get packet
	if (packetSize){
		int len = udp.read(packetBuffer, packetSize);
		if (len > 0){
			packetBuffer[len] = '\0'; // end
		}
		TTS.play(packetBuffer, 80);
		avatar.setSpeechText(packetBuffer);
		delay(1000);
		// clear "c"
		while (len >= 0){
			len--;
			packetBuffer[len] = ' ';
		}
	}
}

UDPデータ送信用のPythonソースコードは同じものを使います。

通信方式が違うだけで、やってることは「おしゃべり代行」なので、前回の記事で紹介した動画を改めて紹介。

https://twitter.com/Cpp_Learning/status/1162669032702537733

M5StackとPCやスマホを通信させるの楽しいですね!

我が家の環境だとTelenetよりUDP通信の方が安定します。。なぜだろう?

まとめ

M5Stack(Arduino)とPC(Python)でUDP通信する『雛形ソースコード』を紹介しました。

また、雛形コードを使った応用として「おしゃべり代行アプリ」を作ってみました。参考になれば嬉しいです。

冒頭にも書きましたが、深層学習などの負荷が大きい演算はPC(Python)にやらせて、演算結果をM5Stackに送信して、ごにょごにょ…

みたいなことを実践する人が現れたら最高に嬉しいです。

はやぶさ
はやぶさ
本記事のソースコードは好きに改良してOKです!

自由な発想でプログラミングを楽しんでくださいね(*・ω・)ノ♪

M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

M5Stack Faces(9軸IMU搭載、各種カバー付き)
スイッチサイエンス

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...
M5Stackおしゃべり代行アプリ
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作るM5Stack(Wifiサーバ)とPC(クライアント)をTelnetで無線通信して、PCのキーボードから入力した文字をM5Stackアバターが読み上げる「おしゃべり代行アプリ」を作りました。アプリの使い方はもちろんソースコードも公開しています。遊んでくれたら嬉しいです。...
M5Stackでスマホのセンサ値を取得
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET-M5Stackとスマートフォン(iPhone/Android)を無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)を取得する汎用的なアプリを作りました。アプリの使い方やソースコードを公開するので、自由な発想で楽しんでほしいです。...

 

]]>
https://cpp-learning.com/m5stack_udp/feed/ 0 3437
【M5Stack】無線通信でスマホの各センサ値を取得する -加速度・ジャイロ・GPSまるっとGET- https://cpp-learning.com/m5stack_iphone/ https://cpp-learning.com/m5stack_iphone/#respond Sun, 25 Aug 2019 02:07:53 +0000 https://cpp-learning.com/?p=3383 こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

最近、M5Stackで遊ぶのがマイブームです!”調べた内容”や”自作アプリ”については本ブログで公開しています。

【M5Stack入門】初心者向け情報まとめ
M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
M5Stackアバターおしゃべりアプリの作り方 -30分クッキング-
M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作る
M5Stackおしゃべり代行アプリ
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作るM5Stack(Wifiサーバ)とPC(クライアント)をTelnetで無線通信して、PCのキーボードから入力した文字をM5Stackアバターが読み上げる「おしゃべり代行アプリ」を作りました。アプリの使い方はもちろんソースコードも公開しています。遊んでくれたら嬉しいです。...

今回は『M5Stackでスマホのセンサ値を取得するアプリ』を作りました。

https://twitter.com/Cpp_Learning/status/1165095945970667520

M5Stackとスマホを無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)をまるっと取得しています。

本記事で「アプリの作り方」・「使い方」を説明します。

スマートフォンを多機能センサとして使う

以前、私の仕事道具について記事を書きました。その中の一つにスマートフォンがあります。

カメラ・加速度・ジャイロスコープ・磁力計・GPU・時計などオールインワン計器としてスマホを活用するのオススメ
現役エンジニアおすすめの仕事道具
【仕事効率化】現役エンジニアおすすめの仕事道具(キーボード・文房具など)現役エンジニアの”はやぶさ”が仕事効率UPのために使っている仕事道具(キーボード・マウス・文房具など)を紹介します。自分に合う道具を使って気持ちよく仕事をしましょう!...

スマホの加速度センサで腹筋データ取得して振動解析してみたり…

振動の基礎
【データ分析入門】機械学習未使用!Pythonでゼロから始める振動解析機械学習(深層学習含む)によるデータサイエンスが流行っていますが、フーリエ解析などの振動解析により、異常検知を行うこともできます。本記事はデータ分析/振動解析学ぶための実践的なチュートリアル記事です。...

スマホのジャイロスコープで波動拳モーションのデータ取得して時系列データ予測してみたり…

MXNetとGluonTSによる時系列データ予測
MXNetとLSTMで時系列データ予測 -入門から実践まで-こんにちは。 ディープラーニングお兄さんの”はやぶさ”@Cpp_Learningだよー 前回『MXNetで物体検出』に関する...

スマホ一つで様々なデータを取得することができます!

スマホのセンサ値をM5Stackで活用する例

多くのセンサが手のひらサイズに収まるので、スマホは本当に便利です。このスマホを上手に活用することで、M5Stackを手軽にパワーアップできます。

【スマホ活用術】

  • M5Stackとスマホを接触した状態で使って手軽にM5Stackを”多機能化”
  • スマホの加速度やジャイロを使ってM5Stackを”リモートコントロール”
  • スマホのGPSや磁力計データをM5Stackでモニターする”スマホ状態監視”

などスマホとM5Stackの連携で、出来ることの自由度が大幅に広がります!

ZIG SIM -電子工作のプロトタイピング用スマホアプリ-

今回、M5Stackアプリは自作しましたが、スマホアプリについてはZIG SIMを使いました。

ZIG SIM

ZIG SIM

1-10無料posted withアプリーチ

ZIG SIMとは、スマホを多機能センサとして活用し、電子工作やマイコンプログラミングのプロトタイピングを強力にサポートしてくれスマホアプリです。

【ZIG SIMの特徴】

  • スマホに搭載されたセンサを簡単に使える
  • 複数のセンサ値を同時に取得できる
  • センサ値をJSON形式で扱える
  • Wifi(UDP/TCP)通信で簡単にセンサ値を送信できる
  • タイムスタンプも取得できる

M5StackなどのWifi搭載モジュールにデータ送信でき、かつセンサ値がJSON形式で扱えるので、データ受信とJSON形式の読み込みができれば、スマホのセンサ値を活用したアプリを自作できます。

ZIG SIMのデータ構造(JSON形式)については、以下の記事が参考になりました。

【ArduinoJSON】M5Stackで使えるJSONライブラリ

M5Stack(Arduino)でJSON読み書きするなら、直観的に使えるArduinoJSONがオススメです。

ArduinoJSON

引用元:ArduinoJSON|公式サイト

インストール方法については、以下の記事が参考になります。

実践!M5Stackでスマホの各センサ値を取得する

今回、ZIG SIMArduinoJSONなどを上手に利用して『M5Stackでスマホの各センサ値を取得する』M5Stackアプリを作成しました。

通信メインのアプリなので、ネットワーク概要を説明した後でソースコードを公開します。

アクセスポイント・データ送信側・データ受信側・通信方式・ネットワークなどの説明があると、とても勉強になるので読んでて嬉しくなるよね(*・ω・)ノ♪

ネットワーク概要

今回、構築したネットワークの概要は以下の通りです。また、通信方式にはUDPを採用しました。

M5StackとスマホのUDP通信

【ネットワーク概要】

  • アクセスポイント:ホームルータ
  • UDPデータ送信側:ZIG SIMインストール済みスマホ※
  • UDPデータ受信側:M5Stack※

※iPhoneXとM5Stack Grayで動作確認しました

UDPを採用した理由は、通信の信頼性よりも高速性を重視したかったからです。

M5Stackアプリ』のソースコード

『UDP受信でスマホのセンサ値(JSON形式)を取得するM5Stackアプリ』のソースコードが以下です。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>

#define N 1024

const char* ssid     = "yourssid";
const char* password = "yourpassword";
const int port = ****;

// The udp library class
WiFiUDP udp;

void print_wifi_state(){
	M5.Lcd.clear(BLACK);  // clear LCD
  	M5.Lcd.setTextColor(YELLOW);
  	M5.Lcd.setCursor(3, 3);
	M5.Lcd.println("");
	M5.Lcd.println("WiFi connected.");
	M5.Lcd.print("IP address: ");
	M5.Lcd.println(WiFi.localIP());
	M5.Lcd.print("Port: ");
	M5.Lcd.println(port);
}

void setup_wifi(){
	M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    M5.Lcd.print("Connecting to ");
    M5.Lcd.println(ssid);

	// setup wifi
    WiFi.mode(WIFI_STA);  // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
    WiFi.begin(ssid, password);
	// WiFi.begin();

	// Connecting ..
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        M5.Lcd.print(".");
    }

	// print state
    print_wifi_state();

    udp.begin(port);
}

void printSensorValue(String name, 
						double x, 
						double y, 
						double z, 
						String timestamp, 
						boolean printTime){
	String nameX = name + ":x: ";
	String nameY = name + ":y: ";
	String nameZ = name + ":z: ";

	if(printTime == true){
		M5.Lcd.println(timestamp);
		M5.Lcd.println("");
	}
	M5.Lcd.print(nameX);
	M5.Lcd.println(x);
	M5.Lcd.print(nameY);
	M5.Lcd.println(y);
	M5.Lcd.print(nameZ);
	M5.Lcd.println(z);
	M5.Lcd.println("");
}

void setup() {
	M5.begin();

	// setup wifi
	setup_wifi();
}

void loop() {
	char packetBuffer[N];
	int packetSize = udp.parsePacket();
	DynamicJsonDocument doc(N);

	// get packet
	if (packetSize){
		int len = udp.read(packetBuffer, packetSize);
		if (len > 0){
			packetBuffer[len] = '\0'; // end
		}
		// for JSON
		deserializeJson(doc, packetBuffer);
  		JsonObject obj = doc.as<JsonObject>();

		// get param
		String timestamp = obj["timestamp"];
		double accelX = obj["sensordata"]["accel"]["x"];
    	double accelY = obj["sensordata"]["accel"]["y"];
    	double accelZ = obj["sensordata"]["accel"]["z"];
		double gravityX = obj["sensordata"]["gravity"]["x"];
    	double gravityY = obj["sensordata"]["gravity"]["y"];
    	double gravityZ = obj["sensordata"]["gravity"]["z"];
		double gyroX = obj["sensordata"]["gyro"]["x"];
    	double gyroY = obj["sensordata"]["gyro"]["y"];
    	double gyroZ = obj["sensordata"]["gyro"]["z"];

		// print param
		M5.Lcd.clear(BLACK);
  		M5.Lcd.setCursor(3, 3);
		M5.Lcd.setTextColor(GREEN);
		printSensorValue("accel", accelX, accelY, accelZ, timestamp, true);
		printSensorValue("gravity", gravityX, gravityY, gravityZ, "", false);
		printSensorValue("gyro", gyroX, gyroY, gyroZ, "", false);
	}
}

個人的によく使う「加速度」・「重力加速度」・「ジャイロスコープ」を扱う仕様になっています。「GPS」・「磁力計」などを扱いたい場合は、該当するセンサのJSON形式を確認し、本ソースコードを改良して下さいな(*・ω・)ノ♪

『M5Stackでスマホのセンサ値を取得するアプリ』の使い方

以降で受信側(M5Stackアプリ)・送信側(ZIG SIM)の使い方を説明します。

M5StackとスマホのUDP通信

M5Stackアプリの使い方 -UDPデータ受信-

まずは、受信側(M5Stackアプリ)の使い方を説明します。上記ソースコードをインストールしたM5Stackを用意して、電源ONするだけです。

M5StackとスマホのUDP通信

電源ONすれば、自動で「ネットワーク接続」 ⇒ 「UDP受信待ち」状態に移行します。

「UDP受信待ち」状態でデータ受信したら、タイムスタンプとセンサ値を表示します。

M5Stackの通信状態に応じて表示が変わりますので、〇〇状態のときに通信が不安定になる…などを確認してみて下さい。

「❶ネットワーク接続」が上手くいかないときは、アクセスポイントの電源がOFFになっていないか?などを疑ってみてください。

ZIG SIMの使い方 -UDPデータ送信-

続いて、送信側(ZIG SIM)の使い方を説明します。

ZIG SIM

「Setting(設定)」⇒「Select(センサ選択)」⇒「Sensing(計測開始)」の順にスマホを操作すれば、選択したセンサで「計測」および「センサ値の送信」が始まります。

IPアドレス/ポート番号はM5Stackの表示「❷UDP受信待ち」で確認できます

アプリを動作確認したときの動画が以下です。スマホのセンサ値と同じ値がM5Stackにも表示できています。

https://twitter.com/Cpp_Learning/status/1165095945970667520

※冒頭と同じ動画です

まとめ

M5Stackは大人も子供もプログラミングを楽しめる素敵なマイコンモジュールです。

くるる
くるる
無線通信やセンサを使ったM5Stackアプリを作りたい!

と考えているフクロウ@kururu_owlや人をサポートしたいと想い…

汎用的な『M5Stackでスマホのセンサ値を取得するアプリ』の作り方・使い方を公開しました。

このアプリをベースにしたオリジナルアプリを作りました!

なんて人が現れたら最高に嬉しいです!

はやぶさ
はやぶさ
本記事のソースコードは好き改良してOKです!

自由な発想でプログラミングを楽しんでくださいね(*・ω・)ノ♪

M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...
M5Stackおしゃべり代行アプリ
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作るM5Stack(Wifiサーバ)とPC(クライアント)をTelnetで無線通信して、PCのキーボードから入力した文字をM5Stackアバターが読み上げる「おしゃべり代行アプリ」を作りました。アプリの使い方はもちろんソースコードも公開しています。遊んでくれたら嬉しいです。...
]]>
https://cpp-learning.com/m5stack_iphone/feed/ 0 3383
M5StackとPCの無線通信による「おしゃべり代行アプリ」を作る https://cpp-learning.com/m5stack_telnet/ https://cpp-learning.com/m5stack_telnet/#respond Tue, 20 Aug 2019 12:20:46 +0000 https://cpp-learning.com/?p=3326 こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

前回『M5Stackアバターおしゃべりアプリ』の作り方に関する記事を書きました。

M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...

Aボタン(一番左のボタン)を押すと”設定したセリフ”をしゃべるアプリです。

ただし、このアプリだと1フレーズしかしゃべれないので…

くるる
くるる
もっと色んなセリフをしゃべらせたーい♪
くるる
くるる
口内炎が痛いときに代行にしゃべらせたーい♪

と面白いアイデアを閃くフクロウの”くるる”ちゃん@kururu_owlがいるので…

作ってみました(*・ω・)ノ♪

https://twitter.com/Cpp_Learning/status/1162669032702537733

M5Stackと無線接続したPCのキーボードから文字を入力すると、その文字をアバターがおしゃべりしてくれます!

くるる
くるる
こういうの待ってた!

本記事で『おしゃべり代行アプリ』の作り方を説明します。

注意点

最初に注意点を説明しておきます。

私の保有しているアクセスポイントとM5Stackの相性が良くないみたいで、通信が不安定な状態で動作確認しています…

また、M5Stack Grayを使っているのですが、M5Stack-AvatarやWifi接続などの複数機能を盛り込むとメモリ不足になるという情報をキャッチしています。

  • 通信状態が不安定な環境
  • メモリ不足
  • ひょっとしたらソースコードにバグあり

以上3点により、ご紹介する「おしゃべり代行アプリ」が上手く動作しない可能性があります。

こんな状態でブログ記事を書いて良いのか少し悩みましたが…

私自身が「上手くいった事例」と同じくらい「上手くいかなかった事例」を欲しているので…

「良い所」も「悪い所」も情報共有したいと想い、本記事を書きました。

くるる
くるる
くるる
「おしゃべり代行アプリ」を試してみて、不具合が出たらごめんなさい

以上の注意点を考慮し、それでも興味を持ってくれる人は以降を読み進めて頂けると嬉しいです!

本記事を書くモチベーション(読み飛ばしOK)

はやぶさ
はやぶさ
「良い所」も「悪い所」も情報共有したい

という理由以外にも本記事を書きたいと思った理由がありますので、少し小話を…

くるる
くるる
口内炎が痛いときに代行でしゃべらせたーい♪

その気持ち…分かる!

くるる
くるる
目が合うと上手く喋れない!でもメールだと味気ない…

うん。まぁ分かるかも…

あと少しだけ真面目な話をすると、口内炎に限らず「手は動くけど、口を上手く動かせない…」という人がいるかもしれない。。

くるる
くるる
くるる
可愛らしいM5Stackアバターが代行して、自分の言葉をしゃべってくれる!嬉しい!!
はやぶさ
はやぶさ
”くるる”ちゃんのように笑顔になってくれる人が少しでもいたら嬉しいな!

とか考えながら「おしゃべり代行アプリ」を作成しました(*・ω・)ノ♪

(小話 完)

以降から本編です。

機能検討

最初に『開発したいアプリ』を実現するための”機能”を検討します。

今回の場合アバターにおしゃべり代行してもらうアプリ』です。

”アバターおしゃべりアプリ”については、以下の記事で作り方を紹介しています。

M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...

なので、この記事で紹介した”おしゃべりアプリ””代行の機能”を追加してみます。

TelnetでWifiサーバ(M5Stack)とクライアント(PC)を通信

「手は動く」という前提で”おしゃべり代行の機能”を検討してみます。色んな方法がありますが…

M5StackとTelnet通信

使い易さなどを考慮すると、キーボード入力した文字列をM5Stackに読み上げてもらうのが良さそうです。

具体的には、ホームルータやスマホなどをアクセスポイントとしたネットワークを構築し、Telnetで通信を行います(以下がイメージ図です)

ネットワークやIPアドレス

今回、Telnetを採用した理由については以下の通りです。

  • 単純な文字データが送信できれば良い
  • セキュリティよりも(私が)実現しやすい方法を優先

M5StackとPC間でTelnetを使う方法については、先駆者がいますので参考にさせて頂きます。

実践!M5Stackアバターによる「おしゃべり代行アプリ」を作る

m5stack-avatar/examples/talkM5Stack/Telnetを組み合わせた「おしゃべり代行アプリ」のソースコードが以下です。

#include <AquesTalkTTS.h>
#include <Avatar.h>
#include <M5Stack.h>
#include <tasks/LipSync.h>
#include <WiFi.h>
#include <string>

#define N 15

using namespace m5avatar;

// AquesTalk License Key
// NULL or wrong value is just ignored
const char* AQUESTALK_KEY = "XXXX-XXXX-XXXX-XXXX";

// for wifi setup
const char* ssid     = "yourssid";
const char* password = "yourpassword";
const int port = ****;

Avatar avatar;
WiFiServer server(port);

void setup_wifi(){
	M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(3, 10);
    M5.Lcd.print("Connecting to ");
    M5.Lcd.println(ssid);

	// wifi setup
    WiFi.mode(WIFI_STA);  // WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF
    WiFi.begin(ssid, password);
	// WiFi.begin();

	// Connecting ..
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        M5.Lcd.print(".");
    }

    // run server
    server.begin();
}

void setup() {
    int iret;
    M5.begin();

	// setup wifi
	setup_wifi();

    // For Kanji-to-speech mode (requires dictionary file saved on microSD)
    // See http://blog-yama.a-quest.com/?eid=970195
    // iret = TTS.createK(AQUESTALK_KEY);
	iret = TTS.create(AQUESTALK_KEY);
    M5.Lcd.setBrightness(30);
    M5.Lcd.clear();
    avatar.init();
    avatar.addTask(lipSync, "lipSync");
}

void loop() {
	WiFiClient client = server.available();

	char c;
	char message[N];
	int i = 0;

	if (client) {
		while (client.connected()) {
			if (client.available()) {
				c = client.read();
				// push "c"
				if (c != '\n' && i < N-1) {
					message[i] = c;
					i++;
				}else{
					// Need to initialize with createK(AQUESTALK_KEY)
					// TTS.play("こんにちは。", 80);
					TTS.play(message, 80);
					avatar.setSpeechText(message);
					delay(1000);
					// clear "c"
					while (i >= 0){
						i--;
						message[i] = ' ';
					}
					i = 0;
				}
			}
		}
	}else{
		avatar.setSpeechText("Client Disconnected.");
		delay(1000);
		avatar.setSpeechText("");
	}
}

通信アプリを作るとき、送信側と受信側でそれぞれアプリを作成する場合が多いけど、今回は受信側(M5Stack)のアプリのみでOKです!

Telenetのインストール方法

おしゃべり代行」を使う前準備として、PC側でTelenetが使えるようにしておきます。

今回はWindow10からTelnetを使ってみます。セットアップ手順については、以下の記事が参考になりました。

「おしゃべり代行アプリ」の使い方

おしゃべり代行アプリ」を使うときの手順は以下の通りです。

おしゃべり代行アプリの使い方

  1. 「おしゃべり代行アプリ」をインストールしたM5Stackの電源ON
  2. PCのTelenet起動
  3. キーボードで文字入力(14文字以内)
  4. 「Enterキー」を押すとM5Stackが入力した文字を読み上げます

順番に説明しますね(*・ω・)ノ♪

M5Stackの通信状態を見ながらキーボードで遠隔操作

PCとの通信状態に応じて、M5Stackアバターの表示が以下のように変化します。

M5Stackおしゃべり代行アプリ

「おしゃべり代行アプリ」をインストールしたM5Stackを電源ONすると「PC通信待ち」の状態になります。M5Stack側の操作はこれだけで、以降はPC側の操作になります。

コマンドプロンプトに以下のコマンドを入力してTelnetを起動します。

telnet M5StackのIPアドレス [ポート番号]

例えば、こんな感じです。

telnet 192.168.2.3 5555

ただし、これだとローカルエコー(キーボード入力した文字の表示)がないため、以下のコマンドでローカルエコーを有効にする方が個人的に好きです。

telnet
set localecho
o 192.168.2.3 5555

PCがM5Stackとの通信接続に成功すると「文字入力待ち」状態になるので、14文字以内のフレーズを入力します。例えば「kururu」と入力してみます。

kururu

するとM5Stackアバターに入力した文字が表示されます。最後に「Enterキー」を押すとM5Stackアバターが入力した文字を読み上げます。

Telnetの起動は最初の1度だけで良く、「キーボード文字入力」→「Enter」を繰り返すことで、M5Stackアバターが「おしゃべり代行」してくれます。

https://twitter.com/Cpp_Learning/status/1162669032702537733

※冒頭と同じ動画です。

くるる
くるる
くるる
kururukawaii

M5Stackアバターに色んなセリフを喋らせてニコニコしてる”くるる”ちゃんが今日も可愛い♪

まとめ

M5Stackを使って「何かの役に立つアプリ」や「楽しいアプリ」を作りたいと思い…

『おしゃべり代行アプリ』を作ってみました。

不具合がでる可能性もありますが、このアプリを使ってくれた人が笑顔になってくれたら最高に嬉しいです。

くるる
くるる
これはM5Stackによる告白代行が流行る予感!

誰に何を告白するのか気になるぞ!笑

はやぶさ
はやぶさ
アプリの使い方はお任せします。楽しんでくれたら嬉しいです。
M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
M5Stack Avatar Talk
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編-こんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 前回『M5Stack初心者におすすめしたい情報ま...
]]>
https://cpp-learning.com/m5stack_telnet/feed/ 0 3326
【M5Stack入門】アバターおしゃべりアプリの作り方 -PlatformIO IDE for VSCode編- https://cpp-learning.com/m5stack-talk/ https://cpp-learning.com/m5stack-talk/#respond Wed, 14 Aug 2019 02:46:46 +0000 https://cpp-learning.com/?p=3276 こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

前回『M5Stack初心者におすすめしたい情報まとめ』の記事を書きました。

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...

この記事を読んだらアプリ自作したくなっちゃうよね(*・ω・)ノ♪

くるる
くるる
う~ん。。自作したいけど、どんなアプリを作ろうかな?

と悩んでいるフクロウの”くるる”ちゃん@kururu_owlがいるので…

はやぶさ
はやぶさ
『アバターがしゃべるアプリ』などはいかがですか?

https://twitter.com/Cpp_Learning/status/1161188352642572289

くるる
くるる
こういうの待ってた!

本記事で『アバターに好きな言葉をしゃべらせるアプリ』の作り方を説明します。

機能検討

最初に『開発したいアプリ』を実現するための”機能”を検討します。

今回の場合アバターに好きな言葉をしゃべらせるアプリ』なので、以下の機能で実現できます。

アバターお喋りアプリの機能
  • アバター表示(アニメーション)
  • テキストを読み上げる(音声合成)

アバター表示については、M5Stack-Avatarというライブラリがあります!

テキスト読み上げについては、音声合成エンジンAquesTalk pico for ESP32があります!

先人の知恵を借りる

先に種明かしすると、m5stack-avatar/examples/talkのソースコードを使えば、簡単に『好きな言葉をしゃべらせる』を実現できました。

Aruduino IDEにAquesTalk-ESPをセットアップする方法は、以下のサイトで紹介しています。

本記事を書くモチベーション

くるる
くるる
くるる
サンプルコードがあって、セットアップ手順の紹介記事もあるなら、本記事を書く意味が…ない?

うむ!『M5Stackのアバターにしゃべらせる』ことが目的だと本記事を書く意味はないね(備忘録としては役に立つ)

ただ、”くるる”ちゃんVisual Studio Code好きでしょう?

くるる
くるる
すきー♪

PlatformIO IDE for VSCodeから『アバターに好きな言葉をしゃべらせる』アプリの開発ができたら嬉しい?

くるる
くるる
嬉しいー♪

もっと言うと、30分くらいでサンプルコード動かせたら…どうかな?

くるる
くるる
最高ー♪

というわけで、本記事は以下のモチベーションで書き上げました。

本記事の役割

PlatformIO IDE for VSCodeを使って、手軽に『M5Stackアバターお喋りアプリ』を動かす方法を伝えること

動作確認

今回は、Windows10にPlatformIO IDE for VSCodeをインストールしました。また、M5Stack Grayで動作確認しました。

M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

PlatformIO IDE for VSCodeインストール方法や基本的な使い方については、以下の記事で説明済みなので割愛します。

M5Stack
【M5Stack入門】初心者におすすめしたい情報まとめこんにちは。 現役エンジニアの”はやぶさ”@Cpp_Learningです。 先日、Maker Faire Tokyoや趣味T...
くるる
くるる
環境構築OK!今から30分でアプリ動かすよー

くるるやる気満々の”くるる”ちゃんが今日も可愛い(*・ω・)ノ♪

実践!M5Stack-AvatarのTalkアプリを動かす

先に手順を確認しておきます。

  1. 各種ダウンロード
  2. 各種設定
  3. プロジェクト生成
  4. ソースコード生成
  5. 動作確認

順番に説明していきます!

各種ダウンロード

最初に、M5Stack-Avatarをダウンロードします。

M5Stack_Avatar続いて、AquesTalk-ESPをダウンロードします。

AquesTalk-ESP

いずれもZIPファイルなので、適当な場所に展開してください。

各種設定

「m5stack-avatar-master」フォルダをリネームして、そのままプロジェクトとして使うので、今回は「m5stack-avatar-master」 ⇒ 「m5stack-avatar-kururu」とリネームしました。

AquesTalk-ESP解凍後にできる「aquestalk_esp32」を「m5stack-avatar-kururu/lib/」に移動させます。

M5Stack_Avatar

本来なら、platformio.ini(設定ファイル)を新規で作成するのですが、今回は既に用意してあるものを使います!

以上で前準備完了です。

くるる
くるる
10分経過~

プロジェクト生成

PlatformIO IDEを起動して「Import Arduino Project」をクリック

PlatformIO IDE for VSCode

以下の手順で「Import」します

PlatformIO IDE for VSCode
Import Arduino Project
  1. お使いのボード(M5Stack)を選択
  2. チェックを入れる
  3. Importしたいプロジェクトフォルダ(m5stack-avatar-kururu)を選択
  4. Importをクリック

ソースコード生成

「m5stack-avatar-kururu」が表示され、▷をクリックすると中身が確認できます。以下の手順で「main.cpp」を作成します

PlatformIO IDE for VSCode
ファイル追加
  1. srcをクリック
  2. 「新規ファイル作成ボタン」をクリック
  3. main.cpp作成

m5stack-avatar/examples/talkのソースコードをmain.cppにコピペします。そのままでも問題ありませんが、少し改良したものが以下です。

#include <AquesTalkTTS.h>
#include <Avatar.h>
#include <M5Stack.h>
#include <tasks/LipSync.h>
#include <M5StackUpdater.h> // for bin file

using namespace m5avatar;

// AquesTalk License Key
// NULL or wrong value is just ignored
const char* AQUESTALK_KEY = "XXXX-XXXX-XXXX-XXXX";

Avatar avatar;
void setup() {
  int iret;
  M5.begin();
  // for bin file
  if(digitalRead(BUTTON_A_PIN) == 0) {
    Serial.println("Will Load menu binary");
    updateFromFS(SD);
    ESP.restart();
  }
  // For Kanji-to-speech mode (requires dictionary file saved on microSD)
  // See http://blog-yama.a-quest.com/?eid=970195
  // iret = TTS.createK(AQUESTALK_KEY);
  iret = TTS.create(AQUESTALK_KEY);
  M5.Lcd.setBrightness(30);
  M5.Lcd.clear();
  avatar.init();
  avatar.addTask(lipSync, "lipSync");
}

void loop() {
  M5.update();
  if (M5.BtnA.wasPressed()) {
    // Need to initialize with createK(AQUESTALK_KEY)
    // TTS.play("こんにちは。", 80);
    TTS.play("hiyokodaisuki", 70);
    avatar.setSpeechText("PIYO PIYO");
    delay(1000);
    avatar.setSpeechText("");
  }
}

改良ポイントは以下の通り。

M5Stack LovyanLauncher対応】

  • 5行目:SD-Updater用のヘッダーファイル追記
  • 17~22行目:binファイル生成用コード追記

【好きな言葉をしゃべらせる】

  • 38行目:「喋らせたい言葉」と「喋る速さ」を変更
  • 39行目:アバターに表示する「吹き出し文字列」を変更
くるる
くるる
20分経過~

動作確認

左下の「チェックボタン」クリックでビルドが始まります。

PlatformIO IDE for VSCode

ビルド後に”firmware.bin”という名前で下記の場所に保存されます。

~\m5stack-avatar-kururu
      └─.pio
          └─build
             └─m5stack-grey
                └─firmware.bin

今回は「firmware.bin」 ⇒ 「piyopiyo.bin」にリネームします。このbinファイルをSDカードに移動して、SD-Updaterから実行すればOK!

https://twitter.com/Cpp_Learning/status/1161188352642572289

※冒頭と同じ動画です

くるる
くるる
ひよこ大好き♪
くるる
はやぶさ
はやぶさ
どっちも可愛いよー♪

FTP Server(SDCard)を使えば、SDカードを抜き差しせずにbinファイルを移動できます。以下のサイトが参考になります。

M5Stack LovyanLauncherの使い方|ラズパイズキノニッキ

くるる
くるる
25分で動作確認完了!すごーい♪

まとめ

『アバターに好きな言葉をしゃべらせるアプリ』の作り方を説明しました。ただし、Aruduino IDEを使った例は既にあったので、以下のモチベーションで本記事を書き上げました。

本記事の役割

PlatformIO IDE for VSCodeを使って、手軽に『M5Stackアバターお喋りアプリ』を動かす方法を伝えること

慣れもあると思いますが、30分以内に動作確認まで実施できると考えています。

くるる
くるる
時間がかかる”PlatformIO IDE”や”M5Stack用ライブラリ”がインストール済みな所からスタートするけどね
くるる
くるる
それでも”PlatformIO IDE”の使い方とか参考になりました!

”くるる”ちゃんのように感じてくれる人がいれば嬉しいです。

はやぶさ
はやぶさ
理系応援ブロガー”はやぶさ”@Cpp_Learningは頑張る理系を応援します!
M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

]]>
https://cpp-learning.com/m5stack-talk/feed/ 0 3276
【M5Stack入門】初心者におすすめしたい情報まとめ https://cpp-learning.com/m5stack/ https://cpp-learning.com/m5stack/#respond Mon, 12 Aug 2019 01:35:06 +0000 https://cpp-learning.com/?p=3154 こんにちは。

現役エンジニアの”はやぶさ”@Cpp_Learningです。

先日、Maker Faire Tokyo趣味TECH祭(旧裏メイカー祭)に遊びに行きました!

もう楽しくて楽しくて!笑顔の絶えない素敵なお祭りでした!

会場のあちこちで使われていたM5Stackが面白そう!ということで買っちゃいました(*・ω・)ノ♪

買ったは良いけど、何から始めれば良いの?どの言語を使うのかも分からない…

と少し悩んでいたら…Twitter経由で色々と教えて頂きました!感謝!!

おかげ様で順調なスタートを切ることができました!

教えて頂いた情報や調べて分かった内容など、M5Stack初心者向け情報をまとめました。

私のようなM5Stack入門者が道に迷わず進むためのガイドブックとして、本記事がお役に立つと嬉しいです!

M5Stackとは

M5Stackとは、5cm×5cmの小さくて可愛らしいマイコンモジュールです。

M5Stack

中身はこんな感じ。

M5Stack

小さくても機能たっぷりです!

仕様
  • Wi-Fi
  • Bluetooth
  • カラーTFT LCD(液晶)
  • ボタン
  • microSDカードスロット
  • バッテリー
  • スピーカー
  • Groveコネクタ

私が購入したM5Stack Grayだと、さらに加速度/ジャイロ/磁気を計測できる9軸センサを搭載しています!

M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

M5Stackの拡張モジュール

M5StackはWi-FiやBluetooth通信ができるので、IoTモジュールとして楽しむことができます。

また、拡張モジュールで機能を追加することもできます!個人的には、以下の拡張モジュールが気になっています(*・ω・)ノ♪

M5Stack用電池モジュール
スイッチサイエンス

M5Stack用GPSモジュール V2
スイッチサイエンス

M5Stack用ミニサーマルカメラユニット
スイッチサイエンス

このような拡張モジュールを積み上げて(Stackして)使える5cm×5cmサイズの凄いやつが”M5Stack”です!

M5Stackでできること

”ググると”M5Stackを使った作品を見つけることができます。

ゲーム/スマートウォッチ/水やりロボットなど、アイデア次第で様々なことができますね!

どのM5Stackシリーズを購入すべきか?

2019/08/10時点でM5Stackシリーズは全8種あり、今後も新製品がぞくぞく発売予定です。

そのため「どのM5Stackがオススメか?」という質問に対する回答は、とても悩ましいのですが…

初心者だし、最初はBasicを…

と考えている人はちょっと待って!

くるる
くるる
「数百円プラスするだけで9軸センサも手に入るGrayがオススメです!」と”くるる”は”くるる”は念を押します!!

某アニメの影響なのか、いつもと喋り方が違うフクロウの”くるる”ちゃん@kururu_owlが今日も可愛い(*・ω・)ノ♪

M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

SDカード選定

Raspberry PiだとSDカードとの相性問題がありますが、M5Stackだと相性問題がないのか、ほとんど情報を見つけられず、むしろ1,000円以下の安価なもので問題なし!という情報を得られました。

なので、このあたりのSDカードを使えば良いかと。

M5Stack公式ドキュメント

SDカードの容量については、32GB以下までOKという情報もありますが、公式では16GB以下を推奨しています(出荷時期に依存するかもしれません)

開発言語

以下の言語でM5Stack用アプリを開発することができます。

M5Stackの開発言語

好みもありますが、”ユーザー数の多さ”・”充実したライブラリ”・”サンプルコード数の多さ”を考慮すると、Aruduinoを使うのが良いと思います。

ユーザー数の多い言語やツールは情報量も多いので、知りたい情報を取得しやすい

開発環境構築

Aruduinoを使える二つの開発環境(IDE)を紹介します。

開発環境構築 -Arduino IDE編-

くるる
くるる
まずは”サッと”サンプルコードを動かしたい!

というフクロウや人には、Arduino IDEがオススメです。

環境構築からサンプルコード(スケッチ例)の動かし方まで、以下のサイトでとても丁寧に解説しています。

開発環境構築 -PlatformIO IDE for VSCode編-

くるる
くるる
使い慣れているVSCodeも使いたいな…

というフクロウや人には、Visual Studio Codeの拡張機能“PlatformIO IDE for VSCode”がオススメです。

環境構築からソースコードの”ビルド”・”書き込み”まで、以下の記事がイラスト付きで解説しており、とても参考になりました。

電源オフの仕方

側面の電源ボタンを2回押す。

くるる
くるる
誰かさんが電源オフできずに、何度もdeepSleep(PowerOFF)のスケッチを書いてたのは、ここだけの秘密だよ♪
  • 「長押し」では電源オフできません
  • 「USB給電中」は電源オフにできません ⇒ 気のせいかも

API

内蔵スピーカー/LCD/ボタンなどを使うためのAPIが用意してあります。

はやぶさ
はやぶさ
上手に利用して効率よくソースコード(アプリ)を開発しよう!
くるる
くるる
くるる
有るものは使う!無ければ作る!

駆け出しエンジニアの”くるる”ちゃん順調に成長中です(*・ω・)ノ♪

ライブラリ追加

標準ライブラリではなく、有志が公開している自作ライブラリを使いたい場合は、使用しているIDEにインストール(ライブラリ追加)をする必要があります。

例えば、M5Stack-Avatarというライブラリ使ってみたいですよね?

https://twitter.com/Cpp_Learning/status/1160181546667499520

ライブラリの追加方法は使用する開発環境(IDE)に依存するので、それぞれ説明します。

ライブラリ追加 -Arduino IDE編-

Arduino IDEにライブラリを追加する方法は、以下の記事で丁寧に説明しています。

ライブラリ追加 -PlatformIO IDE for VSCode編-

PlatformIO IDE for VSCodeにライブラリを追加する方法は、以下の記事で丁寧に説明しています。

【開発環境構築 -PlatformIO IDE for VSCode編-】でも紹介した記事です

M5Stack用ランチャー -LovyanLauncher-

M5Stackをあっと言う間に多機能化できるM5Stack LovyanLauncherがスゴ過ぎる!

らびやんランチャー開発者様のTwitterより

くるる
くるる
凄すぎて~凄すぎて~♪

くるるM5Stack LovyanLauncherの存在を知ったあと、速攻でインストールしました!

以降でインストール方法とおそらく一番よく使う機能”SD-Updater”の使い方を紹介します。

らびやんランチャーのインストール方法

M5Burnerを使うと簡単にインストール/アンインストールが行えます

なので、まずはM5Stack|公式ダウンロードページから使っているOSを選択してM5Burnerをダウンロードします。

M5Burner

例えば、Windowsを選択すると”M5Burner.zip”がダウンロードされるので、適当な場所に展開してださい。

M5Burner

M5StackとPCを接続した状態で”M5Burner.exe”を起動し、以下の手順で”LovyanLauncher”をインストールします。

M5Burnerでらびやんランチャーをインストールする
M5Burnerによるインストール手順
  1. ”LovyanLauncher”を選択
  2. COMポート/ボーレート/シリーズ(フラッシュの容量)を設定
  3. ”Burn”で書き込み/”Erase”で削除

❷について、少し注意したい点があります。

【COMポート】

M5Stackが接続されたCOMポートを選択(自動で候補が出てくるハズ)

【ボーレート】

通信に失敗する場合は、”115200”など小さい値を設定

【シリーズ】

M5Stack Grayの新モデル(2019/02/07以降に出荷したもの)は、フラッシュの容量が16 MBに増量されたモデルなので、”Stask-16MB”を選択※

※Stask-4MBでも動作確認完了。もしモデル不明の場合は4MB選択でも良いかと

SD-Updaterの使い方

SD-Updaterとは、SDカードに保存した複数アプリを切り替えて実行できる機能です。

https://twitter.com/Cpp_Learning/status/1160446425689313280

動画を見るだけで、直観的に使えそうですが、言語化すると以下の通りです。

SD-Updaterの使い方
  1. SDカードにアプリ(binファイル)を保存
  2. M5StackにSDカードを挿して、電源ON
  3. SD Updaterを選択
  4. 好きなアプリ(binファイル)を選択
くるる
くるる
何度でも~何度でも~言うよ~♪
くるる

らびやんランチャー用binファイルの作り方

SDカードに保存するbinファイルの作成方法ですが、こちらもIDE別で説明します。

binファイルの作り方 -Arduino IDE編-

“M5Stack-SD-Updaterライブラリ”の追加方法からbinファイルの作成方法まで、以下のサイトでとても丁寧に解説しています。

【開発環境構築 -Aruduino IDE編-】でも紹介したサイトです

binファイルの作り方 -PlatformIO IDE for VSCode編-

”M5Stack-SD-Updaterライブラリ”の追加方法については、本記事の【ライブラリ追加 -PlatformIO IDE for VSCode編-】をご参照ください。

binファイル作成のために”main.cpp”へ追記するコードは、上記【binファイルの作り方 -Arduino IDE編-】と同じです。

Arduino IDEとの違いはbinファイルの保存場所です。PlatformIO IDEの場合、ビルド後に”firmware.bin”という名前で下記の場所に保存されます。

~\my_project
      └─.pio
          └─build
             └─m5stack-grey
                └─firmware.bin

その他 -困ったときは-

本記事を読んでも解決できなかった問題については、以下の公式サイトなどを参照することで解決できるかもしれません(*・ω・)ノ♪

おわりに

本記事で、M5Stack初心者におすすめしたい情報をまとめました。私自身がM5Stack入門したばかりなので、入門者という視点で…

はやぶさ
はやぶさ
これだけ知っていれば、あとはアイデア次第で何でも出来そう!

という内容に仕上げました。

今後、私のようにM5Stack入門したい人が最短コースで学べるガイドブックとして、本記事がお役に立つと嬉しいです!

はやぶさ
はやぶさ
理系応援ブロガー”はやぶさ”@Cpp_Learningは頑張る理系を応援します!
くるる
くるる
M5Stackライフを満喫してねー♪
M5Stack Gray(9軸IMU搭載)
スイッチサイエンス

]]>
https://cpp-learning.com/m5stack/feed/ 0 3154