diff --git a/src/mqtt01pub.ino b/src/mqtt01pub.ino index aee91ff..eeb2724 100644 --- a/src/mqtt01pub.ino +++ b/src/mqtt01pub.ino @@ -1,70 +1,79 @@ -// MQTT Publisher example -//#include -#include -// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ -#include - -const char* ssid = "miura2g"; -const char* password = "jikken2022"; - -const char* server = "192.168.11.11"; // "mqtt.istlab.info"; -const int port = 1883; // 注:学内ネットワークはポート制限あり。 -const char* pubTopic = "office/temp"; //"ex1/groupXX/sensor";のようにして、他の班とかぶらないようにすること。 -const char* mquser = "ex1"; -//const char* mqpass = "***PASSWORD***"; // 講義システム(三浦担当講義用)を参照すること。 -const char* mqpass = ""; // 講義システム(三浦担当講義用)を参照すること。 -WiFiClient wifiClient; -char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい -PubSubClient mqttClient(wifiClient); // MQTT Client - -void setup() { - // M5.begin(); - Serial.begin(115200); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { // 接続中... - Serial.print("."); - delay(200); - } - Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス - // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる - // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい) - // uint8_t mac[6]; - // esp_read_mac(mac, ESP_MAC_WIFI_STA); - // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X", - // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); - mqttClient.setServer(server, port); - - if (!mqttClient.connected()) { - Serial.println("Try (re)connecting..."); - reconnect(); - } -} - -void loop() { - // シリアルコンソールから書き込みがあれば, publishする - byte mbuf[100]; int pos = 0; - while (Serial.available()) { // ノンブロッキング - mbuf[pos] = Serial.read(); - pos++; - } - if (pos > 0) { - mbuf[pos-1] = 0; //改行をNULLに置き換える - Serial.println((char*)mbuf); - // ブローカにデータを送信する。最後の false を true にすると、retained になる。 - bool ret = mqttClient.publish(pubTopic, mbuf, pos-1, false); - if (!ret){ - Serial.println("publish failed."); - } - } - delay(10); -} - -void reconnect() { - while (!mqttClient.connected()) { - if (mqttClient.connect(clientid, mquser, mqpass)) { - Serial.println("Connected to MQTT Broker."); - } else { - Serial.printf("Connect Failed. state=%d", mqttClient.state()); - } - } -} +// MQTT Publisher example +//#include +#include +// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ +#include + +const char* ssid = "miura2g"; +const char* password = "jikken2022"; + +const char* server = "192.168.11.11"; // "mqtt.istlab.info"; +const int port = 1883; // 注:学内ネットワークはポート制限あり。 +const char* pubTopic = "jikken"; // 班名を入れれば他の班とかぶらない。+にはしない。ex. jikken/A4han + +WiFiClient wifiClient; +char* clientid = "m5stickc01_00000002"; //デバイス個別に設定すればなんでもよい +PubSubClient mqttClient(wifiClient); // MQTT Client + +void setup() { + // M5.begin(); + Serial.begin(115200); + WiFi.begin(ssid, password); + while ( WiFi.status() != WL_CONNECTED ) { // 接続中... + Serial.print("."); + delay(200); + } + Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス + + mqttClient.setServer(server, port); + + if ( !mqttClient.connected() ) { + Serial.println("Try connecting MQTT ..."); + reconnect(); + } + + // 参考:WiFiデバイスのMACアドレスを取得し、送信する + uint8_t mac[6]; + esp_read_mac(mac, ESP_MAC_WIFI_STA); + char mbuf[100]; + sprintf(mbuf, "Message from %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); + + mqttClient.publish( pubTopic , mbuf ); // MQTT publish message + Serial.println(mbuf); //送信した内容をシリアルに表示して確認 + + Serial.println("publishするメッセージをSerialから送信してください"); +} + +void loop() { + // シリアルコンソールから書き込みがあれば, publishする + char mbuf[100]; int pos = 0; + while ( Serial.available() ) { // ノンブロッキング + mbuf[pos] = Serial.read(); + pos++; + } + if (pos > 0) { + mbuf[pos-1] = 0; //改行をNULLに置き換える + Serial.println(mbuf); + if ( !mqttClient.connected() ) reconnect(); + // ブローカにデータを送信する。最後の false を true にすると、retained になる。 + // boolean ret = mqttClient.publish( pubTopic , mbuf, size, false ); + mqttClient.publish( pubTopic , mbuf ); + // if ( !ret ){ + // Serial.println("publish failed."); + // } + } + delay(100); +} + +void reconnect() { + while ( !mqttClient.connected() ) { + if ( mqttClient.connect(clientid) ) { + Serial.println("Connected to MQTT Broker."); + } else { + Serial.printf("Connect Failed. state=%d", mqttClient.state()); + } + } +} + + + diff --git a/src/mqtt01sub.ino b/src/mqtt01sub.ino index 6852c61..2e852a2 100644 --- a/src/mqtt01sub.ino +++ b/src/mqtt01sub.ino @@ -1,82 +1,83 @@ -// MQTT Subscriber example -// #include -#include -// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ -#include -// ライブラリで ArduinoJson v6.xをいれておく ★★★ 重要 ★★★ -// (注意:Arduino_Json v0.1.0 は別物) -#include - -const char* ssid = "miura2g"; -const char* password = "jikken2022"; - -const char* server = "192.168.11.11"; // "mqtt.istlab.info"; -const int port = 1883; // 注:学内ネットワークはポート制限あり。 -const char* pubTopic = "office/temp"; // 例: ex1/groupXX/sensor -const char* mquser = "ex1"; -const char* mqpass = "***PASSWORD***"; -WiFiClient wifiClient; -char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい -PubSubClient mqttClient(wifiClient); // MQTT Client - -void setup() { -// M5.begin(); - Serial.begin(115200); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { // 接続中... - Serial.print("."); - delay(200); - } - Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス - // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる - // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい) - // uint8_t mac[6]; - // esp_read_mac(mac, ESP_MAC_WIFI_STA); - // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X", - // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); - mqttClient.setServer(server, port); - mqttClient.setCallback(callback_on_subscribe); - - if (!mqttClient.connected()) { - Serial.println("Try (re)connecting..."); - reconnect(); - } - mqttClient.subscribe(pubTopic); - -} - -void loop() { - - mqttClient.loop(); // データがpublishされたら、callback_on_subscribe が呼ばれる - - delay(100); -} - -void reconnect() { - while (!mqttClient.connected()) { - if (mqttClient.connect(clientid, mquser, mqpass)) { - Serial.println("Connected to MQTT Broker."); - } else { - Serial.printf("Connect Failed. state=%d", mqttClient.state()); - } - } -} - -// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため) -void callback_on_subscribe(char* topic, byte* payload, unsigned int len) { - char buf[100]; - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - for (int i = 0; i < len ; i++) { - buf[i] = (char)payload[i]; - } - buf[len] = 0; - Serial.println(buf); - return; - // 参考:JSON Parsing example - // StaticJsonDocument<200> sjdoc; - // deserializeJson(sjdoc, buf); - // int intval = sjdoc["intval"]; - // const char* str = sjdoc["string"]; -} \ No newline at end of file +// MQTT Subscriber example +// #include +#include +// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ +#include +// ライブラリで ArduinoJson v6.xをいれておく ★★★ 重要 ★★★ +// (注意:Arduino_Json v0.1.0 は別物) +#include + +const char* ssid = "miura2g"; +const char* password = "jikken2022"; + +const char* server = "192.168.11.11"; // "mqtt.istlab.info"; +const int port = 1883; // 注:学内ネットワークはポート制限あり。 +const char* pubTopic = "+"; // 例: ex1/groupXX/sensor + +WiFiClient wifiClient; +char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい +PubSubClient mqttClient(wifiClient); // MQTT Client + +void setup() { + // M5.begin(); + Serial.begin(115200); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { // 接続中... + Serial.print("."); + delay(200); + } + Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス + // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる + // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい) + // uint8_t mac[6]; + // esp_read_mac(mac, ESP_MAC_WIFI_STA); + // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X", + // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); + mqttClient.setServer(server, port); + mqttClient.setCallback(callback_on_subscribe); + + if (!mqttClient.connected()) { + Serial.println("Try (re)connecting..."); + reconnect(); + } + mqttClient.subscribe(pubTopic); + +} + +void loop() { + + mqttClient.loop(); // データがpublishされたら、callback_on_subscribe が呼ばれる + + delay(100); +} + +void reconnect() { + while (!mqttClient.connected()) { + if (mqttClient.connect(clientid)) { + Serial.println("Connected to MQTT Broker."); + } else { + Serial.printf("Connect Failed. state=%d", mqttClient.state()); + } + } +} + +// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため) +void callback_on_subscribe(char* topic, byte* payload, unsigned int len) { + char buf[100]; + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + for (int i = 0; i < len ; i++) { + buf[i] = (char)payload[i]; + } + buf[len] = 0; + Serial.println(buf); + return; + // 参考:JSON Parsing example + // StaticJsonDocument<200> sjdoc; + // deserializeJson(sjdoc, buf); + // int intval = sjdoc["intval"]; + // const char* str = sjdoc["string"]; +} + + diff --git a/week1.rst b/week1.rst index bee0929..962c2a3 100755 --- a/week1.rst +++ b/week1.rst @@ -18,13 +18,16 @@ プログラムの書き込み方 -------------------------------------- -:ref:`writetom5` を参照してください。 +IoTP プログラムで、ソースコード(.ino)を開いて、**Uploadボタン** を押してください。 +または、git bash で SampleSrc フォルダに cd で移動したあとで、``./Upload.sh`` を実行してください。なお、引数にファイルを指定する(例えば ``./Upload.sh lcd01.ino``)と、直接コンパイル&書き込みを行います。 + +.. note:: IoTP プログラムのUploadボタンは、Upload.bat (または Upload.sh) を実行しているだけです。このバッチファイル(またはスクリプト)は、指定したソースコードを TestBuild/TestBuild.ino にコピーしたのち、フォルダを指定してコンパイルします。実行ファイルはbuildフォルダの中に生成されます。arduino-cli では、実行ファイルを直接指定して書き込む方法もあります。(参考:``_Upload_FactoryTest.bat``) コードを書くときのヒントと注意 ------------------------------------------------------- -- 以下のソースコード例は、リストの右上の□ボタンを押すと、クリップボードに簡単にコピーできます。右上のボタンが表示されていないときは、右にスクロールしてください。 +- 以下のソースコード例は、リストの右上の□ボタンを押すと、クリップボードに簡単にコピーできます。右上のボタンが表示されていないときは、右にスクロールしてください。**(ただし、一部のWeb掲載プログラムは古くなっていますので、IoTPプログラムが一覧をだしてくれる SampleSrcフォルダ 内のファイルをつかってください。)** - ソースコードのインデントは、CTRL+T (Macの場合はCommand+T)キーで、自動整形できます。 - ``#include `` は、M5StickC用のヘッダファイル指定です。 **M5StickCPlus** では、画面解像度が異なるので、 ``#include `` に変更しないと、表示がおかしくなることがあります。 - 大文字と小文字は厳密に区別されます。 @@ -397,11 +400,11 @@ Google Apps Scriptを用いると、HTTP通信で Google Spreadsheet にデータを書き込んだり、読み取ったりするWebサービスを作成し、WebAPIとして公開することができます。 -(Google Spreadsheetのメニューで) 拡張機能→Apps Script または、ツール→スクリプトエディタ で、:numref:`doget` を「コード.gs」に書き込みます。14行目で「シート1」の一番下の行に、配列array の要素を追加します。18行目のgetRange(1,3).getValue()は、スプレッドシートのC1(3列1行)の値を取得しています。ここに「=average(C2:C200)」のようにしておくと、データの平均値を取得することもできます。 +(Google Spreadsheetのメニューで) 拡張機能→Apps Script で、:numref:`doget` を「コード.gs」に書き込みます。14行目で「シート1」の一番下の行に、配列array の要素を追加します。18行目のgetRange(1,3).getValue()は、スプレッドシートのC1(3列1行)の値を取得しています。ここに「=average(C2:C200)」のようにしておくと、データの平均値を取得することもできます。 -作成した「コード.gs」について、「公開」→「ウェブアプリケーションとして導入...」で、Webアプリとして公開できます。(なお、「新しいエディタ」では表示が異なるため、できない可能性があります。) +作成した「コード.gs」について、「デプロイ」→「新しいデプロイ」で、アクセスできるユーザを「全員」にし、「デプロイ」を押します。すると、ウェブアプリのURLが表示されますのでコピーします。**このあと、Googleアカウント権限について聞かれる場合があります。** -作成できたかどうかをパソコンから確認するには、コマンドラインから、以下のように入力します(ただし、curlが必要です。val1=10 と val2=20 のあいだは&記号ですので、シェルでバックグラウンド処理されないように、URLをシングルクォートで囲っています。-L (--location)は、リダイレクト先にリクエストを発行するcurlのオプションです。) :: +作成できたかどうかをパソコンから確認するには、コマンドラインから、以下のように入力します(ただし、curlが必要です。val1=10 と val2=20 のあいだは&記号ですので、シェルでバックグラウンド処理されないように、URLをシングルクォートで囲っています。-L (--location)は、リダイレクト先にリクエストを発行するcurlのオプションです。) exec のあとに ? をいれて、名前1=値1&名前2=値2 のようにしてデータを渡します。 :: curl -L 'https://script.google.com/macros/s/XxXxXxXxXx/exec?val1=10&val2=20' @@ -456,7 +459,7 @@ MQTT Publish ~~~~~~~~~~~~~~~~~~~~~~~~ -:numref:`mqtt01pub` は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ``office/temp`` というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 **パスワードはここには書けませんので、講義システム(三浦担当講義用)を参照してください。** +:numref:`mqtt01pub` は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ``office/temp`` というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 .. literalinclude:: src/mqtt01pub.ino @@ -471,20 +474,20 @@ MQTT Subscribe ~~~~~~~~~~~~~~~~~~~~~~~~ -:numref:`mqtt01sub` は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ``office/temp`` というトピックを購読します。 **パスワードはここには書けませんので、講義システム(三浦担当講義用)を参照してください。** JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング/deserialize すると便利です(78行目以降にサンプルがあります)。 +:numref:`mqtt01sub` は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ワイルドカード文字 ``+`` (プラス) は、任意の単一トピック階層にマッチするすべてのトピックを購読します。ワイルドカード文字 ``#`` は / で区切られた下位トピック階層も含めてマッチします。 JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング(deserialize) すると便利です(76行目以降にサンプルがあります)。 .. literalinclude:: src/mqtt01sub.ino :caption: :name: mqtt01sub :language: arduino :linenos: - :emphasize-lines: 38-39 + :emphasize-lines: 36-37 トピック名とワイルドカード ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -サブスクライブするときのトピック名には、ワイルドカードが指定できます。例えば、 ``office/+`` -と指定すると、 ``office/temp`` にも ``office/humid`` にもマッチします。`参考:MQTT の仕様 `_ +上述のとおり、サブスクライブするときのトピック名には、ワイルドカード文字が指定できます。例えば、 ``office/+`` +と指定すると、 ``office/temp`` にも ``office/humid`` にもマッチします。`参考:MQTT トピック `_ mosquitto コマンド例 @@ -553,7 +556,7 @@ https://lang-ship.com/blog/work/m5stickc-esp-now-1/ を参照してください。 :numref:`espnow02` に、MACアドレスにFF:FF:FF:FF:FF:FF を指定し、ブロードキャストする例を示します。 -ブロードキャストの場合、送信先のMACアドレスを指定しなくてよいので楽ですが、他の班のデバイスからも受信できます。 +ブロードキャストの場合、送信先のMACアドレスを指定しなくてよいので楽ですが、他の班のデバイスからも受信できます。espnow02.ino は、数値データのみを送受信する例です。espnow03.ino は、整数・小数・文字列をまとめてbyte (uint8_t) 配列に埋め込んで送受信する例です。 .. literalinclude:: src/espnow02.ino :caption: