こんにちは。
現役エンジニアの”はやぶさ”@Cpp_Learningです。
前回、M5StackとスマホをUDP通信するアプリの作り方・使い方の記事を書きました。
今回は、スマホではなくPCとUDP通信するM5Stackアプリを作りました。
深層学習などの負荷が大きい演算はPC(Python)にやらせて、演算結果をM5Stackに送信して、ごにょごにょ…
みたいなことが出来ると面白そうなので、送信側のソースコードはPythonで作成しました。
本記事で、受信側(Arduino)と送信側(Python)の両ソースコードを紹介します。
Contents
UDP通信用ネットワーク
今回、通信テストのために構築したネットワークの概要は以下の通りです。
ホームルータやスマホなどをアクセスポイントとしたネットワークを構築し、UDPで通信します。
【ネットワーク概要】
- アクセスポイント:ホームルータまたはスマホ(※1)
- UDPデータ送信側:Python環境構築済みPC
- UDPデータ受信側:M5Stack(※2)
(※1)ホームルータおよびiPhoneXのテザリングでテストしました
(※2)M5Stack Grayを使いました
M5Stackアプリのソースコード -UDPデータ受信-
M5StackでUDPデータを受信するアプリについては、以下の記事で説明しています。
この記事のソースコードをシンプルに通信のみを行うコードに改良します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#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通信するソースコードについては、以下の記事のコードがそのまま使えました。
この記事で送受信のコードを紹介していますが、今回使うのは送信側のコードのみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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通信の手順】
- 「UDP通信アプリ」をインストールしたM5Stackの電源ON
- PCのターミナルからudpy.pyを起動
- ターミナルにキーボードから文字入力
私が通信テストしたときの様子が以下です。
M5StackとPCのUDP通信テスト
PC側の言語はPythonです pic.twitter.com/dA8E7igfoa— はやぶさ (@Cpp_Learning) August 28, 2019
【応用】おしゃべり代行アプリ(UDP版)を作る
雛形コードの紹介だけだと、あまり面白くないので…ちょっとだけ応用を考えてみます。
以前、Telnet通信を使った「おしゃべり代行アプリ」を作りました。
今回は、TelnetではなくUDPで「おしゃべり代行」を実現してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
#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ソースコードは同じものを使います。
通信方式が違うだけで、やってることは「おしゃべり代行」なので、前回の記事で紹介した動画を改めて紹介。
#M5Stack とPCを無線通信させて実現したかった「おしゃべり代行アプリ(仮)」ができた! pic.twitter.com/lkoKzvHV43
— はやぶさ (@Cpp_Learning) August 17, 2019
M5StackとPCやスマホを通信させるの楽しいですね!
我が家の環境だとTelenetよりUDP通信の方が安定します。。なぜだろう?
まとめ
M5Stack(Arduino)とPC(Python)でUDP通信する『雛形ソースコード』を紹介しました。
また、雛形コードを使った応用として「おしゃべり代行アプリ」を作ってみました。参考になれば嬉しいです。
冒頭にも書きましたが、深層学習などの負荷が大きい演算はPC(Python)にやらせて、演算結果をM5Stackに送信して、ごにょごにょ…
みたいなことを実践する人が現れたら最高に嬉しいです。
自由な発想でプログラミングを楽しんでくださいね(*・ω・)ノ♪