ESP32

2020年12月28日 (月)

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

2020/12/28:
初版

board3 Ascii STARWARS v2

board3 Ascii STARWARS v2

概要

Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(STARWARS編)
本記事は「 Wio-TerminalでWiFiで使う(その2: STARTWARS,WEB_ACCESS) 」 のStarwarsのスケッチを複数ボード対応とwio-terminalのファームウェア・バージョンアップに対応したものである。

wio-terminalのファームウェアのバージョンアップで以下の不具合も解消している。
(描画速度も大幅な改善が見られる)

一部、以下のようなATコマンドのレスポンス・ヘッダーが表示されることがある。 wifi関係のライブラリにバグがあるようだ。 +IPD,4,988,94.142.241.111,23:__|_____|___________|__|____________|_||____ +IPD,4,1460,94.142.241.111,23: +IPD,4,1460,94.142.241.111,23: |(I/ /][][\| {}/ {} \[][][]

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

デモ・スケッチ

src/wifi_starwars.ino

// select board ////#define WIO_TERMINAL ////#define ESP8266 ////#define ESP32 ////#define M5ATOM //------------------ #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 const char* ssid = "your_ssid"; const char* passwd = "yours_passwd"; // Use WiFiClient class to create TCP connections WiFiClient client; void setup() { Serial.begin(115200); while(!Serial); // Wait for Serial to be ready delay(1000); // Set WiFi to station mode and disconnect from an AP if it was previously connected WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(2000); WiFi.begin(ssid, passwd); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Connecting to WiFi.."); } Serial.println("Connected to the WiFi network"); Serial.print("IP Address: "); Serial.println (WiFi.localIP()); // prints out the device's IP address // set url for telnet const char* host = "towel.blinkenlights.nl"; const uint16_t port = 23; Serial.print("Connecting to "); Serial.println(host); while (!client.connect(host, port)) { Serial.println("Connection failed."); Serial.println("Waiting 5 seconds before retrying..."); delay(5000); } } void loop() { while (!client.available()) { delay(1); //delay 1 msec } // no buffering for ASCII Art Animation while (client.available()) { char c = client.read(); Serial.write(c); } /*********** if (client.available() > 0) { String line = client.readString(); // Read from the server response Serial.print(line); } ************/ }

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 passwd[] = "yours_passwd";

書き込み後に「picocom /dev/ttyACM0 -b115200」または「picocom /dev/ttyUSB0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:
(M5Atomの場合、実行時にリセット・ボタンを押す必要があるようだ)

$ picocom /dev/ttyACM0 -b115200 #以下のようなAsciiArtのアニメが実行される: ........... @@@@@ @@@@@ ........... .......... @ @ @ @ .......... ........ @@@ @ @ .......... ....... @@ @ @ ......... ...... @@@@@@@ @@@@@ th ........ ..... ----------------------- ....... .... C E N T U R Y ....... ... ----------------------- ..... .. @@@@@ @@@@@ @ @ @@@@@ ... == @ @ @ @ @ == __||__ @ @@@@ @ @ __||__ | | @ @ @ @ @ | | _________|______|_____ @ @@@@@ @ @ @ _____|______|_________

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

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

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 build_flags = -DESP32 monitor_speed = 115200 lib_ldf_mode = deep+

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+

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

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

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

参考情報

PlatformIO Core (CLI)

以上

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

| | コメント (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)

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

2020/12/27+
初版

board3 REST API v2

board3 REST API v2

概要

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

wio-terminalのファームウェアのバージョンアップで以下の不具合も解消している。

Wio-Terminalの場合、REST-APIは、起動後の1回しか動作しなかった。(原因不明)

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

デモ・スケッチ

src/REST-API_test.ino

// select board ////#define M5ATOM ////#define WIO_TERMINAL ////#define ESP8266 ////#define ESP32 //------------------ // REST-API server for Wio-Terminal/ESP8266/ESP32 /* * Forked from the following code: * * Simple hello world Json REST response * by Mischianti Renzo <https://www.mischianti.org> * * https://www.mischianti.org/ * */ #ifdef M5ATOM #include "M5Atom.h" #define ESP32 #endif #ifdef WIO_TERMINAL //#include <AtWiFi.h> #include <rpcWiFi.h> #include <WebServer.h> #include <WiFiUdp.h> #include <ArduinoMDNS.h> #endif #ifdef ESP8266 #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #endif #ifdef ESP32 #include <WiFi.h> #include <WebServer.h> #include <ESPmDNS.h> #endif const char* ssid = "<your-ssid>"; const char* password = "<your-passwd>"; #ifdef WIO_TERMINAL WiFiUDP udp; MDNS mdns(udp); WebServer server(80); #endif #ifdef ESP8266 ESP8266WebServer server(80); #endif #ifdef ESP32 WebServer server(80); #endif // Serving Hello world void getHelloWord() { server.send(200, "text/json", "{\"name\": \"Hello world\"}\r\n"); } void ledOff() { // do something for LED off server.send(200, "text/json", "{\"led\": \"OFF\"}\r\n"); } void ledOn() { // do something for LED on server.send(200, "text/json", "{\"led\": \"ON\"}\r\n"); } // Define routing void restServerRouting() { server.on("/", HTTP_GET, []() { server.send(200, F("text/html"), F("Welcome to the REST Web Server")); }); server.on(F("/helloWorld"), HTTP_GET, getHelloWord); server.on(F("/api/v1/led=0"), HTTP_GET, ledOff); server.on(F("/api/v1/led=1"), HTTP_GET, ledOn); } // Manage not found URL void handleNotFound() { String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); } void setup(void) { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Activate mDNS this is used to be able to connect to the server // with local DNS hostmane esp8266.local #ifdef WIO_TERMINAL mdns.begin(WiFi.localIP(), "wiot"); Serial.println("MDNS responder started(wiot)"); #endif #ifdef ESP8266 if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started(esp8266)"); } #endif #ifdef ESP32 if (MDNS.begin("esp32")) { Serial.println("MDNS responder started(esp32)"); } #endif // Set server routing restServerRouting(); // Set not found response server.onNotFound(handleNotFound); // Start server server.begin(); Serial.println("HTTP server started"); } void loop(void) { #ifdef WIO_TERMINAL mdns.run(); // This actually runs the mDNS module. YOU HAVE TO CALL THIS PERIODICALLY #endif #ifdef ESP8266 MDNS.update(); #endif #ifdef ESP32 //MDNS.update(); // no need to update on ESP32 #endif server.handleClient(); }

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";

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

$ picocom /dev/ttyACM0 -b115200 # ESP8266の場合 ... Connected to xxxxxxxx IP address: 192.168.0.5 MDNS responder started(esp8266) HTTP server started # M5Atom/ESP32の場合 .. Connected to xxxxxxxx IP address: 192.168.0.15 MDNS responder started(esp32) HTTP server started # Wio-Terminalの場合 .. Connected to xxxxxxxx IP address: 192.168.0.15 MDNS responder started(wiot) HTTP server started

curlによるコマンド実行例:

# ESP8266の場合 $ curl 'http://esp8266.local:80/helloWorld' {"name": "Hello world"} $ curl 'http://esp8266.local:80/api/v1/led=1' {"led": "ON"} $ curl 'http://esp8266.local:80/api/v1/led=0' {"led": "OFF"} # ESP32の場合 $ curl 'http://esp32.local:80/helloWorld' {"name": "Hello world"} $ curl 'http://esp32.local:80/api/v1/led=0' {"led": "OFF"} $ curl 'http://esp32.local:80/api/v1/led=1' {"led": "ON"} # wio-terminalの場合 $ curl 'http://wiot.local:80/helloWorld' {"name": "Hello world"} $ curl 'http://wiot.local:80/api/v1/led=0' {"led": "OFF"} $ curl 'http://wiot.local:80/api/v1/led=1' {"led": "ON"}

mDNSによる名前解決には時間がかかることがあるので その場合、IPアドレスでアクセスすること。
また、M5Atomの場合、プログラム起動後、リセットボタンを押す必要があるようだ。

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 # # mDNS lib "ArduinoMDNS" 2848

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

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 build_flags = -DESP32 monitor_speed = 115200 lib_ldf_mode = deep+

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+

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

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

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

参考情報

PlatformIO Core (CLI)

以上

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

| | コメント (0)

2020年12月26日 (土)

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

2020/12/26+
初版

board3 OSC v2

board3 OSC v2

概要

Wio-Terminal/M5Atom/ESP8622/ESP32ボードを共通のスケッチで動かす(v2)(OSC編)
本記事は「Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(OSC編)」の改版にあたる。wio-terminalのWiFi/BLEファームウェアがバージョンアップしたので、それの対応方法を記載した。これにより、wio-terminalの古いファームウェアで原因不明で動作しなかったOSC受信が動作するようになった。

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

OSCcodecライブラリ

OSC_codecライブラリとしてプロジェクトのsrcディレクトリに以下の2つのファイルを置く:

src/OSCmsgCodec.h

// OSC message Codec Header // 2013/10/28 #ifndef _OSCMSGCODEC_H #define _OSCMSGCODEC_H #include <string.h> int encOSCmsg(char *packet , union OSCarg *msg); // makes packet from OSC message and returns packet size void decOSCmsg(char *packet , union OSCarg *msg); // makes OSC message from packet union OSCarg { // char*, int and float are assumed four bytes char *address; char *typeTag; long int i; // int32 for Arduino(16bits) float f; char *s; struct { long int len; // is "int i" char *p; } blob; char m[4]; // for MIDI char _b[4]; // endian conversion temp variable }; #endif // _OSCMSGCODEC_H

src/OSCmsgCodec.cpp

/* <---------------------------------------------------------------------------------- OSC message Codec(encoder/decoder) version: 1.3 (2014/ 8/31) encoder bufix(enoceder returns byte length) version: 1.2 (2014/ 8/30) decoder bufix version: 1.1 (2013/11/20) support BIG_ENDIAN by #define version: 1.0 (2013/11/10) Copyright (C) 2011,2013,2014 S.Komatsu released under the MIT License: http://mbed.org/license/mit please refer to: http://opensoundcontrol.org/introduction-osc for OSC(Open Sound Control) The followings are supported: Features: Packet Parsing (Client) Packet Construction (Server) Bundle NOT Support Timetag NOT Support Type Support: i: int32 b: blob s: string f: float32 m: MIDI message(port id, status byte, data1, data2) // I don't know the detail Change Log: Bug(string length is not correct in encoding) Fix on 2013/11/10 (v0.9 -> v1.0) >---------------------------------------------------------------------------------- */ #include "OSCmsgCodec.h" //#define BIG_ENDIAN int lenAlign4B(int len) { if ((len % 4) == 0) {return len; } else {return len+4-(len % 4);} } int encOSCmsg(char *packet , union OSCarg *msg){ // *** important notice *** // output buffer must be cleared before call this char *p, *s, *d, *typeTag; char c; p=packet; d=p; s=msg[0].address; // address for(int i=0; i<strlen(msg[0].address); i++) *d++ = *s++; *d=0; // terminator // p += 4*((strlen(msg[0].address)+1)/4+1); p += lenAlign4B(strlen(msg[0].address)+1); // s=msg[1].typeTag; d=p; for(int i=0; i<strlen(msg[1].typeTag); i++) *d++ = *s++; *d=0; // terminator // p += 4*((strlen(msg[1].s)+1)/4+1); p += lenAlign4B(strlen(msg[1].typeTag)+1); // typeTag=msg[1].s+1; // skip ',' for(int n=0; n<strlen(typeTag); n++){ c = typeTag[n]; if (('s'==c)) { s=msg[n+2].s; d=p; for(int i=0; i<strlen(msg[n+2].s); i++) *d++ = *s++; *d=0; // terminater // p += 4*((strlen(msg[n+2].s)+1)/4+1); p += lenAlign4B(strlen(msg[n+2].s)+1); } else if (('i'==c)||('f'==c)) { #ifdef BIG_ENDIAN // no change endian (big to big) p[0]=msg[n+2]._b[0]; p[1]=msg[n+2]._b[1]; p[2]=msg[n+2]._b[2]; p[3]=msg[n+2]._b[3]; #else // change endian (little to big) p[0]=msg[n+2]._b[3]; p[1]=msg[n+2]._b[2]; p[2]=msg[n+2]._b[1]; p[3]=msg[n+2]._b[0]; #endif p +=4; } else if ('b'==c) { // put length of blog #ifdef BIG_ENDIAN // no change endian (big to big) p[0]=msg[n+2]._b[0]; p[1]=msg[n+2]._b[1]; p[2]=msg[n+2]._b[2]; p[3]=msg[n+2]._b[3]; #else // change endian (little to big) p[0]=msg[n+2]._b[3]; p[1]=msg[n+2]._b[2]; p[2]=msg[n+2]._b[1]; p[3]=msg[n+2]._b[0]; #endif p +=4; // get ponter of blog (copy to msg[n].blog.p) s=msg[n+2].blob.p; d=p; for(int i=0; i<msg[n+2].blob.len; i++) *d++ = *s++; p += 4*(msg[n+2].blob.len/4+1); } else if ('m'==c) { // get midi data (copy to msg[n].m[]) p[0]=msg[n+2].m[0]; p[1]=msg[n+2].m[1]; p[2]=msg[n+2].m[2]; p[3]=msg[n+2].m[3]; p +=4; } else { //printf("*** Not Supported TypeTag:%s ****\n",typeTag); } }; //return (p-packet); // return packet size // bugfix 2014/8/31 return sizeof(char)*(p-packet); // return byte length }; void decOSCmsg(char *packet , union OSCarg *msg){ // Caution: the returned result points to packet as blobs or strings (not newly allocatd) char *p, *typeTag; char c; int n; msg[0].address = packet; // address msg[1].typeTag = packet+4*((strlen(msg[0].s)+1)/4+1);//typeTag typeTag=msg[1].s+1; // skip ',' // bugfix 2014/8/30 if (strlen(typeTag)%2 == 0) p= msg[1].s+4*((strlen(msg[1].s)+1)/4); else p= msg[1].s+4*((strlen(msg[1].s)+1)/4+1); for(n=0; n<strlen(typeTag); n++){ c = typeTag[n]; if (('s'==c)) { msg[n+2].s=p; //p += 4*((strlen(msg[n+2].s)+1)/4+1); p += lenAlign4B(strlen(msg[n+2].s)+1); } else if (('i'==c)||('f'==c)) { #ifdef BIG_ENDIAN // no change endian (big to big) msg[n+2]._b[0]=p[0]; msg[n+2]._b[1]=p[1]; msg[n+2]._b[2]=p[2]; msg[n+2]._b[3]=p[3]; #else // change endian (big to little) msg[n+2]._b[3]=p[0]; msg[n+2]._b[2]=p[1]; msg[n+2]._b[1]=p[2]; msg[n+2]._b[0]=p[3]; #endif p +=4; } else if ('b'==c) { // get lenth of blog (copy to msg[n].blog.len) #ifdef BIG_ENDIAN // no change endian (big to big) msg[n+2]._b[0]=p[0]; msg[n+2]._b[1]=p[1]; msg[n+2]._b[2]=p[2]; msg[n+2]._b[3]=p[3]; #else // change endian (big to little) msg[n+2]._b[3]=p[0]; msg[n+2]._b[2]=p[1]; msg[n+2]._b[1]=p[2]; msg[n+2]._b[0]=p[3]; #endif p +=4; // get ponter of blog (copy to msg[n].blog.p) msg[n+2].blob.p=p; //p += 4*(msg[n+2].blob.len/4+1); p += lenAlign4B(msg[n+2].blob.len+1); } else if ('m'==c) { // get midi data (copy to msg[n].m[]) msg[n+2].m[0]=p[0]; msg[n+2].m[1]=p[1]; msg[n+2].m[2]=p[2]; msg[n+2].m[3]=p[3]; p +=4; } else { //printf("*** Not Supported TypeTag:%s ****\n",typeTag); } }; };

デモ・スケッチ

src/main.ino

// select board ////#define WIO_TERMINAL ////#define ESP8266 ////#define ESP32 ////#define M5ATOM /* OSC sender/receiver Forked for Wio-Terminal/ESP8266(ESP-WROOM-02)/ESP32 from: This sketch sends random data over UDP on a ESP32 device */ #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 <WiFiUdp.h> // WiFi network name and password: const char* ssid = "your-ssid"; const char* passwd = "your-password"; //IP address to send UDP data to: const char* udpAddress = "192.168.0.18"; // target IP const int udpInPort = 8000; // incomming port const int udpOutPort = 9000; // outgoing port //<<<<<<<<<<<<<<<<<<<<< // OSC related #include "OSCmsgCodec.h" #define PACKET_SIZE 512 #define RECBUF_SIZE 256 union OSCarg msg[10], outmsg[10]; char buff[PACKET_SIZE],packet[PACKET_SIZE]; //>>>>>>>>>>>>>>>>>>>> char recbuf[128]; // buffer for incoming packets //The udp library class WiFiUDP udp; void setup() { Serial.begin(115200); Serial.println("OSC test program start..."); Serial.println(""); // delete old config WiFi.disconnect(true); Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, passwd); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" connected"); udp.begin(udpInPort); Serial.printf("Now listening at IP %s, UDP port %d\r\n", WiFi.localIP().toString().c_str(), udpInPort); } void loop() { int packetSize = udp.parsePacket(); if (packetSize>0) { Serial.printf("Received %d bytes from %s, port %d\r\n", packetSize, udp.remoteIP().toString().c_str(), udpInPort); int len = udp.read(recbuf, 128); if (len > 0) { decOSCmsg(recbuf, msg); Serial.printf("incomming OSC msg:\r\n%s %s", msg[0].address, msg[1].typeTag); for(int m=0; m < (strlen(msg[1].typeTag)-1); m++) { if (msg[1].typeTag[m+1]=='f') Serial.printf(" %f",msg[m+2].f); if (msg[1].typeTag[m+1]=='i') Serial.printf(" %d",msg[m+2].i); }; Serial.printf("\r\n"); Serial.printf("-------------------\r\n"); } } else { // test send // fader // send OSC message with random values (to touchOSC) // make OSC message for sending outmsg[0].address="/1/fader5"; outmsg[1].typeTag=",f"; outmsg[2].f= rand()%1000/1000.0; memset(packet,0,sizeof(packet)); // clear send buff for OSC msg int plen=encOSCmsg(packet,outmsg); // send it // Send a packet udp.beginPacket(udpAddress, udpOutPort); udp.write((const uint8_t*)packet, plen); udp.endPacket(); // //Serial.print("."); // indicate sending packet //Wait delay(10); // seems 'must' (for platformio) } }

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

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

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

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

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

// WiFi network name and password: const char* ssid = "your_ssid"; const char* passwd = "your_passwd"; //IP address to send UDP data to: const char* udpAddress = "192.168.0.18"; // target IP const int udpInPort = 8000; // incomming port const int udpOutPort = 9000; // outgoing port

udpAddressは、対向するOSC受信デバイス(touchOSCなど)のIPを設定する。

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

$ picocom /dev/ttyACM0 -b115200 ........... connected Now listening at IP 192.168.0.11, UDP port 8000

上の例ではTouchOSCから192.168.0.11:8000へOSCパッケットに送る(ようにTouchOSCを設定する)。

または、動作としては、touchOSCのsimpleレイアウトの画面で、最上行の受信アイコンがOSCを受信すると「赤」になり、fader5のfaderが送られてきたOSCの内容に従ってランダムに変化する。

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 #

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

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

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

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

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

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

参考情報

TouchOSC - Modular touch control surface for OSC & MIDI
TouchOSC - iPhone
TouchOSC - Android

OSCmsgCode lib:
https://os.mbed.com/users/xshige/code/Sparkfun_CC3000_WiFi_OSCtranceiver//raw-file/e62251d890c1/OSCmsgCodec.h
https://os.mbed.com/users/xshige/code/Sparkfun_CC3000_WiFi_OSCtranceiver//raw-file/e62251d890c1/OSCmsgCodec.cpp
https://os.mbed.com/users/xshige/code/Sparkfun_CC3000_WiFi_OSCtranceiver//file/e62251d890c1/main.cpp/

Platform/Wio Terminal Network/Wi-Fi - example sketches

Wio Terminalをはじめよう(ピン配置、データシート、回路図など)

PlatformIO Core (CLI)

old version:
Wio-TerminalでWiFiで使う(その4:OSC)

以上

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

| | コメント (0)

2020年10月 9日 (金)

M5Atomを開発ツールPlatformIOで使う(Windows10版)

2020/10/9+

PlatformIO M5ATOM on Windows10

PlatformIO M5ATOM on Windows10

概要

以下のM5Atomを開発ツールPlatformIOで使う(Windows10版)。
ホストPCとしてはwindows10を想定している。

ATOM Lite
ATOM Matrix

Peripherals Pin Map

Lite:

Func GPIO
RGB Led(Neo) G27
Btn G39
IR G12

Matrix:

Func GPIO
Neo G27
Btn G39
IR G12
CLK(MPU6886) G21
SDA(MPU6886) GP25

Grove Interface

GND 5V G26 G32
GND 5V SDA SCL

platformioをインストールする

以下の手順でインストールする:
PowerShell:

# scoopをインストール Set-ExecutionPolicy RemoteSigned -scope CurrentUser iwr -useb get.scoop.sh | iex # pythonをインストールする scoop install python pip3 install platformio # windows用VScodeをインストールする scoop bucket add extras scoop install vscode

scoopの簡単な説明:

# xxxxをインストール scoop install # Scoop自身とローカル内にあるアプリの更新情報を更新 scoop update # 最新バージョンでないアプリがあるかをチェック scoop status # xxxxを更新 scoop update xxxx # すべてのアプリを更新 scoop update * # xxxxをアンインストール scoop uninstall xxxx

テスト用プロジェクト sample を作成/実行する

# プロジェクト sample のディレクトリを作成する mkdir sample cd sample # 以下を実行して必要なファイルを作成する pio init --board m5stick-c # platformをupdateする pio platform update code 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:esp32dev] platform = espressif32 board = m5stick-c framework = arduino monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 lib_ldf_mode = deep+
# テスト用のbutton.inoを作成する code src/button.ino 以下のように編集する:
/**************************************************************** * * This Example is used to test button * * Arduino tools Setting * -board : M5StickC * -Upload Speed: 115200 / 750000 / 1500000 * ****************************************************************/ #include "M5Atom.h" uint8_t DisBuff[2 + 5 * 5 * 3]; void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata) { DisBuff[0] = 0x05; DisBuff[1] = 0x05; for (int i = 0; i < 25; i++) { DisBuff[2 + i * 3 + 0] = Rdata; DisBuff[2 + i * 3 + 1] = Gdata; DisBuff[2 + i * 3 + 2] = Bdata; } } void setup() { M5.begin(true, false, true); delay(10); setBuff(0xff, 0x00, 0x00); M5.dis.displaybuff(DisBuff); } uint8_t FSM = 0; void loop() { if (M5.Btn.wasPressed()) { switch (FSM) { case 0: setBuff(0x40, 0x00, 0x00); break; case 1: setBuff(0x00, 0x40, 0x00); break; case 2: setBuff(0x00, 0x00, 0x40); break; case 3: setBuff(0x20, 0x20, 0x20); break; default: break; } M5.dis.displaybuff(DisBuff); FSM++; if (FSM >= 4) { FSM = 0; } } delay(50); M5.update(); }

続き:

# build pio run # ボードをホストPCに接続する # build&upload(flash) pio run -t upload # buildしないで書き込む場合は以下を実行する: pio run -t nobuild -t upload -v # -v は、詳細を表示するオプション # 以上で、基本的な操作としては完了となる

書き込み後、ボタンを押す度に、LEDの色が変化する。 (本スケッチは、Matrix/Lite兼用になっていて、Matrixの場合、5x5のLEDが同じ色で光る。Liteの場合、一つのLEDが光る)

これ以降、別のプログラムを動かすときは sampleのディレクトリをまるごと コピーして別のプロジェクトのディレクトリを作り そこにプログラム(.ino)を置く。

例:

cp sample m5a_proj01 cd m5a_proj01 ...

MPU6886を利用するスケッチ#1(Matrix限定)

src/mpu6886_2.ino

#include "M5Atom.h" #define SIG_MAX (4096) uint8_t DisBuff[2 + 5 * 5 * 3]; int16_t adX,adY,adZ; void setBuffP(uint8_t posData, uint8_t Rdata, uint8_t Gdata, uint8_t Bdata) { DisBuff[2 + posData * 3 + 0] = Rdata; DisBuff[2 + posData * 3 + 1] = Gdata; DisBuff[2 + posData * 3 + 2] = Bdata; } void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata) { for (uint8_t i = 0; i < 25; i++) setBuffP(i, Rdata, Gdata, Bdata); } void shftBuff() { for (uint8_t i = 24; i > 0; i--) { for (uint8_t j = 0; j < 3; j++) DisBuff[2 + i * 3 + j] = DisBuff[2 + (i-1) * 3 + j]; } } void setup() { DisBuff[0] = 0x05; DisBuff[1] = 0x05; M5.begin(false, true, true); delay(10); M5.IMU.Init(); setBuff(0x20, 0x20, 0x20); M5.dis.displaybuff(DisBuff); // Serial.begin(115200); } void loop() { M5.update(); if (M5.Btn.read()==0) { M5.IMU.getAccelAdc(&adX, &adY, &adZ); int r = min(max((int)map(adX,-SIG_MAX,SIG_MAX,0,255),0),255); int g = min(max((int)map(adY,-SIG_MAX,SIG_MAX,0,255),0),255); int b = min(max((int)map(adZ,-SIG_MAX,SIG_MAX,0,255),0),255); shftBuff(); setBuffP(0,r,g,b); M5.dis.displaybuff(DisBuff); // Serial.printf("x,y,z: %d,%d,%d\r\n", adX, adY, adZ); } delay(20); }

書き込み実行し、M5Atomを傾けるとそれに応じて5x5のLEDの色が変化する。

MPU6886を利用するスケッチ#2(Matrix限定)

src/mpu6886_3.ino

#include "M5Atom.h" float accX = 0, accY = 0, accZ = 0; float gyroX = 0, gyroY = 0, gyroZ = 0; float temp = 0; bool IMU6886Flag = false; void setup() { M5.begin(true, false, true); if (M5.IMU.Init() != 0) IMU6886Flag = false; else IMU6886Flag = true; } void loop() { if (IMU6886Flag == true) { M5.IMU.getGyroData(&gyroX, &gyroY, &gyroZ); M5.IMU.getAccelData(&accX, &accY, &accZ); M5.IMU.getTempData(&temp); Serial.printf("%.2f,%.2f,%.2f o/s \r\n", gyroX, gyroY, gyroZ); Serial.printf("%.2f,%.2f,%.2f mg\r\n", accX * 1000, accY * 1000, accZ * 1000); Serial.printf("Temperature : %.2f C \r\n", temp); } delay(500); M5.update(); }

WiFi対応スケッチ

ESP32のWiFi対応スケッチと互換性があるので、以下をソースの先頭に入れると動作するようだ。

#ifdef M5ATOM #include "M5Atom.h" #define ESP32 #endif

したがって、以下のスケッチの先頭に上のコードを入れるとM5Atomでも動作するようになる:
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチでWorld Time APIを使う(WorldTimeAPI編)
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(HTTP-ACCESS編)
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(NTP-CLIENT編)
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(REST-API2編)
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(OSC編)
Wio-Terminal/ESP8622/ESP32ボードを共通のスケッチで動かす(MQTT編)

補足

「Serial.printf("Temperature : %.2f C \r\n", temp);」などが動作していないようだ。 (USBシリアルが動作していないようだ)

参考情報

WindowsコマンドラインツールScoopのすすめ(基礎編)
Windowsでパッケージ管理したいなら、先ずScoopより始めよ

Atom pixel tool
wget https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/software/AtomPixTool.exe
windowsのプログラムだがlinuxのwineでも動作するようだ。
マトリックスのデザインを作成でき、それを保存すると、そのデータのC言語ソースができあがる

Display API Document:
https://github.com/m5stack/M5Atom

サンプル・スケッチ:
git clone https://github.com/m5stack/M5Atom.git
git clone https://github.com/hajimef/m5atom-matrix-samples.git
M5AtomをPlatformIOで動かす-ライブラリインストールから加速度取得まで

PlatformIO Core (CLI)

以上

続きを読む "M5Atomを開発ツールPlatformIOで使う(Windows10版)"

| | コメント (0)

2020年10月 7日 (水)

ESP32ボードでTinyGOを動かす(v2)

2020/10/8:
もう一つのnexpixelのデモを追加した。

2020/10/7:
初版

TinyGO Install ESP32 v2

TinyGO Install ESP32 v2

概要

ESP32ボードでTinyGOを動かす(v2)。
tinygo_0.15.0でesp32が正式にサポートされたので、それをインストールして使ってみる。
なお、ホストPCとしてはubuntu20.04を想定している。

ESP32ボードとしては、M5Stack,M5Stick-C,M5Atomなどがある。

準備

以下のツールを予めインストールする:
(0)udev設定
以下を実行する:

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules sudo udevadm control --reload-rules sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER

(1)TinyGOのインストール
以下の手順でインストールする:

mkdir tinygo_ws cd tinygo_ws wget https://github.com/tinygo-org/tinygo/releases/download/v0.15.0/tinygo_0.15.0_amd64.deb sudo dpkg -i tinygo_0.15.0_amd64.deb export PATH=$PATH:/usr/local/tinygo/bin # esp32には不要だが、ターゲットがarduinoのときに # 必要となるツールをついでにインストールする sudo apt-get install gcc-avr sudo apt-get install avr-libc sudo apt-get install avrdude

(2)GOのインストール
TinyGOのモジュールを使用するのにGOが必要なので 予めインストールする。
(ただし、TinyGOとの整合性により最新版ではない)

wget https://dl.google.com/go/go1.13.7.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.13.7.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/tinygo_ws

なお、GOPATHのパス設定値は、任意だが、それをベースに その配下にTinyGO/GOの関係ファイル/ディレクトリが置かれる。

(3)esptoolのインストール
ESP32の書き込みツールをインストールする:

# python2.xのpipをインストールする mkdir tools cd tools sudo add-apt-repository universe sudo apt update sudo apt install python2 curl https://bootstrap.pypa.io/get-pip.py --output get-pip.py sudo python2 get-pip.py # esptoolをインストールする git clone https://github.com/espressif/esptool.git cd esptool pip install --user -e .

以上のexportは、.bashrcに登録する。

(4)export登録(まとめ)
以下を.bashrcに追加する:

# tinygo/go export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:/usr/local/tinygo/bin export GOPATH=$HOME/tinygo_ws export TIGOLIBS=$GOPATH/src/tinygo.org/x/drivers/

examples/serialを動かす

M5Atomをホストに接続して、以下を実行する:

tinygo flash -size full -target=esp32-wroom-32 -port=/dev/ttyUSB0 examples/serial #ビルド時の出力 code rodata data bss | flash ram | package 115 0 0 0 | 115 0 | (bootstrap) 120 12 0 0 | 132 0 | examples/serial 200 76 0 8 | 276 8 | runtime 21 0 0 0 | 21 0 | runtime/volatile 456 88 0 8 | 544 8 | (sum) 673 - 0 4108 | 673 4108 | (all) esptool.py v3.0-dev Serial port /dev/ttyUSB0 Connecting.... Chip is ESP32-PICO-D4 (revision 1) Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None Crystal is 40MHz MAC: 50:02:91:91:19:20 Uploading stub... Running stub... Stub running... Configuring flash size... Auto-detected Flash size: 4MB Flash params set to 0x032f Compressed 880 bytes to 678... Wrote 880 bytes (678 compressed) at 0x00001000 in 0.1 seconds (effective 103.8 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...

コンパイルと書き込み実行が自動的に行わるので、その後、 以下のように通信ソフトを起動する:

$ picocom /dev/ttyUSB0 -b115200 <省略> Type [C-a] [C-h] to see available commands Terminal ready 2:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 188777542, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_dr hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! <省略>

任意のプログラムを動かす

(1)以下のようにプロジェクト用ディレクトリを作成する:

cd tigo_ws mkdir blink cd blink

(2)プロジェクト(blink)ディレクトリに以下のファイルを作成する:
main.go

package main // This is the most minimal blinky example and should run almost everywhere. import ( "machine" "time" ) func main() { led := machine.Pin(25) // G25 for M5Atom led.Configure(machine.PinConfig{Mode: machine.PinOutput}) for { led.Low() time.Sleep(time.Millisecond * 1000) led.High() time.Sleep(time.Millisecond * 1000) } }

抵抗付きLEDをG25に接続する。

(3)ビルド実行
M5Atomをホストに接続して、以下を実行する:

tinygo flash -size full -target=esp32-wroom-32 -port=/dev/ttyUSB0 .

コンパイルと書き込み実行が自動的に行われ、接続したLEDが点滅する。

TinyGOのモジュールを利用する

実行例: # 以下で、モジュールをインストールする go get tinygo.org/x/drivers # インストールしたモジュールのパスを設定する export TIGOLIBS=$GOPATH/src/tinygo.org/x/drivers/ # インポートしたいモジュールを確認する ls $TIGOLIBS ... adt7410 ds1307 l9110x shifter vl53l1x adxl345 ds3231 lis3dh shiftregister waveshare-epd amg88xx easystepper lsm6ds3 sht3x wifinina apa102 espat mag3110 ssd1306 ws2812 at24cx examples mcp3008 ssd1331 bh1750 flash microbitmatrix st7735 ... # ここでは例として「ws2812」を使用する mkdir ws2812 cd ws2812 # exampleのmain.goをコピーする cp $TIGOLIBS/examples/ws2812/main.go .

以下のようにmain.goを変更する:
main.go

// Connects to an WS2812 RGB LED strip with 10 LEDS. // // See either the others.go or digispark.go files in this directory // for the neopixels pin assignments. package main import ( "image/color" "machine" "time" "tinygo.org/x/drivers/ws2812" ) var leds [15]color.RGBA func main() { led := machine.LED led.Configure(machine.PinConfig{Mode: machine.PinOutput}) // neo := machine.Pin(26) // G26 for Grove connector of M5Atom neo := machine.Pin(25) // G25 for M5Atom // neo := machine.D4 // for Feater-M4/XIAO // neo := machine.NEOPIXELS neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) ws := ws2812.New(neo) rg := false for { rg = !rg for i := range leds { rg = !rg if rg { // Alpha channel is not supported by WS2812 so we leave it out leds[i] = color.RGBA{R: 0xff, G: 0x00, B: 0x00} } else { leds[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00} } } ws.WriteColors(leds[:]) led.Set(rg) time.Sleep(100 * time.Millisecond) } }

以下でビルド実行する:

tinygo flash -size full -target=esp32-wroom-32 -port=/dev/ttyUSB0 .

M5AtomのG25をneopixelsのDIN,5VをVCC,GNDをGNDに接続する。
(または、Groveコネクタに接続する)
書き込み実行すると、接続したneopixelsが光る。

他の外部モジュールを利用する

# 以下で、モジュールをインストールする go get github.com/aykevl/ledsgo # 参考(以下のディレクトリにダウンロードしたものが置かれる) ls $GOPATH/src github.com tinygo.org ls $GOPATH/src/github.com aykevl # プログラムを置くディレクトリを作る mkdir neopixels0 cd neopixels0 # デモ・プログラムをダウンロードする wget https://gist.githubusercontent.com/aykevl/47d0a24408cf585f6ba181c4dc663bca/raw/c4db52a1fedb215b4743a31842aeba31a4f2fe77/ws2812.go

以下のようにws2812.goを修正する:
ws2812.go

package main // This is an example of controlling WS2812 LEDs from an ESP32. // The following PRs are still needed to get this to work: // https://github.com/tinygo-org/tinygo/pull/1353 // https://github.com/tinygo-org/tinygo/pull/1354 // https://github.com/tinygo-org/drivers/pull/198 import ( "machine" "time" "github.com/aykevl/ledsgo" "tinygo.org/x/drivers/ws2812" ) const brightness = 0x44 const pin = machine.Pin(27) // G27 for Matrix(5x5) of M5Atom //const pin = machine.Pin(26) // G26 for Grove Connector of M5Atom //const pin = machine.Pin(25) // G25 for M5Atom var ws ws2812.Device func main() { strip := make(ledsgo.Strip, 25) // for Matrix(5x5) M5Atom //strip := make(ledsgo.Strip, 15) // for Grove Neopixel //strip := make(ledsgo.Strip, 50) pin.Configure(machine.PinConfig{Mode: machine.PinOutput}) ws = ws2812.New(pin) rainbow(strip) } func rainbow(strip ledsgo.Strip) { for { now := time.Now().UnixNano() for i := range strip { strip[i] = ledsgo.Color{uint16(now>>15) - uint16(i)<<12, 0xff, brightness}.Spectrum() } ws.WriteColors(strip) time.Sleep(time.Second / 100) } } func noise(strip ledsgo.Strip) { for { now := time.Now().UnixNano() for i := range strip { const spread = 100 val := int32(ledsgo.Noise2(int32(now>>22), int32(i*spread))) * 3 / 2 strip[i] = ledsgo.Color{uint16(val), 0xff, brightness}.Spectrum() } ws.WriteColors(strip) time.Sleep(time.Second / 100) } }

以下の選択肢があるので、それに応じてソースをコメントアウトする:
(1)M5Atom_Matrixの内蔵のLED(5x5)を使用する。
(2)M5AtomのGroveコネクタにnexpixelsを接続する。
(3)M5AtomのG25をneopixelsのDIN,5VをVCC,GNDをGNDに接続する。

以下でビルド実行する:

tinygo flash -size full -target=esp32-wroom-32 -port=/dev/ttyUSB0 .

書き込み実行すると、neopixelsが虹色に変化して光る。

参考情報

ESP32 and ESP8266 support in TinyGo

https://github.com/tinygo-org/tinygo
https://tinygo.org/
https://tinygo.org/getting-started/linux/

コンピュータボードでTinyGOを動かす
docker/TinyGO Helper Script
TinyGOでLightSensorを動かす

TinyGoで始める組み込みプログラミング
TinyGo on Arduino Uno: An Introduction

Circuit Playground Express
Adafruit Circuit Playground Express - Overview
Infrared Receive and Transmit with Circuit Playground Express

Adafruit Circuit Playground Express - PINOUT
Adafruit Circuit Playground Express Pin Assign

NUCLEO-F103RB mbed pinout
NUCLEO-F103RB Pin Assign
STM32F4DISCO Pin Assign
MICROBIT Pin Assign
ARDUINO-NANO Pin Assign
ARDUINO Pin Assign

TinyGo Drivers

USB Flashing Format (UF2)

XIAO Schematic(zip)
How to use Seeeduino XIAO to log in to your Raspberry PI

以上

続きを読む "ESP32ボードでTinyGOを動かす(v2)"

| | コメント (0)

Moddableをインストールする(v2)

2020/10/7:
esp32/xxxのtarget名称が以下のように変更になったので それに対応した:

~/Projects/moddable/build/devices/esp32/targets$ ls esp32_thing m5atom_echo m5stack m5stick_c nodemcu lilygo_t5s m5atom_lite m5stack_core2 moddable_two oddwires lilygo_taudio m5atom_matrix m5stack_fire moddable_zero wrover_kit

2020/10/6:
初版

Moddable install v2

Moddable install v2

概要

以下のModdableをインストールする(v2)。
(前の記事からubuntu20.04に対応した)
ボードコンピュータでJavascriptを動かす環境としてModdableがあるが、それのインストールについて記する。
 組み込み系ソフトとしてJavascriptが動作する例として、Fitbit_Versaなどがあるが、これは、簡単な言い方をすると、 画面関係はSVG、ロジックはJavascriptで作成できる。JavascriptのインタープリタはVersa本体に組み込まれていて、 プログラムしたJavascriptのソースをVersa本体に書き込んで実行することになる。(ソース自身はコンパクトな形に変換される)
 obnizでもJavascriptが利用できるが、サーバークライアント・ベースでWebブラウザーでJavascriptが動作して、obnizのハードウェア自身はIOプロセッサ的に動作する。
 TesselボードでもJavascriptが動作する。ただし、特定のハードウェアに限定される。
 これに対して、moddableでは、Javascriptの機能自身が書き込む実行形式に含まれるので、これのみで完結する。

moddable

install(シミュレータ)

以下の手順でツールをインストールする:

sudo apt-get install libgtk-3-dev mkdir ~/Projects #(Projectsは任意) cd ~/Projects git clone https://github.com/Moddable-OpenSource/moddable export MODDABLE=~/Projects/moddable # Moddableのコマンドラインツール(mcconfig),シミュレータ(simulator),デバッガ(xsbug)をビルドする cd $MODDABLE/build/makefiles/lin make make install export PATH=$PATH:$MODDABLE/build/bin/lin/release # デバッグ起動テスト xsbug # ここでxsbugのウィンドウが立ち上がる。 # アプリケーションと接続していないので、空の画面になる。 # サンプルをコンパイル&実行する cd $MODDABLE/examples/piu/balls mcconfig -d -m -p lin # ここで、M5Stick-Cのシミュレータが動作して画面にバウンドしているボールが表示される。 # mcconfigがビルド用のツールになる; # オプションの意味は以下のとおり: # -d デバッグモードでビルド # -m ビルドとデバイスへの書き込みを同時に行う # -p ビルド対象のプラットフォームを指定するオプション。linは「LinuxのModdableシミュレータ」を指す。

install(ESP32)

以下の手順でESP32用ツールをインストールする:

cd ~ mkdir esp32 cd ~/esp32 wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz tar -xvf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz git clone -b v3.3.2 --recursive https://github.com/espressif/esp-idf.git # ubuntu20.04の場合(python3.xがサポートされている場合) sudo apt-get install gcc git wget make libncurses-dev flex bison gperf cmake ninja-build python-is-python3 python3-pip python3-serial # ubuntu20.04よりも古いubuntuの場合(python2.xがサポートされている場合) sudo apt-get install gcc git wget make libncurses-dev flex bison gperf python python-pip python-setuptools python-serial export IDF_PATH=~/esp32/esp-idf export PATH=$PATH:~/esp32/xtensa-esp32-elf/bin:$IDF_PATH/tools python -m pip install --user -r $IDF_PATH/requirements.txt # サンプルをコンパイル&実行する cd $MODDABLE/examples/piu/balls export UPLOAD_PORT=/dev/ttyUSB0 M5Stackの場合: mcconfig -d -m -p esp32/m5stack # または mcconfig -d -m -p esp32/m5stack_core2 M5Stack Fireの場合: mcconfig -d -m -p esp32/m5stack_fire # コンパイル実行するとデバッガ画面が表示されるので、実行アイコン(▶)を押す。 M5Stick-Cの場合: mcconfig -d -m -p esp32/m5stick_c M5Atomの場合: mcconfig -d -m -p esp32/m5atom_matrix # または mcconfig -d -m -p esp32/m5atom_lite # または mcconfig -d -m -p esp32/m5atom_echo

export登録

.bashrcに以下を登録する:

# moddable export MODDABLE=~/Projects/moddable export PATH=$PATH:$MODDABLE/build/bin/lin/release export IDF_PATH=~/esp32/esp-idf export PATH=$PATH:~/esp32/xtensa-esp32-elf/bin:$IDF_PATH/tools

sample code(参考)

balls/main.js

/* * Copyright (c) 2016-2020 Moddable Tech, Inc. * * This file is part of the Moddable SDK. * * This work is licensed under the * Creative Commons Attribution 4.0 International License. * To view a copy of this license, visit * <https://creativecommons.org/licenses/by/4.0> * or send a letter to Creative Commons, PO Box 1866, * Mountain View, CA 94042, USA. * */ import {} from "piu/MC"; const backgroundSkin = new Skin({ fill:"silver" }); const ballTexture = new Texture("balls.png"); const ballSkin = new Skin({ texture:ballTexture, x:0, y:0, width:30, height:30, variants:30 }); class BallBehavior extends Behavior { onCreate(ball, delta) { this.dx = delta; this.dy = delta; } onDisplaying(ball) { this.x = ball.x; this.y = ball.y; this.width = ball.container.width - ball.width; this.height = ball.container.height - ball.height; ball.start(); } onTimeChanged(ball) { var dx = this.dx; var dy = this.dy; ball.moveBy(dx, dy); var x = this.x + dx; var y = this.y + dy; if ((x < 0) || (x > this.width)) dx = -dx; if ((y < 0) || (y > this.height)) dy = -dy; this.dx = dx; this.dy = dy; this.x = x; this.y = y; } }; let BallApplication = Application.template($ => ({ skin:backgroundSkin, contents: [ Content(6, { left:0, top:0, skin:ballSkin, variant:0, Behavior: BallBehavior } ), Content(5, { right:0, top:0, skin:ballSkin, variant:1, Behavior: BallBehavior } ), Content(4, { right:0, bottom:0, skin:ballSkin, variant:2, Behavior: BallBehavior } ), Content(3, { left:0, bottom:0, skin:ballSkin, variant:3, Behavior: BallBehavior } ), ] })); export default new BallApplication(null, { displayListLength:4096, touchCount:0 });

ネットワーク対応のサンプル

ネットワーク対応のサンプルをビルド実行する場合、以下のように設定するssid,passwordを コマンドラインのオプションとして追加する:

mcconfig -d -m -p esp32/m5atom_xxxx ssid=your_ssid password=your_passswd

MQTT

ビルド実行:

cd $MODDABLE/examples/network/mqtt/mqttbasic mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.17 received "moddable/mqtt/example/date": Sun Sep 20 2020 18:24:23 GMT+0900 received "moddable/mqtt/example/random": 0.8646926234626893 received "moddable/mqtt/example/date": Sun Sep 20 2020 18:24:24 GMT+0900 received "moddable/mqtt/example/random": 0.3546896857104007 <省略> received "moddable/mqtt/example/random": 0.9578066274891157 received "moddable/mqtt/example/date": Sun Sep 20 2020 18:25:34 GMT+0900 received "moddable/mqtt/example/random": 0.7666543393318203 received "moddable/mqtt/example/date": Sun Sep 20 2020 18:25:35 GMT+0900 received "moddable/mqtt/example/random": 0.3196750421355653

httpserver

ビルド実行:

cd $MODDABLE/examples/network/http/httpserver mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.17

コンソール画面のIPアドレスで webブラウザーでアクセスすると 以下のように表示される;

hello, client at path /.

httpget

ビルド実行:

cd $MODDABLE/examples/network/http/httpget mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.4 <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>

httpgetjson

ビルド実行:

cd $MODDABLE/examples/network/http/httpgetjson mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.4 The temperature in Menlo Park is 60.21 F. The weather condition is Clouds.

httpserverbmp

ビルド実行:

cd $MODDABLE/examples/network/http/httpserverbmp mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.19

コンソール画面のIPアドレスで webブラウザーでアクセスする。 BMP画像が表示される。

httppost

ビルド実行:

cd $MODDABLE/examples/network/http/httppost mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.26 name: Moddable value: 123

このサンプルで利用しているテスト用サーバーについては以下を参照のこと:
httpbin - HTTP通信のテストに便利なWebサービス&ソフト

socketreadwrite

ビルド実行:

cd $MODDABLE/examples/network/socket/socketreadwrite mcconfig -d -m -p esp32/m5atom_lite ssid=your_ssid password=your_passswd

xsbugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.15 socket created. Socket message connect Socket message dataSent VALUE = 5744 Socket message dataReceived VALUE = 1436 HTTP/1.1 200 OK Accept-Ranges: bytes Age: 501726 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Sun, 20 Sep 2020 12:26:21 GMT Etag: "3147526947" Expires: Sun, 27 Sep 2020 12:26:21 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECS (sjc/4E74) Vary: Accept-Encoding X-Cache: HIT Content-Length: 1256 Connection: close <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use th Socket message dataReceived VALUE = 190 is domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>

他のサンプル

他のgitのサンプルを動かしてみる。 以下の手順でダウンロードする:

mkdir ~/moddable_test cd ~/moddable git clone https://github.com/meganetaaan/moddable-examples.git

サンプルの簡単な説明は以下を参照のこと:
https://github.com/meganetaaan/moddable-examples/blob/master/README.md

bongo

ボンゴ(打楽器)のデモ:

cd ~/moddable_test/moddable-examples/bongo mcconfig -d -m -p esp32/m5stack_fire

pomodoro

タイマーデモ:

cd ~/moddable_test/moddable-examples/pomodoro mcconfig -d -m -p esp32/m5stack_fire

neopixel

内蔵のneopixelを光らせる:

cd ~/moddable_test/moddable-examples/unit/neopixel mcconfig -d -m -p esp32/m5stack_fire

実行すると、内蔵neopixelが色を変えて光る

light-server

LEDが制御できるhttpサーバー:

cd ~/moddable_test/moddable-examples/network/light-server mcconfig -d -m -p esp32/m5stack_fire ssid=your_ssid password=your_passwd または mcconfig -d -m -p esp32/m5atom_matrix ssid=your_ssid password=your_passwd

xsdebugのコンソール画面:

Wi-Fi connected to "your_ssid" IP address 192.168.0.19 [object Object]probe for m5stack probe 1 probe 2 probe 3 probe claimed m5stack

webブラウザーで以下のurlでアクセスする:

http://192.168.0.19/off The light is off http://192.168.0.19/on The light is on http://m5stack.local/on The light is on http://m5stack.local/off The light is off

lightのオン/オフに応じて本体のLEDがオン/オフする。

接続:
M5Atomに抵抗付きLEDをG25に接続する。(5V,G(ND)も接続する)

~/moddable_test/blink/main.js

import Timer from 'timer'; import Digital from 'pins/digital'; let led = 25; // IO25 for M5Atom let toggle = 0; // Blink LED Timer.repeat(() => { Digital.write(led, toggle); toggle = ~toggle; }, 100);

~/moddable_test/blink/manifest.json

{ "include": [ "$(MODDABLE)/examples/manifest_base.json", "$(MODULES)/pins/digital/manifest.json", ], "modules": { "*": "./main", }, }

ビルド実行:

cd ~/moddable_test/blink mcconfig -m -p esp32/m5atom_lite

実行するとG25に接続したLEDが点滅する。

参照情報

https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/Moddable%20SDK%20-%20Getting%20Started.md

旧版:Moddableをインストールする

ATOM Echo - スマートスピーカー開発キット

versaアプリ「HR/LCD clock」の紹介

obniz
https://obniz.com/ja/doc/reference/

Tessel1
https://github.com/tessel/t1-docs
https://github.com/tessel/hardware/blob/master/tessel-hardware-overview.md
Tessel2
https://tessel.gitbooks.io/t2-docs/content/
https://tessel.gitbooks.io/t2-docs/content/Hardware/Tessel_2_Overview.html

以上

続きを読む "Moddableをインストールする(v2)"

| | コメント (0)

2020年9月27日 (日)

ModdableのREPLを動かす

2020/9/27:
初版

Moddable REPL

Moddable REPL

概要

以下のModdableのREPLを動かす。
本記事は「Moddableをインストールする」の続きになる。 Moddableのインストールは「Moddableをインストールする」を参照のこと。

moddable

修正

関係ソースを修正する:

cd $MODDABLE/examples/js/repl leafpad replcore.js

replcare.jsの22行目を以下のように修正する:

const newline = "\n"; → const newline = "\r\n\r\n";

manifest.json修正

(base64のモジュールを組み込むために)以下のように修正する: $MODDABLE/examples/js/repl/manifest.json

{ "include": [ "$(MODDABLE)/examples/manifest_base.json", ], "modules": { "*": [ "./main", "./replcore", "$(MODULES)/data/base64/*", ] }, "preload": [ "repl", "replcore", "base64", ], "strip": [], <以下、変更がないので省略>

ビルド実行

以下の手順でビルド実行する:

cd $MODDABLE/examples/js/repl mcconfig -m -p esp32/m5atom

出力例(REPL例)

mcconfig -m -p esp32/m5atom <省略> --- idf_monitor on /dev/ttyUSB0 115200 --- --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 188777542, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0018,len:4 load:0x3fff001c,len:768 ho 0 tail 12 room 4 load:0x40078000,len:9756 load:0x40080400,len:5620 entry 0x40080644 Moddable REPL (version 0.0.1) > var x = 12 undefined > x 12 > x + 5 17 > x ** 2 144 > eval("x + 3") 15 > const Timer = require("timer") ReferenceError: get require: undefined variable > Object.keys(require.cache) ReferenceError: get require: undefined variable > const Base64 = require("base64") ReferenceError: get require: undefined variable >

上の出力はビルド画面からlog出力されている例だが、 実行後、「picocom /dev/ttyUSB0 -b115200」で出力することもできる。 「Compiling JavaScript on Embedded Devices」の説明では requireが動作するようだが、実際には、現状のバージョンでは、requireが実装されていない?ようでエラーになっている。

$MODDABLE/examples/js/repl/main.jsを以下のように修正して
「mcconfig -d -m -p esp32/m5atom」(デバッガ付き)でビルド実行すると base64のモジュールが動作することが確認できるので、manifest.jsonの修正としては正しいようだ。
$MODDABLE/examples/js/repl/main.js

import REPL from "repl"; import Base64 from "base64"; let console = new REPL; trace(Base64.decode("aGVsbG8sIHdvcmxk")+"\n"); trace(Base64.encode("hello, world")+"\n");

デバッグ・コンソール画面:

[object ArrayBuffer] aGVsbG8sIHdvcmxk

参照情報

https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/Moddable%20SDK%20-%20Getting%20Started.md

Compiling JavaScript on Embedded Devices

以上

続きを読む "ModdableのREPLを動かす"

| | コメント (0)

2020年9月24日 (木)

Moddableにconsole.logを追加する

2020/9/24+:
別のconsole.logを追加した。

2020/9/24:
初版

Moddable console.log

Moddable console.log

概要

以下のModdableにconsole.logを追加する。
本記事は「Moddableをインストールする」の続きになる。 ModdableのインストールはModdableをインストールするを参照のこと。

moddable

console.logを追加する

Moddable SDKを使ってJavaScriptでIoT開発してみたのconsole.logの追加方法を利用したが、そのままでは、動作しなかったので、manifest.json,main.jsを変更した。

manifest.json

proj/manifest.json

{ "include": "$(MODDABLE)/examples/manifest_base.json", "modules": { "*": [ "./main", "./esp/*", ] } }

main.js

proj/main.js

import Timer from "timer"; //import console from "console"; import "console"; const a = 'a'; const z = 'z'; let c = a; let i = 0; Timer.repeat(() => { console.log(`${String(Date.now()).padStart(15)}:${i}`+'\r'); i = (i >= 10) ? 0 : i + 1; }, 1000); Timer.repeat(() => { console.log(`${String(Date.now()).padStart(15)}:${c}`+'\r'); c = (c >= z) ? a : String.fromCharCode(c.charCodeAt(0) + 1); }, 1500);

console.c

proj/esp/console.c

#include "xsAll.h" #include "xs.h" void xs_console_destructor(void) { } void xs_console_log(xsMachine *the) { int argc = xsToInteger(xsArgc), i; for (i = 0; i < argc; i++) { char *str = xsToString(xsArg(i)); do { uint8_t c = c_read8(str); if (!c) { ESP_putc('\n'); break; } ESP_putc(c); str++; } while (1); } }

console.js

proj/esp/console.js

class Console @ "xs_console_destructor" { static log() @ "xs_console_log" static debug() { trace(args); } constructor() { } } Object.freeze(Console.prototype); global.console = Console;

ビルド実行

以下の手順で実行する:

M5Atomの場合: mcconfig -m -p esp32/m5atom M5Stackの場合: mcconfig -m -p esp32/m5stack

デバッガを起動したい場合、「-d」を追加する。 ただし、console.log出力しているので デバッグのコンソール画面には、何も表示されない。

出力例

mcconfig -m -p esp32/m5atom <省略> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 188777542, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0018,len:4 load:0x3fff001c,len:768 ho 0 tail 12 room 4 load:0x40078000,len:9756 load:0x40080400,len:5620 entry 0x40080644 1023:0 1523:a 2023:1 3023:2 3023:b 4023:3 4523:c 5023:4 6023:5 6024:d 7023:6 7523:e 8023:7 9023:8 9024:f 10023:9 10523:g 11023:10 12023:0 12024:h 13023:1 13523:i 14023:2 15023:3 15023:j ...

上の出力はビルド画面からlog出力されている例だが、 実行後、「picocom /dev/ttyUSB0 -b115200」で出力することができる。

別のconsole.log

moddable-polyfillにもconsole.logがあるので、そのダウンロードについて説明する。 以下の手順でダウンロードする:

mkdir polyfill cd polyfill git clone https://github.com/horihiro/moddable-polyfill.git cd moddable-polyfill/example/timer

ビルド実行

以下の手順で実行する:

M5Atomの場合: mcconfig -d -m -p esp32/m5atom ssid=your_ssid password=your_passwd M5Stackの場合: mcconfig -d -m -p esp32/m5stack ssid=your_ssid password=your_passwd

breakpointが設定されて、デバッグ画面で停止するので[▶]を押して再スタートする。 ただし、console.log出力しているのでデバッグのコンソール画面には、何も表示されない。

出力例

<省略> Detecting chip type... ESP32 Chip is ESP32-PICO-D4 (revision 1) Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None Crystal is 40MHz MAC: 50:02:91:91:19:20 Uploading stub... Running stub... Stub running... Changing baud rate to 1500000 Changed. Configuring flash size... Compressed 18352 bytes to 11964... Wrote 18352 bytes (11964 compressed) at 0x00001000 in 0.1 seconds (effective 1114.9 kbit/s)... Hash of data verified. Compressed 3072 bytes to 144... Wrote 3072 bytes (144 compressed) at 0x00008000 in 0.0 seconds (effective 6153.2 kbit/s)... Hash of data verified. Compressed 783520 bytes to 478987... Wrote 783520 bytes (478987 compressed) at 0x00010000 in 7.6 seconds (effective 825.6 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin... <省略> Done #以下、console.log出力 fired 1600919068256 1600919069256 1600919070256 1600919071256

main.jsからbreakpointを外し(debuggerを外し) [-d]を外してビルドし直すと、「picocom /dev/ttyUSB0 -b115200」でconsole.log出力を表示できる。

manifest.json

manifest.json

{ "config": { "sntp": "pool.ntp.org", }, "include": [ "../../esp/console/manifest_console.json", "../../all/timer/manifest_timer.json", ], "modules": { "*": [ "./main", ], }, }

main.js

main.js

debugger; import {} from 'w3c_timer'; import {} from 'console'; const id_timeout = setTimeout(() => { console.log('fired'); }, 2000); const id_interval = setInterval(() => { console.log(Date.now()); }, 1000);

polyfillでsetTimeout/setIntervalも実装されている。

参照情報

https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/Moddable%20SDK%20-%20Getting%20Started.md

moddable 用 Polyfill ライブラリーを作ってます

以上

続きを読む "Moddableにconsole.logを追加する"

| | コメント (0)

2020年8月 9日 (日)

M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)

2020/8/9:
ChestTypeとWristTypeの両方対応にスケッチを改善した。

2020/8/8+

PlatformIO M5Atom BLE HR Sensor Receiver

PlatformIO M5Atom BLE HR Sensor Receiver

概要

M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)
開発ツールのインストールについては「M5Atomを開発ツールPlatformIOで使う(M5Atom/Arduino版)」を参照のこと。 (ホストPCとしてはubuntuを想定している)

platformio.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:esp32dev] platform = espressif32 board = m5stick-c framework = arduino monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 lib_ldf_mode = deep+

M5Atom特有のライブラリを使用していないので、ESP32で動作させる場合は 通常のESP32のplatformio.iniで良い。

テスト用スケッチをダウンロードする

cd src wget https://cdn.hackaday.io/files/880553767345120/Pulse.ino

テスト・スケッチ

ダウンロードしたスケッチを以下の修正点に対応して変更する:

修正点:
(1)余計なスペースを削除する
(2)Wrist-TypeのHRセンサー対応を追加する
(3)HRデータを表示する際、タイムスタンプ表示を追加する
(4)LED点滅をコメントアウトする

src/Pluse.ino(編集済み)
#余計なスペースを削除するなど大幅な修正になっているので
#オリジナルを修正するよりも、以下の修正済みのものをコピー&ペーストすることを勧める:

// modified/bufix 2020/8/9 by: xshige #define CHEST //#define WRIST // fix info: // https://github.com/nkolban/esp32-snippets/issues/837 // Using BLE for Heart Rate Monitors, newer belts don't work #837 unsigned long startMillis; /************************************************************************/ /****************** Heart Rate BLE gateway for Technogym ****************/ /************ Outputs a 30 ms pulse at recieved HR frequency ************/ /**************** Indicates the remote HR battery level *****************/ /*********************** Vincent HORN - march 2018 **********************/ /**************************** version 1.0 *******************************/ #include "BLEDevice.h" // Device connection static BLEAddress *pServerAddress; BLEClient* pClient; static boolean doConnect = false; static boolean isconnect = false; // The remote HR service & characteristic static BLEUUID service_HR_UUID(BLEUUID((uint16_t)0x180D)); static BLEUUID char_HR_UUID(BLEUUID((uint16_t)0x2A37)); static BLERemoteCharacteristic* pRemote_HR_Characteristic; const uint8_t notificationOn[] = {0x1, 0x0}; // HR Pulse timer hw_timer_t * timer = NULL; // Timer volatile SemaphoreHandle_t timerSemaphore; // Timer portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;// Timer volatile uint32_t isrCounter = 0; // Timer volatile uint32_t lastIsrAt = 0; // Timer // HR Pulse output int ms_pb = 500; //millis per beat const int pulse_pin = 23; // pulse output pin bool pulse_on = false; // flag when pulse have to be fired unsigned long pulse_off_at = 0; // Time to stop the pulse // The remote BATT service a characteristic static BLEUUID service_BATT_UUID(BLEUUID((uint16_t)0x180F)); static BLEUUID char_BATT_UUID(BLEUUID((uint16_t)0x2A19)); static BLERemoteCharacteristic* pRemote_BATT_Characteristic; // BATT indicator const int battery_scan = 60000; // Scan interval in msec. unsigned long batt_read_start_at = 0; bool batt_indicator = false; // time to indicate de battery level int batt_flash = 0; // number of flash int i_flash = 1; // flash counter bool init_time = true; // flag for init on/off time unsigned long on_at = 0; // Time to turn LED ON unsigned long off_at = 0; // Time to turn LED OFF const int led_pin = 22; // Battery indicator LED static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { uint8_t HR_val = 0; // RAW HR value //< support both Chest/Wrist type 2020/8/9 by: xshige //if (pData[0] == 22 || pData[0] == 6) { if (pData[0] == 16) { // for Chest Type HR sensor (Polar H10) if (pData[1] > 10 && pData[1] < 254) {// HR must be between 10 and 254 bpm HR_val = pData[1]; } else HR_val =0; } else if (pData[0] == 0) { // for Wrist Type HR sensor (Polar A370, OH1) if (pData[1] > 10 && pData[1] < 254) {// HR must be between 10 and 254 bpm HR_val = pData[1]; } else HR_val =0; } else HR_val = 0; //> // display timestamp(sec) unsigned long currentMillis = millis()-startMillis; //Serial.println(pData[0]); Serial.print(currentMillis/1000); Serial.print(": "); // Serial.print("HR : "); Serial.print(HR_val); Serial.print(" bpm \t Battery : "); Serial.print(batt_flash*10); Serial.println(" %"); if (HR_val != 0) {ms_pb = (int)60000/HR_val;} // interval in ms between 2 heart beat if no value (zero) is recieved, ms_pb is set to 100s } bool connectToServer(BLEAddress pAddress) { Serial.print("Forming a connection to "); Serial.println(pAddress.toString().c_str()); // create a new client pClient = BLEDevice::createClient(); Serial.println("Created client"); // Connect to the remove BLE Server. #ifdef CHEST pClient->connect(pAddress, (esp_ble_addr_type_t)1); // bug fix 2020/8/9 (Chest type can be OK) #endif #ifdef WRIST pClient->connect(pAddress); // Chest can Not be OK #endif Serial.println("Connected to server"); // Obtain a reference to the HR service of the remote BLE server. BLERemoteService* pRemote_HR_Service = pClient->getService(service_HR_UUID); if (pRemote_HR_Service == nullptr) { Serial.print("Failed to find HR service : "); //Serial.println(service_HR_UUID.toString().c_str()); return false; } else Serial.println("Found HR service"); // Obtain a reference to the BATT service of the remote BLE server. BLERemoteService* pRemote_BATT_Service = pClient->getService(service_BATT_UUID); if (pRemote_BATT_Service == nullptr) { Serial.print("Failed to find BATT service : "); //Serial.println(service_BATT_UUID.toString().c_str()); return false; } else Serial.println("Found BATT service"); // Obtain a reference to the HR characteristic in the service of the remote BLE server. pRemote_HR_Characteristic = pRemote_HR_Service->getCharacteristic(char_HR_UUID); if (pRemote_HR_Characteristic == nullptr) { Serial.print("Failed to find HR characteristic : "); //Serial.println(char_HR_UUID.toString().c_str()); return false; } else Serial.println("Found HR characteristic"); // Obtain a reference to the BATT characteristic in the service of the remote BLE server. pRemote_BATT_Characteristic = pRemote_BATT_Service->getCharacteristic(char_BATT_UUID); if (pRemote_BATT_Characteristic == nullptr) { Serial.print("Failed to find BATT characteristic : "); //Serial.println(char_BATT_UUID.toString().c_str()); return false; } else Serial.println("Found BATT characteristic"); // Set notification pRemote_HR_Characteristic->registerForNotify(notifyCallback); pRemote_HR_Characteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true); } class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str()); // We have found a device, let us now see if it contains the service we are looking for. if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(service_HR_UUID)) { Serial.println("Found Heart Rate device! "); advertisedDevice.getScan()->stop(); pServerAddress = new BLEAddress(advertisedDevice.getAddress()); doConnect = true; } } }; void device_scan(){ // Retrieve a Scanner and set the callback we want to use to be informed when we // have detected a new device. Specify that we want active scanning and start the // scan to run for 15 seconds. BLEScan* pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); while (!doConnect) { // Scan till a connection is found Serial.println("Scanning for BLE devices ..."); BLEScanResults foundDevices = pBLEScan->start(15); Serial.print("Devices found: "); Serial.println(foundDevices.getCount()); } } void IRAM_ATTR onTimer(){ // Increment the counter and set the time of ISR portENTER_CRITICAL_ISR(&timerMux); isrCounter++; lastIsrAt = millis(); portEXIT_CRITICAL_ISR(&timerMux); // Give a semaphore that we can check in the loop xSemaphoreGiveFromISR(timerSemaphore, NULL); // It is safe to use digitalRead/Write here if you want to toggle an output } void setup() { Serial.begin(115200); Serial.println("------------------------------------------"); Serial.println("Starting Arduino BLE Client application..."); // initialize pulse_pin as an output //pinMode(pulse_pin, OUTPUT); // initialize battery pin led as an output //pinMode(led_pin, OUTPUT); // initialize timer timerSemaphore = xSemaphoreCreateBinary(); // Create semaphore to inform us when the timer has fired timer = timerBegin(0, 80, true); // Attach onTimer function to our timer. timerAttachInterrupt(timer, &onTimer, true); // initialize BLE BLEDevice::init(""); // Scan for devices device_scan(); startMillis = millis(); } void loop() { // If the flag "doConnect" is true then we have scanned for and found the desired BLE Server with which we wish to connect. if (doConnect == true) { if (connectToServer(*pServerAddress)) { Serial.println("Connected to the BLE Server."); isconnect = true; // First timer set to 10 sec. timerAlarmWrite(timer, 10000000, true); timerAlarmEnable(timer); } else { Serial.println("We have failed to connect to the server; there is nothin more we will do."); isconnect = false; } doConnect = false; } // when interrupt occurres if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){ uint32_t isrCount = 0, isrTime = 0; // Read the interrupt count and time portENTER_CRITICAL(&timerMux); isrTime = lastIsrAt; isrCount = isrCounter; portEXIT_CRITICAL(&timerMux); // create a 30 ms pulse on pulse_pin pulse_on = true; pulse_off_at = millis() + 30; //digitalWrite(pulse_pin, HIGH); //delay(30); //digitalWrite(pulse_pin, LOW); // rearm the timer with previous incomming ms per beat (ms_pb) value timerAlarmDisable(timer); timerAlarmWrite(timer, 1000*ms_pb, true); timerAlarmEnable(timer); /* Serial.print("at "); Serial.print(isrTime); Serial.print(" ms"); Serial.print("\t new timer "); Serial.print(ms_pb); Serial.println(" ms"); */ } // Create Pulse if (pulse_on) { if (millis() < pulse_off_at) { //digitalWrite(PULSE_PIN, HIGH); // turn the LED on (HIGH is the voltage level) } else { //digitalWrite(PULSE_PIN, LOW); // turn the LED off by making the voltage LOW pulse_on = false; } } // Read the value of the battery level characteristic each battery_scan ms (only if connected) if (isconnect && (millis()-batt_read_start_at > battery_scan)) { std::string value = pRemote_BATT_Characteristic->readValue(); String batt_caracteristic = value.c_str(); // convert string to char char buf[2]; batt_caracteristic.toCharArray(buf, 2); // BATT_val is the numeric ASCII value int BATT_val = int(buf[0]); // batt_flash number of flash (30% battery => 3 flashs) batt_flash = (int)BATT_val/10; // fire the LED batt_indicator = true; batt_read_start_at = millis(); } // Battery indicator if (batt_indicator){ if (i_flash <= batt_flash){ if (init_time){ off_at = millis() + 40; on_at = off_at + 500; init_time = false; } if (millis() <= off_at){ digitalWrite(led_pin, HIGH); } if ((millis() > off_at) && (millis() <= on_at)){ digitalWrite(led_pin, LOW); } else if (millis() > on_at){ init_time = true; i_flash++; } } else { i_flash = 1; batt_indicator = false; } } // Watch if client is still connected. When not reboot ESP32 if (pClient->isConnected() == false) { Serial.println("Device disconnected ! ESP 32 rebooting ....."); ESP.restart(); } }

使用するHRセンサーのタイプで以下の#defineのうち一つを有効にして、コンパイル&実行する。

#define CHEST #define WRIST

書き込み後、実行するとBLEデバイスをスキャンしてHRセンサーが見つかれば自動的にペアリングして、HRデータを表示する。 既にHRセンサーが(スマフォなどと)ペアリング済みだと接続できないので、その場合、該当のスマフォのペアリングを解除する。

出力例:(Polar A370の場合)

picocom /dev/ttyUSB0 -b115200 Starting Arduino BLE Client application... Scanning for BLE devices ... BLE Advertised Device found: Name: Polar A370 1D44A125, Address: a0:9e:1a:1d:44:a1, manufacturer data: 6b002f0000, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb Found Heart Rate device! Devices found: 1 Forming a connection to a0:9e:1a:1d:44:a1 Created client Connected to server Found HR service Found BATT service Found HR characteristic Found BATT characteristic Connected to the BLE Server. 1: HR : 69 bpm Battery : 0 % 2: HR : 69 bpm Battery : 0 % 3: HR : 70 bpm Battery : 0 % 4: HR : 70 bpm Battery : 0 % 5: HR : 69 bpm Battery : 0 % 6: HR : 69 bpm Battery : 0 % 7: HR : 70 bpm Battery : 0 % 8: HR : 70 bpm Battery : 0 % 9: HR : 70 bpm Battery : 0 % # バッテリ残量が0%なのは、バッテリ残量を取得するのに時間がかかるせいのようだ。 # 待っていると自動的に表示されるようになる。

出力例:(Polar H10の場合)

picocom /dev/ttyUSB0 -b115200 Starting Arduino BLE Client application... Scanning for BLE devices ... BLE Advertised Device found: Name: , Address: 7d:01:bf:c3:6f:ff, manufacturer data: 4c0010050318e24cea BLE Advertised Device found: Name: Polar H10 31BFD72E, Address: fd:e0:ff:99:cc:1e, manufacturer data: 6b00330c4243 Devices found: 2 Scanning for BLE devices ... BLE Advertised Device found: Name: , Address: fd:e0:ff:99:cc:1e, manufacturer data: 6b002f0c4343, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb, txPower: 4 Found Heart Rate device! Devices found: 1 Forming a connection to fd:e0:ff:99:cc:1e Created client Connected to server Found HR service Found BATT service [E][BLERemoteCharacteristic.cpp:274] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown Found HR characteristic Found BATT characteristic Connected to the BLE Server. 2: HR : 67 bpm Battery : 0 % 3: HR : 66 bpm Battery : 0 % 4: HR : 66 bpm Battery : 0 % 5: HR : 66 bpm Battery : 0 % 6: HR : 66 bpm Battery : 0 % 7: HR : 66 bpm Battery : 0 % 8: HR : 66 bpm Battery : 0 % 9: HR : 67 bpm Battery : 0 % # バッテリ残量が0%なのは、バッテリ残量を取得するのに時間がかかるせいのようだ。 # 待っていると自動的に表示されるようになる。

参考情報

https://hackaday.io/project/88055-technogym-new-heart-rate-ble-sensor
Technogym : new Heart Rate BLE sensor
Replace the RF HR receiver with a new BLE sensor based on ESP32.

Web-BluetoothでHRセンサーを接続する
Web-Bluetooth:HR(心拍)センサーのロガー
Web-Bluetooth:CSC(自転車)センサーのロガー

PlatformIO Core (CLI)

以上

続きを読む "M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)"

| | コメント (0)