第9回 - インターネット 編【PLEN5Stackでプログラミング学習】
こんにちは!
PLEN Projectの松原です。
第9回となる インターネット 編では、
・JSON形式とは
・インターネットから天気予報を取得
・天気予報に応じたロボット制御
以上をご紹介致します。
PLEN5Stackについての詳細は、ホームページをご確認ください。
この記事は連載形式となっておりますので、他の回は以下のマガジンから!
0. 下準備
まずUIFlowにアクセスしましょう。
☆UIFlowはM5Stackをビジュアルプログラミングするためのツール
☆Chrome系ブラウザでのご利用を推奨します
☆ブックマーク登録を行うと次回以降便利です
以下から最新版のライブラリーをダウンロードし、UIFlowで開いてください。
2020/11/4 のライブラリー更新で、連続歩行に対応しました
下準備の詳細に関しましては、第1回の記事をご確認ください。
今回は、OpenWeatherMapというサイトから、天気予報のデータを取得してみます。
そのデータを使って、ディスプレイ表示や目の色の変更、腕を使ったアナログメーターの実装などを行ってみましょう!
1. OpenWeatherMap
今回は、OpenWeatherMapというサイトから、天気を取得しますが、取得には、アカウント作成が必要です(無料)。
以下のサイトにアクセスします。
Sign in を押し、ログイン画面を開きます。
初回利用ですので、Create an Account を押し、アカウントを作成します。
ユーザー名やメールアドレス、パスワード等を設定し、Create Account を押して、アカウントを作成します。
登録メールアドレスに届いた認証メールを開き、 Verify your email を押して、認証を行います。
Verify your email を押すと、以下の画面が表示されます。Companyは空白に、Purposeは Education/Science に設定し、Save を押して保存します。
天気予報の取得には、API key と呼ばれる認証コードが必要なので、API keysを押して、APIキーを確認します。
APIキーをコピーしておきます。
以下にアクセスすると、現在の天気が取得できます。
(都市名とAPIキーは書き換えて下さい)
https://api.openweathermap.org/data/2.5/weather?units=metric&lang=en&q=都市名,jp&appid=APIキー
例えば、都市名 Osaka でアクセスすると、ブラウザには以下のように表示されました。
{"coord":{"lon":135.5,"lat":34.69},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":17.41,"feels_like":15.07,"temp_min":16,"temp_max":18,"pressure":1025,"humidity":36},"visibility":10000,"wind":{"speed":1,"deg":0},"clouds":{"all":0},"dt":1604558384,"sys":{"type":1,"id":8032,"country":"JP","sunrise":1604524931,"sunset":1604563258},"timezone":32400,"id":1853909,"name":"Osaka","cod":200}
少し分かりにくいので、改行してみます。
以下のようなデータ形式のことを JSON形式 (ジェーソン) と呼びます。
{
"coord": {
"lon": 135.5,
"lat": 34.69
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 17.41,
"feels_like": 15.07,
"temp_min": 16,
"temp_max": 18,
"pressure": 1025,
"humidity": 36
},
"visibility": 10000,
"wind": {
"speed": 1,
"deg": 0
},
"clouds": {
"all": 0
},
"dt": 1604558384,
"sys": {
"type": 1,
"id": 8032,
"country": "JP",
"sunrise": 1604524931,
"sunset": 1604563258
},
"timezone": 32400,
"id": 1853909,
"name": "Osaka",
"cod": 200
}
今回は、上記のようなデータを取得し、太文字部分を抜き出してM5Stackの画面に表示してみます。
icon 現在の天気のアイコン
description 現在の天気
feels_like 体感気温
humidity 湿度
name 地名
iconやdescriptionは、以下の通りとなります。
アイコンは、種類が多いため、オリジナルアイコンを用います。
2. JSON形式
例えば、以下の変数があり、それぞれ値が代入されているとします。
これらの変数を1つにする方法として リスト というものがあります。
以下のように、[ ] の中に、, (コンマ) で区切って複数の値をまとめることができます。
ただし、これには、変数名が含まれない上に、全て文字列となってしまいます。
(リストに入れることのできる型は1種類)
そこで、JSON の出番となります。
以下のように { } の中に、 , (コンマ) で区切って複数の変数名と値をまとめることができます。
(JSONに入れることのできる型は自由)
ただし、JSONは形式がややこしいため、時と場合に応じて、リストと使い分けることが重要です。
JSON=複数の変数を文字列にまとめたもの!
3. データの受信
では、UIFlowを用いてM5Stackで天気のJSONデータを受け取ってみましょう。
Httpブロックを配置します。
これは、指定したURL先の内容を文字列で取得するブロックとなります。
先ほど確認した、OpenWeatherMapのURLを入力します。
https://api.openweathermap.org/data/2.5/weather?units=metric&lang=en&q=都市名,jp&appid=APIキー
(都市名とAPIキーは書き換え)
受け取ったデータを代入する変数 天気JSONデータ を作成します。
指定したURLから、データを取得できた場合、Success下にある処理が実行されます。
(これ以降の処理はSuccess下に配置していきましょう)
変数 天気JSONデータ に受け取ったデータをJSON形式として代入します。
(そのまま代入すると文字列扱い)
LCDに適当なラベルを配置し、変数 天気JSONデータ の中身を表示し、確認してみます。
実行してみると、
以下が表示されました。
(先ほど、ブラウザで確認した内容と同じですね!)
{"coord":{"lon":135.5,"lat":34.69},"weather":[{"id":520,"main":"Rain","description":"light intensity shower rain","icon":"09d"}],"base":"stations","main":{"temp":15.14,"feels_like":10.63,"temp_min":14.44,"temp_max":16,"pressure":1022,"humidity":54},"visibility":10000,"wind":{"speed":5.1,"deg":320},"clouds":{"all":75},"dt":1604992918,"sys":{"type":1,"id":8032,"country":"JP","sunrise":1604957221,"sunset":1604995015},"timezone":32400,"id":1853909,"name":"Osaka","cod":200}
整理したものが以下となります。
この中から、weather を抜き出してみます。
weather の中身を格納する変数を作成します。
Mapブロックを用いると、JSONデータから、名前を指定して特定の要素を抜き出すことができます。
以下を取得することができました。
[
{
"id": 520,
"main": "Rain",
"description": "light intensity shower rain",
"icon": "09d"
}
],
[ ] はリストなので、リストブロックを用いると、リストの中身が取得できます。
では、 description の中身を取得し、表示させてみましょう。
↓解答↓
description の中身を代入する変数を作成します。
Mapブロックを用いて、description を抜き出します。
今回、扱いたいデータは以下となります。
icon 現在の天気のアイコン
description 現在の天気
feels_like 体感気温
humidity 湿度
name 地名
先程と同様に、取得してみましょう!
↓解答↓
icon を取得してみます。
feels_like と humidity は main の中にあるため、
main を抜き出し、
feels_like と humidity を取得します。
name を取得します。
これで、必要なデータをインタネットから取得することができました!
次項では、取得したデータを表示させてみます。
ここまでのプロジェクトデータは以下より確認できます。
(UIFlowにライブラリーを追加してから開いてください)
4. UIデザイン
それでは、画面で表示する内容をUIFlowでデザインしてみましょう!
始めに、天気アイコンの画像をM5Stackに転送します。
以下のアイコンデータをダウンロードし、解凍してください。
UIFlow右上のからファイルマネージャーを開きます。
ファイルマネージャーでは、M5Stackへの画像データ転送や、転送データの削除などが可能です。
Reload を押して、M5Stackと接続します。
UIFlowがM5Stackと接続されたら、Add Image を押し、転送する画像データを選択します。
先ほどダウンロードしたアイコン画像を転送していきます。
(小,中,大のいずれかを転送してください)
全ての画像がM5Stackに保存されれば、UIFlowで Image をLCDに配置します。
プロパティを開き、転送したアイコン画像を選択し、変更します。
晴れアイコン(Fine.png) が表示されました。
あとはこれまで通り、長方形やラベル等を配置し、以下を表示できるようにします。
icon 現在の天気のアイコン
description 現在の天気
feels_like 体感気温
humidity 湿度
name 地名
↓解答↓
UIデザインは以下のようにしてみました。
(自由にデザインして下さいね!)
℃などの特殊記号や日本語を表示させる場合は、フォントを Unicode に変更します。
ラベル名は以下のように設定してください。
ここまでのプロジェクトデータは以下より確認できます。
(UIFlowにライブラリーを追加してから開いてください)
5. プログラムの作成
現在の状況を整理してみます。
OpenWeatherMapから取得したデータが以下の変数に代入されています。
icon 現在の天気のアイコン
description 現在の天気
feels_like 体感気温
humidity 湿度
name 地名
変数 icon と description には、天気に合わせて以下の値が代入されます。
(d と n は、昼と夜の略です)
全てのアイコン画像を用いるのは量が多いため、オリジナルアイコンを使用します。
LCDのラベル名は以下の通りとなります。
まずは、地名,気温,湿度,天気情報といったデータをラベルに表示させてみましょう!
↓解答↓
受け取ったデータをラベルに表示させてみます。
実行してみると、温度表記が小数になっており、はみ出てしまいました。
よって、温度の小数点以下を四捨五入して表示させます。
実行してみると、小数点以下が消え、いい感じに収まりました。
では、天気アイコンの表示を行います。
上の表を参考にすると、
変数 icon に 01d,01n,02d,02n のいずれかが代入されていれば、オリジナルアイコン Fine.png を表示させてば良いことが分かります。
『~ならば~を実行する』、条件分岐の出番となります。
今回は、変数 icon が 01d または 01n または 02d または 02n ならばFine を表示なので、または の条件ブロックを3つ配置します。
条件式と画像処理を加えます。
以下は、晴れアイコンの表示処理となります。
ここの画像処理、画像 Image_icon に Fine.png を表示 だけれは上手く動きません。
以下のように、元々表示していたアイコン画像が消えずに残ってしまいます。
表示アイコンを消し、再描画してあげましょう。
では、同様にして、曇り,雨,雷 アイコンの表示も行ってみましょう。
↓解答↓
雨アイコンの条件は8個と多いため、そうでなければ (else) を用いました。
現在、天気は表示されたあと更新されません。
これを1分毎に更新させるようにしてみましょう!
『~を繰り返す』、ループの出番となります。
↓解答↓
1分おきの無限ループを作成します。
これまで作成した処理をまとめてループの先頭に入れます。
ただ、これだと1分毎にアイコンの再描画が入ってしまいます。
変数 表示アイコン を作成し、
以下の処理を書き加えることにより、天気に変化があった場合のみ、アイコン画像を再描画するようになります。
ここまでのプロジェクトデータは以下より確認できます。
(UIFlowにライブラリーを追加してから開いてください)
6. PLEN5Stackとの連携
OpenWeatherMapの登録、JSON形式とは、データ取得&表示...
前置きが長くなってしまいましたが、これらのことはM5Stack単体で可能です。
では、本題の、PLEN5Stackとの連携を行ってみましょう。
具体的には、天気に合わせて目の色を変え、気温や湿度に合わせて手を動かしてみます。
6.1 PLEN5Stackとの連携【目の色】
例えば、以下のようにしてみましょう。
天気 目の色
晴 緑
曇り 白
雨 水色
雷 黄色
↓解答↓
色が合っていれば、数字が異なっていても大丈夫です!
6.1 PLEN5Stackとの連携【腕の動き】
サーボ番号は以下の通りとなります。
腕のサーボモータは、110°くらいまでは動かすことができます。
右手を体感温度(-10℃~40℃)、左手を湿度(0%~100%)に合わせて動かしてみます。
そして、計算式は以下の通りとなります。
(数値を代入してみてくださいね!)
では、以下の情報を用いて、気温と湿度に合わせた手の動きを実装してみましょう!
↓解答↓
腕のサーボ角を代入する変数 体感温度角度 と 湿度角度 を作成します。
現在の体感温度 (feels_like) と 現在の湿度 (humidity) を用いてサーボ角を計算し、代入します。
条件分岐を用いて、角度が0°~110°に収まるようにします。
(例えば、気温が40℃を超えると、温度角度が110°を超えてしまう)
1000ミリ秒 (1秒) かけてモータを動かします。
うまく動作したでしょうか(^^♪
ここまでのプロジェクトデータは以下より確認できます。
(UIFlowにライブラリーを追加してから開いてください)
これで完成でも良いのですが、折角なので、アナログメーターにしてみましょう。
以下のpdfをダウンロードし、A4サイズで印刷して下さい。
(ペーパークラフト用紙がお勧めです)
はさみやカッターを用いて切断します。
PLEN5Stackの背面に差し込み、完成です。
羽は生えましたでしょうか?
余裕があれば白紙のメーターを用いて、自由にアレンジしてみてくださいね!
6.3 PLEN5Stackとの連携【Appモードで動かす】
これでプログラムは完成となりますが、毎回UIFlowを経由するのは少し面倒だと思います。ですので、完成したプログラムは、M5Stack本体に保存し、Appモード で直接起動できるようにしてみましょう!
しかし、Appモード では、Wi-Fiに接続しないでプログラムが起動してしまい、今回のような インターネットを用いたプログラム はうまく動きません( ノД`)シクシク…。
プログラム開始後、Wi-Fiに接続してから情報を取得するようにしてみます。
高度なブロック → Network 内にある wifi connect ブロックを先頭に配置します。
wifi接続画面の表示は無効 (false) に変更しておきます。
ダウンロードボタンを押し、M5Stackにプログラムを保存・実行します。
Appモードでは、保存したプログラムが起動直後に実行されます。
AppモードからWi-Fiモード(UIFlowと接続)に切り替える際は、中央のボタンを押しながら電源を入れてください。
ここまでのプロジェクトデータは以下より確認できます。
(UIFlowにライブラリーを追加してから開いてください)
7. おわりに
今回は、JSON形式に始まり、インターネットからのデータ取得やサーボモーターの制御方法についてご紹介しました。
全体量としては多かったなと思いますが、できるだけ噛み砕いてご説明できたと思います。リストやJSON形式の説明に関しましては、不完全な説明となったため、興味のある方は検索してみてくださいね。たくさんの変数も、リストを使えば少なく済みます。
意見・ご質問等ございましたら、
ご気軽にコメント欄まで頂ければありがたいです。
この記事は連載形式となっておりますので、
是非以下のマガジンをフォローしてくださいね。
それでは、また次回の記事でお会いしましょう!
See you next time!