こんにちは。
現役エンジニアの”はやぶさ”@Cpp_Learningです。
最近、M5Stackで遊ぶのがマイブームです!”調べた内容”や”自作アプリ”については本ブログで公開しています。
今回は『M5Stackでスマホのセンサ値を取得するアプリ』を作りました。
#M5Stack でスマホのセンサ値を取得できるアプリ作った! pic.twitter.com/Qq1lMPD2dg
— はやぶさ (@Cpp_Learning) August 24, 2019
M5Stackとスマホを無線通信(UDP)で接続して、スマホの各センサ値(加速度・ジャイロ・GPSなど)をまるっと取得しています。
本記事で「アプリの作り方」・「使い方」を説明します。
Contents
スマートフォンを多機能センサとして使う
以前、私の仕事道具について記事を書きました。その中の一つにスマートフォンがあります。
スマホの加速度センサで腹筋データ取得して振動解析してみたり…
スマホのジャイロスコープで波動拳モーションのデータ取得して時系列データ予測してみたり…
スマホ一つで様々なデータを取得することができます!
スマホのセンサ値をM5Stackで活用する例
多くのセンサが手のひらサイズに収まるので、スマホは本当に便利です。このスマホを上手に活用することで、M5Stackを手軽にパワーアップできます。
【スマホ活用術】
- M5Stackとスマホを接触した状態で使って手軽にM5Stackを”多機能化”
- スマホの加速度やジャイロを使ってM5Stackを”リモートコントロール”
- スマホのGPSや磁力計データをM5Stackでモニターする”スマホ状態監視”
などスマホとM5Stackの連携で、出来ることの自由度が大幅に広がります!
ZIG SIM -電子工作のプロトタイピング用スマホアプリ-
今回、M5Stackアプリは自作しましたが、スマホアプリについては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がオススメです。
インストール方法については、以下の記事が参考になります。
実践!M5Stackでスマホの各センサ値を取得する
今回、ZIG SIM・ArduinoJSONなどを上手に利用して『M5Stackでスマホの各センサ値を取得する』M5Stackアプリを作成しました。
通信メインのアプリなので、ネットワーク概要を説明した後でソースコードを公開します。
アクセスポイント・データ送信側・データ受信側・通信方式・ネットワークなどの説明があると、とても勉強になるので読んでて嬉しくなるよね(*・ω・)ノ♪
ネットワーク概要
今回、構築したネットワークの概要は以下の通りです。また、通信方式にはUDPを採用しました。
【ネットワーク概要】
- アクセスポイント:ホームルータ
- UDPデータ送信側:ZIG SIMインストール済みスマホ※
- UDPデータ受信側:M5Stack※
※iPhoneXとM5Stack Grayで動作確認しました
UDPを採用した理由は、通信の信頼性よりも高速性を重視したかったからです。
『M5Stackアプリ』のソースコード
『UDP受信でスマホのセンサ値(JSON形式)を取得するM5Stackアプリ』のソースコードが以下です。
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#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アプリ)の使い方を説明します。上記ソースコードをインストールしたM5Stackを用意して、電源ONするだけです。
電源ONすれば、自動で「ネットワーク接続」 ⇒ 「UDP受信待ち」状態に移行します。
「UDP受信待ち」状態でデータ受信したら、タイムスタンプとセンサ値を表示します。
M5Stackの通信状態に応じて表示が変わりますので、〇〇状態のときに通信が不安定になる…などを確認してみて下さい。
「❶ネットワーク接続」が上手くいかないときは、アクセスポイントの電源がOFFになっていないか?などを疑ってみてください。
ZIG SIMの使い方 -UDPデータ送信-
続いて、送信側(ZIG SIM)の使い方を説明します。
「Setting(設定)」⇒「Select(センサ選択)」⇒「Sensing(計測開始)」の順にスマホを操作すれば、選択したセンサで「計測」および「センサ値の送信」が始まります。
IPアドレス/ポート番号はM5Stackの表示「❷UDP受信待ち」で確認できます
アプリを動作確認したときの動画が以下です。スマホのセンサ値と同じ値がM5Stackにも表示できています。
#M5Stack でスマホのセンサ値を取得できるアプリ作った! pic.twitter.com/Qq1lMPD2dg
— はやぶさ (@Cpp_Learning) August 24, 2019
※冒頭と同じ動画です
まとめ
M5Stackは大人も子供もプログラミングを楽しめる素敵なマイコンモジュールです。
と考えているフクロウ@kururu_owlや人をサポートしたいと想い…
汎用的な『M5Stackでスマホのセンサ値を取得するアプリ』の作り方・使い方を公開しました。
なんて人が現れたら最高に嬉しいです!
自由な発想でプログラミングを楽しんでくださいね(*・ω・)ノ♪