MQTT

2022年1月20日 (木)

Wio-TerminalでMQTTを動かす

2022/1/20
初版

Wio-Terminal MQTT

Wio-Terminal MQTT

概要

Wio-TerminalでMQTTを動かす。
MQTT on Wio Terminal」の記事のコードを利用して、Wio-TerminalでMQTTを動かす。
ビルド環境としては、platformioを使用する。
ここでは、Wio-TerminalをPublisher(送信側)、PCやiPhoneをSubscriber(受信側)にする。

Publisher(送信側)

当該の「MQTT on Wio Terminal」の記事のコードにある[ボタン]でコードをコピーまたはダウンロードして platformioのプロジェクト(ディレクトリ)のsrc配下に置く。
# ダウンロードしたものは、ファイルタイプが「.c」になっているので、「.ino」にする。

src配下に置いたコードに以下のパッチを当てる:

src/WioTerminal_MQTT_Example.ino

#6行目付近を以下のように変更する。(新しいファームを使用する) //#include <AtWiFi.h> // old firmware #include <rpcWiFi.h> #22行目付近を自分のWiFi環境に合わせて変更する。 // Update these with values suitable for your network. const char* ssid = "***"; // WiFi Name const char* password = "***"; // WiFi Password const char* mqtt_server = "broker.mqtt-dashboard.com"; // MQTT Broker URL

plaformio.iniは以下のものにする: platformio.ini

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:seeed_wio_terminal] platform = atmelsam board = seeed_wio_terminal framework = arduino build_flags = -DWIO_TERMINAL upload_protocol = sam-ba monitor_speed = 115200 lib_ldf_mode = deep+ lib_deps = https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls/archive/dev.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcUnified/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcBLE/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_FreeRTOS/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_FS/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_SFUD/archive/master.zip # https://github.com/Seeed-Studio/Seeed_Arduino_LCD/archive/master.zip # arduino-libraries/NTPClient@^3.1.0 # powerbroker2/SafeString@^4.1.14 seeed-studio/Seeed Arduino RTC@^2.0.0 # lovyan03/LovyanGFX@^0.4.10 https://github.com/tanakamasayuki/efont.git https://github.com/Tamakichi/Arduino-misakiUTF16.git # adafruit/Adafruit Unified Sensor@^1.1.4 adafruit/Adafruit BME280 Library@^2.2.2 adafruit/Adafruit DPS310@^1.1.1 adafruit/RTClib@^2.0.2 ;neironx/RTCLib@^1.6.0 ;wemos/WEMOS SHT3x@^1.0.0 https://github.com/Seeed-Studio/Grove_SHT31_Temp_Humi_Sensor.git # knolleary/PubSubClient@^2.8

以下のコマンドラインでビルドと書き込みを行う:

pio run -t upload #通信ソフトを起動する bt -L 1

USBシリアルからは、publishしているメッセージが表示される。

Subscriber(受信側)

Subscriberとしては、Andoroid,iPhone,PCが使用できるが、ここでは、PCとiPhoneを取り上げる:

PCの場合:
以下のurlにwebブラウザーでアクセスする。
http://www.hivemq.com/demos/websocket-client/
websocket client

[Connect]をクリックして、broker-serverに接続して Subscriptionsの[Add New Topic Subuscription]をクリックして Wio-TerminalのPublisherで使用しているTopicの「WTout」を入力して Subscribeする。
そうすると、Wio-Terminalからのメッセージが表示される。 以下、表示例:

Messages 2022-01-20 09:02:49 Topic: WTout Qos: 0 Wio Terminal #6241 2022-01-20 09:02:47 Topic: WTout Qos: 0 Wio Terminal #6240 2022-01-20 09:02:45 Topic: WTout Qos: 0 Wio Terminal #6239 2022-01-20 09:02:42 Topic: WTout Qos: 0 Wio Terminal #6238   ...

iPhoneの場合:
アプリとしてMQTTtoolかEasyMQTTをインストールして 以下の情報を設定する:

MQTTtool設定情報:

HOST broker.mqtt-dashboard.com Port 1883 Client ID アプリ側で自動設定されるので特に入力は無い Username/Passwaordは不要。 SubscribeのTopicは「WTout」を設定する。

EasyMQTT設定情報:

HOST broker.mqtt-dashboard.com Port 1883 Client ID Wio Terminal MQTT Username/Passwaordは不要。 SubscribeのTopicは「WTout」を設定する。

broker-serverの設定情報

MQTT connection settings

Connection Name: Public MQTT Broker Client ID: Wio Terminal MQTT(任意) Broker Web/IP address: broker.mqtt-dashboard.com TCP Port: 1883 Websocket Port: 8000

以下をアクセスするとMQTTのアクセス状況が表示される:
http://broker.mqtt-dashboard.com/
HIVEMQ MQTT Dashboard

参考情報

terminal関連:
Bootterm – a developer-friendly serial terminal program

Wio-Terminal関連:
wio-terminal firmware update(v2) (linux)
nixieクロックにNTPクライアントの機能を追加する(v2,rpcファーム対応)

MQTT関連:
Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(MQTT編)
10 Free Public MQTT Brokers(Private & Public)

platformio関連:
arduinoフレームワーク用platformio.ini集
Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(STARWARS編)
Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(MQTT編)
Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(REST-API編)
Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(OSC編)
Building Core2 FactoryDemo in PlatformIO
VSCodeとPlatformIOでM5Stack Core2開発
M5Stack Core2とVSCode + PlatformIOとでM5Stackプログラミングを始めてみた。
Arduino勉強会/37-RaspberryPi Picoをはじめよう - デバッガー

Arduino-IDE関連:
Raspberry Pi PicoでI2C/SPI通信
Arduino IDE environment - M5Paper
Arduino IDEのインストールと設定 (Windows, Mac, Linux対応)

以上

続きを読む "Wio-TerminalでMQTTを動かす"

| | コメント (0)

2020年12月27日 (日)

Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(MQTT編)

2020/12/27:
初版

board3 MQTT v2

board3 MQTT v2

概要

Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(MQTT編)

本記事は「 Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(MQTT編) 」 の改版にあたり、wio-terminalのファームウェア・バージョンアップに対応している。

wio-terminalのファームウェアのアップデート方法については以下を参照のこと:
wio-terminalのファームウェア・アップデートについて(v2)(linux版)

デモ・スケッチ

src/MQTT_test.ino

// select board ////#define WIO_TERMINAL ////#define ESP8266 ////#define ESP32 ////#define M5ATOM //------------------ // // MQTT program for Wio-Terminal/ESP8266/ESP32 // // Forked from the following code: //-------------------------------------------- // This example uses an Adafruit Huzzah ESP8266 // to connect to shiftr.io. // // You can check on your device after a successful // connection here: https://shiftr.io/try. // // by Joël Gähwiler // https://github.com/256dpi/arduino-mqtt //-------------------------------------------- #ifdef M5ATOM #include "M5Atom.h" #define ESP32 #endif #ifdef WIO_TERMINAL //#include <AtWiFi.h> #include <rpcWiFi.h> #endif #ifdef ESP8266 #include <ESP8266WiFi.h> #endif #ifdef ESP32 #include <WiFi.h> #endif #include <MQTT.h> const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd"; WiFiClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("checking wifi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } Serial.print("\nconnecting..."); while (!client.connect("arduino", "try", "try")) { // for "broker.shiftr.io" //while (!client.connect("arduino", "", "")) { // no username. no passwd (for "mqtt.eclipse.org") Serial.print("."); delay(1000); } Serial.println("\nconnected!"); client.subscribe("topic0"); // client.unsubscribe("/hello"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); } void setup() { Serial.begin(115200); WiFi.begin(ssid, pass); // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino. // You need to set the IP address directly. // uncomment one of them to select MQTT server client.begin("broker.shiftr.io", net); //OK //client.begin("mqtt.eclipse.org", net); //OK //client.begin("test.mosquitto.org", net); //NG? client.onMessage(messageReceived); connect(); } void loop() { char s[100]; // buf for sprintf // dumy sensor values float pascals = 101312; float altm = 42; //m float tempC = 28.7; // deg C client.loop(); delay(10); // <- fixes some issues with WiFi stability if (!client.connected()) { connect(); } // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); // publish sensor values sprintf(s,"{ \"press\" : %.2f, \"altm\" : %.1f, \"tempC\" : %.1f}", pascals/100, altm, tempC); client.publish("topic0", &s[0]); } delay(1000); }

wio-terminalのファームウェアのバージョン・アップにともない
以下のようにヘッダーが変更になっている:

//#include <AtWiFi.h> #include <rpcWiFi.h>

以下の#defineでボードを切り換えているがボードの種類を設定すると、 システムで設定されている定義が有効になるので特にソースを変更する必要はない。

#define WIO_TERMINAL #define ESP8266 #define ESP32 #define M5ATOM

以下については、自分の環境に合わせて変更すること:

const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd";

以下は利用するMQTTサーバー(broker)に合わせてコメントアウトする:

<省略> while (!client.connect("arduino", "try", "try")) { // for "broker.shiftr.io" //while (!client.connect("arduino", "", "")) { // no username. no passwd (for "mqtt.eclipse.org") <省略> <省略> client.begin("broker.shiftr.io", net); //OK //client.begin("mqtt.eclipse.org", net); //OK <省略>

書き込み後に「picocom /dev/ttyACM0 -b115200」または「picocom /dev/ttyUSB0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyACM0 -b115200 Terminal ready # 実際のセンサーを接続していないので一定のダミーデータを受信する incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ... <省略>

対向する送受信プログラム

以下をブラウザ(chromeのみ)で動かす:

MQTT_AT_webTestZero_02.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //var mqtt_url = 'ws://test.mosquitto.org:8081' //var mqtt_url = 'ws://mqtt.eclipse.org/mqtt:443' var mqtt_url = 'wss://try:try@broker.shiftr.io' document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test'+'('+mqtt_url+')<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt'); var client = mqtt.connect(mqtt_url); // subscribe Topic //client.subscribe('hello'); client.subscribe('topic0'); //client.subscribe('topic0/sample/hello'); //client.subscribe('topic0/sample/#'); // wildcard topic //client.subscribe('topic0/#'); //client.subscribe('#'); client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages client.publish('topic0', 'hello world of MQTT! #1'); client.publish('topic0', 'hello world of MQTT! #2'); client.publish('topic0', 'hello world of MQTT! #3'); client.publish('topic0', 'hello world of MQTT! #4'); client.publish('topic0', 'hello world of MQTT! #5'); </script> </body> </html>

以下の部分は使用しているbrokerによって変更すること:
(brokerが止まっていることがあるようなので、そのときはbrokerを変えてみる)

//var mqtt_url = 'ws://test.mosquitto.org:8081' //var mqtt_url = 'ws://mqtt.eclipse.org/mqtt:443' var mqtt_url = 'wss://try:try@broker.shiftr.io'

デモプログラムを起動後、上の「MQTT_AT_webTestZero_02.html」をプラウザーで起動すると
以下のweb画面が表示される(例):

MQTT over WebSockets Test(wss://try:try@broker.shiftr.io) topic0: hello world of MQTT! #1 topic0: hello world of MQTT! #2 topic0: hello world of MQTT! #3 topic0: hello world of MQTT! #4 topic0: hello world of MQTT! #5 topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ...

platformio.ini

platformio.iniは、ボードに合わせて以下を使用する:

wio-terminalの場合:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:seeed_wio_terminal] platform = atmelsam board = seeed_wio_terminal framework = arduino build_flags = -DWIO_TERMINAL upload_protocol = sam-ba monitor_speed = 115200 lib_ldf_mode = deep+ lib_deps = https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls/archive/dev.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcUnified/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcBLE/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_FreeRTOS/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_FS/archive/master.zip https://github.com/Seeed-Studio/Seeed_Arduino_SFUD/archive/master.zip # https://github.com/Seeed-Studio/Seeed_Arduino_LCD/archive/master.zip # MQTT lib 617

M5Atomの場合:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] platform = espressif32 #board = esp32dev board = m5stick-c framework = arduino monitor_speed = 115200 lib_ldf_mode = deep+ lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 # MQTT lib 617

ESP32の場合:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 lib_ldf_mode = deep+ lib_deps = # MQTT lib 617

ESP8266の場合:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:huzzah] platform = espressif8266 #board = huzzah board = esp_wroom_02 framework = arduino monitor_speed = 115200 lib_ldf_mode = deep+ lib_deps = # MQTT lib 617

wio-terminalのファームウェアを切り替えたときの注意

古いファームウェアのライブラリを動かした後は、古いライブラリがキャッシュで残っていると ビルド・エラーになるので以下を実行すること:

cd project_directory rm -r .pio/libdeps/seeed_wio_terminal/* rm -r .pio/build/seeed_wio_terminal/*

参考情報

https://docs.shiftr.io/interfaces/mqtt/

The following ports are available on the broker.shiftr.io host: MQTT MQTTS MQTTWS MQTTWSS 1883 8883 80 443

MQTT test server @mosquitto.org

https://test.mosquitto.org/ The server listens on the following ports: 1883 : MQTT, unencrypted 8883 : MQTT, encrypted 8884 : MQTT, encrypted, client certificate required 8080 : MQTT over WebSockets, unencrypted 8081 : MQTT over WebSockets, encrypted websocketで使用するurlは以下になる: 'ws://test.mosquitto.org:8081'

MQTT test server @eclipse.org

http://mqtt.eclipse.org/ This is a public test MQTT broker service. It currently listens on the following ports: 1883 : MQTT over unencrypted TCP 8883 : MQTT over encrypted TCP 80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt ) 443 : MQTT over encrypted WebSockets (note: URL must be /mqtt ) websocketで使用するurlは以下になる: 'ws://mqtt.eclipse.org/mqtt:443'

10 Free Public & Private MQTT Brokers(For Testing & Production)

PlatformIO Core (CLI)

ESP-WROOM-02ボードでMQTTとMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)
本記事のスケッチは、この記事のスケッチとほとんど同じであるので参考にできる。

以上

続きを読む "Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(MQTT編)"

| | コメント (0)

2020年7月21日 (火)

Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(MQTT編)

2020/7/21:
初版

board3 MQTT

board3 MQTT

概要

Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(MQTT編)
(ホストPCとしてはubuntuを想定している)

外部ライブラリ(platformioの場合)

以下を実行してライブラリをインストールする:

# MQTT lib インストール pio lib install 617

外部ライブラリ(Arduino-IDEの場合)

Arduino-IDEでMQTTライブラリをインストールする。 MQTTは同じようなライブラリが見つかるが 「author:Joel Gaehwiler」のものをインストールする。

デモ・スケッチ

src/MQTT_test.ino

// select board ////#define WIO_TERMINAL ////#define ESP8266 ////#define ESP32 //------------------ // // MQTT program for Wio-Terminal/ESP8266/ESP32 // // Forked from the following code: //-------------------------------------------- // This example uses an Adafruit Huzzah ESP8266 // to connect to shiftr.io. // // You can check on your device after a successful // connection here: https://shiftr.io/try. // // by Joël Gähwiler // https://github.com/256dpi/arduino-mqtt //-------------------------------------------- #ifdef WIO_TERMINAL #include <AtWiFi.h> #endif #ifdef ESP8266 #include <ESP8266WiFi.h> #endif #ifdef ESP32 #include <WiFi.h> #endif #include <MQTT.h> const char ssid[] = "your_ssid"; const char pass[] = "your_passwd"; WiFiClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("checking wifi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } Serial.print("\nconnecting..."); //while (!client.connect("arduino", "try", "try")) { // for "broker.shiftr.io" while (!client.connect("arduino", "", "")) { // no username. no passwd (for "mqtt.eclipse.org") Serial.print("."); delay(1000); } Serial.println("\nconnected!"); client.subscribe("topic0"); // client.unsubscribe("/hello"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); } void setup() { Serial.begin(115200); WiFi.begin(ssid, pass); // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino. // You need to set the IP address directly. // uncomment one of them to select MQTT server //client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK //client.begin("test.mosquitto.org", net); //NG? client.onMessage(messageReceived); connect(); } void loop() { char s[100]; // buf for sprintf // dumy sensor values float pascals = 101312; float altm = 42; //m float tempC = 28.7; // deg C client.loop(); delay(10); // <- fixes some issues with WiFi stability if (!client.connected()) { connect(); } // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); // publish sensor values sprintf(s,"{ \"press\" : %.2f, \"altm\" : %.1f, \"tempC\" : %.1f}", pascals/100, altm, tempC); client.publish("topic0", &s[0]); } delay(1000); }

以下の#defineでボードを切り換えているがボードの種類を設定すると、 システムで設定されている定義が有効になるので特にソースを変更する必要はない。

#define WIO_TERMINAL #define ESP8266 #define ESP32

以下については、自分の環境に合わせて変更すること:

const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd";

以下は利用するMQTTサーバー(broker)に合わせてコメントアウトする:

//client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK

書き込み後に「picocom /dev/ttyACM0 -b115200」または「picocom /dev/ttyUSB0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyACM0 -b115200 Terminal ready # 実際のセンサーを接続していないので一定のダミーデータを受信する incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ... <省略>

対向する送受信プログラム

以下をブラウザ(chromeのみ)で動かす:

MQTT_AT_webTestZero.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //var mqtt_url = 'ws://test.mosquitto.org:8081' var mqtt_url = 'ws://mqtt.eclipse.org/mqtt:443' //var mqtt_url = 'wss://try:try@broker.shiftr.io' document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test'+'('+mqtt_url+')<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt'); var client = mqtt.connect(mqtt_url); // subscribe Topic //client.subscribe('hello'); client.subscribe('topic0'); //client.subscribe('topic0/sample/hello'); //client.subscribe('topic0/sample/#'); // wildcard topic //client.subscribe('topic0/#'); //client.subscribe('#'); client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages client.publish('topic0', 'hello world of MQTT! #1'); client.publish('topic0', 'hello world of MQTT! #2'); client.publish('topic0', 'hello world of MQTT! #3'); client.publish('topic0', 'hello world of MQTT! #4'); client.publish('topic0', 'hello world of MQTT! #5'); </script> </body> </html>

デモプログラムを起動後、上の「MQTT_AT_webTestZero.html」をプラウザーで起動すると
以下のweb画面が表示される(例):

MQTT over WebSockets Test(ws://mqtt.eclipse.org/mqtt:443) topic0: hello world of MQTT! #1 topic0: hello world of MQTT! #2 topic0: hello world of MQTT! #3 topic0: hello world of MQTT! #4 topic0: hello world of MQTT! #5 topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ...

Arduino-IDEのボードマネージャーのURL

以下のURLを設定することで3つのボード(Wio-Terminal/ESP8266/ESP32)が使用可能になる。

https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json http://arduino.esp8266.com/stable/package_esp8266com_index.json https://dl.espressif.com/dl/package_esp32_index.json

参考情報

https://docs.shiftr.io/interfaces/mqtt/

The following ports are available on the broker.shiftr.io host: MQTT MQTTS MQTTWS MQTTWSS 1883 8883 80 443

MQTT test server @mosquitto.org

https://test.mosquitto.org/ The server listens on the following ports: 1883 : MQTT, unencrypted 8883 : MQTT, encrypted 8884 : MQTT, encrypted, client certificate required 8080 : MQTT over WebSockets, unencrypted 8081 : MQTT over WebSockets, encrypted websocketで使用するurlは以下になる: 'ws://test.mosquitto.org:8081'

MQTT test server @eclipse.org

http://mqtt.eclipse.org/ This is a public test MQTT broker service. It currently listens on the following ports: 1883 : MQTT over unencrypted TCP 8883 : MQTT over encrypted TCP 80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt ) 443 : MQTT over encrypted WebSockets (note: URL must be /mqtt ) websocketで使用するurlは以下になる: 'ws://mqtt.eclipse.org/mqtt:443'

10 Free Public & Private MQTT Brokers(For Testing & Production)

PlatformIO Core (CLI)

ESP-WROOM-02ボードでMQTTとMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)
本記事のスケッチは、この記事のスケッチとほとんど同じであるので参考にできる。

以上

続きを読む "Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(MQTT編)"

| | コメント (0)

2020年7月13日 (月)

Wio-TerminalでWiFiで使う(その5:MQTT)

2020/7/13:
初版

PlatformIO Wio Terminal WiFi5 MQTT

PlatformIO Wio Terminal WiFi5 MQTT

概要

Wio-TerminalでWiFiで使う(その5:MQTT)
これは「Wio-TerminalでWiFiで使う(その4:OSC)」の続きでMQTTデモプログラムについて記載する
(ホストPCとしてはubuntuを想定している)

外部ライブラリ

以下を実行してライブラリをインストールする:

# MQTT lib インストール pio lib install 617

MQTT_test

src/MQTT_test.ino

#include <SPI.h> // forced // // Wio Terminal MQTT program // // Forked from the following code: //-------------------------------------------- // This example uses an Adafruit Huzzah ESP8266 // to connect to shiftr.io. // // You can check on your device after a successful // connection here: https://shiftr.io/try. // // by Joël Gähwiler // https://github.com/256dpi/arduino-mqtt //-------------------------------------------- //#include <ESP8266WiFi.h> #include <AtWiFi.h> #include <MQTT.h> const char ssid[] = "your_ssid"; const char pass[] = "your_passwd"; WiFiClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("checking wifi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } Serial.print("\nconnecting..."); //while (!client.connect("arduino", "try", "try")) { // for "broker.shiftr.io" while (!client.connect("arduino", "", "")) { // no username. no passwd (for "mqtt.eclipse.org") Serial.print("."); delay(1000); } Serial.println("\nconnected!"); client.subscribe("topic0"); // client.unsubscribe("/hello"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); } void setup() { Serial.begin(115200); WiFi.begin(ssid, pass); // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino. // You need to set the IP address directly. // uncomment one of them to select MQTT server //client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK //client.begin("test.mosquitto.org", net); //NG? client.onMessage(messageReceived); connect(); } void loop() { char s[100]; // buf for sprintf // dumy sensor values float pascals = 101312; float altm = 42; //m float tempC = 28.7; // deg C client.loop(); delay(10); // <- fixes some issues with WiFi stability if (!client.connected()) { connect(); } // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); // publish sensor values sprintf(s,"{ \"press\" : %.2f, \"altm\" : %.1f, \"tempC\" : %.1f}", pascals/100, altm, tempC); client.publish("topic0", &s[0]); } delay(1000); }

以下については、自分の環境に合わせて変更すること:

const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd";

以下は利用するMQTTサーバー(broker)に合わせてコメントアウトする:

//client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK

書き込み後に「picocom /dev/ttyACM0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyACM0 -b115200 Terminal ready # 実際のセンサーを接続していないので一定のダミーデータを受信する incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} incoming: topic0 - { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ... <省略>

対向する送受信プログラム

以下をブラウザ(chromeのみ)で動かす:

MQTT_AT_webTestZero.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //var mqtt_url = 'ws://test.mosquitto.org:8081' var mqtt_url = 'ws://mqtt.eclipse.org/mqtt:443' //var mqtt_url = 'wss://try:try@broker.shiftr.io' document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test'+'('+mqtt_url+')<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt'); var client = mqtt.connect(mqtt_url); // subscribe Topic //client.subscribe('hello'); client.subscribe('topic0'); //client.subscribe('topic0/sample/hello'); //client.subscribe('topic0/sample/#'); // wildcard topic //client.subscribe('topic0/#'); //client.subscribe('#'); client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages client.publish('topic0', 'hello world of MQTT! #1'); client.publish('topic0', 'hello world of MQTT! #2'); client.publish('topic0', 'hello world of MQTT! #3'); client.publish('topic0', 'hello world of MQTT! #4'); client.publish('topic0', 'hello world of MQTT! #5'); </script> </body> </html>

デモプログラムを起動後、上の「MQTT_AT_webTestZero.html」をプラウザーで起動すると
以下のweb画面が表示される(例):

MQTT over WebSockets Test(ws://mqtt.eclipse.org/mqtt:443) topic0: hello world of MQTT! #1 topic0: hello world of MQTT! #2 topic0: hello world of MQTT! #3 topic0: hello world of MQTT! #4 topic0: hello world of MQTT! #5 topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} topic0: { "press" : 1013.12, "altm" : 42.0, "tempC" : 28.7} ...

補足

ESP8266WiFiライブラリとWio-TerminalのWiFiモジュールのAtWiFiライブラリは、互換性があるようなので、基本的には、ソース上は以下のような変更を行なうと動作するようだ:

//#include <ESP8266WiFi.h> #include <AtWiFi.h>

参考情報

https://docs.shiftr.io/interfaces/mqtt/

The following ports are available on the broker.shiftr.io host: MQTT MQTTS MQTTWS MQTTWSS 1883 8883 80 443

MQTT test server @mosquitto.org

https://test.mosquitto.org/ The server listens on the following ports: 1883 : MQTT, unencrypted 8883 : MQTT, encrypted 8884 : MQTT, encrypted, client certificate required 8080 : MQTT over WebSockets, unencrypted 8081 : MQTT over WebSockets, encrypted websocketで使用するurlは以下になる: 'ws://test.mosquitto.org:8081'

MQTT test server @eclipse.org

http://mqtt.eclipse.org/ This is a public test MQTT broker service. It currently listens on the following ports: 1883 : MQTT over unencrypted TCP 8883 : MQTT over encrypted TCP 80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt ) 443 : MQTT over encrypted WebSockets (note: URL must be /mqtt ) websocketで使用するurlは以下になる: 'ws://mqtt.eclipse.org/mqtt:443'

10 Free Public & Private MQTT Brokers(For Testing & Production)

PlatformIO Core (CLI)

ESP-WROOM-02ボードでMQTTとMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)
本記事のスケッチは、この記事のスケッチとほとんど同じであるので参考にできる。

以上

続きを読む "Wio-TerminalでWiFiで使う(その5:MQTT)"

| | コメント (0)

2020年7月 5日 (日)

ESP-WROOM-02ボードでMQTTとMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)

2020/7/5:
初版

PlatformIO ESP-WROOM-02 MQTT MPL3115A2

PlatformIO ESP-WROOM-02 MQTT MPL3115A2

概要

以下のESP-WROOM-02ボードでMQTTと以下のMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)。 (ホストPCとしてはubuntuを想定している)

ESPr® Developer(ESP-WROOM-02開発ボード)
MPL3115A2 - I2C気圧・高度・気温センサ

PINOUT

部品面から見てボードのUSBコネクタを下にした配置

ESP-WROOM-02(Right)
GND
IO16
TOUT
RESET
IO5
TXD
RXD
IO4
GND
VOUT
ESP-WROOM-02(Left)
3V3
EN
IO1
IO12
IO13
IO15
IO2
IO0
GND
VIN

接続

ESP-WROOM-02 MPL3115A2
IO5 SCL
IO4 SDA
GND GND
3V3 Vin

platformio.ini

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:huzzah] platform = espressif8266 #board = huzzah board = esp_wroom_02 framework = arduino

外部ライブラリ

以下を実行してライブラリをインストールする:

# MQTT lib インストール pio lib install 617 # Adafruit MPL3115A2 Lib インストール pio lib install 796 #実際に、これだと、コンパイルがエラーになったので、 #以下のように直接ライブラリのソースをダウンロードする: cd src wget https://raw.githubusercontent.com/adafruit/Adafruit_MPL3115A2_Library/master/Adafruit_MPL3115A2.cpp wget https://raw.githubusercontent.com/adafruit/Adafruit_MPL3115A2_Library/master/Adafruit_MPL3115A2.h

MQTT_MPL3115A2_test

src/MQTT_MPL3115A2_test.ino

// // MPL3115A2 sensor data publisher/subscriber // // MPL3115A2 Library url: // https://github.com/adafruit/Adafruit_MPL3115A2_Library // MQTT lib url: // https://github.com/256dpi/arduino-mqtt #include <Wire.h> #include <Adafruit_MPL3115A2.h> #include <ESP8266WiFi.h> #include <MQTT.h> const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd"; Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2(); WiFiClient net; MQTTClient client; unsigned long lastMillis = 0; void connect() { Serial.print("checking wifi..."); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } Serial.print("\nconnecting..."); //while (!client.connect("arduino", "try", "try")) { // for "broker.shiftr.io" while (!client.connect("", "", "")) { // no username. no passwd (for "mqtt.eclipse.org") Serial.print("."); delay(1000); } Serial.println("\nconnected!"); client.subscribe("topic0"); // client.unsubscribe("/hello"); } void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); } void setup() { Serial.begin(115200); WiFi.begin(ssid, pass); // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino. // You need to set the IP address directly. //client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK //client.begin("test.mosquitto.org", net); //NG? client.onMessage(messageReceived); connect(); } void loop() { char s[100]; // buf for sprintf if (! baro.begin()) { Serial.println("Couldnt find sensor"); return; } float pascals = baro.getPressure(); Serial.print(pascals/100); Serial.println(" hPa"); // float altm = baro.getAltitude(); Serial.print(altm); Serial.println(" meters"); // float tempC = baro.getTemperature(); client.loop(); delay(10); // <- fixes some issues with WiFi stability if (!client.connected()) { connect(); } // publish a message roughly every second. if (millis() - lastMillis > 1000) { lastMillis = millis(); //client.publish("topic0", String((int)pascals)); sprintf(s,"{ \"press\" : %.2f, \"altm\" : %.1f, \"tempC\" : %.1f}", pascals/100, altm, tempC); client.publish("topic0", &s[0]); } delay(2000); }

以下については、自分の環境に合わせて変更すること:

const char ssid[] = "yours_ssid"; const char pass[] = "yours_passwd";

以下は利用するMQTTサーバー(broker)に合わせてコメントアウトする:

//client.begin("broker.shiftr.io", net); //OK client.begin("mqtt.eclipse.org", net); //OK

書き込み後に「picocom /dev/ttyUSB0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyUSB0 -b115200 Terminal ready 1002.88 hPa 86.88 meters incoming: topic0 - { "press" : 1002.88, "altm" : 87.000000.1, "tempC" : 28.1} 1002.86 hPa 87.00 meters incoming: topic0 - { "press" : 1002.88, "altm" : 86.875000.1, "tempC" : 28.1} 1002.86 hPa 86.44 meters incoming: topic0 - { "press" : 1002.86, "altm" : 87.000000.1, "tempC" : 28.1} 1002.86 hPa 86.50 meters incoming: topic0 - { "press" : 1002.86, "altm" : 86.437500.1, "tempC" : 28.2} 1002.87 hPa 86.94 meters incoming: topic0 - { "press" : 1002.86, "altm" : 86.500000.1, "tempC" : 28.2} 1002.90 hPa 87.06 meters incoming: topic0 - { "press" : 1002.87, "altm" : 86.937500.1, "tempC" : 28.1} 1002.85 hPa 86.75 meters incoming: topic0 - { "press" : 1002.90, "altm" : 87.062500.1, "tempC" : 28.1} 1002.89 hPa 86.56 meters incoming: topic0 - { "press" : 1002.85, "altm" : 86.750000.1, "tempC" : 28.2} 1002.90 hPa 86.44 meters incoming: topic0 - { "press" : 1002.89, "altm" : 86.562500.1, "tempC" : 28.2} 1002.90 hPa 86.69 meters incoming: topic0 - { "press" : 1002.90, "altm" : 86.437500.1, "tempC" : 28.2} 1002.96 hPa 86.44 meters ... <省略>

対向する送受信プログラム

以下をブラウザ(chromeのみ)で動かす:

MQTT_AT_webTestZero.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //var mqtt_url = 'ws://test.mosquitto.org:8081' var mqtt_url = 'ws://mqtt.eclipse.org/mqtt:443' //var mqtt_url = 'wss://try:try@broker.shiftr.io' document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test'+'('+mqtt_url+')<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt'); var client = mqtt.connect(mqtt_url); // subscribe Topic //client.subscribe('hello'); client.subscribe('topic0'); //client.subscribe('topic0/sample/hello'); //client.subscribe('topic0/sample/#'); // wildcard topic //client.subscribe('topic0/#'); //client.subscribe('#'); client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages client.publish('topic0', 'hello world of MQTT! #1'); client.publish('topic0', 'hello world of MQTT! #2'); client.publish('topic0', 'hello world of MQTT! #3'); client.publish('topic0', 'hello world of MQTT! #4'); client.publish('topic0', 'hello world of MQTT! #5'); </script> </body> </html>

デモプログラムを起動後、上の「MQTT_AT_webTestZero.html」をプラウザーで起動すると
以下のweb画面が表示される(例):

MQTT over WebSockets Test(ws://mqtt.eclipse.org/mqtt:443) topic0: hello world of MQTT! #1 topic0: hello world of MQTT! #2 topic0: hello world of MQTT! #3 topic0: hello world of MQTT! #4 topic0: hello world of MQTT! #5 topic0: { "press" : 1002.58, "altm" : 88.3, "tempC" : 28.7} topic0: { "press" : 1002.58, "altm" : 88.4, "tempC" : 28.7} topic0: { "press" : 1002.56, "altm" : 88.1, "tempC" : 28.8} topic0: { "press" : 1002.61, "altm" : 88.3, "tempC" : 28.8} topic0: { "press" : 1002.59, "altm" : 88.4, "tempC" : 28.7} topic0: { "press" : 1002.59, "altm" : 88.4, "tempC" : 28.7} topic0: { "press" : 1002.57, "altm" : 88.6, "tempC" : 28.7} topic0: { "press" : 1002.59, "altm" : 89.0, "tempC" : 28.7} topic0: { "press" : 1002.58, "altm" : 88.2, "tempC" : 28.7} topic0: { "press" : 1002.61, "altm" : 88.2, "tempC" : 28.7} topic0: { "press" : 1002.60, "altm" : 88.8, "tempC" : 28.7} topic0: { "press" : 1002.59, "altm" : 88.6, "tempC" : 28.7} topic0: { "press" : 1002.63, "altm" : 88.3, "tempC" : 28.7} topic0: { "press" : 1002.59, "altm" : 88.3, "tempC" : 28.8} topic0: { "press" : 1002.60, "altm" : 88.3, "tempC" : 28.7} ...

参考情報

https://docs.shiftr.io/interfaces/mqtt/

The following ports are available on the broker.shiftr.io host: MQTT MQTTS MQTTWS MQTTWSS 1883 8883 80 443

MQTT test server @mosquitto.org

https://test.mosquitto.org/ The server listens on the following ports: 1883 : MQTT, unencrypted 8883 : MQTT, encrypted 8884 : MQTT, encrypted, client certificate required 8080 : MQTT over WebSockets, unencrypted 8081 : MQTT over WebSockets, encrypted websocketで使用するurlは以下になる: 'ws://test.mosquitto.org:8081'

MQTT test server @eclipse.org

http://mqtt.eclipse.org/ This is a public test MQTT broker service. It currently listens on the following ports: 1883 : MQTT over unencrypted TCP 8883 : MQTT over encrypted TCP 80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt ) 443 : MQTT over encrypted WebSockets (note: URL must be /mqtt ) websocketで使用するurlは以下になる: 'ws://mqtt.eclipse.org/mqtt:443'

10 Free Public & Private MQTT Brokers(For Testing & Production)

PlatformIO Core (CLI)

以上

続きを読む "ESP-WROOM-02ボードでMQTTとMPL3115A2(気圧・高度・気温センサ)を動かす(Arduino版)"

| | コメント (0)

2020年6月29日 (月)

Wio_Lite_RISC-VボードでWiFiを動かす(その4:MQTT)

2020/6/28:
初版

PlatformIO Wio Lite RISC-V WiFi4 MQTT

PlatformIO Wio Lite RISC-V WiFi4 MQTT

概要

Wio_Lite_RISC-VボードでWiFiを動かす(その4:MQTT)。 これは「Wio_Lite_RISC-VボードでWiFiを動かす(その3:OSC)」の続きになる。ここでは、MQTTのデモプログラムについて記載する
開発ツール(PlatformIOなど)のインストールについては「開発ツールPlatformIOをcliで使う(Wio_Lite_RISC-V版)」を参照のこと、ここでは、WiFiを動かすためのプログラムについて記載する。 (ホストPCとしてはubuntuを想定している)

プログラムにある以下の関数に関しては、 https://github.com/nopnop2002/MQTT_via_ESP01/blob/master/MQTT_Subscribe_ESP01/MQTT_Subscribe_ESP01.inoにあるものを、そのまま流用した:
・int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg)
・int buildSubscribe(char *buf, char *topic)
・int buildPublish(char *buf, char *topic, char *msg)

接続

wio-lite-rvボードのPA9(TX). PA10(RX)、GNDをUSBシリアルに接続する。
ちなみに、XIAOをUSBシリアルとして使用する場合は以下のように接続する:

wio-lite-rv XIAO
PA10(RX) D6(TX)
PA9(TX) D7(RX)
GND GND

MQTT_pub_test

MQTT送信プログラム:
src/MQTT_pub_test.cpp

#include <Arduino.h> #include <stdio.h> #include <stdarg.h> #include <math.h> #define MY_SSID "your_ssid" #define MY_PASSWD "your_passwd" #define TARGET_IP "test.mosquitto.org" #define OUT_PORT 1883 #define IN_PORT 1883 char ipAddress [20]; #define CLIENT_ID "fedx" // unique string(you can use MAC address) You can change #define MQTT_KEEP_ALIVE 60 #define MQTT_WILL_TOPIC "ESP8266AT-MQTT/" // You can change #define MQTT_WILL_MSG "I am leaving..." // You can change //----- MSTT con/sub/pub func ----- char con[20]; char sub[100]; char pub[100]; int msize, plen, slen; int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg) { int rlen = 12; int pos = 14; int client_id_len = strlen(client_id); //Serial.println(client_id_len); buf[pos++] = 0x00; buf[pos++] = client_id_len; for(int i=0;i<client_id_len;i++) { buf[pos++] = client_id[i]; } rlen = rlen + 2 + client_id_len; int will_topic_len = strlen(will_topic); // Serial.print("will_topic_len="); // Serial.println(will_topic_len); int will_msg_len = strlen(will_msg); // Serial.print("will_msg_len="); // Serial.println(will_msg_len); if (will_topic_len > 0 && will_msg_len > 0) { buf[pos++] = 0x00; buf[pos++] = will_topic_len; for(int i=0;i<will_topic_len;i++) { buf[pos++] = will_topic[i]; } buf[pos++] = 0x00; buf[pos++] = will_msg_len; for(int i=0;i<will_msg_len;i++) { buf[pos++] = will_msg[i]; } rlen = rlen + 2 + will_topic_len + 2 + will_msg_len; } buf[0] = 0x10; buf[1] = rlen; buf[2] = 0x00; buf[3] = 0x06; buf[4] = 'M'; buf[5] = 'Q'; buf[6] = 'I'; buf[7] = 's'; buf[8] = 'd'; buf[9] = 'p'; buf[10] = 0x03; buf[11] = 0x02; if (will_topic_len > 0 && will_msg_len > 0) buf[11] = 0x06; buf[12] = 0x00; buf[13] = keep_alive; return buf[1] + 2; } int buildSubscribe(char *buf, char *topic) { int tlen = strlen(topic); for(int i=0;i<tlen;i++) { buf[6+i] = topic[i]; } buf[0] = 0x82; buf[1] = tlen + 5; buf[2] = 0x00; buf[3] = 0x01; buf[4] = 0x00; buf[5] = tlen; buf[tlen+6] = 0x00; return buf[1] + 2; } int buildPublish(char *buf, char *topic, char *msg) { int tlen = strlen(topic); for(int i=0;i<tlen;i++) { buf[4+i] = topic[i]; } int mlen = strlen(msg); for(int i=0;i<mlen;i++) { buf[4+tlen+i] = msg[i]; } buf[0] = 0x30; buf[1] = tlen + mlen + 2; buf[2] = 0x00; buf[3] = tlen; return buf[1] + 2; } //------------------------------ static void wio_serial_init(void) { // enable GPIO clock for USART0 rcu_periph_clock_enable(RCU_GPIOA); // enable USART clock rcu_periph_clock_enable(RCU_USART0); /* connect port to USARTx_Tx(PA9) */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); /* connect port to USARTx_Rx(PA10) */ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // enable GPIO clock for USART1 rcu_periph_clock_enable(RCU_GPIOA); // enable USART clock rcu_periph_clock_enable(RCU_USART1); /* connect port to USARTx_Tx(PA2) */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); /* connect port to USARTx_Rx(PA3) */ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3); // USART0 configure usart_deinit(USART0); usart_baudrate_set(USART0, 115200U); usart_word_length_set(USART0, USART_WL_8BIT); usart_stop_bit_set(USART0, USART_STB_1BIT); usart_parity_config(USART0, USART_PM_NONE); usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); usart_enable(USART0); // USART1 configure usart_deinit(USART1); usart_baudrate_set(USART1, 115200U); usart_word_length_set(USART1, USART_WL_8BIT); usart_stop_bit_set(USART1, USART_STB_1BIT); usart_parity_config(USART1, USART_PM_NONE); usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE); usart_receive_config(USART1, USART_RECEIVE_ENABLE); usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); usart_enable(USART1); } int _get0_char(void) { while ( usart_flag_get(USART0, USART_FLAG_RBNE)== RESET){ } return (uint8_t)usart_data_receive(USART0); } int _get1_char(void) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== RESET){ } return (uint8_t)usart_data_receive(USART1); } int _put0_char(int ch) { usart_data_transmit(USART0, (uint8_t) ch ); while ( usart_flag_get(USART0, USART_FLAG_TBE)== RESET){ } return ch; } int _put1_char(int ch) { usart_data_transmit(USART1, (uint8_t) ch ); while ( usart_flag_get(USART1, USART_FLAG_TBE)== RESET){ } return ch; } void usart0_printf(const char *fmt, ...) { char buf[100]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); char *p = buf; while( *p != '\0' ) { _put0_char(*p); p++; } } void usart0_print(const char *s) { while( *s != '\0' ) { _put0_char(*s); s++; } } void usart0_println(const char *s) { while( *s != '\0' ) { _put0_char(*s); s++; } _put0_char('\r'); _put0_char('\n'); } void usart1_printf(const char *fmt, ...) { char buf[100]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); char *p = buf; while( *p != '\0' ) { _put1_char(*p); p++; } } void usart1_print(const char *s) { while( *s != '\0' ) { _put1_char(*s); s++; } } void usart1_println(const char *s) { while( *s != '\0' ) { _put1_char(*s); s++; } _put1_char('\r'); _put1_char('\n'); } int usart1_available(void) { return ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET); } //------------------------------------------------------- char res[500]; void get_res(void) { int cpos = 0; for(int cc=0; cc<24000000; cc++) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) { //res[cpos] = (char) _get1_char(); cpos++; res[cpos] = (char) usart_data_receive(USART1); cpos++; }; }; res[cpos] = 0; } void get_res2(void) { int cpos = 0; for(int cc=0; cc<500000; cc++) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) { //res[cpos] = (char) _get1_char(); cpos++; res[cpos] = (char) usart_data_receive(USART1); cpos++; }; }; res[cpos] = 0; } //--------------------------------- void setup() { wio_serial_init(); //Serial.begin(115200); //serial port of GD32 //Serial1.begin(115200); //serial port of ESP8266 pinMode(LED_BUILTIN, OUTPUT); delay(3000); usart0_print("\r\n\r\n\r\n\r\n\r\n"); // rest ESP8266 usart0_println("SEND:"); usart0_print("AT+RST\r\n"); usart1_print("AT+RST\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // get firmware version usart0_println("SEND:"); usart0_print("AT+GMR\r\n"); usart1_print("AT+GMR\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CWQAP\r\n"); usart1_print("AT+CWQAP\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CWMODE=1\r\n"); usart1_print("AT+CWMODE=1\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); //Serial1.println("AT+CWJAP=\"Your WiFi SSID\",\"Password\""); // add your own wifi usart0_println("SEND:"); usart0_print("AT+CWJAP=\""); usart0_print(MY_SSID); usart0_print("\",\""); usart0_print(MY_PASSWD); usart0_print("\"\r\n"); usart1_print("AT+CWJAP=\""); usart1_print(MY_SSID); usart1_print("\",\""); usart1_print(MY_PASSWD); usart1_print("\"\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CIFSR\r\n"); usart1_print("AT+CIFSR\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); //-- get IP Address -- int len = strlen( res ); bool done=false; bool error = false; int pos = 0; while (!done) { if ( res[pos] == '\"') { done = true;} pos++; if (pos > len) { done = true; error = true;} } if (!error) { int buffpos = 0; done = false; while (!done) { if ( res[pos] == '\"' ) { done = true; } else { ipAddress[buffpos] = res[pos]; buffpos++; pos++;} } ipAddress[buffpos] = 0; } else { strcpy(ipAddress,"ERROR"); } //usart0_printf("ipAddress:%s\r\n",ipAddress); //----------------- usart0_println("SEND:"); usart0_print("AT+CIPMUX=1\r\n"); usart1_print("AT+CIPMUX=1\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CIPSERVER=1,80\r\n"); ; usart1_print("AT+CIPSERVER=1,80\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_printf("\r\nipAddress: %s\r\n\r\n",ipAddress); //------------------------------------------ // TCP access usart0_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT); usart1_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // build connect info msize = buildConnect(con,MQTT_KEEP_ALIVE,CLIENT_ID,MQTT_WILL_TOPIC,MQTT_WILL_MSG); // send connect info usart0_printf("AT+CIPSEND=1,%d\r\n",msize); usart1_printf("AT+CIPSEND=1,%d\r\n",msize); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // send connect info for (int i=0;i<msize;i++) _put1_char(con[i]); for (int i=0;i<msize;i++) _put0_char(con[i]); _put0_char('\r'); _put0_char('\n'); get_res(); } //------------ void dispatch(void) { // setup string pointer table char *h[20]; for(int i=0; i<20; i++) h[i]=NULL; h[0] = &res[0]; int pi = 1; int cp; int len = (int)strlen(res); // keep length of res[] for (int i=0; i<len; i++) { //if ((res[i]=='I') && (res[i+1]=='P') && (res[i+2]=='D') ) { // check IPD if ((res[i]=='+') && (res[i+1]=='I') && (res[i+2]=='P') && (res[i+3]=='D') ) { // check +IPD //for (cp = i+3; cp<len; cp++) { for (cp = i+4; cp<len; cp++) { if (res[cp]==':') break; } res[i] = 0; // make string terminator h[pi] = &res[cp+1]; pi++; } }; // display removed IPD header for(int i=0; i<20; i++) { if (h[i] != NULL) usart0_print(h[i]); } } //------------ void loop() { digitalWrite(LED_BUILTIN, HIGH); // debug: for indicate in-loop /** // test loop while(true) { if ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) _put0_char(_get1_char()); if ( usart_flag_get(USART0, USART_FLAG_RBNE)== SET) _put1_char(_get0_char()); }; **/ while(true) { get_res2(); if ((int)strlen(res) != 0) { //usart0_print("\r\nRES:\r\n"); //usart0_println(res); dispatch(); } else { //usart0_print("."); // indicating input wait // publishing // message#0 plen = buildPublish(pub, "topic0", "msg-hello00"); usart0_printf("AT+CIPSEND=1,%d\r\n",plen); usart1_printf("AT+CIPSEND=1,%d\r\n",plen); get_res(); // send pub info for (int i=0;i<plen;i++) _put1_char(pub[i]); get_res(); usart0_println("pub-res:"); usart0_println(res); usart0_println("-----------"); // message#1 plen = buildPublish(pub, "topic0", "msg-hello01"); usart0_printf("AT+CIPSEND=1,%d\r\n",plen); usart1_printf("AT+CIPSEND=1,%d\r\n",plen); get_res(); // send pub info for (int i=0;i<plen;i++) _put1_char(pub[i]); get_res(); usart0_println("pub-res:"); usart0_println(res); usart0_println("-----------"); // message#2 plen = buildPublish(pub, "topic0", "msg-hello02"); usart0_printf("AT+CIPSEND=1,%d\r\n",plen); usart1_printf("AT+CIPSEND=1,%d\r\n",plen); get_res(); // send pub info for (int i=0;i<plen;i++) _put1_char(pub[i]); get_res(); usart0_println("pub-res:"); usart0_println(res); usart0_println("-----------"); } } }

以下については、自分の環境に合わせて変更すること:

#define MY_SSID "your_ssid" #define MY_PASSWD "your_passwd"

以下は利用するMQTTサーバー(broker)に合わせる:

#define TARGET_IP "test.mosquitto.org" #define OUT_PORT 1883 #define IN_PORT 1883

書き込み後に「picocom /dev/ttyACM0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyACM0 -b115200 SEND: AT+RST RES: AT+RST OK I (2989) wifi: state: 5 -> 0 (0) WIFI DISCONNECT sl ----------- SEND: AT+GMR RES: AT+GMR AT version:2.1.0.0-dev(d25f6d2 - Oct 15 2019 12:03:04) SDK version:v3.2-192-g81655f39 compile time(525fbfe):Oct 17 2019 05:39:13 Bin version:2.0.0(WROOM-02) OK ... <省略> ... ----------- ipAddress: 192.168.0.18 AT+CIPSTART=1,"TCP","test.mosquitto.org",1883 RES: AT+CIPSTART=1,"TCP","test.mosquitto.org",1883 1,CONNECT OK ... <省略>

対向する送受信プログラム

以下をブラウザ(chromeのみ)で動かす:

MQTT_AT_webTest.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test'+'<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt') var client = mqtt.connect('ws://test.mosquitto.org:8081') // subscribe Topic client.subscribe('topic0'); //client.subscribe('topic0/sample/hello'); //client.subscribe('topic0/sample/#'); // wildcard topic //client.subscribe('topic0/#'); //client.subscribe('#'); client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages client.publish('topic0', 'hello world of MQTT! #1'); client.publish('topic0', 'hello world of MQTT! #2'); client.publish('topic0', 'hello world of MQTT! #3'); client.publish('topic0', 'hello world of MQTT! #4'); client.publish('topic0', 'hello world of MQTT! #5'); </script> </body> </html>

上をプラウザーで起動した後、 wio-liteの送信プログラムを動作させる。

以下のweb画面が表示される(例):

MQTT over WebSockets Test topic0: Bienvenue sur mosquitto.org topic0: hello world of MQTT! #1   # webアプリで送信(publish)したものを受信している topic0: hello world of MQTT! #2   # webアプリで送信(publish)したものを受信している topic0: hello world of MQTT! #3   # webアプリで送信(publish)したものを受信している topic0: hello world of MQTT! #4   # webアプリで送信(publish)したものを受信している topic0: hello world of MQTT! #5   # webアプリで送信(publish)したものを受信している topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している ...

MQTT_sub_test

MQTT受信プログラム:
src/MQTT_sub_test.cpp

#include <Arduino.h> #include <stdio.h> #include <stdarg.h> #include <math.h> #define MY_SSID "your_ssid" #define MY_PASSWD "your_passswd" #define TARGET_IP "test.mosquitto.org" #define OUT_PORT 1883 #define IN_PORT 1883 char ipAddress [20]; #define CLIENT_ID "fedx" // unique string(you can use MAC address) You can change #define MQTT_KEEP_ALIVE 3600 // 60 #define MQTT_WILL_TOPIC "ESP8266AT-MQTT/" // You can change #define MQTT_WILL_MSG "I am leaving..." // You can change //----- MSTT con/sub/pub func ----- char con[20]; char sub[100]; char pub[100]; int msize, plen, slen; int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg) { int rlen = 12; int pos = 14; int client_id_len = strlen(client_id); //Serial.println(client_id_len); buf[pos++] = 0x00; buf[pos++] = client_id_len; for(int i=0;i<client_id_len;i++) { buf[pos++] = client_id[i]; } rlen = rlen + 2 + client_id_len; int will_topic_len = strlen(will_topic); // Serial.print("will_topic_len="); // Serial.println(will_topic_len); int will_msg_len = strlen(will_msg); // Serial.print("will_msg_len="); // Serial.println(will_msg_len); if (will_topic_len > 0 && will_msg_len > 0) { buf[pos++] = 0x00; buf[pos++] = will_topic_len; for(int i=0;i<will_topic_len;i++) { buf[pos++] = will_topic[i]; } buf[pos++] = 0x00; buf[pos++] = will_msg_len; for(int i=0;i<will_msg_len;i++) { buf[pos++] = will_msg[i]; } rlen = rlen + 2 + will_topic_len + 2 + will_msg_len; } buf[0] = 0x10; buf[1] = rlen; buf[2] = 0x00; buf[3] = 0x06; buf[4] = 'M'; buf[5] = 'Q'; buf[6] = 'I'; buf[7] = 's'; buf[8] = 'd'; buf[9] = 'p'; buf[10] = 0x03; buf[11] = 0x02; if (will_topic_len > 0 && will_msg_len > 0) buf[11] = 0x06; /* buf[12] = 0x00; buf[13] = keep_alive; */ buf[12] = 0xff & (keep_alive >> 8); buf[13] = 0xff & keep_alive; return buf[1] + 2; } int buildSubscribe(char *buf, char *topic) { int tlen = strlen(topic); for(int i=0;i<tlen;i++) { buf[6+i] = topic[i]; } buf[0] = 0x82; buf[1] = tlen + 5; buf[2] = 0x00; buf[3] = 0x01; buf[4] = 0x00; buf[5] = tlen; buf[tlen+6] = 0x00; return buf[1] + 2; } int buildPublish(char *buf, char *topic, char *msg) { int tlen = strlen(topic); for(int i=0;i<tlen;i++) { buf[4+i] = topic[i]; } int mlen = strlen(msg); for(int i=0;i<mlen;i++) { buf[4+tlen+i] = msg[i]; } buf[0] = 0x30; buf[1] = tlen + mlen + 2; buf[2] = 0x00; buf[3] = tlen; return buf[1] + 2; } //------------------------------ static void wio_serial_init(void) { // enable GPIO clock for USART0 rcu_periph_clock_enable(RCU_GPIOA); // enable USART clock rcu_periph_clock_enable(RCU_USART0); /* connect port to USARTx_Tx(PA9) */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); /* connect port to USARTx_Rx(PA10) */ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // enable GPIO clock for USART1 rcu_periph_clock_enable(RCU_GPIOA); // enable USART clock rcu_periph_clock_enable(RCU_USART1); /* connect port to USARTx_Tx(PA2) */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); /* connect port to USARTx_Rx(PA3) */ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3); // USART0 configure usart_deinit(USART0); usart_baudrate_set(USART0, 115200U); usart_word_length_set(USART0, USART_WL_8BIT); usart_stop_bit_set(USART0, USART_STB_1BIT); usart_parity_config(USART0, USART_PM_NONE); usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); usart_enable(USART0); // USART1 configure usart_deinit(USART1); usart_baudrate_set(USART1, 115200U); usart_word_length_set(USART1, USART_WL_8BIT); usart_stop_bit_set(USART1, USART_STB_1BIT); usart_parity_config(USART1, USART_PM_NONE); usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE); usart_receive_config(USART1, USART_RECEIVE_ENABLE); usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); usart_enable(USART1); } int _get0_char(void) { while ( usart_flag_get(USART0, USART_FLAG_RBNE)== RESET){ } return (uint8_t)usart_data_receive(USART0); } int _get1_char(void) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== RESET){ } return (uint8_t)usart_data_receive(USART1); } int _put0_char(int ch) { usart_data_transmit(USART0, (uint8_t) ch ); while ( usart_flag_get(USART0, USART_FLAG_TBE)== RESET){ } return ch; } int _put1_char(int ch) { usart_data_transmit(USART1, (uint8_t) ch ); while ( usart_flag_get(USART1, USART_FLAG_TBE)== RESET){ } return ch; } void usart0_printf(const char *fmt, ...) { char buf[100]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); char *p = buf; while( *p != '\0' ) { _put0_char(*p); p++; } } void usart0_print(const char *s) { while( *s != '\0' ) { _put0_char(*s); s++; } } void usart0_println(const char *s) { while( *s != '\0' ) { _put0_char(*s); s++; } _put0_char('\r'); _put0_char('\n'); } void usart1_printf(const char *fmt, ...) { char buf[100]; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); char *p = buf; while( *p != '\0' ) { _put1_char(*p); p++; } } void usart1_print(const char *s) { while( *s != '\0' ) { _put1_char(*s); s++; } } void usart1_println(const char *s) { while( *s != '\0' ) { _put1_char(*s); s++; } _put1_char('\r'); _put1_char('\n'); } int usart1_available(void) { return ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET); } //------------------------------------------------------- char res[500]; int reslen; // received char number for res[] void get_res(void) { int cpos = 0; for(int cc=0; cc<24000000; cc++) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) { //res[cpos] = (char) _get1_char(); cpos++; res[cpos] = (char) usart_data_receive(USART1); cpos++; }; }; res[cpos] = 0; reslen = cpos; // save # of received chars } void get_res2(void) { int cpos = 0; for(int cc=0; cc<500000; cc++) { while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) { //res[cpos] = (char) _get1_char(); cpos++; res[cpos] = (char) usart_data_receive(USART1); cpos++; }; }; res[cpos] = 0; reslen = cpos; // save # of received chars } //--------------------------------- void setup() { wio_serial_init(); //Serial.begin(115200); //serial port of GD32 //Serial1.begin(115200); //serial port of ESP8266 pinMode(LED_BUILTIN, OUTPUT); delay(3000); usart0_print("\r\n\r\n\r\n\r\n\r\n"); // rest ESP8266 usart0_println("SEND:"); usart0_print("AT+RST\r\n"); usart1_print("AT+RST\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // get firmware version usart0_println("SEND:"); usart0_print("AT+GMR\r\n"); usart1_print("AT+GMR\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CWQAP\r\n"); usart1_print("AT+CWQAP\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CWMODE=1\r\n"); usart1_print("AT+CWMODE=1\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); //Serial1.println("AT+CWJAP=\"Your WiFi SSID\",\"Password\""); // add your own wifi usart0_println("SEND:"); usart0_print("AT+CWJAP=\""); usart0_print(MY_SSID); usart0_print("\",\""); usart0_print(MY_PASSWD); usart0_print("\"\r\n"); usart1_print("AT+CWJAP=\""); usart1_print(MY_SSID); usart1_print("\",\""); usart1_print(MY_PASSWD); usart1_print("\"\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CIFSR\r\n"); usart1_print("AT+CIFSR\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); //-- get IP Address -- int len = strlen( res ); bool done=false; bool error = false; int pos = 0; while (!done) { if ( res[pos] == '\"') { done = true;} pos++; if (pos > len) { done = true; error = true;} } if (!error) { int buffpos = 0; done = false; while (!done) { if ( res[pos] == '\"' ) { done = true; } else { ipAddress[buffpos] = res[pos]; buffpos++; pos++;} } ipAddress[buffpos] = 0; } else { strcpy(ipAddress,"ERROR"); } //usart0_printf("ipAddress:%s\r\n",ipAddress); //----------------- usart0_println("SEND:"); usart0_print("AT+CIPMUX=1\r\n"); usart1_print("AT+CIPMUX=1\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_println("SEND:"); usart0_print("AT+CIPSERVER=1,80\r\n"); ; usart1_print("AT+CIPSERVER=1,80\r\n"); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); usart0_printf("\r\nipAddress: %s\r\n\r\n",ipAddress); //------------------------------------------ // TCP access usart0_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT); usart1_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // build connect info msize = buildConnect(con,MQTT_KEEP_ALIVE,CLIENT_ID,MQTT_WILL_TOPIC,MQTT_WILL_MSG); // send connect info usart0_printf("AT+CIPSEND=1,%d\r\n",msize); usart1_printf("AT+CIPSEND=1,%d\r\n",msize); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // send connect info for (int i=0;i<msize;i++) _put1_char(con[i]); for (int i=0;i<msize;i++) _put0_char(con[i]); _put0_char('\r'); _put0_char('\n'); get_res(); // send sub info slen = buildSubscribe(sub, "topic0"); usart0_printf("AT+CIPSEND=1,%d\r\n",slen); usart1_printf("AT+CIPSEND=1,%d\r\n",slen); get_res(); usart0_println("RES:"); usart0_println(res); usart0_println("-----------"); // send connect info for (int i=0;i<slen;i++) _put1_char(sub[i]); get_res(); } //------------ void dispatch(void) { char ph0,ph1,ph2,ph3; char rtopic[20],rmsg[50]; int pd, ps; // payload dest/src index int cp; //int len = (int)strlen(res); // keep length of res[] int len = reslen; // get # of received chars for (int i=0; i<len; i++) { if ((res[i]=='+') && (res[i+1]=='I') && (res[i+2]=='P') && (res[i+3]=='D') ) { // check +IPD for (cp = i+4; cp<len; cp++) { if (res[cp]==':') break; } ph0 = res[cp+1]; // ph0 (Payload Header 0) ph1 = res[cp+2]; // topic_length + msg_length +2 ph2 = res[cp+3]; ph3 = res[cp+4]; // topic_length //usart0_printf("ph0:0x%x ph2:0x%x\r\n",(int)ph0,(int)ph2); // for debug //usart0_printf("ph1:%d ph3:%d\r\n",(int)ph1,(int)ph3); // for debug ps = cp+5; for(pd=0; pd<ph3; pd++) {rtopic[pd]=res[ps]; ps++; }; rtopic[pd] = 0; for(pd=0; pd<(ph1-ph3-2); pd++) {rmsg[pd]=res[ps]; ps++; }; rmsg[pd] = 0; // display received topic,message usart0_printf("received %s: %s\r\n",rtopic,rmsg); } }; } //------------ void loop() { digitalWrite(LED_BUILTIN, HIGH); // debug: for indicate in-loop /** // test loop while(true) { if ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) _put0_char(_get1_char()); if ( usart_flag_get(USART0, USART_FLAG_RBNE)== SET) _put1_char(_get0_char()); }; **/ while(true) { get_res2(); //if ((int)strlen(res) != 0) { if (reslen != 0) { //usart0_print("\r\nRES:\r\n"); //usart0_println(res); dispatch(); } else { //usart0_print("."); // indicating input wait } } }

「MQTT_AT_webTest.html」をプラウザで起動した後、 wio-liteの受信プログラムを動作させる。

書き込み後に「picocom /dev/ttyACM0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:

$ picocom /dev/ttyACM0 -b115200 SEND: AT+RST RES: AT+RST OK I (2989) wifi: state: 5 -> 0 (0) WIFI DISCONNECT sl ----------- SEND: AT+GMR RES: AT+GMR AT version:2.1.0.0-dev(d25f6d2 - Oct 15 2019 12:03:04) SDK version:v3.2-192-g81655f39 compile time(525fbfe):Oct 17 2019 05:39:13 Bin version:2.0.0(WROOM-02) OK ... <省略> OK #以下、ブラウザーをリフレッシュ(リロード)するたびにpublishされ #受信したものが以下のように表示される: > ----------- received topic0: hello world of MQTT! #1 received topic0: hello world of MQTT! #2 received topic0: hello world of MQTT! #3 received topic0: hello world of MQTT! #4 received topic0: hello world of MQTT! #5 received topic0: hello world of MQTT! #1 received topic0: hello world of MQTT! #2 received topic0: hello world of MQTT! #3 received topic0: hello world of MQTT! #4 received topic0: hello world of MQTT! #5 received topic0: hello world of MQTT! #1 received topic0: hello world of MQTT! #2 received topic0: hello world of MQTT! #3 received topic0: hello world of MQTT! #4 received topic0: hello world of MQTT! #5 received topic0: hello world of MQTT! #1 received topic0: hello world of MQTT! #2 received topic0: hello world of MQTT! #3 received topic0: hello world of MQTT! #4 received topic0: hello world of MQTT! #5 received topic0: hello world of MQTT! #1 received topic0: hello world of MQTT! #2 received topic0: hello world of MQTT! #3 received topic0: hello world of MQTT! #4 received topic0: hello world of MQTT! #5 ... ...

参考情報

MQTT test server @mosquitto.org

https://test.mosquitto.org/ The server listens on the following ports: 1883 : MQTT, unencrypted 8883 : MQTT, encrypted 8884 : MQTT, encrypted, client certificate required 8080 : MQTT over WebSockets, unencrypted 8081 : MQTT over WebSockets, encrypted websocketで使用するurlは以下になる: 'ws://test.mosquitto.org:8081'

MQTT test server @eclipse.org

http://mqtt.eclipse.org/ This is a public test MQTT broker service. It currently listens on the following ports: 1883 : MQTT over unencrypted TCP 8883 : MQTT over encrypted TCP 80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt ) 443 : MQTT over encrypted WebSockets (note: URL must be /mqtt ) websocketで使用するurlは以下になる: 'ws://mqtt.eclipse.org/mqtt:443'

10 Free Public & Private MQTT Brokers(For Testing & Production)

Wio Lite RISC-V(GD32VF103)

Wio Lite RISC V GD32VF103 with ESP8266
Blink with a Wio Lite RISC-V with ESP8266

PlatformIO Core (CLI)

ESP8266をTCPサーバとTCPクライアントにするATコマンド実例 (1/4)
esp8266_at_command_examples_en.pdf

ESP8266をWifiモデムとして使う - ATコマンドによるMQTT通信
MQTT_via_ESP01
Arduino WiFi library for ESP8266 modules

espressif/ESP8266_AT - examples
Espressif Documentation

以上

続きを読む "Wio_Lite_RISC-VボードでWiFiを動かす(その4:MQTT)"

| | コメント (0)

2020年6月 7日 (日)

Adafruit-IOのMQTT(REST-APIも含む)を利用してみる

2020/6/7

Adafruit IO MQTT REST-API

Adafruit IO MQTT REST-API

概要

AdafruitのクラウドサービスであるAdafruit-IOのMQTT(REST-APIも含む)を利用してみる。 (ホストPCとしてはubuntuを想定している)

準備

adafruitのアカウントを用意する必要があるので 以下にアクセスしてアカウントを作る。(無償)

https://accounts.adafruit.com

アカウントを作成したら、Adafruit-IOにアクセスするための アクセスキー(Adafruit IO KEY)を取得する必要があるので 以下にアクセスする:

https://io.adafruit.com/USERNAME/dashboards
(USERNAMEは作ったアカウントのユーザー名になる)

ブラウザー画面の最上行の右端「Adafruit IO KEY」をクリックすると アクセスキーが表示される。

以下、このアクセスキー(IO_KEY)とアカウントのユーザー名(IO_USERNAME)を プログラムに設定して使用する。

以下にアクセスライブラリ(Arduino,Python,CircuitPython,MicroPython,Ruby)が載っているが

https://io.adafruit.com/api/docs/mqtt.html#client-libraries

このうちPython3を使用してみる。

ライブラリのインストール:

python3 -m venv aio_env source aio_env/bin/activate pip3 install adafruit-io

mqtt_time.py

MQTTを利用する形で時刻を提供しているので、それを利用するデモプログラム。

get https://raw.githubusercontent.com/adafruit/Adafruit_IO_Python/master/examples/mqtt/mqtt_time.py # 取得したソースのIO_USERNAME,IO_KEYの部分を取得したものに置き換える。

出力例:

$ python3 mqtt_time.py * Subscribing to time/seconds * Subscribing to time/millis * Subscribing to time/ISO-8601 Connected to Adafruit IO! Feed time received new value: 2020-06-05T03:19:29.402Z Feed time received new value: 1591327169402 Feed time received new value: 1591327169 Feed time received new value: 2020-06-05T03:19:30.403Z Feed time received new value: 1591327170403 Feed time received new value: 1591327170 Feed time received new value: 2020-06-05T03:19:31.404Z Feed time received new value: 1591327171404 Feed time received new value: 1591327171 Feed time received new value: 2020-06-05T03:19:32.405Z Feed time received new value: 1591327172405 Feed time received new value: 1591327172

mqtt_client_class.py

トピックDemoFeedにsubscribe/publishするプログラム。

wget https://raw.githubusercontent.com/adafruit/Adafruit_IO_Python/master/examples/mqtt/mqtt_client_class.py # 取得したソースのIO_USERNAME,IO_KEYの部分を取得したものに置き換える。

出力例:

$ python3 mqtt_client_class.py Publishing a new message every 10 seconds (press Ctrl-C to quit)... Connected to Adafruit IO! Connected to Adafruit IO! Listening for DemoFeed changes... Publishing 6 to DemoFeed. #送信 Feed DemoFeed received new value: 6 #受信 Publishing 60 to DemoFeed. #送信 Feed DemoFeed received new value: 60 #受信 Publishing 63 to DemoFeed. #送信 Feed DemoFeed received new value: 63 #受信

mqtt_subscribe.py

MQTTの受信プログラム。

wget https://raw.githubusercontent.com/adafruit/Adafruit_IO_Python/master/examples/mqtt/mqtt_subscribe.py # 取得したソースのIO_USERNAME,IO_KEYの部分を取得したものに置き換える。

出力例:

$ python3 mqtt_subscribe.py Connected to Adafruit IO! Connected to Adafruit IO! Listening for DemoFeed changes... Subscribed to DemoFeed with QoS 0 Feed DemoFeed received new value: 5 Feed DemoFeed received new value: 97 Feed DemoFeed received new value: 18 Feed DemoFeed received new value: 44 Feed DemoFeed received new value: 87 Feed DemoFeed received new value: 60 Feed DemoFeed received new value: 1

別の端末から送信プログラムを動かしている必要がある。 (mqtt_client_class.pyでも良い)

REST-APIによるアクセス(curl)

https://io.adafruit.com/api/docs/#get-feed のドキュメントより REST-APIとしては以下であることが分かる:

GET /api/v2/{username}/feeds/{feed_key}

curlを使用して実際に利用するには以下のようになる:

curl -X GET 'https://io.adafruit.com/api/v2/USERNAME/feeds/demofeed?X-AIO-Key=aio_xxxxx' #USERNAMEでフィードキーdemofeedにアクセスする具体例になる。(aio_xxxxxは、aioのアクセスキーになる) なお、''で囲まれた部分をURLとしてブラウザーに与えると同様の出力が表示される。

出力例:

{"username":"USERNAME","owner":{"id":44xxxx,"username":"USERNAME"},"id":138xxxx,"name":"DemoFeed","description":null,"license":null, "history":true,"enabled":true,"visibility":"private","unit_type":null,"unit_symbol":null, "last_value":"41","created_at":"2020-06-05T02:15:31Z","updated_at":"2020-06-06T15:16:53Z", "status_notify":false,"status_timeout":4320,"status":"online","key":"demofeed","writable":true, "group":{"id":36xxxx,"key":"default","name":"Default","user_id":44xxxx},"groups":[{"id":36xxxx,"key":"default","name":"Default","user_id":44xxxx}],"feed_webhook_receivers":[],"feed_status_changes":[]} 一部伏せ文字にしてある

上の情報から フィードキーは、DemoFeedで "updated_at":"2020-06-06T15:16:53Z"時点での 値が"last_value":"41"であることが分かる。

REST-APIによるアクセス(html+javascript)

fetch_aio.html

<!DOCTYPE html> <head> <meta charset="utf-8"> <title>Fetch Adafruit IO</title> </head> <body > <div id="text0">Fetch Adafruit IO</div> <div id="text1"></div> <script> let IO_USERNAME='username' let IO_KEY='aio_xxxxxx' let IO_URL='https://io.adafruit.com' let FEED_KEY='demofeed' let feed; fetch(IO_URL+'/api/v2/'+IO_USERNAME+'/feeds/'+FEED_KEY+'?X-AIO-Key='+IO_KEY).then(function (response) { return response.text(); }).then(function (text) { console.log('RESULT: ' + text); feed=JSON.parse(text); console.log(feed['name']+': '+feed['last_value']+' @'+feed['updated_at']); text1.innerHTML = feed['name']+': '+feed['last_value']+' @'+feed['updated_at']; }); </script> </body> </html>

以下の部分は、自分の環境にあわせて書き換える:

let IO_USERNAME='username' let IO_KEY='aio_xxxxxx'

アクセス時のweb画面(例)

Fetch Adafruit IO DemoFeed: 94 @2020-06-07T02:20:30Z

別端末で送信プログラム(mqtt_client_class.py)を動かしておく。 ブラウザー画面をリフレッシュするたびに、最新の(受信した)値が表示される。 ブラウザーのconsoleにもアクセスした情報が出力される。

参考情報

Client Libraries
Adafruit IO HTTP API

JavaScriptのFetch APIを利用してリクエストを送信する
javascript.info - Fetch
fetch の使い方

以上

続きを読む "Adafruit-IOのMQTT(REST-APIも含む)を利用してみる"

| | コメント (0)

2020年3月 6日 (金)

ESP32/ESP8266のMicroPythonのDHTセンサーデータをホストPCのpythonでMQTT受信する

2020/3/6

ESP32/ESP8266 MicroPython DHT Python MQTT test

ESP32/ESP8266 MicroPython DHT Python MQTT test

概要

ESP32/ESP8266のMicroPythonのDHTセンサーデータをホストPCのpythonでMQTT受信する。MicroPython側が送信側、ホストPCのpythonが受信側になる。

接続

Grove-DHT11センサーをGrove-Base-Shield経由でGrove-D5-Slotに接続すると 以下のように接続したことになる。

Grove D5 solot

Arduino-Pin ESP8266
D5 IO04
D6 IO05(NOT USED)
VCC 3.3V
GND GND

受信側Pythonスクリプト

PY_MQTT_DHT_recv.py

#!usr/bin/env python # -*- coding: utf-8 -*- # receving DHT11 sensor data from ESP_MicroPython via MQTT import paho.mqtt.client as mqtt import json def on_connect(client, userdata, flags, respons_code): topic = 'DHT11' print('watch %s' % topic) client.subscribe(topic) def on_message(client, userdata, msg): #print(msg.topic + ' ' + str(msg.payload)) print(msg.topic+':') parsed = json.loads(str(msg.payload)) print('time: '+parsed['time']) print('Temperature: '+str(parsed['Temperature'])) print('Humidity: '+str(parsed['humidity'])) print('---------------------------') client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message #client.connect('5.196.95.208', 1883, keepalive=60) client.connect('test.mosquitto.org', 1883, keepalive=60) client.loop_forever()

該当ライブラリーは以下でインストールする:

pip install paho-mqtt

送信側micropythonスクリプト

MQTT_DHT_send.py
以下は自分の環境に合わせる:
ssid = 'your_ssid'
password = 'your_passwd'

# boot.py ssid = 'your_ssid' password = 'your_passwd' mqtt_server = '5.196.95.208' # Complete project details at https://RandomNerdTutorials.com import time from umqttsimple import MQTTClient import ubinascii import machine import micropython import network import esp esp.osdebug(None) import gc gc.collect() client_id = ubinascii.hexlify(machine.unique_id()) last_message = 0 #message_interval = 5 counter = 0 station = network.WLAN(network.STA_IF) station.active(True) station.connect(ssid, password) while station.isconnected() == False: pass print('Connection successful') print(station.ifconfig()) #=========================================== from machine import RTC import utime import ntptime rtc = RTC() ntptime.settime() # setup time by remote NTP server def get_jst(): tm = utime.localtime(utime.time()) # UTC now jst = str(tm[0])+'/'+str(tm[1])+'/'+str(tm[2])+' '+str((tm[3]+9)%24)+':'+str(tm[4])+':'+str(tm[5]) return jst #=========================================== import ujson import dht from machine import Pin d = dht.DHT11(Pin(4)) message_interval = 1 # sec def connect_and_subscribe(): global client_id, mqtt_server, topic_sub client = MQTTClient(client_id, mqtt_server) # client.set_callback(sub_cb) client.connect() # client.subscribe(topic_sub) # print('Connected to %s MQTT broker, subscribed to %s topic' % (mqtt_server, topic_sub)) print('Connected to MQTT broker:'+mqtt_server) return client def restart_and_reconnect(): print('Failed to connect to MQTT broker. Reconnecting...') time.sleep(10) machine.reset() try: client = connect_and_subscribe() except OSError as e: restart_and_reconnect() while True: try: # client.check_msg() if (time.time() - last_message) > message_interval: dict = {} dict['time'] = get_jst() dict['sensorType'] = 'DHT11' d.measure() dict['Temperature'] = d.temperature() dict['humidity'] = d.humidity() msg = ujson.dumps(dict) topic = 'DHT11' print(topic+':'+msg) # debug client.publish(topic, msg) last_message = time.time() counter += 1 except OSError as e: restart_and_reconnect()

実行画面

ESP32/SP8266のMicroPython側は MQTT_DHT_send.py を実行し、
受信側は 「python PY_MQTT_DHT_recv.py」を実行すると
以下のような実行画面になる:

ホストPCのシェル画面:

$ python PY_MQTT_DHT_recv.py watch DHT11 DHT11: time: 2020/3/6 21:56:0 Temperature: 18 Humidity: 13 --------------------------- DHT11: time: 2020/3/6 21:56:2 Temperature: 18 Humidity: 13 --------------------------- ...

おまけ(pythonの受信/送信サンプル)

送信サンプル:
PY_publisher.py

#!usr/bin/env python # -*- coding: utf-8 -*- import paho.mqtt.client as mqtt client = mqtt.Client() #client.connect('5.196.95.208', 1883, keepalive=60) client.connect('test.mosquitto.org', 1883, keepalive=60) for n in range(24): client.publish('test/topic', 'hello world #'+str(n))

受信側サンプル:
PY_subsriber.py

#!usr/bin/env python # -*- coding: utf-8 -*- import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, respons_code): topic = 'test/topic' print('watch %s' % topic) client.subscribe(topic) def on_message(client, userdata, msg): print(msg.topic + ' ' + str(msg.payload)) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message #client.connect('5.196.95.208', 1883, keepalive=60) client.connect('test.mosquitto.org', 1883, keepalive=60) client.loop_forever()

参考情報

paho-mqtt 1.5.0

MQTT.js

MQTT test server @mosquitto.org
The server listens on the following ports:
1883 : MQTT, unencrypted
8883 : MQTT, encrypted
8884 : MQTT, encrypted, client certificate required
8080 : MQTT over WebSockets, unencrypted
8081 : MQTT over WebSockets, encrypted

MQTT test server @eclipse.org
This is a public test MQTT broker service.
It currently listens on the following ports:
1883 : MQTT over unencrypted TCP
8883 : MQTT over encrypted TCP
80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt )
443 : MQTT over encrypted WebSockets (note: URL must be /mqtt )

10 Free Public & Private MQTT Brokers(For Testing & Production)
http://www.mqtt-dashboard.com/
MQTT is a machine-to-machine (M2M)/"Internet of Things"

ESP32/ESP8266のMicroPythonでMQTTを使ってみた
MQTT(over WebSocket)をブラウザーで使ってみた

MicroPython – Getting Started with MQTT on ESP32/ESP8266

ESP32-DevKitC ESP-WROOM-32開発ボード
MicroPython - Quick reference for the ESP32
Streaming Data from ESP32 using MicroPython and MQTT
ampyを用いたMicroPythonのファイル操作とプログラム実行

以上

続きを読む "ESP32/ESP8266のMicroPythonのDHTセンサーデータをホストPCのpythonでMQTT受信する"

| | コメント (0)

ESP32/ESP8266のMicroPythonでDHTセンサーデータをMQTTで送信する

2020/3/5

ESP32/ESP8266 MicroPython DHT Web MQTT test

ESP32/ESP8266 MicroPython DHT Web MQTT test

概要

ESP32/ESP8266のMicroPythonでDHTセンサーデータをMQTTで送信する。
受信側はweb-browserを利用する。

接続

Grove-DHT11センサーをGrove-Base-Shield経由でGrove-D5-Slotに接続すると 以下のように接続したことになる。

Grove D5 solot

Arduino-Pin ESP8266
D5 IO04
D6 IO05(NOT USED)
VCC 3.3V
GND GND

受信側のhtmlスクリプト

MQTT_DHT_recv.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test(DHT11 recv)'+'<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt') var client = mqtt.connect('ws://test.mosquitto.org:8081') // subscribe Topic client.subscribe('DHT11'); client.on('message', function(topic, payload) { var sensor = JSON.parse(payload) // JSON parsing test console.log(sensor) consout += topic+':'+'<br>'+JSON.stringify(sensor)+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); </script> </body> </html>

送信側のmicropythonスクリプト

MQTT_DHT_send.py
以下は自分の環境に合わせる:
ssid = 'your_ssid'
password = 'your_passwd'

# boot.py ssid = 'your_ssid' password = 'your_passwd' mqtt_server = '5.196.95.208' # Complete project details at https://RandomNerdTutorials.com import time from umqttsimple import MQTTClient import ubinascii import machine import micropython import network import esp esp.osdebug(None) import gc gc.collect() client_id = ubinascii.hexlify(machine.unique_id()) last_message = 0 #message_interval = 5 counter = 0 station = network.WLAN(network.STA_IF) station.active(True) station.connect(ssid, password) while station.isconnected() == False: pass print('Connection successful') print(station.ifconfig()) #=========================================== from machine import RTC import utime import ntptime rtc = RTC() ntptime.settime() # setup time by remote NTP server def get_jst(): tm = utime.localtime(utime.time()) # UTC now jst = str(tm[0])+'/'+str(tm[1])+'/'+str(tm[2])+' '+str((tm[3]+9)%24)+':'+str(tm[4])+':'+str(tm[5]) return jst #=========================================== import ujson import dht from machine import Pin d = dht.DHT11(Pin(4)) message_interval = 1 # sec def connect_and_subscribe(): global client_id, mqtt_server, topic_sub client = MQTTClient(client_id, mqtt_server) # client.set_callback(sub_cb) client.connect() # client.subscribe(topic_sub) # print('Connected to %s MQTT broker, subscribed to %s topic' % (mqtt_server, topic_sub)) print('Connected to MQTT broker:'+mqtt_server) return client def restart_and_reconnect(): print('Failed to connect to MQTT broker. Reconnecting...') time.sleep(10) machine.reset() try: client = connect_and_subscribe() except OSError as e: restart_and_reconnect() while True: try: # client.check_msg() if (time.time() - last_message) > message_interval: dict = {} dict['time'] = get_jst() dict['sensorType'] = 'DHT11' d.measure() dict['Temperature'] = d.temperature() dict['humidity'] = d.humidity() msg = ujson.dumps(dict) topic = 'DHT11' print(topic+':'+msg) # debug client.publish(topic, msg) last_message = time.time() counter += 1 except OSError as e: restart_and_reconnect()

実行画面

ESP32/SP8266のMicroPython側は MQTT_DHT_send.py を実行し、
ブラウザー側は MQTT_DHT_recv.html を実行すると
以下のような実行画面になる:

MQTT_DHT_recv.html のブラウザー画面:

MQTT over WebSockets Test(DHT11 recv) DHT11: {"time":"2020/3/5 23:16:46","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:48","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:50","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:52","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:54","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:56","Temperature":15,"humidity":14,"sensorType":"DHT11"} DHT11: {"time":"2020/3/5 23:16:58","Temperature":15,"humidity":14,"sensorType":"DHT11"} ...

センサーデータはJSONフォーマットのものを(テストのために)パースしたものを再度JSONフォーマットにして表示している。

参考情報

MQTT.js

MQTT test server @mosquitto.org
The server listens on the following ports:
1883 : MQTT, unencrypted
8883 : MQTT, encrypted
8884 : MQTT, encrypted, client certificate required
8080 : MQTT over WebSockets, unencrypted
8081 : MQTT over WebSockets, encrypted

MQTT test server @eclipse.org
This is a public test MQTT broker service.
It currently listens on the following ports:
1883 : MQTT over unencrypted TCP
8883 : MQTT over encrypted TCP
80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt )
443 : MQTT over encrypted WebSockets (note: URL must be /mqtt )

10 Free Public & Private MQTT Brokers(For Testing & Production)
http://www.mqtt-dashboard.com/
MQTT is a machine-to-machine (M2M)/"Internet of Things"

ESP32/ESP8266のMicroPythonでMQTTを使ってみた
MQTT(over WebSocket)をブラウザーで使ってみた

MicroPython – Getting Started with MQTT on ESP32/ESP8266

ESP32-DevKitC ESP-WROOM-32開発ボード
MicroPython - Quick reference for the ESP32
Streaming Data from ESP32 using MicroPython and MQTT
ampyを用いたMicroPythonのファイル操作とプログラム実行

以上

続きを読む "ESP32/ESP8266のMicroPythonでDHTセンサーデータをMQTTで送信する"

| | コメント (0)

2020年3月 4日 (水)

ESP32/ESP8266のMicroPythonとWeb-browserの間でMQTT通信をする

2020/3/4

ESP32/ESP8266 MicroPython vs Web MQTT test

ESP32/ESP8266 MicroPython vs Web MQTT test

概要

ESP32/ESP8266のMicroPythonとWeb-browserの間でMQTT通信をする。
ESP32/ESP8266のMicroPython側は以下のリンクのスクリプトをそのまま使用するので、 ここではweb-browser側のhtmlのスクリプトについて記する。

ESP32/ESP8266のMicroPythonでMQTTを使ってみた

htmlスクリプト

web-browser側もスクリプトは以下の2つになる。
それぞれMQTT01_test.py,MQTT02_test.pyと同機能のスクリプトになる。
(browserは、chromeを推奨する)

MQTT_ESP01_webTest.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //ESP#1 var topic_sub = 'notification'; var topic_pub = 'hello'; document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test(ESP01)'+'<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt') var client = mqtt.connect('ws://test.mosquitto.org:8081') // subscribe Topic client.subscribe(topic_sub); //client.subscribe(topic_pub); // for echo back test client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages var counter = 0; var msg = ''; /********************************** // infinite while loop does Not work! (can not go into event listener) while (true) { msg = 'Hello #'+counter; console.log('publishing:: '+topic_pub+':'+msg); client.publish(topic_pub, msg); counter += 1 } *********************************/ function repeatUnit() { msg = 'Hello #'+counter; console.log('publishing:: '+topic_pub+':'+msg); client.publish(topic_pub, msg); counter += 1 } setInterval(repeatUnit, 100); // msec </script> </body> </html>

MQTT_ESP02_webTest.html

<html> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <body> <script> //ESP#2 var topic_sub = 'hello'; var topic_pub = 'notification'; document.body.innerHTML = ''; var consout = 'MQTT over WebSockets Test(ESP02)'+'<br>' document.body.innerHTML = consout; //var mqtt = require('mqtt') var client = mqtt.connect('ws://test.mosquitto.org:8081') // subscribe Topic client.subscribe(topic_sub); //client.subscribe(topic_pub); // for echo back test client.on('message', function(topic, payload) { console.log([topic, payload].join(': ')); consout += [topic, payload].join(': ')+'<br>' document.body.innerHTML = consout // disconnect //client.end(); }); // publish messages /**************************************** // infinite while loop does Not work! (can not go into event listener) while (true) { client.publish(topic_pub, 'received'); } ****************************************/ function repeatUnit() { client.publish(topic_pub, 'received'); } setInterval(repeatUnit, 100); // msec </script> </body> </html>

単純な無限ループ(while (true))でpublishした場合、 イベントリスナーに制御が行かずにメッセージ受信ができなくなるので、 繰り返しは、setintervalを利用する必要がある。

実行画面

ESP32/SP8266のMicroPython側は MQTT02_testを実行し、
ブラウザー側は MQTT_ESP01_webTest.htmlを実行すると
以下のような実行画面になる:

MQTT_ESP01_webTest.htmlのブラウザー画面:

MQTT over WebSockets Test(ESP01) notification: received notification: received notification: received notification: received notification: received notification: received notification: received notification: received notification: received notification: received notification: received notification: received

ESP32/SP8266のMicroPython側は MQTT01_testを実行し、
ブラウザー側は MQTT_ESP02_webTest.htmlを実行すると
以下のような実行画面になる:

MQTT_ESP02_webTest.htmlのブラウザー画面:

MQTT over WebSockets Test(ESP02) hello: Hello #1 hello: Hello #2 hello: Hello #3 hello: Hello #4 hello: Hello #5 hello: Hello #6 hello: Hello #7 hello: Hello #8 hello: Hello #9 hello: Hello #10 hello: Hello #11 hello: Hello #12 hello: Hello #13 hello: Hello #14 hello: Hello #15

参考情報

MQTT.js

MQTT test server @mosquitto.org
The server listens on the following ports:
1883 : MQTT, unencrypted
8883 : MQTT, encrypted
8884 : MQTT, encrypted, client certificate required
8080 : MQTT over WebSockets, unencrypted
8081 : MQTT over WebSockets, encrypted

MQTT test server @eclipse.org
This is a public test MQTT broker service.
It currently listens on the following ports:
1883 : MQTT over unencrypted TCP
8883 : MQTT over encrypted TCP
80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt )
443 : MQTT over encrypted WebSockets (note: URL must be /mqtt )

10 Free Public & Private MQTT Brokers(For Testing & Production)
http://www.mqtt-dashboard.com/
MQTT is a machine-to-machine (M2M)/"Internet of Things"

ESP32/ESP8266のMicroPythonでMQTTを使ってみた
MQTT(over WebSocket)をブラウザーで使ってみた

MicroPython – Getting Started with MQTT on ESP32/ESP8266

ESP32-DevKitC ESP-WROOM-32開発ボード
MicroPython - Quick reference for the ESP32
Streaming Data from ESP32 using MicroPython and MQTT
ampyを用いたMicroPythonのファイル操作とプログラム実行

以上

続きを読む "ESP32/ESP8266のMicroPythonとWeb-browserの間でMQTT通信をする"

| | コメント (0)

より以前の記事一覧