サーバーにメッセージを送ってみる
今回のプログラムはどのように動くか
このような仕組みです。
起動時にサーバーにメッセージが送られ、その後、各ボタンをクリックしてサーバーにメッセージが送られます。
テストサーバーを用意しました
授業のためにテストサーバーを用意しました
https://app-1ft-iot-test-server.herokuapp.com/ui
- こういうサーバーがあるとデータがちゃんと届いているかのチェックがしやすいです
- ひとまず今回は HTTP で受信するとログが出ます
- 時間に余裕があれば軽くデモします
ソースコードを反映
Arduino IDE で新規ファイルを作成し、以下のコードをコピーアンドペーストします。こちらを handson-Test-HTTP-POST-JSON
で保存します。
#include <M5Stack.h>
// HTTP 通信を行うライブラリ
#include <HTTPClient.h>
// Wi-FiのSSID
char *ssid = "Wi-FiのSSID";
// Wi-Fiのパスワード
char *password = "Wi-Fiのパスワード";
void setup() {
// init lcd, serial, but don't init sd card
// LCD ディスプレイとシリアルは動かして、SDカードは動かさない設定
M5.begin(true, false, true);
// スタート
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(2);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.print("START"); // Arduino のシリアルモニタにメッセージを出す
M5.Lcd.print("START"); // M5Stack LCDディスプレイにメッセージを出す(英語のみ)
// WiFi 接続開始
WiFi.begin(ssid, password);
// 勝手に Button A が押されることを回避
WiFi.setSleep(false);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.print(".");
M5.Lcd.print(".");
}
// WiFi Connected
// WiFi 接続完了
M5.Lcd.setCursor(10, 40);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(2);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
// 前のメッセージが print で改行入っていないので println で一つ入れる
Serial.println(""); // Arduino のシリアルモニタにメッセージを出し改行が最後に入る
M5.Lcd.println(""); // M5Stack LCDディスプレイにメッセージを出す改行が最後に入る(英語のみ)
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.println("WiFi Connected."); // Arduino のシリアルモニタにメッセージを出す
M5.Lcd.println("WiFi Connected."); // M5Stack LCDディスプレイにメッセージを出す(英語のみ)
// 起動時に送る
delay(1000);
send_message("{\"message\":\"Launched!\"}");
}
// HTTP でメッセージ送信部分
void send_message(String msg) {
// 今回送るURL
String url = "https://app-1ft-iot-test-server.herokuapp.com/api/test/message";
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.println("-> send_message");
M5.Lcd.print("msg: ");
M5.Lcd.println(msg);
// 送るデータ
String queryString = msg;
// HTTPClient 準備
HTTPClient httpClient;
// URL 設定
httpClient.begin(url);
// Content-Type
httpClient.addHeader("Content-Type", "application/json");
M5.Lcd.println("sended.");
Serial.println("sended.");
// ポストする
int status_code = httpClient.POST(queryString);
if( status_code == 200 ){
String response = httpClient.getString();
M5.Lcd.println("response:");
M5.Lcd.println(response);
}
httpClient.end();
delay(2000);
}
void loop() {
M5.update();
if (M5.BtnA.wasReleased()) {
// A ボタンを押したら JSON 形式のメッセージを飛ばす
// \" はダブルクォーテーションで囲まれた中で JSON 内のダブルクォーテーションを表現するために \" でエスケープしてます。
send_message("{\"message\":\"Pushed A\"}");
} else if (M5.BtnB.wasReleased()) {
// B ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Pushed B\"}");
} else if (M5.BtnC.wasReleased()) {
// C ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Pushed C\"}");
}
}
Wi-Fi 情報を反映して、また保存
// Wi-FiのSSID
char *ssid = "Wi-FiのSSID";
// Wi-Fiのパスワード
char *password = "Wi-Fiのパスワード";
先ほどと同じように Wi-Fi 情報を反映します。もう一度保存します。(大事)
M5Stack に書き込んでみましょう。
動かしてみる
起動時に サーバーに {"message":"Launched!"}
という JSON データが送られます。
また、3つボタンが並んでいますが、Aボタン、Bボタン、Cボタンでプログラムと対応しています。クリックしてサーバーにメッセージが送られるか確認してみましょう。
たとえば、Cボタンをクリックすると {"message":"Pushed C"}
という JSON データが送られます。
送るデータを変更してみる(書き換え訓練)
これだと送った人が分からないので、英数字で自分の名前を決めて、送るデータをちょっと書き換えましょう。
Launched メッセージをちょっと変更
// 起動時に送る
delay(1000);
send_message("{\"message\":\"Launched!\"}");
を、以下のように書き加えます。Seigo で変更した例です。
// 起動時に送る
delay(1000);
send_message("{\"message\":\"Seigo Launched!\"}");
ボタンを押したときのメッセージをちょっと変更
void loop() {
M5.update();
if (M5.BtnA.wasReleased()) {
// A ボタンを押したら JSON 形式のメッセージを飛ばす
// \" はダブルクォーテーションで囲まれた中で JSON 内のダブルクォーテーションを表現するために \" でエスケープしてます。
send_message("{\"message\":\"Pushed A\"}");
} else if (M5.BtnB.wasReleased()) {
// B ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Pushed B\"}");
} else if (M5.BtnC.wasReleased()) {
// C ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Pushed C\"}");
}
}
を、以下のように書き加えます。Seigo で変更した例です。
void loop() {
M5.update();
if (M5.BtnA.wasReleased()) {
// A ボタンを押したら JSON 形式のメッセージを飛ばす
// \" はダブルクォーテーションで囲まれた中で JSON 内のダブルクォーテーションを表現するために \" でエスケープしてます。
send_message("{\"message\":\"Seigo Pushed A\"}");
} else if (M5.BtnB.wasReleased()) {
// B ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Seigo Pushed B\"}");
} else if (M5.BtnC.wasReleased()) {
// C ボタンを押したら JSON 形式のメッセージを飛ばす
send_message("{\"message\":\"Seigo Pushed C\"}");
}
}
余談:英数字で顔文字表現テクニック
もし余裕があれば、
(^_^)
(=_=)
:-)
;-)
(*o*)/
のような顔文字は英数字でも表現できるので、ぜひ試してみましょう~。
エクストラ : ArduinoJson
send_message("{\"message\":\"Pushed A\"}");
という書き方で JSON を作るのはシンプルな値では何とかなりますが複雑なデータを作ったり読み込んだりするケースでツラくなってきます。
そのときは、ArduinoJson というライブラリを使いましょう。 JSON データが格段に扱いやすくなります。
// JSON を格納するオブジェクト DynamicJsonDocument
DynamicJsonDocument doc(255);
// JSON データ作成
doc["message"] = "Pushed A";
// 変換後の char を準備
char serializedJsonString[255];
// JSON オブジェクトを String に変換して serializedJsonString 変数に格納
// 中身は {"message":"Pushed A"}
serializeJson(doc,serializedJsonString);
// send_message 関数に serializedJsonString を送る
send_message(serializedJsonString);
たとえば、このように JSON を格納するオブジェクト DynamicJsonDocument を作成し、JSON データ作成したあと、変換後の String を準備して serializeJson 関数で JSON オブジェクトを String に変換して serializedJsonString 変数に格納します。
- メニュー > ツール > ライブラリを管理
- ライブラリから ArduinoJson を完全一致で検索
- ArduinoJson が見つかったらインストール
でインストールを済ませたら、該当のコードで #include <ArduinoJson.h>
で呼び出して使います。
全体を書き換えた例がこちらです。
#include <M5Stack.h>
// HTTP 通信を行うライブラリ
#include <HTTPClient.h>
// Wi-FiのSSID
char *ssid = "Wi-FiのSSID";
// Wi-Fiのパスワード
char *password = "Wi-Fiのパスワード";
// JSON を扱いやすくするライブラリ
#include <ArduinoJson.h>
// JSON を格納するオブジェクト DynamicJsonDocument
DynamicJsonDocument doc(255);
// 変換後の char を準備
char serializedJsonString[255];
void setup() {
// init lcd, serial, but don't init sd card
// LCD ディスプレイとシリアルは動かして、SDカードは動かさない設定
M5.begin(true, false, true);
// スタート
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(2);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.print("START"); // Arduino のシリアルモニタにメッセージを出す
M5.Lcd.print("START"); // M5Stack LCDディスプレイにメッセージを出す(英語のみ)
// WiFi 接続開始
WiFi.begin(ssid, password);
// 勝手に Button A が押されることを回避
WiFi.setSleep(false);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.print(".");
M5.Lcd.print(".");
}
// WiFi Connected
// WiFi 接続完了
M5.Lcd.setCursor(10, 40);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(2);
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
// 前のメッセージが print で改行入っていないので println で一つ入れる
Serial.println(""); // Arduino のシリアルモニタにメッセージを出し改行が最後に入る
M5.Lcd.println(""); // M5Stack LCDディスプレイにメッセージを出す改行が最後に入る(英語のみ)
// Arduino のシリアルモニタ・M5Stack LCDディスプレイ両方にメッセージを出す
Serial.println("WiFi Connected."); // Arduino のシリアルモニタにメッセージを出す
M5.Lcd.println("WiFi Connected."); // M5Stack LCDディスプレイにメッセージを出す(英語のみ)
// 起動時に送る
delay(1000);
// JSON を格納するオブジェクト DynamicJsonDocument
DynamicJsonDocument doc(255);
// JSON データ作成
doc["message"] = "Launched!";
// JSON 変換
serializeJson(doc,serializedJsonString);
// データを送る
send_message(serializedJsonString);
}
// HTTP でメッセージ送信部分
void send_message(String msg) {
// 今回送るURL
String url = "https://app-1ft-iot-test-server.herokuapp.com/api/test/message";
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.println("-> send_message");
M5.Lcd.print("msg: ");
M5.Lcd.println(msg);
// 送るデータ
String queryString = msg;
// HTTPClient 準備
HTTPClient httpClient;
// URL 設定
httpClient.begin(url);
// Content-Type
httpClient.addHeader("Content-Type", "application/json");
M5.Lcd.println("sended.");
Serial.println("sended.");
// ポストする
int status_code = httpClient.POST(queryString);
if( status_code == 200 ){
String response = httpClient.getString();
M5.Lcd.println("response:");
M5.Lcd.println(response);
}
httpClient.end();
delay(2000);
}
void loop() {
M5.update();
if (M5.BtnA.wasReleased()) {
// A ボタンを押したら JSON 形式のメッセージを飛ばす
// JSON データ作成
doc["message"] = "Pushed A";
// JSON 変換
serializeJson(doc,serializedJsonString);
// データを送る
send_message(serializedJsonString);
} else if (M5.BtnB.wasReleased()) {
// B ボタンを押したら JSON 形式のメッセージを飛ばす
// JSON データ作成
doc["message"] = "Pushed B";
// JSON 変換
serializeJson(doc,serializedJsonString);
// データを送る
send_message(serializedJsonString);
} else if (M5.BtnC.wasReleased()) {
// C ボタンを押したら JSON 形式のメッセージを飛ばす
// JSON データ作成
doc["message"] = "Pushed C";
// JSON 変換
serializeJson(doc,serializedJsonString);
// データを送る
send_message(serializedJsonString);
}
}
エクストラ : LINE BOT サーバーに M5Stack からデータを送る
まったく別で構築した LINE BOT サーバーの /<Path>/from/m5stack
という POST リクエストを受け付ける仕組みを作った後、今回の M5Stack のサーバーにメッセージを送ってみるコードの送り先の URL を、さきほどの LINE BOT サーバーに向けるとLINE BOT サーバーに M5Stack からデータを送る仕組みが作れます。
今回は講師の方で enebular のクラウド実行環境で作った LINE BOT サーバーにPOST リクエストを受け付ける仕組みを作りました。
Arduino のソースコードを変更して書き込んでみます。
// 今回送るURL
String url = "https://app-1ft-iot-test-server.herokuapp.com/api/test/message";
この部分 https://app-1ft-iot-test-server.herokuapp.com/api/test/message
をハンズオン中に連絡する URL に変更して M5Stack に書き込んでみましょう。
Connected の表示が出たら M5Stack の A B C ボタンを押して、 LINE BOT にメッセージが表示されます。
たぶん、みんなでやると、どかどか送られてカオスで楽しい。
次は
左のメニューから、次に進みましょう。