SORACOM レシピ:IoTで外部データを表示する情報端末
M5Stackと3G拡張ボードで作る「IoT情報表示システム」
公開日: 2020年4月
レシピ難易度:★★★☆☆

IoTシステムでは現場の情報を取得するだけでなく、手軽に見える状態にすることが重要です。このレシピでは、液晶ディスプレイ付きプロトタイピング向けマイコンキット “M5Stack” を使って、情報表示システムの構築を体験します。
このレシピではWifi環境の無い場所に “M5Stack” を置いても情報表示ができるよう、 “3G 拡張モジュール” を組み合わせてモバイルデータ通信機能を加えます。モバイルデータ通信に SORACOM IoT SIM をデバイスとクラウドへのデータ転送支援に SORACOM Beam を使いますので、ソラコムの基本サービスを体験する目的にもピッタリなレシピです。
本レシピを行うのに必要な時間、概算費用
本レシピは以下の通りです。
- 必要な時間: 約2時間30分
- 概算費用: 約14,100円
※ 概算費用: ハードウェアや SORACOM を始めとした各種サービスの概ねの費用 (税や送料などの付帯費用や無料枠適用は考慮しないものとしています)
このコンテンツの進め方
上から内容を読み進みながら作業を行なっていきます。また左サイドに追従する目次からページ内の移動が可能です。
本コンテンツは現状のままで提供され、株式会社ソラコムは、誤りがないことの保証を含め、明示であると黙示であるとを問わず、本コンテンツの記載内容につき、いかなる種類の表明も保証も行いません。
掲載情報の閲覧及び利用により、利用者自身、もしくは第三者が被った損害に対して、直接的、間接的を問わず、株式会社ソラコムは責任を負いかねます。
本コンテンツを実践する中で用意された機器、利用されたサービスについてのご質問は、それぞれの機器やサービスの提供元にお問い合わせをお願いします。機器やサービスの仕様は、本コンテンツ作成当時のものです。
株式会社ソラコムが提供する機器・サービスについてのご質問は、 https://soracom.jp/contact/ をご確認の上、適切な窓口へのお問い合わせをお願いします。機器・サービスご利用前の導入相談は https://soracom.jp/contact/contactsales/ に、機器・サービスご利用開始後のサポートは、SORACOMユーザーコンソール内のサポートサイトから「リクエストを送信」(要ログイン)にてお問い合わせください。
Copyright (c) 2021 SORACOM, INC.
準備
本レシピを行うためには以下のものをご用意ください。
ハードウェア
品名 | 数量 | 価格 | 購入先 | 備考 |
M5Stack Basic 3G 拡張ボード セット※1 | 1 | 12,800円 | ソラコム | M5Stack と M5Stack 用 3G 拡張ボードをそれぞれ準備いただいてもレシピを進めることができます。M5Stack 用 3G 拡張ボードが対応している M5Stack は Basic と Gray の2モデルです。M5Stack FIRE は非対応ですのでご注意ください。 |
SORACOM 特定地域向け IoT SIM (plan-D / データ通信のみ / nanoSIM サイズ) | 1 | 852円 | ソラコムAmazon.co.jp | サイズは nano をお求めください。「マルチカット」には nano サイズが含まれています。 |
対辺1.5mm 六角レンチ(ドライバー) | 1 | 約410円 | Amazon.co.jp | M5Stack 用 3G 拡張ボードへ SIM を挿す際にボードの取り付け・取り外しに使用します。 |
開発用パソコン | 1 | ― | ― | インターネット接続が可能でサイトへの接続が自由であること。USB Type-A ポートが最低1つ以上用意出来ること。USB ポートからの電力供給が1A以上であること。OS は macOS(10.11 El Capitan 以上) もしくは Windows(8.1 以上)。管理者権限を有しており、アプリケーションやドライバソフトウェアのインストールが自由であること。Arduino IDE と M5Stack 開発環境が整っていること (セットアップ方法は 【SORACOM ハンズオン】M5Stack 開発環境セットアップ (Windows / macOS 共通) (全体で約90分) をご覧ください) |
(必要な方のみ)USB 変換アダプタ | 1 | ― | ― | パソコンに USB Type-A ポートがない場合に準備してください。1A 以上の電力が供給できるものを利用してください。(USB 3.0以上に対応していれば概ね安心です) |
(必要な方のみ)USB Type-C ↔ Type-C ケーブル | 1 | ― | ― | パソコンに USB Type-A ポートが用意できず、また、USB 変換アダプタも用意できない場合に準備してください。 |
※1 ※ 金額はレシピ作成時となります。ソラコムで販売している金額は税抜き・送料別です。
その他必要なもの
必要なもの | 費用 | 作成方法など |
SORACOM アカウント | 無料※ | SORACOM アカウントの作成 (JP) |
Yahoo! JAPAN ID | 無料※ | Yahoo! JAPAN IDを登録するには |
※ アカウント作成・維持の費用の料金です。
M5Stack 用 3G 拡張ボードに SIM を取り付ける
M5Stack 用 3G 拡張ボード(以下、3G拡張ボード)には SIM スロットが備わっており、ここに SIM を入れることで 3G 通信が可能となります。 SIM の取り付け・取り外しは 3G拡張ボードをケースから取り外す必要があります。
3G拡張ボードをケースから取り外す
3G拡張ボードの四隅にあるネジを取り外します。ネジは紛失しないようにしてください。

SIM を取り付ける(取り外し方法含む)
SIM のサイズは nano です。取り付けはSIMをスロットに挿入したら「カチッ」と音が鳴るまで押し込みます。音が鳴ったら完了です。取り外しはSIMを奥まで押し込み「カチッ」と音が鳴ればSIMが出てきますので取り外しできます。

3G拡張ボードをケースに取り付ける
再度3G拡張ボードをケースに取り付けます。取り付け向きはピンが外側 (ケースから飛び出るように) します。逆向き (ピンがケースの内側を向いてしまっている) には取り付け内でください。
最後はネジで固定します。

M5Stack ボードの取り付け向き
M5Stack は正方形であるためボードとケースの取り付け方角がわかりづらいのですが、ボード上のピン(M5-BUS と呼ばれる)の辺と、ケース側面の切れ込みの辺を合わせるようです。
重ねる
取り付け終わったら一番下から「BOTTOM」「3G拡張ボード」「Core※」と重ねていきます。
※ Core = M5Stack の LCD(モニター)やボタンがついているモジュール
以上で3G 拡張ボードへの SIM 取り付け作業は完了です。
SORACOM Air を利用してセルラー通信をしてみる
3G 拡張ボードを使って SORACOM Air によるセルラー通信を行い、3G 拡張ボードの動作確認を行います。
セルラー通信ライブラリのインストール
3G 拡張ボードで利用できる通信ライブラリをインストールします。今回は TinyGSM というオープンソースライブラリを利用して、世界時計を M5Stack で表示してみます。
[スケッチ]>[ライブラリをインクルード]>[ライブラリを管理…]をクリックします

※ 画面は macOS ですが、Windows も同様です。
“TinyGSM” をインストールする
ライブラリマネージャの一覧から TinyGSM (by Volodymyr Shymanskyy) を選んで[インストール]をクリックします。
バージョンはインストール時における最新バージョンを選んでください。

インストールが終了したら[閉じる]をクリックします。
“TinyGSM” を簡単に探し出す方法
検索用のテキストボックスへ tinygsm
と入力すると素早く見つけることができます。
World Time API を取得して表示するスケッチ
動作テストを兼ねて世界時計を API で提供している World Time API から日時を取得して表示します。
ブラウザで試してみるには?
World Time API を始めとした、いわゆる Web API はブラウザでも実行できることがあります。今回の World Time API であればブラウザで http://worldtimeapi.org/api/timezone/Asia/Tokyo.txt
を開いてみると、API で取得できる値をブラウザで表示できます。
Arduino IDE を起動し[ファイル]>[新規ファイル]を開くと void setup() {
から始まる「空のスケッチ」が表示されます。
一度スケッチの内容を削除してから、後述のスケッチで置き換えてください。

m5stack_3gextboard_worldclock.ino
/* * Copyright (c) 2019 Kohei "Max" MATSUSHITA * Released under the MIT license * https://opensource.org/licenses/mit-license.php */ #include <M5Stack.h> #define TINY_GSM_MODEM_UBLOX #include <TinyGsmClient.h> TinyGsm modem(Serial2); /* 3G board modem */ TinyGsmClient ctx(modem); void setup() { Serial.begin(115200); M5.begin(); M5.Lcd.clear(BLACK); M5.Lcd.setTextColor(WHITE); M5.Lcd.println(F("M5Stack + 3G Module")); M5.Lcd.print(F("modem.restart()")); Serial2.begin(115200, SERIAL_8N1, 16, 17); modem.restart(); M5.Lcd.println(F("done")); M5.Lcd.print(F("getModemInfo:")); String modemInfo = modem.getModemInfo(); M5.Lcd.println(modemInfo); M5.Lcd.print(F("waitForNetwork()")); while (!modem.waitForNetwork()) M5.Lcd.print("."); M5.Lcd.println(F("Ok")); M5.Lcd.print(F("gprsConnect(soracom.io)")); modem.gprsConnect("soracom.io", "sora", "sora"); M5.Lcd.println(F("done")); M5.Lcd.print(F("isNetworkConnected()")); while (!modem.isNetworkConnected()) M5.Lcd.print("."); M5.Lcd.println(F("Ok")); M5.Lcd.print(F("My IP addr: ")); IPAddress ipaddr = modem.localIP(); M5.Lcd.print(ipaddr); delay(2000); } void loop() { M5.update(); M5.Lcd.clear(BLACK); M5.Lcd.setCursor(0, 0); M5.Lcd.println(F("World Clock from worldtimeapi.org")); /* HTTP GET example */ if (!ctx.connect("worldtimeapi.org", 80)) { Serial.println(F("Connect failed.")); return; } Serial.println(F("connected.")); /* send request */ ctx.println("GET /api/timezone/Asia/Tokyo.txt HTTP/1.0"); ctx.println("Host: worldtimeapi.org"); ctx.println(); Serial.println("sent."); /* receive response */ while (ctx.connected()) { String line = ctx.readStringUntil('n'); Serial.println(line); if (line == "r") { Serial.println("headers received."); break; } } char buf[1 * 1024] = {0}; ctx.readBytes(buf, sizeof(buf)); /* body */ ctx.stop(); M5.Lcd.println(buf); delay(1000 * 10); }
マイコンボードに書き込む
Arduino IDE でボタンをクリックします。ボードへの書き込みが完了しました。と表示されたら正常終了です。
ファイルの保存ダイアログが表示されたら
ファイルを保存してください。ファイル名は任意ですが m5stack_3gextboard_worldclock
というファイル名はどうでしょうか。
ファイルを保存しない (キャンセル) してもコンパイルとスケッチの転送はされます。
実行の様子
最初にモデムの型番や IP アドレスを表示した後に World Time API から取得したデータを表示します。
gprsConnect(soracom.io)
から実際に IP アドレスが表示される(= 接続される)までに30~45秒程度掛かりますが正常です。


うまく動作しなかった場合
症状 | 考えられる原因 | 対策 |
getModemInfo() の結果が SARA-U201... と表示されない(空の場合など) | 3G 拡張ボードで内部エラーが発生している可能性がある | カスタマーサポートへご連絡ください。 |
waitForNetwork() より先に進まない | SIM が取り付けられていない。(もしくは SORACOM IoT SIM ではない) | SORACOM 特定地域向け IoT SIM plan-D を取り付けてください。 |
電波が圏外もしくは微弱である可能性がある | 窓際等、通信条件が良い環境でお試しください。 | |
SIM が SORACOM に登録されていない※ SORACOM ユーザーコンソールで確認できます ( “登録されてない” 事が確認できます) | 発注済みの SIM を登録する もしくは 通販サイトやイベント等で入手した SIM を登録する を行ってください。 | |
SIM の「状態」が “準備完了” となっている( “使用中” でない)※ SORACOM ユーザーコンソールで確認できます | 当該 SIM のチェックボックスをチェックしてから[操作]>[使用開始]をクリックして “使用中” に変更してください。 |
以上で M5Stack の開発環境から M5Stack 本体と 3G 拡張ボードの動作確認が完了しました。
Yahoo! デベロッパーネットワークへのアプリケーション登録
雨雲レーダーの情報は Yahoo! デベロッパーネットワーク (YOLP) を利用します。YOLPに「アプリケーション登録」すると、Web API で利用できる情報が入手できます。
YOLP アプリケーションの管理を開き[新しいアプリケーションを開発]をクリックします

アプリケーション情報の入力で以下のように入力します
アプリケーションの種類 | サーバーサイド(Yahoo! ID連携 v2) |
アプリケーション名 | M5Stack RainRadar app ※ 任意のアプリケーション名で構いません |
サイトURL | (ご自分のブログや会社のURLを記入ください) |
※ アプリケーションの説明、利用するスコープは編集の必要はありません。
ガイドラインに同意しますか?を[同意する]にチェックをしてから[確認]をクリックします。
入力内容の確認で内容を確認したら[登録]をクリックします。登録が完了すると Client ID とシークレットが入手できます。この2つの情報をメモしたうえで漏洩しないようにしてください。

ブラウザでテストする
先ほど入手した Client ID
を使って、まずはブラウザで雨雲レーダーの画像を表示してみます。以下のURLをブラウザのアドレスバーに入力してください。
その際、 <YOUR_CLIENT_ID>
を先ほど入手した Client ID
に置き換えてください。
https://map.yahooapis.jp/map/V1/static?appid=<YOUR_CLIENT_ID>&output=jpg&quality=50&width=320&height=208&overlay=type:rainfall%7Cdatelabel:off&mode=map&style=base:simple&z=8&lat=35.6313456&lon=139.7312189
以下のようにブラウザに地図が表示されれば成功です。(表示したときの雨雲の状況によって水色の掛かり具合は異なります)

M5Stack で雨雲レーダーを表示する (直接アクセス版)
YOLP から取得した雨雲レーダーの画像を M5Stack で表示します。
Arduino IDE を起動し[ファイル]>[新規ファイル]を開き、以下のスケッチを貼り付けます。
M5Stack から YOLP のURL を直接アクセスするため、スケッチ内の103行目の <YOUR_CLIENT_ID>
を Client ID
で置き換えるようにしてください。
/* * Copyright (c) 2019 Kohei "Max" MATSUSHITA * Released under the MIT license * https://opensource.org/licenses/mit-license.php */ #include <M5Stack.h> #define CONSOLE Serial #define MODEM Serial2 /* Serial2 is Modem of 3G Module */ #include <string.h> #define TINY_GSM_MODEM_UBLOX #include <TinyGsmClient.h> TinyGsm modem(MODEM); TinyGsmClientSecure ctx(modem); void modem_enabler(); void render_rain_radar(); void print_top(); void print_bottom(); uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue); void setup() { M5.begin(); CONSOLE.begin(115200); M5.Lcd.clear(BLACK); M5.Lcd.setTextSize(2); print_top(); print_bottom(); M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(0, 16); M5.Lcd.println("## Congrats,"); M5.Lcd.println("## Boot successfuly!"); } void loop() { if (M5.BtnA.wasReleased()) { M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(218, 0); M5.Lcd.print(F("(prog...")); modem_enabler(); get_and_render_rain_radar(); print_top(); print_bottom(); modem.gprsDisconnect(); } M5.update(); } /* ------------------------------------------------------------*/ void modem_enabler() { M5.Lcd.setTextColor(WHITE); MODEM.begin(115200, SERIAL_8N1, 16, 17); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("modem.restart()")); CONSOLE.println(F("modem.restart()")); modem.restart(); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("waitForNetwork()")); CONSOLE.println(F("waitForNetwork()")); while (!modem.waitForNetwork()) M5.Lcd.print("."); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("gprsConnect(soracom.io)")); CONSOLE.println(F("gprsConnect(soracom.io)")); modem.gprsConnect("soracom.io", "sora", "sora"); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("isNetworkConnected()")); CONSOLE.println(F("isNetworkConnected()")); while (!modem.isNetworkConnected()) M5.Lcd.print("."); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.print(F("MyIP:")); CONSOLE.print(F("MyIP: ")); IPAddress ipaddr = modem.localIP(); M5.Lcd.println(ipaddr); CONSOLE.println(ipaddr); } char _buf[32*1024] = {0}; /* store for JPG image data */ void get_and_render_rain_radar() { /* connect to host */ const char *host = "map.yahooapis.jp"; const int port = 443; int timeout_s = 60; CONSOLE.print("Connecting:"); CONSOLE.println(host); if (!ctx.connect(host, port, timeout_s)) { CONSOLE.println("fail"); return; } /* send request */ const char *path = "GET /map/V1/static?appid=<YOUR_CLIENT_ID>&output=jpg&quality=50&width=320&height=208&overlay=type:rainfall%7Cdatelabel:off&mode=map&style=base:simple&z=8&lat=35.6313456&lon=139.7312189 HTTP/1.0"; CONSOLE.println(path); ctx.println(path); ctx.print("Host: "); ctx.println(host); ctx.println(); Serial.println("sent."); /* receive response */ while (ctx.connected()) { String line = ctx.readStringUntil('n'); CONSOLE.println(line); if (line == "r") { CONSOLE.println("headers received."); break; } } ctx.readBytes(_buf, sizeof(_buf)); /* body */ ctx.stop(); /* rendering */ size_t _buf_s = strlen(_buf); CONSOLE.println(_buf_s); CONSOLE.println(_buf); M5.Lcd.drawJpg((const unsigned char *)_buf, _buf_s, 0, 16); _buf[0] = ' '; /* cleanup */ CONSOLE.println("done."); } void print_top() { M5.Lcd.fillRect(0, 0, 320, 16, getColor(51, 244, 204)); M5.Lcd.setTextColor(BLACK); M5.Lcd.setCursor(0, 0); M5.Lcd.print(F("RainRadar by YOLP")); } void print_bottom() { M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(0, 224); M5.Lcd.print(F("Btn => Retreve RainRadar")); } uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue) { return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3); }
実際の動作
このスケッチは M5Stack の一番左のボタンを押したときに 3G 接続~雨雲レーダー画像の取得までを行います。(押下毎に接続から取得までを行います)


M5Stack で雨雲レーダーを表示する (SORACOM Beam 経由版): 概要
ここまでで M5Stack とクラウドサービス(API)をセルラー通信で連携できるようになりました。直接アクセスする場合は Client ID をプログラム(URL)の中に埋め込むことを行いました。
この場合 Client ID を再発行したり、URL に基づいたパラメータの変更を行うためには毎度プログラムを書き換える必要があり、書き換え環境が無ければ何もできなくなります。
この手間を軽減するのが SORACOM Beam / SORACOM Funnel / SORACOM Funk といった SORACOM のサービスです。Client ID やアクセス先の URL をプログラムに埋め込むのではなく、「設定情報」としてSORACOM に保管します。そして SIM が持つ固有の情報で設定情報の引き出しを行い、その情報に基づいて URLやサービスへのアクセスを中継する仕組みです。

ここからは直接アクセス方法から SORACOM Beam を中継する方法へ切り替えていきます。
M5Stack で雨雲レーダーを表示する (SORACOM Beam 経由版): SORACOM Beam 設定
SORACOM Beam では http://beam.soracom.io/rainradar
へのアクセスを YOLP へのアクセスとして中継する設定とします。
beam.soracom.io へのアクセスは http で大丈夫?
M5Stack から beam.soracom.io (以下beam) へのアクセスは “http://” と暗号化されていませんが、安全なのでしょうか?結果から言えば、安全であると言えます。これは M5Stack から beam までで使われている 3G や LTE と呼ばれる「セルラー通信」は、その通信自体が暗号化されているためです。一方、スマートフォンのアプリケーションは暗号化通信を行っていますが、これはセルラー通信のその先にあるインターネット上のサービスと通信するため、本来不要であるはずのセルラー通信の区間も暗号化しています。
SORACOM Beam 等のサービスはアクセス先の中継だけでなく、SORACOM とインターネット上のサービスとの通信区間の暗号化も肩代わります。このため、M5Stack のようなデバイスで暗号化処理が不要になり、プログラムの負担や暗号化に伴うオーバーヘッド通信も削減しつつも、安全にインターネット上のサービスと通信する事ができます。
まずはグループの作成と、作成したグループへ SIM を所属させる事から始めます。
グループとは?
SORACOM サービスのほとんどがグループという単位に対して設定するようになっています。SORACOM Harvest Data 等、SORACOM サービスのほとんどが SIM に直接設定をするのではなくグループに設定をします。そして、SIM をグループに所属させることで SORACOM サービスが利用できるという間接的な仕組みです。
グループを作成してから SIM を所属させる方法の他、グループの作成と SIM の所属を同時に行う方法もあります。本レシピでは後者の「同時に行う」手順で進めていきます。
SORACOM ユーザーコンソールにログインした後[Menu]>[SIM 管理]とクリックして SIM 管理画面を開きます。

[SIM 管理]をクリックしても画面が切り替わらない場合は?
すでに SIM 管理画面を開いている場合は、[SIM 管理]をクリックしても画面が切り替わることがありません。その場合、青の点線で囲まれている「SORACOM ロゴ」をクリックすることでメニューを閉じることができます。
M5Stack に取り付けた SIM にチェックを付け、[操作]>[所属グループ変更]とクリックします。

SORACOM の便利な使い方: 複数の SIM を同時に扱う
チェックをつける対象を複数にすれば、一度の複数の SIM を対象に操作が可能です。
「新しい所属グループ」のプルダウンボックスをクリックした後、[新しいグループを作成…]をクリックします。

「グループ作成」のグループ名を入力して[グループ作成]をクリックします。
項目 | 例 | 備考 |
グループ名 | yahooapis-for-m5stack | 自由に入力可能です。日本語も設定可能です。 |

新しい所属グループが先ほど作成したグループになっていることを確認したら[グループ変更]をクリックします。

自動的に SIM 管理画面に戻ります。
SIM の「グループ」に先ほど作ったグループが設定されていることを確認してください。

以上で、グループの作成と所属の作業は完了です。
SIM 管理画面から、先ほど割り当てたグループ名をクリックします。

[SORACOM Beam 設定]をクリックして設定ができるように開きます。

SORACOM Beam 設定の
をクリックして表示されたメニューの中から HTTP エントリーポイントをクリックします。

「SORACOM Beam – HTTP 設定」では以下のように入力します。
エントリポイント | パス | /rainradar |
転送先 | プロトコル | HTTPS |
ホスト名 | map.yahooapis.jp | |
ポート番号 | (なにも入力しません) | |
パス | 後述の「パス」を入力してください。 ※ <YOUR_CLIENT_ID> を Client ID に置き換えてください | |
ヘッダ操作 | (変更する場所はありません) |
パス
/map/V1/static?appid=<YOUR_CLIENT_ID>&output=jpg&quality=50&width=320&height=208&overlay=type:rainfall%7Cdatelabel:off&mode=map&style=base:simple&z=8&lat=35.6313456&lon=139.7312189

入力したら[保存]をクリックします。SORACOM Beam の設定に、今設定した内容が表示されていることを確認します。

M5Stack で雨雲レーダーを表示する (SORACOM Beam 経由版): スケッチ
YOLP から取得した雨雲レーダーの画像を SORACOM Beam を中継して取得し、 M5Stack で表示します。
Arduino IDE を起動し[ファイル]>[新規ファイル]を開き、以下のスケッチを貼り付けます。
貼り付ける際、スケッチの編集は不要です。
m5stack_rainradar_with_soracom_beam.ino
/* * Copyright (c) 2019 Kohei "Max" MATSUSHITA * Released under the MIT license * https://opensource.org/licenses/mit-license.php */ #include <M5Stack.h> #define CONSOLE Serial #define MODEM Serial2 /* Serial2 is Modem of 3G Module */ #include <string.h> #define TINY_GSM_MODEM_UBLOX #include <TinyGsmClient.h> TinyGsm modem(MODEM); TinyGsmClient ctx(modem); void modem_enabler(); void render_rain_radar(); void print_top(); void print_bottom(); uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue); void setup() { M5.begin(); CONSOLE.begin(115200); M5.Lcd.clear(BLACK); M5.Lcd.setTextSize(2); print_top(); print_bottom(); M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(0, 16); M5.Lcd.println("## Congrats,"); M5.Lcd.println("## Boot successfully!"); } void loop() { if (M5.BtnA.wasReleased()) { M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(218, 0); M5.Lcd.print(F("(prog...")); modem_enabler(); get_and_render_rain_radar(); print_top(); print_bottom(); modem.gprsDisconnect(); } M5.update(); } /* ------------------------------------------------------------*/ void modem_enabler() { M5.Lcd.setTextColor(WHITE); MODEM.begin(115200, SERIAL_8N1, 16, 17); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("modem.restart()")); CONSOLE.println(F("modem.restart()")); modem.restart(); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("waitForNetwork()")); CONSOLE.println(F("waitForNetwork()")); while (!modem.waitForNetwork()) M5.Lcd.print("."); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("gprsConnect(soracom.io)")); CONSOLE.println(F("gprsConnect(soracom.io)")); modem.gprsConnect("soracom.io", "sora", "sora"); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.println(F("isNetworkConnected()")); CONSOLE.println(F("isNetworkConnected()")); while (!modem.isNetworkConnected()) M5.Lcd.print("."); M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setCursor(0, 224); M5.Lcd.print(F("MyIP:")); CONSOLE.print(F("MyIP: ")); IPAddress ipaddr = modem.localIP(); M5.Lcd.println(ipaddr); CONSOLE.println(ipaddr); } char _buf[32*1024] = {0}; /* store for JPG image data */ void get_and_render_rain_radar() { /* connect to host */ const char *host = "beam.soracom.io"; const int port = 8888; int timeout_s = 60; CONSOLE.print("Connecting:"); CONSOLE.println(host); if (!ctx.connect(host, port, timeout_s)) { CONSOLE.println("fail"); return; } /* send request */ const char *path = "GET /rainradar HTTP/1.0"; CONSOLE.println(path); ctx.println(path); ctx.print("Host: "); ctx.println(host); ctx.println(); Serial.println("sent."); /* receive response */ while (ctx.connected()) { String line = ctx.readStringUntil('n'); CONSOLE.println(line); if (line == "r") { CONSOLE.println("headers received."); break; } } ctx.readBytes(_buf, sizeof(_buf)); /* body */ ctx.stop(); /* rendering */ size_t _buf_s = strlen(_buf); CONSOLE.println(_buf_s); CONSOLE.println(_buf); M5.Lcd.drawJpg((const unsigned char *)_buf, _buf_s, 0, 16); _buf[0] = ' '; /* cleanup */ CONSOLE.println("done."); } void print_top() { M5.Lcd.fillRect(0, 0, 320, 16, getColor(51, 244, 204)); M5.Lcd.setTextColor(BLACK); M5.Lcd.setCursor(0, 0); M5.Lcd.print(F("RainRadar by YOLP")); } void print_bottom() { M5.Lcd.fillRect(0, 224, 320, 16, BLACK); /* clean up */ M5.Lcd.setTextColor(WHITE); M5.Lcd.setCursor(0, 224); M5.Lcd.print(F("Btn => Retreve RainRadar")); } uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue) { return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3); }
実際の動作
動作自体は直接アクセス版と同じとなります。M5Stack の一番左のボタンを押したときに 3G 接続~雨雲レーダー画像の取得までを行います。(押下毎に接続から取得までを行います)
直接アクセス版との差分
- TLS (暗号化処理) が不要となった
- 接続先ホストが
map.yahooapis.jp
からbeam.soracom.io
へ変更となった - 接続先パスが
/map/V1/static?.....
から/rainradar
へ変更となった
--- m5stack_rainradar.ino 2019-08-21 08:43:01.819963700 +0900 +++ m5stack_rainradar_with_soracom_beam.ino 2019-08-21 08:42:25.247913200 +0900 @@ -11,7 +11,7 @@ #define TINY_GSM_MODEM_UBLOX #include <TinyGsmClient.h> TinyGsm modem(MODEM); -TinyGsmClientSecure ctx(modem); +TinyGsmClient ctx(modem); void modem_enabler(); void render_rain_radar(); @@ -89,8 +89,8 @@ char _buf[32*1024] = {0}; /* store for JPG image data */ void get_and_render_rain_radar() { /* connect to host */ - const char *host = "map.yahooapis.jp"; - const int port = 443; + const char *host = "beam.soracom.io"; + const int port = 8888; int timeout_s = 60; CONSOLE.print("Connecting:"); CONSOLE.println(host); @@ -100,7 +100,7 @@ } /* send request */ - const char *path = "GET /map/V1/static?appid=<YOUR_CLIENT_ID>&output=jpg&quality=50&width=320&height=208&overlay=type:rainfall%7Cdatelabel:off&mode=map&style=base:simple&z=8&lat=35.6313456&lon=139.7312189 HTTP/1.0"; + const char *path = "GET /rainradar HTTP/1.0"; CONSOLE.println(path); ctx.println(path); ctx.print("Host: ");
URL を変更してみる
アクセス先 URL は SORACOM Beam に設定という形で保管されるようになったため、 URL 内のパラメータの変更は M5Stack の書き換えが不要となったことを確認してみます。
ここでは表示位置の経度を表す lon パラメータの値を東京近辺(東経139.xx度)から京都周辺(東経135.xx度)に変更し、M5Stack のボタンを押して画像の再取得を行っています。
このようにスケッチの書き換えが不要になったことが確認できました。
あとかたづけと注意事項
本レシピでは費用がかかるサービスを利用しています。
本項をよく読み、必要な操作や解除作業を行うようにして、想定外の費用が掛からないようにしてください。
費用について
ここで記載している金額は全て税別、送料別となります。
SORACOM プラットフォームの利用料金
サービス/機能 | 料金 |
SORACOM Air (plan-D) | 基本料: 10円/日通信料: 0.2円~/MB(今回の利用であれば 1MB 以内で収まる範囲) |
SORACOM Beam | 0.0018円/リクエスト (SORACOM への IN で 0.0009円/リクエスト、SORACOM からの OUT で 0.0009円/リクエストであるが、今回の利用方法だとIN/OUTが1:1であるため1リクエスト当たり0.0018円となる) |
※ 費用詳細はリンク先をご確認ください。
無料利用枠について
SORACOM サービスでは一部サービスにおいて無料枠が設定されています。たとえば SORACOM Air for セルラーであればアカウント毎で30円/月の通信分や、SORACOM Beam であれば100,000リクエスト分などです。料金詳細に「無料利用枠」として掲載されていますので、ご確認ください。
グループ解除
SORACOM Beam はリクエスト発生時毎の従量課金となっているため、作成したグループ内の設定が SORACOM Beam のみであれば、存在し続けることによる費用の発生はありませんが、後日利用の目途がない場合は早々にグループからの解除をお勧めいたします。
グループ解除の方法はグループからの解除 (JP)をご覧ください。
次のステップ
本レシピでは、M5Stack と 3G 拡張ボードを組み合わせた「情報表示端末」を作りました。M5Stack は文字だけでなく画像表示も可能であるため、表現力は非常に高いデバイスと言えます。
元々 M5Stack が採用している ESP32 というマイコンは Wi-Fi 通信機能が搭載されていますが、3G 拡張ボードを用いることで SSID といった設定が無くともインターネット上のサービスと接続できるといった利点、そして SORACOM サービスを組み合わせることによる「変化・変更に強いデバイス」を学んでいただけたら幸いです。
よくあるご質問はLet’s try IoT プロトタイピング ~ 雨雲レーダー表示デバイスを M5Stack で作ってみよう 〜 動画とQAのご紹介でご案内しています。こちらもご覧ください。