diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.vscode/arduino.json b/.vscode/arduino.json old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/_static/custom.css b/_static/custom.css new file mode 100755 index 0000000..acd885c --- /dev/null +++ b/_static/custom.css @@ -0,0 +1,23 @@ +/* ナビゲーションバーの背景色を変更 */ +.wy-nav-top { + background-color: #6600ff !important; /* オレンジ */ +} + +/* サイドバーの背景色を変更 */ +.wy-side-nav-search { + background-color: #6688aa !important; /* 濃い青 */ +} + +/* リンクの色を変更 */ +.wy-menu-vertical a { + color: #006699 !important; /* 緑系 */ +} +.wy-menu-vertical a:hover { + background-color: #aaccff; +} + +.wy-nav-side { + background: #ccddee; +} + + diff --git a/appendix.rst b/appendix.rst index b45ad0c..b5666d9 100755 --- a/appendix.rst +++ b/appendix.rst @@ -59,6 +59,8 @@ https://notify-bot.line.me/ja/ で、トークンを取得しておく必要があります。 +**2025年3月31日をもって、** `LINE Notify `_ **のサービスは終了しました。** + .. literalinclude:: src/line01.ino :caption: diff --git a/cheatsheet.txt b/cheatsheet.txt old mode 100644 new mode 100755 diff --git a/conf.py b/conf.py index 376280e..74cd9a3 100755 --- a/conf.py +++ b/conf.py @@ -18,7 +18,7 @@ # -- Project information ----------------------------------------------------- project = 'IoT Programming' -copyright = '2021-2023, Motoki Miura' +copyright = '2021-2025, Motoki Miura' author = 'Motoki Miura' diff --git a/images/._biohazard.png b/images/._biohazard.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/._lcd_sample.png b/images/._lcd_sample.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/._pwm.jpg b/images/._pwm.jpg old mode 100644 new mode 100755 Binary files differ diff --git a/images/._servohat.png b/images/._servohat.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/._setRotation.gif b/images/._setRotation.gif old mode 100644 new mode 100755 Binary files differ diff --git a/images/SimpleLED_m5s.png b/images/SimpleLED_m5s.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/biohazard.png b/images/biohazard.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/board_manager_esp32.png b/images/board_manager_esp32.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/board_manager_esp32_installed.png b/images/board_manager_esp32_installed.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/build_factorytest.png b/images/build_factorytest.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/build_factorytest_finished.png b/images/build_factorytest_finished.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/ipconfig.png b/images/ipconfig.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/ir_sensor.png b/images/ir_sensor.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/ir_sensor_47owm.png b/images/ir_sensor_47owm.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/isprime.c b/images/isprime.c old mode 100644 new mode 100755 diff --git a/images/lcd_sample.png b/images/lcd_sample.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/library_manager_m5stickcplus.png b/images/library_manager_m5stickcplus.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/menu_file_sketchexample_m5stick_factory.png b/images/menu_file_sketchexample_m5stick_factory.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/menu_tool_board_esp32_m5stickc.png b/images/menu_tool_board_esp32_m5stickc.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/pwm.jpg b/images/pwm.jpg old mode 100644 new mode 100755 Binary files differ diff --git a/images/select_serialport.png b/images/select_serialport.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/servohat.png b/images/servohat.png old mode 100644 new mode 100755 Binary files differ diff --git a/images/setRotation.gif b/images/setRotation.gif old mode 100644 new mode 100755 Binary files differ diff --git a/img/22_0323_143952.png b/img/22_0323_143952.png old mode 100644 new mode 100755 Binary files differ diff --git a/img/22_0323_144455.png b/img/22_0323_144455.png old mode 100644 new mode 100755 Binary files differ diff --git a/img/22_0323_151537.png b/img/22_0323_151537.png old mode 100644 new mode 100755 Binary files differ diff --git a/img/22_0323_154834.png b/img/22_0323_154834.png old mode 100644 new mode 100755 Binary files differ diff --git a/index.rst b/index.rst index e0f889d..74a5a14 100755 --- a/index.rst +++ b/index.rst @@ -15,9 +15,7 @@ :caption: Contents: intro - pre2023 - pre2022 - pre2021 + pre2025 week1 week2 git diff --git a/intro.rst b/intro.rst index da2c756..7187598 100755 --- a/intro.rst +++ b/intro.rst @@ -54,8 +54,12 @@ ========================================== - arduino-cli https://arduino.github.io/arduino-cli/ -- arduino-cli コマンドリファレンス https://arduino.github.io/arduino-cli/0.35/commands/arduino-cli/ +- arduino-cli コマンドリファレンス https://arduino.github.io/arduino-cli/1.2/commands/arduino-cli/ - M5StickC非公式日本語リファレンス https://lang-ship.com/reference/unofficial/M5StickC +- スイッチサイエンス M5StickC Plus2 https://www.switch-science.com/catalog/9350 - スイッチサイエンス M5StickC Plus https://www.switch-science.com/catalog/6470 - M5StickCガイド https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/M5StickC_Guide_Japanese.pdf +- **三浦の2024までの資料 (M5StickCPlus)** https://cit.istlab.info/m5stickcplus/ + - 上記では、 ``arduino-cli core install esp32:esp32@2.0.17`` ``M5StickCPlus2.h`` を用いています。 + diff --git a/make.bat b/make.bat old mode 100644 new mode 100755 diff --git a/pre2025.rst b/pre2025.rst new file mode 100644 index 0000000..348c7dd --- /dev/null +++ b/pre2025.rst @@ -0,0 +1,60 @@ +.. _00_pre2025: + +事前準備 (2025年度) +============================================================================== + +`M5StickC Plus2 `_ に、プログラムを書き込むには、 +おもに以下の方法があります。 + +1. Arduino IDE +#. arduino-cli (Command-Line Interface) +#. PlatformIO + +2024年度は `2. の方法 および 独自プログラムIoTP `_ を用いました。 +2025年度も、基本的に 2. の方法で、各自のパソコンに arduino-cli を入れてもらいますが、Windowsだとやたらとビルドに時間がかかるので `講義システム `_ を併用します。 +講義システムでは、Webインタフェースで編集したコードを **サーバ上で** ビルドし、書き込み用のバイナリファイルをダウンロードできます。 +複数のソースファイルやデータを含む複雑なプロジェクトを作成する場合は、`m5scp2_exe `_ のなかの FactoryTest を参考にしてください。また、`Arduino IDE `_ や Visual Studio Code 等を入れてください。 + +.. note:: 以下の手順は、なるべく簡便に環境構築を行えるよう、事前に教員が準備したスクリプトを実行するものです。 + + + +Windows の場合 +~~~~~~~~~~~~~~~~~ + +1. `Git for Windows `_ をインストールしてください。Setup時にいろいろ訊かれますが、すべてそのまま「Next」を押して進めて大丈夫です。 +#. Git Bash を起動して、ターミナル(例: :numref:`fig_cli_iotinst` )に以下のコマンドを入力してください。(この下の灰色のテキストエリアの右端の四角アイコンを押すと、コマンドをコピーできます。) :: + + curl -fsSL istlab.info/iotinst | sh + + +.. _fig_cli_iotinst: + +.. figure:: img/22_0323_144455.png + :scale: 90% + :alt: インストールスクリプト実行後の画面(例) + :name: f_cli_iotinst + + インストールスクリプト実行後の画面(例) + + + +Mac の場合 +~~~~~~~~~~~~~~~~~~ + +1. `Homebrew パッケージマネージャ `_ をまだ入れていない場合は、インストールしてください。ターミナルを開き、以下のコマンドを実行します。 :: + + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + +#. 続けて、ターミナルで、以下のコマンドを実行してください。 ::  + + brew update + brew install git + + curl -fsSL istlab.info/iotinst | sh + + + + + diff --git a/src/TestBuild/arduino-cli.yaml b/src/TestBuild/arduino-cli.yaml old mode 100644 new mode 100755 diff --git a/src/TestBuild/build/esp32.esp32.m5stick-c/TestBuild.ino.partitions.bin b/src/TestBuild/build/esp32.esp32.m5stick-c/TestBuild.ino.partitions.bin old mode 100644 new mode 100755 Binary files differ diff --git a/src/TestBuild/coin05_16k.ino b/src/TestBuild/coin05_16k.ino old mode 100644 new mode 100755 diff --git a/src/TestBuild/coin05_8k.ino b/src/TestBuild/coin05_8k.ino old mode 100644 new mode 100755 diff --git a/src/accgyro.ino b/src/accgyro.ino old mode 100644 new mode 100755 diff --git a/src/analogread.ino b/src/analogread.ino old mode 100644 new mode 100755 diff --git a/src/bts01_master.ino b/src/bts01_master.ino old mode 100644 new mode 100755 diff --git a/src/bts01_showmac.ino b/src/bts01_showmac.ino old mode 100644 new mode 100755 diff --git a/src/bts01_slave.ino b/src/bts01_slave.ino old mode 100644 new mode 100755 diff --git a/src/button01.ino b/src/button01.ino old mode 100644 new mode 100755 index c125448..7674e5a --- a/src/button01.ino +++ b/src/button01.ino @@ -1,23 +1,28 @@ -#include +#include +#include void setup() { - M5.begin(); - M5.Lcd.setRotation(3); + auto cfg = M5.config(); + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setTextScroll(true); + M5.Display.setTextFont(1); + M5.Display.println("started!!"); } void loop() { M5.update(); // 各ボタンの状態を(読み取って)更新する:ボタンを判定するときは必須。 if (M5.BtnA.wasReleasefor(1000) ) { - Serial.println("[A] was Pressed longer than 1s"); + M5.Display.println("[A] was Pressed longer than 1s"); } else if (M5.BtnA.wasReleased()) { - Serial.println("[A] was Pressed"); + M5.Display.println("[A] was Pressed"); } else if (M5.BtnB.wasReleasefor(1000) ) { - Serial.println("[B] was Pressed longer than 1s"); + M5.Display.println("[B] was Pressed longer than 1s"); } else if (M5.BtnB.wasReleased()) { - Serial.println("[B] was Pressed"); - } else if (M5.Axp.GetBtnPress() == 2) { - Serial.println("[Power] was Pressed"); + M5.Display.println("[B] was Pressed"); + } else if (M5.BtnPWR.wasReleased()) { + M5.Display.println("[Pwr] was Pressed"); } delay(10); } \ No newline at end of file diff --git a/src/cds01.ino b/src/cds01.ino old mode 100644 new mode 100755 diff --git a/src/coin05_16k.ino.txt b/src/coin05_16k.ino.txt old mode 100644 new mode 100755 diff --git a/src/coin05_8k.ino.txt b/src/coin05_8k.ino.txt old mode 100644 new mode 100755 diff --git a/src/doget.js b/src/doget.js old mode 100644 new mode 100755 diff --git a/src/env2.ino b/src/env2.ino old mode 100644 new mode 100755 diff --git a/src/espnow01.ino b/src/espnow01.ino old mode 100644 new mode 100755 diff --git a/src/espnow02.ino b/src/espnow02.ino old mode 100644 new mode 100755 index f2f9147..fa0a4ba --- a/src/espnow02.ino +++ b/src/espnow02.ino @@ -1,109 +1,78 @@ -#include "M5StickCPlus.h" -#include -#include - -esp_now_peer_info_t peerInfo; -int line = 0; - -void Init_ESPNOW() -{ // ESPNowの初期化 - // 引用: https://101010.fun/iot/esp32-m5stickc-plus-esp-now.html - WiFi.mode(WIFI_STA); - WiFi.disconnect(); - if (esp_now_init() == ESP_OK) - { - M5.Lcd.println("ESP-Now Init Success"); - } - else - { - M5.Lcd.println("ESP-Now Init failed"); - ESP.restart(); - } - // マルチキャスト用Slave登録 - memset(&peerInfo, 0, sizeof(peerInfo)); - for (int i = 0; i < 6; ++i) - { - peerInfo.peer_addr[i] = (uint8_t)0xff; - } - esp_err_t addStatus = esp_now_add_peer(&peerInfo); - if (addStatus == ESP_OK) - { - // Pair success - M5.Lcd.println("Pair success"); - esp_now_register_send_cb(onESPNOWSent); //送信後のコールバック関数を指定する - esp_now_register_recv_cb(onESPNOWReceive); ///受信時のコールバック関数を指定する - } -} -// データを送信した後に実行されるコールバック関数 -// 引用: https://101010.fun/iot/esp32-m5stickc-plus-esp-now.html -void onESPNOWSent(const uint8_t *mac_addr, esp_now_send_status_t status) -{ - // char macStr[18]; - // snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", - // mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - line++; - if (line > 3) - { - M5.Lcd.fillScreen(YELLOW); - M5.Lcd.setCursor(0, 0, 1); - line = 0; - M5.Beep.tone(2000, 500); - } - else - { - M5.Beep.tone(1000, 500); - } - M5.Lcd.setTextColor(BLACK, GREEN); - - M5.Lcd.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); -} - -// データを受け取った時に実行されるコールバック関数 -void onESPNOWReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len) -{ - char macStr[18]; - snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - // Serial.println(); - // Serial.printf("Last Packet Recv from: %s\n", macStr); - // Serial.printf("Last Packet Recv Data(%d): ", data_len); - if (data[0] == 100 && data[1] == 254) // 100,254に深い意味はない。uint8_tは0〜255の数値 - { - line++; - if (line > 3) - { - M5.Beep.tone(2000, 1000); - M5.Lcd.fillScreen(YELLOW); - M5.Lcd.setCursor(0, 0, 1); - line = 0; - } - M5.Lcd.setTextColor(BLACK, CYAN); - - M5.Lcd.printf(" %s\n", macStr); - M5.Lcd.printf("Data: %d %d\n", data[0], data[1]); - } -} - -void setup() -{ - M5.begin(); - M5.Lcd.setRotation(3); - M5.Lcd.fillScreen(YELLOW); - - M5.Lcd.setTextColor(BLACK, YELLOW); - M5.Lcd.setCursor(0, 0, 1); - M5.Lcd.setTextSize(2); - - Init_ESPNOW(); -} -void loop() -{ - M5.update(); - M5.Beep.update(); - if (M5.BtnA.wasReleased()) - { - uint8_t data[2] = {100, 254}; // 送信データ  100, 254に深い意味はない。uint8_tは0〜255の数値 - esp_err_t result = esp_now_send(peerInfo.peer_addr, data, sizeof(data)); - } - delay(20); -} +#include +#include +#include + +esp_now_peer_info_t peerInfo; + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // ボーレートを115200に設定 + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("ESPNOW 02"); + M5.Display.setTextScroll(true); + Init_ESPNOW(); +} + +void loop() { + M5.update(); + if (M5.BtnA.wasReleased()) { + uint8_t data[2] = {100, 254}; // 送信データ  100, 254に深い意味はない。uint8_tは0〜255の数値 + esp_err_t result = esp_now_send(peerInfo.peer_addr, data, sizeof(data)); + } + M5.delay(20); +} + +void Init_ESPNOW() +{ // ESPNowの初期化 + // 引用: https://101010.fun/iot/esp32-m5stickc-plus-esp-now.html + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + if (esp_now_init() == ESP_OK) + { + M5.Display.println("ESP-Now Init Success"); + } + else + { + M5.Display.println("ESP-Now Init failed"); + } + // マルチキャスト用Slave登録 + memset(&peerInfo, 0, sizeof(peerInfo)); + for (int i = 0; i < 6; ++i) + { + peerInfo.peer_addr[i] = (uint8_t)0xff; + } + esp_err_t addStatus = esp_now_add_peer(&peerInfo); + if (addStatus == ESP_OK) + { + // Pair success + M5.Display.println("Pair success"); + esp_now_register_send_cb(onESPNOWSent); //送信後のコールバック関数を指定する + esp_now_register_recv_cb(onESPNOWReceive); ///受信時のコールバック関数を指定する + } +} +// データを送信した後に実行されるコールバック関数 +// 引用: https://101010.fun/iot/esp32-m5stickc-plus-esp-now.html +void onESPNOWSent(const uint8_t *mac_addr, esp_now_send_status_t status) +{ + // char macStr[18]; + // snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", + // mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + M5.Display.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); +} + +// データを受け取った時に実行されるコールバック関数 +void onESPNOWReceive(const esp_now_recv_info_t *recv_info, const uint8_t *data, int data_len) +{ + char macStr[18]; + snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", + recv_info->src_addr[0], recv_info->src_addr[1], recv_info->src_addr[2], + recv_info->src_addr[3], recv_info->src_addr[4], recv_info->src_addr[5]); + + if (data[0] == 100 && data[1] == 254) // 100,254に深い意味はない。uint8_tは0〜255の数値 + { + M5.Display.printf(" %s\n", macStr); + M5.Display.printf("Data: %d %d\n", data[0], data[1]); + } +} \ No newline at end of file diff --git a/src/factorytest.ino b/src/factorytest.ino old mode 100644 new mode 100755 diff --git a/src/httpclient01.ino b/src/httpclient01.ino old mode 100644 new mode 100755 diff --git a/src/httpserver01.ino b/src/httpserver01.ino old mode 100644 new mode 100755 diff --git a/src/imu01.ino b/src/imu01.ino new file mode 100644 index 0000000..16ed974 --- /dev/null +++ b/src/imu01.ino @@ -0,0 +1,26 @@ +#include + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("IMU Inertial Measurement Unit: 慣性計測装置"); +} + +void loop() { + M5.update(); + auto imu_update = M5.Imu.update(); + if (imu_update) { + m5::IMU_Class::imu_data_t data = M5.Imu.getImuData(); + M5.Display.setCursor(0, 40); // x,y,fonttype + + M5.Display.printf("加速度 傾↑↓:%7.2f ←→:%7.2f 垂直:%7.2f\n", data.accel.x , data.accel.y , data.accel.z ); + Serial.printf("%7.2f , %7.2f , %7.2f \n", data.accel.x , data.accel.y , data.accel.z); //ArduinoIDE シリアルプロッタ用の出力 + + M5.Display.printf("ジャイロ X:%7.2f Y:%7.2f Z:%7.2f \n", data.gyro.x, data.gyro.y, data.gyro.z); + // Serial.printf("%7.2f,%7.2f,%7.2f,", gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes); + } + M5.delay(10); +} \ No newline at end of file diff --git a/src/irsend01.ino b/src/irsend01.ino old mode 100644 new mode 100755 diff --git a/src/irsend02.ino b/src/irsend02.ino old mode 100644 new mode 100755 diff --git a/src/lcd01.ino b/src/lcd01.ino old mode 100644 new mode 100755 index 123ecda..e56bebb --- a/src/lcd01.ino +++ b/src/lcd01.ino @@ -1,35 +1,39 @@ -#include +#include +#include void setup() { - M5.begin(); - M5.Lcd.setRotation(3); - M5.Lcd.fillRect(0, 0, 240, 135, RED); + auto cfg = M5.config(); + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.fillRect(0, 0, 240, 135, RED); //M5StickCPlusの画面サイズは、240 x 135 - M5.Lcd.fillRect(10, 10, 220, 115, ORANGE); - M5.Lcd.fillRect(20, 20, 200, 95, YELLOW); - M5.Lcd.fillRect(30, 30, 180, 75, GREENYELLOW); - M5.Lcd.fillRect(40, 40, 160, 55, CYAN); - M5.Lcd.fillRect(50, 50, 140, 35, BLUE); - M5.Lcd.fillRect(60, 60, 120, 15, MAGENTA); + M5.Display.fillRect(10, 10, 220, 115, ORANGE); + M5.Display.fillRect(20, 20, 200, 95, YELLOW); + M5.Display.fillRect(30, 30, 180, 75, GREENYELLOW); + M5.Display.fillRect(40, 40, 160, 55, CYAN); + M5.Display.fillRect(50, 50, 140, 35, BLUE); + M5.Display.fillRect(60, 60, 120, 15, MAGENTA); - M5.Lcd.setTextFont(1); // 8pixel ASCII font - M5.Lcd.setTextSize(1); // Magnify (x1-7) - M5.Lcd.setTextColor(WHITE); - M5.Lcd.setCursor(10,1); M5.Lcd.print("RED"); - M5.Lcd.setTextColor(BLACK); - M5.Lcd.setCursor(20,11); M5.Lcd.print("ORANGE"); - M5.Lcd.setCursor(30,21); M5.Lcd.print("YELLOW"); - M5.Lcd.setCursor(40,31); M5.Lcd.print("GREENYELLOW"); - M5.Lcd.setCursor(50,41); M5.Lcd.print("CYAN"); - M5.Lcd.setTextColor(WHITE); - M5.Lcd.setCursor(60,51); M5.Lcd.print("BLUE"); - M5.Lcd.setCursor(70,60,2); M5.Lcd.print("MAGENTA (2)"); + M5.Display.setTextFont(1); // 8pixel ASCII font + M5.Display.setTextSize(1); // Magnify (x1-7) + M5.Display.setTextColor(WHITE); + M5.Display.setCursor(10,1); M5.Lcd.print("RED"); + M5.Display.setTextColor(BLACK); + M5.Display.setCursor(20,11); M5.Lcd.print("ORANGE"); + M5.Display.setCursor(30,21); M5.Lcd.print("YELLOW"); + M5.Display.setCursor(40,31); M5.Lcd.print("GREENYELLOW"); + M5.Display.setCursor(50,41); M5.Lcd.print("CYAN"); + M5.Display.setTextColor(WHITE); + M5.Display.setCursor(60,51); M5.Lcd.print("BLUE"); + M5.Display.setCursor(70,60,2); M5.Lcd.print("MAGENTA (2)"); // setCursorの第3引数は、TextFont番号 - M5.Lcd.setTextColor(BLACK); - M5.Lcd.setCursor(30,90,4); M5.Lcd.print("26pixel ASCII (4)"); + M5.Display.setTextColor(BLACK); + M5.Display.setCursor(30,90,4); + M5.Display.print("26pixel ASCII (4)"); } void loop() { + M5.delay(100); } \ No newline at end of file diff --git a/src/led01.ino b/src/led01.ino old mode 100644 new mode 100755 index 4149c43..8f57a86 --- a/src/led01.ino +++ b/src/led01.ino @@ -1,15 +1,24 @@ -int PIN = 10; // 赤色LED G10 -//int PIN = 9; // Ir LED (カメラには映りますが、肉眼では見えません) G9 -// その他、G0 (0) , G25 (25), G26 (26) がつかえます。 -// https://lang-ship.com/blog/work/m5stickc-io/ +#include +#include + +#define PIN 19 // 赤色LED G19 void setup() { + auto cfg = M5.config(); + M5.begin(cfg); + M5.Display.setRotation(3); + pinMode(PIN, OUTPUT); // PINのモード設定 + + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("led01 (LEDが点滅するデモ)"); + M5.Display.setTextScroll(true); } void loop() { digitalWrite(PIN, HIGH); // HIGH = 1 - delay(1000); + M5.delay(1000); digitalWrite(PIN, LOW); // LOW = 0 - delay(500); + M5.delay(1000); } \ No newline at end of file diff --git a/src/line01.ino b/src/line01.ino old mode 100644 new mode 100755 diff --git a/src/mqtt01pub.ino b/src/mqtt01pub.ino old mode 100644 new mode 100755 index 1920578..0e1d3e9 --- a/src/mqtt01pub.ino +++ b/src/mqtt01pub.ino @@ -1,79 +1,95 @@ -// MQTT Publisher example -//#include -#include -// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ -#include - -const char* ssid = "ics-ap"; -const char* password = "jikkenics"; - -const char* server = "mqtt.istlab.info"; -const int port = 1883; -const char* pubTopic = "jikken"; // 班名を入れれば他の班とかぶらない。+にはしない。ex. jikken/A4han - -WiFiClient wifiClient; -char* clientid = "m5stickc01_00000002"; //デバイス個別に設定すればなんでもよい -PubSubClient mqttClient(wifiClient); // MQTT Client - -void setup() { - // M5.begin(); - Serial.begin(115200); - WiFi.begin(ssid, password); - while ( WiFi.status() != WL_CONNECTED ) { // 接続中... - Serial.print("."); - delay(200); - } - Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス - - mqttClient.setServer(server, port); - - if ( !mqttClient.connected() ) { - Serial.println("Try connecting MQTT ..."); - reconnect(); - } - - // 参考:WiFiデバイスのMACアドレスを取得し、送信する - uint8_t mac[6]; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - char mbuf[100]; - sprintf(mbuf, "Message from %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); - - mqttClient.publish( pubTopic , mbuf ); // MQTT publish message - Serial.println(mbuf); //送信した内容をシリアルに表示して確認 - - Serial.println("publishするメッセージをSerialから送信してください"); -} - -void loop() { - // シリアルコンソールから書き込みがあれば, publishする - char mbuf[100]; int pos = 0; - while ( Serial.available() ) { // ノンブロッキング - mbuf[pos] = Serial.read(); - pos++; - } - if (pos > 0) { - mbuf[pos-1] = 0; //改行をNULLに置き換える - Serial.println(mbuf); - if ( !mqttClient.connected() ) reconnect(); - // ブローカにデータを送信する。最後の false を true にすると、retained になる。 - // boolean ret = mqttClient.publish( pubTopic , mbuf, size, false ); - mqttClient.publish( pubTopic , mbuf ); - // if ( !ret ){ - // Serial.println("publish failed."); - // } - } - delay(100); -} - -void reconnect() { - while ( !mqttClient.connected() ) { - if ( mqttClient.connect(clientid) ) { - Serial.println("Connected to MQTT Broker."); - } else { - Serial.printf("Connect Failed. state=%d", mqttClient.state()); - } - } -} - - - +#include +#include +// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ +#include + +const char* ssid = "ics-ap"; +const char* password = "jikkenics"; + +const char* server = "mqtt.istlab.info"; +const int port = 1883; +const char* pubTopic = "jikken"; // 班名を入れれば他の班とかぶらない。+にはしない。ex. jikken/A4han + +WiFiClient wifiClient; +char* clientid = "m5scp2_001"; //デバイス個別に設定すればなんでもよい +PubSubClient mqttClient(wifiClient); // MQTT Client + +char macaddr[100]; + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("mqtt01pub"); + M5.Display.setTextScroll(false); + + WiFi.begin(ssid, password); // 接続開始 + while (WiFi.status() != WL_CONNECTED) { // 接続中... + M5.Display.print("."); + M5.delay(500); + } + // 接続完了!! + M5.Display.fillScreen(CYAN); + M5.Display.setCursor(0, 8, 4);//x,y,fonttype + M5.Display.setTextColor(BLACK, CYAN); + M5.Display.print(" Wifi Connected!\n"); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + + mqttClient.setServer(server, port); + if ( !mqttClient.connected() ) { + Serial.println("Try connecting MQTT..."); + reconnect(); + } + // 参考:WiFiデバイスのMACアドレスを取得し、送信する + uint8_t mac[6]; + WiFi.macAddress(mac); + sprintf(macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); + M5.Display.println(macaddr); + + M5.delay(2000); + Serial.println("publishするメッセージをSerialから送信してください。またはAボタンを押してください。"); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("publishするメッセージをSerialから送信してください。またはAボタンを押してください。"); +} + +void loop() { + // シリアルコンソールから書き込みがあれば, publishする + char mbuf[100]; int pos = 0; + while ( Serial.available() ) { // ノンブロッキング + mbuf[pos] = Serial.read(); + pos++; + } + if (pos > 0) { + mbuf[pos-1] = 0; //改行をNULLに置き換える + Serial.println(mbuf); + if ( !mqttClient.connected() ) reconnect(); + // ブローカにデータを送信する。最後の false を true にすると、retained になる。 + // boolean ret = mqttClient.publish( pubTopic , mbuf, size, false ); + boolean ret = mqttClient.publish( pubTopic , mbuf ); + if ( !ret ){ + Serial.println("publish failed."); + } + } + M5.update(); // ボタン読み取りの前にはupdateが必要 + if (M5.BtnA.wasReleased()) { + if ( !mqttClient.connected() ) reconnect(); + boolean ret = mqttClient.publish( pubTopic , macaddr ); + if ( !ret ){ + Serial.println("publish failed."); + } + } + M5.delay(50); +} + +void reconnect() { + while ( !mqttClient.connected() ) { + if ( mqttClient.connect(clientid) ) { + Serial.println("Connected to MQTT Broker."); + } else { + Serial.printf("Connect Failed. state=%d", mqttClient.state()); + } + } +} \ No newline at end of file diff --git a/src/mqtt01sub.ino b/src/mqtt01sub.ino old mode 100644 new mode 100755 index 48da129..521fec1 --- a/src/mqtt01sub.ino +++ b/src/mqtt01sub.ino @@ -1,83 +1,95 @@ -// MQTT Subscriber example -// #include -#include -// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★ -#include -// ライブラリで ArduinoJson v6.xをいれておく ★★★ 重要 ★★★ -// (注意:Arduino_Json v0.1.0 は別物) -#include - -const char* ssid = "ics-ap"; -const char* password = "jikkenics"; - -const char* server = "mqtt.istlab.info"; -const int port = 1883; -const char* pubTopic = "+"; // 例: ex1/groupXX/sensor - -WiFiClient wifiClient; -char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい -PubSubClient mqttClient(wifiClient); // MQTT Client - -void setup() { - // M5.begin(); - Serial.begin(115200); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { // 接続中... - Serial.print("."); - delay(200); - } - Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス - // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる - // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい) - // uint8_t mac[6]; - // esp_read_mac(mac, ESP_MAC_WIFI_STA); - // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X", - // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); - mqttClient.setServer(server, port); - mqttClient.setCallback(callback_on_subscribe); - - if (!mqttClient.connected()) { - Serial.println("Try (re)connecting..."); - reconnect(); - } - mqttClient.subscribe(pubTopic); - -} - -void loop() { - - mqttClient.loop(); // データがpublishされたら、callback_on_subscribe が呼ばれる - - delay(100); -} - -void reconnect() { - while (!mqttClient.connected()) { - if (mqttClient.connect(clientid)) { - Serial.println("Connected to MQTT Broker."); - } else { - Serial.printf("Connect Failed. state=%d", mqttClient.state()); - } - } -} - -// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため) -void callback_on_subscribe(char* topic, byte* payload, unsigned int len) { - char buf[100]; - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - for (int i = 0; i < len ; i++) { - buf[i] = (char)payload[i]; - } - buf[len] = 0; - Serial.println(buf); - return; - // 参考:JSON Parsing example - // StaticJsonDocument<200> sjdoc; - // deserializeJson(sjdoc, buf); - // int intval = sjdoc["intval"]; - // const char* str = sjdoc["string"]; -} - - +#include +#include +#include +#include + +const char* ssid = "ics-ap"; +const char* password = "jikkenics"; + +const char* server = "mqtt.istlab.info"; +const int port = 1883; +const char* pubTopic = "+"; // 班名を入れれば他の班とかぶらない。+にはしない。ex. jikken/A4han + +WiFiClient wifiClient; +char* clientid = "m5scp2_002"; //デバイス個別に設定すればなんでもよい +PubSubClient mqttClient(wifiClient); // MQTT Client + +char macaddr[100]; + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("mqtt01sub"); + M5.Display.setTextScroll(true); + + WiFi.begin(ssid, password); // 接続開始 + while (WiFi.status() != WL_CONNECTED) { // 接続中... + M5.Display.print("."); + M5.delay(500); + } + // 接続完了!! + M5.Display.fillScreen(BLUE); + M5.Display.setCursor(0, 8, 4);//x,y,fonttype + M5.Display.setTextColor(WHITE, BLUE); + M5.Display.print(" Wifi Connected!\n"); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + + // 参考:WiFiデバイスのMACアドレスを取得し、送信する + uint8_t mac[6]; + WiFi.macAddress(mac); + sprintf(macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); + M5.Display.println(macaddr); + + mqttClient.setServer(server, port); + mqttClient.setCallback(callback_on_subscribe); + + if (!mqttClient.connected()) { + Serial.println("Try (re)connecting..."); + reconnect(); + } + mqttClient.subscribe(pubTopic); + + M5.delay(2000); + Serial.println("自動的にsubscribeします。Serialと画面に出力します。"); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("自動的にsubscribeします。Serialと画面に出力します。"); +} + +void loop() { + mqttClient.loop(); // データがpublishされたら、callback_on_subscribe が呼ばれる + M5.delay(50); +} + +void reconnect() { + while ( !mqttClient.connected() ) { + if ( mqttClient.connect(clientid) ) { + Serial.println("Connected to MQTT Broker."); + } else { + Serial.printf("Connect Failed. state=%d", mqttClient.state()); + } + } +} + +// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため) +void callback_on_subscribe(char* topic, byte* payload, unsigned int len) { + char buf[100]; + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + for (int i = 0; i < len ; i++) { + buf[i] = (char)payload[i]; + } + buf[len] = 0; + Serial.println(buf); + M5.Display.println(buf); + return; + // 参考:JSON Parsing example + // StaticJsonDocument<200> sjdoc; + // deserializeJson(sjdoc, buf); + // int intval = sjdoc["intval"]; + // const char* str = sjdoc["string"]; +} \ No newline at end of file diff --git a/src/ntp01.ino b/src/ntp01.ino old mode 100644 new mode 100755 index 6f4f96e..38ec51a --- a/src/ntp01.ino +++ b/src/ntp01.ino @@ -1,24 +1,46 @@ +#include #include const char* ssid = "ics-ap"; const char* password = "jikkenics"; void setup() { - Serial.begin(115200); - WiFi.begin(ssid, password); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // ボーレートを115200に設定 + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("NTP 01"); + M5.Display.setTextScroll(true); + // Serial.begin(115200); + // M5.Display.println("シリアル開始"); + + WiFi.begin(ssid, password); // 接続開始 while (WiFi.status() != WL_CONNECTED) { // 接続中... - Serial.print("."); + M5.Display.print("."); + M5.delay(500); } -// char* ntpserver = "ntp.nict.jp"; // 学内のNetworkを利用するときは、10.64.7.184 にする - char* ntpserver = "10.64.7.184"; // 学内のNetworkを利用するときは、10.64.7.184 にする - configTime(9 * 3600, 0, ntpserver);//GMTとの時差(秒) が9*3600, サマータイムで進める時間(秒)が0 + // 接続完了!! + char* ntpserver = "ntp.nict.jp" ; + configTime(9 * 3600, 0, ntpserver) ; //GMTとの時差(秒) が9*3600, サマータイムで進める時間(秒)が0 + + + M5.Display.fillScreen(GREEN); + M5.Display.setCursor(0, 40); + M5.Display.setTextColor(BLACK, GREEN); + M5.Display.print(" Wifi Connected!\n "); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + M5.delay(1500); } void loop() { + M5.update(); + struct tm localTime; char buf[30]; getLocalTime(&localTime); - sprintf(buf, ">> %04d/%02d/%02d %02d:%02d:%02d", + sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d\n", localTime.tm_year + 1900, localTime.tm_mon + 1, localTime.tm_mday, @@ -26,6 +48,12 @@ localTime.tm_min, localTime.tm_sec ); - Serial.println(buf); - delay(1000); -} + M5.Display.setTextColor(GREEN,BLACK); + M5.Display.print(buf); + Serial.print(buf); + + if (M5.BtnA.wasReleased()) { + M5.Display.print(WiFi.localIP().toString()); + } + M5.delay(1000); +} \ No newline at end of file diff --git a/src/ota01.ino b/src/ota01.ino old mode 100644 new mode 100755 diff --git a/src/pref01.ino b/src/pref01.ino old mode 100644 new mode 100755 index a86d7cc..4ca8d0c --- a/src/pref01.ino +++ b/src/pref01.ino @@ -1,45 +1,50 @@ -#include +#include #include Preferences pref; - int count = 0; + void setup() { - M5.begin(); - M5.Lcd.setRotation(0); //縦型 - M5.Lcd.fillScreen(CYAN); - M5.Lcd.setTextSize(2); + auto cfg = M5.config(); // M5Unified の設定 + M5.begin(cfg); + + M5.Display.setRotation(0); // 縦型 + M5.Display.fillScreen(CYAN); + M5.Display.setTextSize(2); + M5.Display.setTextScroll(true); loadCount(&count); - M5.Beep.tone(2000, 500); - M5.Lcd.printf("count = %d\n", count); + M5.Speaker.tone(2000, 500); + M5.Display.printf("count = %d\n", count); } void loop() { - M5.Beep.update(); M5.update(); - if (M5.BtnA.wasReleasefor(1000) ) { // Aボタン長押し + + if (M5.BtnA.wasReleaseFor(1000)) { // Aボタン長押し count = 0; saveCount(&count); - M5.Beep.tone(1200, 300); - M5.Lcd.printf("count = %d\n", count); + M5.Speaker.tone(1200, 300); + M5.Display.printf("count = %d\n", count); } else if (M5.BtnA.wasReleased()) { // Aボタン押し - count++ ; + count++; saveCount(&count); - M5.Beep.tone(2000, 300); - M5.Lcd.printf("count = %d\n", count); + M5.Speaker.tone(2000, 300); + M5.Display.printf("count = %d\n", count); } else if (M5.BtnB.wasReleased()) { // Bボタン押し reboot(); - } else if (M5.Axp.GetBtnPress() == 2) { // 電源ボタン押し + } else if (M5.Power.isCharging() == false && M5.BtnPWR.wasReleased()) { // 電源ボタン押し poweroff(); } + delay(50); } void loadCount(int *c) { pref.begin("mydata", false); - *c = pref.getInt("count"); + *c = pref.getInt("count", 0); // 初回時に 0 をデフォルト値とする pref.end(); } + void saveCount(int *c) { pref.begin("mydata", false); pref.putInt("count", *c); @@ -47,7 +52,7 @@ } void poweroff() { - M5.Axp.Write1Byte(0x32, M5.Axp.Read8bit(0x32) | 0x80);//PowerOff + M5.Power.powerOff(); } void reboot() { diff --git a/src/pwm01.ino b/src/pwm01.ino old mode 100644 new mode 100755 index d2c8bf6..75ef30b --- a/src/pwm01.ino +++ b/src/pwm01.ino @@ -1,22 +1,43 @@ -int PIN = 10; // 内蔵LED -int PWM_CH = 1; // 0~3で指定する。0にすると高音が鳴って耳障り? +#include +#include + +#define LED_PIN 19 // 赤色LED G19 + +#define PWM_CH 1 // PWMチャンネル(0~15) +#define PWM_FREQ 90 // PWM周波数 (Hz) +#define PWM_RES 8 // 分解能 (bit) → 0~255 のデューティ比 void setup() { - pinMode(PIN, OUTPUT); // PINのモード設定 - ledcSetup(PWM_CH, 90, 8); // CH, 周波数(Hz) 【 90Hz より、小さくするとどうなる?】 , 分解能(bit) - ledcAttachPin(PIN, PWM_CH); - // https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/LED_Control/ + M5.begin(); + M5.Display.setRotation(3); + + pinMode(LED_PIN, OUTPUT); // PINのモード設定 + // PWM のセットアップ + ledcAttachChannel(LED_PIN, PWM_FREQ, PWM_RES, PWM_CH); + // PWM_FREQ=周波数Frequency(Hz) 【 90Hz より、小さくするとどうなる?】 + // PWM_RES=分解能Resolution(bit) + + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("pwm01 LED点滅サンプル (PWM=Pulse Width Modulation パルス幅変調)"); + M5.Display.setTextScroll(true); } void loop() { - int i; - - for (int i = 0 ; i < 256 ; i++) { - ledcWrite(PWM_CH, i); - delay( 5 ); + for (int duty = 0; duty <= 255; duty += 5) { + ledcWrite(LED_PIN, duty); + delay(20); } - for (int i = 256 ; i > 0 ; i--) { - ledcWrite(PWM_CH, i); - delay( 5 ); + delay(500); + for (int duty = 255; duty >= 0; duty -= 5) { + ledcWrite(LED_PIN, duty); + delay(20); } + delay(500); + // 別の方法 + // ledcFade(LED_PIN, 255, 10, 1000); + // ledcWrite(LED_PIN, 10); // これがないと切り替わらない + // ledcFade(LED_PIN, 10, 255, 1000); + // ledcWrite(LED_PIN, 255); // これがないと切り替わらない + // delay(500); // 一瞬消灯状態を維持 } \ No newline at end of file diff --git a/src/regexp01.ino b/src/regexp01.ino old mode 100644 new mode 100755 diff --git a/src/rtc01.ino b/src/rtc01.ino old mode 100644 new mode 100755 index 0c641c8..6c53672 --- a/src/rtc01.ino +++ b/src/rtc01.ino @@ -1,64 +1,96 @@ -#include +#include #include -// #include "time.h" -#define USE_NTP 1 // NTPからRTCに時刻設定するなら1 - -void setRTCfromLT(struct tm lt) { - RTC_DateTypeDef DateStruct; - DateStruct.Year = lt.tm_year + 1900; - DateStruct.Month = lt.tm_mon + 1; - DateStruct.Date = lt.tm_mday; - DateStruct.WeekDay = lt.tm_wday; - M5.Rtc.SetData(&DateStruct); - - RTC_TimeTypeDef TimeStruct; - TimeStruct.Hours = lt.tm_hour; - TimeStruct.Minutes = lt.tm_min; - TimeStruct.Seconds = lt.tm_sec+1; - M5.Rtc.SetTime(&TimeStruct); -} - -void getRTC(char* buf) { - RTC_DateTypeDef DateStruct; - RTC_TimeTypeDef TimeStruct; - M5.Rtc.GetData(&DateStruct); - M5.Rtc.GetTime(&TimeStruct); - sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d", - DateStruct.Year, DateStruct.Month, DateStruct.Date, - TimeStruct.Hours, TimeStruct.Minutes, TimeStruct.Seconds - ); -} +const char* ssid = "ics-ap"; +const char* password = "jikkenics"; void setup() { - M5.begin(); - M5.Lcd.setRotation(3); - Serial.begin(115200); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // ボーレートを115200に設定 + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("NTP 01"); + M5.Display.setTextScroll(true); - if (USE_NTP) { - const char* ssid = "ics-ap"; - const char* password = "jikkenics"; - const char* ntpserver = "ntp.nict.jp"; // or 10.64.7.184 for CIT-ap1x - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { // 接続中... - Serial.print("."); - } - configTime(9 * 3600, 0, ntpserver); - - struct tm localTime; - while (localTime.tm_year < 80) { - getLocalTime(&localTime); delay(50); - } - setRTCfromLT(localTime); + WiFi.begin(ssid, password); // 接続開始 + while (WiFi.status() != WL_CONNECTED) { // 接続中... + M5.Display.print("."); + M5.delay(500); } + char* ntpserver = "ntp.nict.jp" ; + configTime(9 * 3600, 0, ntpserver) ; //GMTとの時差(秒) が9*3600, サマータイムで進める時間(秒)が0 + + M5.Display.fillScreen(CYAN); + M5.Display.setCursor(0, 40); + M5.Display.setTextColor(BLACK, CYAN); + M5.Display.print(" Wifi Connected!\n "); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + M5.delay(1500); } void loop() { + M5.update(); char buf[30]; - getRTC(buf); // bufに、日時文字列を書き込む + + getLocalC(buf); // bufに、Local(NTP)日時文字列を書き込む + M5.Display.setTextColor(GREEN,BLACK); + M5.Display.println(buf); Serial.println(buf); - M5.Lcd.fillScreen(BLUE); - M5.Lcd.setCursor(0, 50, 4); - M5.Lcd.println(buf); - delay(1000); + + getRTC(buf); // bufに、日時文字列を書き込む + M5.Display.setTextColor(CYAN,BLACK); + M5.Display.println(buf); + Serial.println(buf); + + + if (M5.BtnA.wasPressed()) { + // NTPからRTCに時刻設定する + struct tm localTime; + getLocalTime(&localTime); + setRTCfromLT(localTime); + M5.Display.setTextColor(WHITE,RED); + M5.Display.println(" LocalTimeをRTCに設定! "); + } + M5.delay(1000); } + +void setRTCfromLT(struct tm lt) { + m5::rtc_date_t DateStruct; + DateStruct.year = lt.tm_year + 1900; + DateStruct.month = lt.tm_mon + 1; + DateStruct.date = lt.tm_mday; + DateStruct.weekDay = lt.tm_wday; + M5.Rtc.setDate(&DateStruct); + + m5::rtc_time_t TimeStruct; + TimeStruct.hours = lt.tm_hour; + TimeStruct.minutes = lt.tm_min; + TimeStruct.seconds = lt.tm_sec+1; + M5.Rtc.setTime(&TimeStruct); +} + +void getRTC(char* buf) { + m5::rtc_date_t DateStruct; + m5::rtc_time_t TimeStruct; + M5.Rtc.getDate(&DateStruct); + M5.Rtc.getTime(&TimeStruct); + sprintf(buf, "RTC %04d/%02d/%02d %02d:%02d:%02d", + DateStruct.year, DateStruct.month, DateStruct.date, + TimeStruct.hours, TimeStruct.minutes, TimeStruct.seconds + ); +} + +void getLocalC(char* buf) { + struct tm localTime; + getLocalTime(&localTime); + sprintf(buf, "LOC %04d/%02d/%02d %02d:%02d:%02d", + localTime.tm_year + 1900, + localTime.tm_mon + 1, + localTime.tm_mday, + localTime.tm_hour, + localTime.tm_min, + localTime.tm_sec + ); +} \ No newline at end of file diff --git a/src/serial01.ino b/src/serial01.ino old mode 100644 new mode 100755 index 2947625..5f81ee4 --- a/src/serial01.ino +++ b/src/serial01.ino @@ -1,9 +1,19 @@ +#include +#include + int num = 0; void setup() { - Serial.begin(115200); // 通信速度をbpsで設定 + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // Serial通信速度(ボーレート)をbpsで設定 + M5.begin(cfg); + M5.Display.setRotation(0); //縦(M5が読める向き) + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("serial01"); + M5.Display.setTextScroll(true); } void loop() { + M5.Display.printf("%d \n" , num); Serial.printf("%d \n" , num); num++; - delay(500); // 500ミリ秒待つ + M5.delay(1000); // 1秒待つ } diff --git a/src/serial02.ino b/src/serial02.ino old mode 100644 new mode 100755 index 5ccd3cb..cd001ca --- a/src/serial02.ino +++ b/src/serial02.ino @@ -1,8 +1,17 @@ +#include +#include + int num = 0; char buf[100]; void setup() { - Serial.begin(115200); // 通信速度をbpsで設定 + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // 通信速度をbpsで設定 + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("シリアルテスト serial02"); + M5.Display.setTextScroll(true); } void loop() { @@ -14,10 +23,13 @@ } if (pos > 0) { buf[pos] = 0; // さいごに Null (文字列の終端)を追加(これを忘れるとどうなる?) + M5.Display.print("> from pc: "); + M5.Display.print( buf ); Serial.print("> from pc: "); Serial.print( buf ); // 格納しておいた文字列を表示 if (buf[0] == '0' && pos == 2) { // buf={ 48(='0'), 10(=改行) } のとき num = 0; // num を 0 にする + M5.Display.println("Reset num"); Serial.println( "Reset num" ); } delay(2000); @@ -25,5 +37,5 @@ Serial.printf("%d \n" , num ); num++; - delay(500); + delay(1000); } \ No newline at end of file diff --git a/src/servohat01.ino b/src/servohat01.ino old mode 100644 new mode 100755 diff --git a/src/setrotation.html b/src/setrotation.html old mode 100644 new mode 100755 diff --git a/src/sketch_feb25a.ino b/src/sketch_feb25a.ino old mode 100644 new mode 100755 diff --git a/src/sound01.ino b/src/sound01.ino old mode 100644 new mode 100755 index f468876..ef4d126 --- a/src/sound01.ino +++ b/src/sound01.ino @@ -1,34 +1,35 @@ -#include +#include +int f[28] = { 262, 294, 330, 349, 392, 440, 494 }; // 配列のサイズは4オクターブ分確保する -int f[28] = { 262, 294, 330, 349, 392, 440, 494 }; // 配列のサイズは4オクターブ分 void setup() { - Serial.begin(115200); - M5.begin(); - M5.Lcd.setRotation(3); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); for (int i = 0; i < 7; i++) { - f[i + 7] = f[i] * 2; + f[i + 7] = f[i] * 2; f[i + 14] = f[i] * 4; f[i + 21] = f[i] * 8; } - // setBeep( Hz, ms) でビープ音を設定して、beep()で鳴らす。 - M5.Beep.setBeep(523, 500); M5.Beep.beep(); delay(500); - // tone( Hz, ms ) で鳴らす方法 - M5.Beep.tone(1046, 500); delay(500); - // msを省略し、tone( Hz ) で鳴らす(結局、delayが必要になるので) - M5.Beep.tone(2092); delay(500); - // ここはmsを指定するとよい (loopのM5.Beep.updateが停めてくれるので、delayを省略できる) - M5.Beep.tone(2092 * 2, 1000); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("サウンドテスト (tone関数)"); + M5.Display.setTextScroll(true); + + tone(GPIO_NUM_2, f[0], 200); + tone(GPIO_NUM_2, f[2], 200); + tone(GPIO_NUM_2, f[4], 200); + tone(GPIO_NUM_2, f[7], 400); + M5.Display.setBrightness(255); } void loop() { - M5.Beep.update(); //tone()やsetBeep()で指定した時間を過ぎていたら音を止める。 - // M5.Beep.mute() とすると、すぐに停止する。 - while (Serial.available()) { char c = Serial.read(); - if (c < 'c' || 'z' < c) continue; // c〜zの文字以外なら、以降のwhile内処理をスキップ - M5.Beep.tone( f[c - 'c'] , 1000); // 1秒鳴らす - Serial.println( f[c - 'c'] ); + if (c < 'c' || 'z' < c) continue; // c〜zの文字以外なら、以降のwhile内処理をスキップ + tone(GPIO_NUM_2, f[c - 'c'], 500); // 0.5秒鳴らす + M5.Display.setBrightness(255); + Serial.printf(" chr=%c %d Hz\n", c, f[c - 'c']); + M5.Display.printf(" chr=%c %d Hz\n", c, f[c - 'c']); } - delay(50); -} + M5.delay(50); +} \ No newline at end of file diff --git a/src/speakerhat01.ino b/src/speakerhat01.ino old mode 100644 new mode 100755 diff --git a/src/sprite01.ino b/src/sprite01.ino old mode 100644 new mode 100755 index bcc0fb8..8192094 --- a/src/sprite01.ino +++ b/src/sprite01.ino @@ -1,17 +1,19 @@ -#include +#include int USE_SPRITE = 0 ; //スプライトを使用するとき1 -TFT_eSprite spu = TFT_eSprite(&M5.Lcd); // Sprite object +// スプライト用のオブジェクト +LGFX_Sprite spu(&M5.Display); void setup() { M5.begin(); - M5.Lcd.setRotation(3); + M5.Display.setRotation(3); + // スプライトの初期化、サイズを設定 spu.setColorDepth(8); spu.createSprite(240, 135); - randomSeed(analogRead(0)); + } void loop() { @@ -23,17 +25,16 @@ spu.printf(" %d \n Sprite ", r ); spu.pushSprite(0, 0); } else { - M5.Lcd.fillScreen( CYAN ); - M5.Lcd.setCursor(30, 34, 4); M5.Lcd.setTextSize(2); - M5.Lcd.setTextColor( WHITE, BLUE ); - M5.Lcd.printf(" %d \n LCD ", r); + M5.Display.fillScreen( TFT_GREENYELLOW ); + M5.Display.setCursor(30, 34, 4); M5.Lcd.setTextSize(2); + M5.Display.setTextColor( WHITE, TFT_DARKGREEN ); + M5.Display.printf(" %d \n LCD ", r); } M5.update(); if (M5.BtnA.wasReleased()) { USE_SPRITE = 1 - USE_SPRITE ; // スプライト使用の切り替え(1なら0、0なら1) - M5.Beep.tone(1000 + 1000 * USE_SPRITE, 500); + M5.Speaker.tone(1000 + 1000 * USE_SPRITE, 500); } - M5.Beep.update(); delay(100); } \ No newline at end of file diff --git a/src/str01.ino b/src/str01.ino old mode 100644 new mode 100755 index 9d99309..cfc914d --- a/src/str01.ino +++ b/src/str01.ino @@ -1,9 +1,15 @@ -#include +#include +#include void setup() { - Serial.begin(115200); - M5.begin(); - M5.Lcd.setRotation(3); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; // シリアル通信を利用する。通信速度(ボーレート)を設定。 + M5.begin(cfg); + + M5.Display.setRotation(3); + M5.Display.setTextScroll(true); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("整数 または 6文字の16進数(RRGGBB)を入力してください。"); Serial.println("整数 または 6文字の16進数(RRGGBB)を入力してください。"); } @@ -31,13 +37,13 @@ uint8_t r = hexToDec( sbuf.substring(0, 2) ); uint8_t g = hexToDec( sbuf.substring(2, 4) ); uint8_t b = hexToDec( sbuf.substring(4, 6) ); - M5.Lcd.fillScreen( getColorUInt16( r , g , b ) ); - M5.Lcd.setCursor(0, 70, 4); - M5.Lcd.printf(" %02x %02x %02x \n", r, g, b); - M5.Lcd.printf(" %d %d %d ", r, g, b); + M5.Display.fillScreen( getColorUInt16( r , g , b ) ); + M5.Display.setCursor(0, 70, 4); + M5.Display.printf(" %02x %02x %02x \n", r, g, b); + M5.Display.printf(" %d %d %d ", r, g, b); } } - delay(50); + M5.delay(50); } //全ての文字が0〜9なら、1(true)を返す bool isDigit(String s) { diff --git a/src/task01.ino b/src/task01.ino old mode 100644 new mode 100755 index 0a4aec8..397a4a6 --- a/src/task01.ino +++ b/src/task01.ino @@ -1,4 +1,4 @@ -#include +#include int interval_msec[] = { 333, 1000, 2000 }; // Led, Lcd, Beep TaskHandle_t tH[3]; @@ -21,21 +21,21 @@ void lcdTask(void *pvParam) { /** setup をここに書く **/ portTickType lastTime; - M5.Lcd.setRotation(0); - M5.Lcd.fillScreen(GREEN); - M5.Lcd.setTextColor(WHITE, OLIVE); - M5.Lcd.setTextSize(2); - M5.Lcd.setCursor(0, 0); + M5.Display.setRotation(0); + M5.Display.fillScreen(GREEN); + M5.Display.setTextColor(WHITE, OLIVE); + M5.Display.setTextSize(2); + M5.Display.setCursor(0, 0); int count = 0; for (;;) { /** loop をここに書く **/ - M5.Lcd.printf("count=%d\n", count); + M5.Display.printf("count=%d\n", count); count++; lastTime = xTaskGetTickCount(); vTaskDelayUntil(&lastTime, interval_msec[1] ); // 第2引数に、実行間隔ミリ秒を指定 if (count % 10 == 0) { - M5.Lcd.fillScreen(GREEN); - M5.Lcd.setCursor(0, 0); + M5.Display.fillScreen(GREEN); + M5.Display.setCursor(0, 0); } } } @@ -48,9 +48,8 @@ for (;;) { /** loop をここに書く **/ lastTime = xTaskGetTickCount(); // ここでの時刻を変数に保存 - M5.Beep.tone( f[note] ); - delay(500); //0.5秒鳴らす - M5.Beep.mute(); + tone(GPIO_NUM_2, f[note], 500); M5.Display.setBrightness(255); + M5.delay(500); //0.5秒鳴らす note = (note+1)%8; vTaskDelayUntil(&lastTime, interval_msec[2] ); // 途中の処理やdelayは含まず、「保存」時刻の2秒後まで待つ。 @@ -58,7 +57,9 @@ } void setup() { - M5.begin(); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); xTaskCreatePinnedToCore(ledTask , "LedT", 4096, NULL, 1, &tH[0], 1/*<= CoreNo.*/ ); xTaskCreatePinnedToCore(lcdTask , "LcdT", 4096, NULL, 1, &tH[1], 1/*<= CoreNo.*/ ); diff --git a/src/task02.ino b/src/task02.ino old mode 100644 new mode 100755 index 5e42e95..20cd39d --- a/src/task02.ino +++ b/src/task02.ino @@ -1,3 +1,5 @@ +#include + xSemaphoreHandle mutex; //ミューテックス(排他制御用) void withArgTask(void *pvParam) { @@ -9,13 +11,17 @@ if (mStatus == pdPASS) { Serial.println("----"); Serial.printf("[%s] ", tsknm ); + M5.Display.println("----"); + M5.Display.printf("[%s] ", tsknm ); delay(500); for (int i = 1; i < 6; i++) { Serial.printf("%d ", i * num); + M5.Display.printf("%d ", i * num); delay(300); } delay(300); Serial.printf("done \n"); + M5.Display.printf("done \n"); delay(300); xSemaphoreGive(mutex); // ミューテックスを解放 vTaskDelete(NULL); // 自タスクを削除する @@ -29,7 +35,14 @@ char tskname[5]; void setup() { - Serial.begin(115200); + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("シリアルにも出力します"); + M5.Display.setTextScroll(true); + mutex = xSemaphoreCreateMutex(); // ミューテックス作成 } @@ -41,5 +54,5 @@ xTaskCreatePinnedToCore(withArgTask, tskname, 4096, &arg[i], 1, NULL , 1); } } - delay(20 * 1000); // 次のタスクの仕込みまで、20秒待つ -} \ No newline at end of file + M5.delay(20 * 1000); // 次のタスクの仕込みまで、20秒待つ +} diff --git a/src/telnet01.ino b/src/telnet01.ino old mode 100644 new mode 100755 diff --git a/src/webclient01.ino b/src/webclient01.ino new file mode 100644 index 0000000..f20611d --- /dev/null +++ b/src/webclient01.ino @@ -0,0 +1,55 @@ +#include +#include +#include // ステータスコードの定義もここにある + +const char* ssid = "ics-ap"; +const char* password = "jikkenics"; +// 天気予報API https://weather.tsukumijima.net/ から、千葉の天気を取得 +const char* weatherapi_url = "https://weather.tsukumijima.net/api/forecast/city/120010"; + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("webclient01 ボタンを押すと天気を取得"); + M5.Display.setTextScroll(true); + M5.Display.fillScreen(BLACK); + M5.Display.setTextColor(WHITE,BLACK); + + WiFi.begin(ssid, password); // 接続開始 + while (WiFi.status() != WL_CONNECTED) { // 接続中... + M5.Display.print("."); + M5.delay(500); + } + // 接続完了!! + M5.Display.fillScreen(GREEN); + M5.Display.setCursor(0, 30, 4);//x,y,fonttype + M5.Display.setTextColor(BLACK, GREEN); + M5.Display.print(" Wifi Connected!\n"); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + M5.Display.println("BtnA to get weather"); + M5.delay(1500); +} + +void loop() { + M5.update(); + if (M5.BtnA.wasReleased()) { + HTTPClient http; // クライアント作成 + http.begin(weatherapi_url); // HTTPでサーバに接続 + int httpCode = http.GET(); // ステータスコードを取得 + if (httpCode > 0) { + Serial.println(httpCode); + M5.Display.setTextColor(GREEN,BLACK); + M5.Display.printf("status code = %d\n ", httpCode); + if (httpCode == HTTP_CODE_OK) { // ステータスコードが「成功」(200) なら + String payload = http.getString(); + Serial.println(payload); + } + } + http.end(); + } + M5.delay(20); +} \ No newline at end of file diff --git a/src/webserver01.ino b/src/webserver01.ino new file mode 100644 index 0000000..edf7dc5 --- /dev/null +++ b/src/webserver01.ino @@ -0,0 +1,100 @@ +#include +#include +#include // ステータスコードの定義もここにある + +const char* ssid = "ics-ap"; +const char* password = "jikkenics"; + +WiFiServer server(80); + +void setup() { + auto cfg = M5.config(); + cfg.serial_baudrate = 115200; + M5.begin(cfg); + M5.Display.setRotation(3); //横向き + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("webserver01"); + M5.Display.setTextScroll(true); + + WiFi.begin(ssid, password); // 接続開始 + while (WiFi.status() != WL_CONNECTED) { // 接続中... + M5.Display.print("."); + M5.delay(500); + } + // 接続完了!! + M5.Display.fillScreen(GREEN); + M5.Display.setCursor(0, 30, 4);//x,y,fonttype + M5.Display.setTextColor(BLACK, GREEN); + M5.Display.print(" Wifi Connected!\n"); + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + M5.Display.println("open Web via HTTP"); + + server.begin(); // Webサーバを開始 +} + +void loop() { + M5.update(); + WiFiClient client = server.available(); + if (client) { + String req = "" ; + String tmp = "" , meth = "" ; + while (client.connected()) { // loop while the client's connected + if (client.available()) { // if there's bytes to read from the client, + char c = client.read(); // read a byte, then + req += c; + if (c == '\n') { // if the byte is a newline character + if (tmp.length() == 0) { // end of request, break while loop + break; + } else { //まだ継続 + if (tmp.startsWith("GET ") || tmp.startsWith("POST ") ) { + meth = tmp; + } + tmp = ""; + } + } else if (c != '\r') { // if you got anything else but a carriage return character, + tmp += c; // add it to the end of the currentLine + } + } + } // end of while + + Serial.println(meth); + if ( meth.startsWith("GET /") ) { + client.println("HTTP/1.1 200 OK"); // header (with response code) + client.println("Content-Type:text/plain"); + client.println(""); // HTTPでは、header と body の区切りは改行 + client.println(meth); + client.println("-- request --"); + client.println(req); + } + + if ( meth.startsWith("POST ") ) { + String post = ""; + char buf[257]; + int n; + while ((n = client.available()) > 0) { + if (n < 256) { + client.readBytes(buf, n) ; + buf[n] = 0 ; + } else { + client.readBytes(buf, 256) ; + buf[256] = 0 ; + } + } + post += buf ; + + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type:text/plain"); + client.println(""); // HTTPでは、header と body の区切りは改行 + client.println(meth); + client.println("-- request --"); + client.println(req); + client.println("-- post data --"); + client.println(post); + } + // close the connection: + client.stop(); + Serial.println(" --- Client Disconnected."); + } + M5.delay(20); +} \ No newline at end of file diff --git a/src/wifi01.ino b/src/wifi01.ino old mode 100644 new mode 100755 index 9b1cd4e..9f26f4e --- a/src/wifi01.ino +++ b/src/wifi01.ino @@ -1,32 +1,39 @@ -#include +#include #include const char* ssid = "ics-ap"; const char* password = "jikkenics"; void setup() { - M5.begin(); - M5.Lcd.setRotation(3); - M5.Lcd.fillScreen(ORANGE); - M5.Lcd.setCursor(10, 50, 4); + auto cfg = M5.config(); + M5.begin(cfg); + M5.Display.setRotation(3); + M5.Display.setFont(&fonts::lgfxJapanGothic_16); + M5.Display.println("WIFI 01"); + M5.Display.setTextScroll(true); + // Serial.begin(115200); + // M5.Display.println("シリアル開始"); WiFi.begin(ssid, password); // 接続開始 while (WiFi.status() != WL_CONNECTED) { // 接続中... - M5.Beep.tone(2000); delay(200); - M5.Beep.mute(); delay(300); - M5.Lcd.print("."); + M5.Display.print("."); + M5.delay(500); } // 接続完了!! - M5.Beep.tone(4000); - M5.Lcd.fillScreen(GREEN); - M5.Lcd.setCursor(0, 40, 4); - M5.Lcd.setTextColor(BLACK, GREEN); - M5.Lcd.print(" Wifi Connected!\n "); + M5.Display.fillScreen(GREEN); + M5.Display.setCursor(0, 40, 4); + M5.Display.setTextColor(BLACK, GREEN); + M5.Display.print(" Wifi Connected!\n "); String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス - M5.Lcd.println(gotip); - delay(1500); - M5.Beep.mute(); + M5.Display.println(gotip); + M5.delay(1500); } void loop() { + M5.update(); + if (M5.BtnA.wasReleased()) { + String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス + M5.Display.println(gotip); + } + M5.delay(20); } \ No newline at end of file diff --git a/src/wifimac.ino b/src/wifimac.ino old mode 100644 new mode 100755 diff --git a/week1.rst b/week1.rst index aa806b3..e09ce54 100755 --- a/week1.rst +++ b/week1.rst @@ -11,50 +11,43 @@ ---------------------------------------- - 電源を入れるには、電源ボタンを、**2秒間** 長押しします。 -- 電源を切るには、電源ボタン(M5と書かれたAボタンの左側面)を、**6秒間** 長押しします。その際、プログラムによっては再スタートしたように見える場合がありますが、気にせずに長押し継続してください。 +- 電源を **完全に** 切るには、**USBを外したうえで** 、電源ボタン(M5と書かれたAボタンの左側面)を、**5秒間** 長押しします。緑色のLEDが点灯したら、ボタンを離します。 - 動画をみる→ https://youtu.be/Lo1jZbAeT8Y - `M5StickCガイド `_ の、4ページ目、ハードウェアの概要も参考になります。 プログラムの書き込み方 -------------------------------------- -IoTP プログラムで、ソースコード(.ino)を開いて、**Uploadボタン** を押してください。 +`講義システム `_ のサンプルソースコードについて、ビルド済みバイナリをダウンロードして書き込むには、Git Bashやターミナルから、以下のように入力してください。 :: -または、git bash で SampleSrc フォルダに cd で移動したあとで、``./Upload.sh`` を実行してください。なお、引数にファイルを指定する(例えば ``./Upload.sh lcd01.ino``)と、直接コンパイル&書き込みを行います。 + $ cd + $ cd m5scp2_exp (実験フォルダに移動) + $ ./upload_by_hash.sh (ハッシュ値) + 例→ ./upload_by_hash.sh 2f4b280a7701 + $ ./upload_by_hash.sh のように、ハッシュ値を省略すると、Enter the hash: と訊かれます。 -.. note:: IoTP プログラムのUploadボタンは、Upload.bat (または Upload.sh) を実行しているだけです。このバッチファイル(またはスクリプト)は、指定したソースコードを TestBuild/TestBuild.ino にコピーしたのち、フォルダを指定してコンパイルします。実行ファイルはbuildフォルダの中に生成されます。arduino-cli では、実行ファイルを直接指定して書き込む方法もあります。(参考:``_Upload_FactoryTest.bat``) +ハッシュ値は、講義システムのHash 列をクリックすると、クリップボードにコピーされます。 + +自分が編集したソースコードについては、ハッシュ値を毎回指定するよりも、`こちらの(方法2) `_ を使うのが便利です。(ハッシュ値はソースコードを修正するたびに変わります。) -実機での動作検証を時間短縮・効率化したいとき ------------------------------------------------------------------------------------------ +以下のサンプルを参考に、コードを書くときのヒントと注意 +---------------------------------------------------------------------------------------------------------- -基本的にはSampleSrc 内のソースコード(.ino) を開き、コンパイル&書き込みを行って確認していくことになりますが、コンパイルに時間がかかる場合は、以下の方法で事前コンパイル済みの実行イメージファイル(.bin.img)を取得し、直接書き込むこともできます。 - -https://git.istlab.info/miura250/TestBuild においてある実行イメージファイルと、シェルスクリプトを用いる方法です。 - -1. ``cd`` で、ホームディレクトリに移動する。 -#. ``git clone https://git.istlab.info/git/miura250/TestBuild.git`` で、ホームディレクトリに ``TestBuild`` フォルダを作成しダウンロードする。 -#. ``cd TestBuild/build`` -#. ``./DirectBinUpdate.sh sprite01.bin.img`` のように、シェルスクリプトを用いて、bin.img ファイルを指定して書き込み(アップロード)をする。 - -.. note:: なお、bin.img 実行イメージファイルは、前述の ``Upload.sh`` シェルスクリプトで自動的に ``M5StickCPlus_FactoryTest2022/SampleSrc/TestBuild/build/`` 以下に生成されます。または、時間がかかりますが、``M5StickCPlus_FactoryTest2022/SampleSrc/_AllBuildTest.sh`` にあるシェルスクリプトですべてのサンプルプログラムをビルドし、実行イメージファイルを準備することもできます。 - -コードを書くときのヒントと注意 -------------------------------------------------------- - -- 以下のソースコード例は、リストの右上の□ボタンを押すと、クリップボードに簡単にコピーできます。右上のボタンが表示されていないときは、右にスクロールしてください。**(ただし、一部のWeb掲載プログラムは古く動かない場合があります。リスト上部のファイル名を確認して、IoTPプログラムが一覧をだしてくれる SampleSrcフォルダ 内のファイルをつかってください。)** -- ソースコードのインデントは、CTRL+T (Macの場合はCommand+T)キーで、自動整形できます。 -- ``#include `` は、M5StickC用のヘッダファイル指定です。 **M5StickCPlus** では、画面解像度が異なるので、 ``#include `` に変更しないと、表示がおかしくなることがあります。 -- 大文字と小文字は厳密に区別されます。 -- 画面(LCD)をつかうプログラムを書き込んだあと、画面を使わないプログラムを書き込むと、前のプログラムの画面が残ることがあります。 -- スケッチブック(プログラムを構成する、複数のソースコードを含むファイル、他のIDEではプロジェクトと呼ぶ場合もある)をコピーしたいときは、内包するフォルダごとコピーしてください。その際、フォルダ名と、メインのソースコードファイル名(拡張子以外の部分)は、一致している必要があります。 +- **以下のサンプルソースコードのキャプション「リスト x src/XXXX.ino」のXXXX部分をみて、講義システムの該当するサンプルを参照してください。** たとえば、リスト 1 src/serial01.ino だったら、Name: serial01 になります。 + - 2025年では、M5Unified.h を使用するため、``#include `` とかかれているプログラムはコンパイルできません。 参考:`2024以前のサイト `_ + - M5Unified.h を用いるときの ``M5.begin()`` の書き方は以前と異なります。講義システムで、ソースコードの新規作成時に生成されるコードを参考にしてください。 + - 一部のサンプルについては、需要がすくないこともあり、M5Unified.h 版のサンプルはまだ準備していません。 +- 画面(LCD)をつかうプログラムを書き込んだあと、画面を使わないプログラムを書き込むと、前のプログラムの画面が残ることがあります。また、画面を使わないプログラムは実行していることが分かりにくいので、注意してください。LCDが付いているとすこしだけ明るくなります。 +- Cプログラムの命令(関数等)について、大文字と小文字は厳密に区別されます。 - その他、よくある質問は、:ref:`FAQ` に随時追記していきます。 Serial通信 --------------------------------------- -:numref:`serial01` は、シリアルモニタへ文字列を出力するシンプルな例です。グローバル変数 num を 0 に設定したうえで、setup()関数が1回実行されます。その後、loop()関数が繰り返し実行されます。 -プログラムの出力をみるには、サンプルフォルダの ./monitor.sh またはVSCodeで 「シリアルモニタ」をひらいてください。 +:numref:`serial01` (``serial01``) は、シリアルモニタおよび画面へ文字列を出力する例です。プログラムでは、まずグローバル変数 num を 0 に設定したうえで、``setup()`` 関数が1回実行されます。その後、``loop()`` 関数が繰り返し実行されます。このあたりは Processing言語のsetup, draw と似ています。( `ChatGPTによると、Arduino側が参考にしたらしい `_ ) + +プログラムの出力をみるには、「シリアルモニタ」をひらいてください。**(ただし、シリアルモニタをひらきっぱなしにすると、プログラムの書き込みができません。ターミナル内であればCTRL+Cで終了してください。)** Serialクラスには、print()関数、println()関数、 printf()関数があります。Serial通信を用いると、デバイス側の変数の値や状況を、PC側で確認するプログラムを書くことができます。 なお、文字化けしたり、???と表示されるときは、シリアルモニタの通信速度(ボーレート)を ``115200 bps`` に変更し、プログラムで設定した速度と一致させてください。 `→動画 serial01 `_ @@ -63,28 +56,28 @@ :caption: :name: serial01 :language: arduino - :emphasize-lines: 2 + :emphasize-lines: 5,14,16 :linenos: -シリアルモニタは、デバイスからの出力を確認するだけではなく、デバイスに文字を送信することもできます。:numref:`serial02` は、シリアルモニタを介して、PCからデバイスに文字を送信する例です。シリアルモニタ上部のテキストエリアから 0 を送信すると、カウンタ num をリセットします。10〜14行目で、PCから送信された文字を、1文字ずつ ``Serial.read()`` で読み取って、配列 ``buf`` に格納しています。PCから複数の文字を1回で送信すると、 ``Serial.available()`` は連続して 1 (=true) を返しますので、1回に送信された文字をすべて ``buf`` に格納することができます。ちなみに、シリアルモニタで送信された文字列の最後は、改行コード(10)が付与されます。 +シリアルモニタは、デバイスからの出力を確認するだけではなく、デバイスに文字を送信することもできます。:numref:`serial02` (``serial02``)は、シリアルモニタを介して、PCからデバイスに文字を送信する例です。シリアルモニタ上部のテキストエリアから 0 を送信すると、カウンタ num をリセットします。19〜23行目で、PCから送信された文字を、1文字ずつ ``Serial.read()`` で読み取って、配列 ``buf`` に格納しています。PCから複数の文字を1回で送信すると、 ``Serial.available()`` は連続して 1 (=true) を返しますので、1回に送信された文字をすべて ``buf`` に格納することができます。ちなみに、シリアルモニタで送信された文字列の最後は、改行コード(10)が付与されます。 `→動画 serial02 `_ .. literalinclude:: src/serial02.ino :caption: :name: serial02 :language: arduino - :emphasize-lines: 10-14 + :emphasize-lines: 19-23 :linenos: -.. note:: 16行目の処理を忘れると、どうなるでしょうか? また、buf が溢れると、なにが起きるでしょうか?プログラムを書くときは、常に例外的な事象がおきる可能性を考えておきましょう。ただし、全ての例外的な事象に対処するのは困難な場合が多いです。 +.. note:: 25行目の処理を忘れると、どうなるでしょうか? また、buf が溢れると、なにが起きるでしょうか?プログラムを書くときは、常に例外的な事象がおきる可能性を考えておきましょう。ただし、全ての例外的な事象に対処するのは困難な場合が多いです。 本体の液晶ディスプレイ(LCD) ------------------------------------------- -- M5StickCのDisplay周り解析 が詳しいです。 -- :numref:`lcd01` のサンプルでは、外側から内側に向かって、10ピクセルずつ余白を残しながら、色を変えて塗りつぶしています。その後、8,16,26ピクセルフォント(それぞれ1,2,4番)をsetCursor()関数で指定して、print()関数で文字列を描画しています。 -- M5StickCPlusの機能である液晶ディスプレイ(LCD)を使用するため、 ``#include `` を指定し、``M5.begin()`` を呼び出しています。 +- M5StickC Plus2動作確認 その1 画面周り が詳しいです。 +- :numref:`lcd01` のサンプル(``lcd01``)では、外側から内側に向かって、10ピクセルずつ余白を残しながら、色を変えて塗りつぶしています。その後、8,16,26ピクセルフォント(それぞれ1,2,4番)をsetCursor()関数で指定して、print()関数で文字列を描画しています。 +- **M5Unified.h では、M5.Lcd → M5.Display になりました。** .. literalinclude:: src/lcd01.ino :caption: @@ -101,7 +94,7 @@ .. figure:: images/setRotation.gif :scale: 100% -.. note:: フォントの種類を設定するときは、setTextFont() や、setCursor()の第3引数をつかいます。setTextSize() は、指定したフォントを「縦横何倍に引き伸ばして表示するか?」を設定します。ここの「倍率」を2以上に増やすと、若干ギザギザが目立つようになります。 +.. note:: フォントの種類を設定するときは、setFont() をつかいます。setTextSize() は、指定したフォントを「縦横何倍に引き伸ばして表示するか?」を設定します。ここの「倍率」を2以上に増やすと、若干ギザギザが目立つようになります。 `M5Unified.h をつかうと、日本語も表示できるようになりました。 `_ 本体のボタン @@ -110,7 +103,7 @@ 本体には、3つのボタンがあります。 (参考:`M5StickCガイド `_ の、4ページ目、ハードウェアの概要) -:numref:`button01` に、ボタンをおしたらシリアルモニタに表示する例を示します。ボタンも、M5StickCPlus の機能なので、 ``#include `` を指定し、``M5.begin()`` を呼び出しておく必要があります。また、ボタンの状態を読み出して、ボタンオブジェクト(BtnA,BtnB)に設定するために、 ``M5.update()`` を、ループのなかに入れておく必要があります( `update()の定義 `_ )。長押しと普通押しを区別したい場合は、ifで確認する順番(長押しを先に判定する)が重要です。 +:numref:`button01` に、ボタンをおしたらシリアルモニタに表示する例を示します。ボタンも、M5StickCPlus の機能なので、 ``#include `` を指定し、``M5.begin()`` を呼び出しておく必要があります。 **また、ボタンの状態を読み出して、ボタンオブジェクト(BtnA,BtnB)に設定するために、** ``M5.update()`` **を、ループのなかに入れておく必要があります** ( `update()の定義 `_ )。長押しと普通押しを区別したい場合は、ifで確認する順番(長押しを先に判定する)が重要です。 .. literalinclude:: src/button01.ino :caption: @@ -148,25 +141,23 @@ :numref:`sound01` は、内蔵Beepを鳴らすサンプルです。音の周波数は、最初の1オクターブ (f[0]〜f[6]) のみを配列宣言時に指定し、残りの3オクターブはsetup()内で、倍数を計算して配列に設定しています。 -``setBeep()`` と ``beep()`` を使うと、同じビープ音を使い回すときは記述が短くて便利ですが、通常は ``tone()`` のほうが簡潔です。 -どちらの記法でも、命令実行のあと、音の停止を待たずに、すぐに次の処理に移行します(ノンブロッキング)。 -継続ミリ秒数(ms)は、 ``M5.Beep.update()`` が周期的に呼び出せるときに指定し、それ以外は省略するとよいでしょう。(結局、 ``delay()`` と ``mute()`` が必要になるため) +Arduino標準tone関数 をつかう方法と、M5.Speaker.tone() をつかう方法があります。`Lang-ship `_ に詳しいです。Arduino標準tone関数をつかうと、画面が暗くなってしまうので、暫定的に M5.Display.setBrightness(255); をいれています。 .. literalinclude:: src/sound01.ino :caption: :name: sound01 :language: arduino :linenos: -.. :emphasize-lines: 10-14 + :emphasize-lines: 18-22,29-30 内蔵LED(赤・赤外) ----------------------------------------- +---------------------------------------------------------- -M5StickCPlusには、2つのLEDランプが内蔵されています。GPIO(General Purpose Input/Output)の10番 には、赤色LED、GPIO9 には、赤外LEDが接続されています。 +M5StickCPlus2には、2つのLEDランプが内蔵されています。GPIO(General Purpose Input/Output)の19番 には、赤色LED および 赤外LEDが接続されています。 場所は、USBケーブルを挿す面の反対側の面にある、小さな穴2つの内側です。 -:numref:`led01` は、赤色LEDを点滅させるシンプルなプログラムです。 +:numref:`led01` は、これらのLEDを点滅させるシンプルなプログラムです。 .. literalinclude:: src/led01.ino :caption: @@ -176,8 +167,8 @@ .. :emphasize-lines: 10-14 -外部のLED等を接続 ------------------------------------------ +外部のLED等を接続(Plus2未確認) +-------------------------------------------------------------- 外部のLED等は、 G0, G25, G26 に接続します。(GROVE端子のG32, G33も利用できます。) サンプルプログラムは、:numref:`led01` と同様です。PIN 番号を、0 / 25 / 26 に変更してください。 @@ -210,12 +201,12 @@ :name: pwm01 :language: arduino :linenos: - :emphasize-lines: 6-7, 15,19 + :emphasize-lines: 6-8, 16,28,33 .. note:: ソースコードのコメントにも書いていますが、周波数を小さくする(20〜30程度)と、どうなるでしょうか?ぜひやってみてください。 -サーボモータ(サーボハット利用) -------------------------------------------------------------- +サーボモータ(サーボハット利用)(Plus2未確認) +----------------------------------------------------------------------------- :numref:`servohat01` は、`サーボハット `_ のサーボモータを動かすサンプルです。サーボモータの制御はPWMですので、基本的に、上のPWMとやっていることは同じです。おまけとして、LEDも点灯させました。``map関数`` は、Arduinoで使える関数で、範囲に対応する値を変換するときに使います。ここでは、サーボ制御で用いる5〜33の値を、LED制御の値0〜256に変換しています。 @@ -232,8 +223,8 @@ -アナログセンサを接続 (ADC) ------------------------------------------ +アナログセンサを接続 (ADC)(Plus2未確認) +----------------------------------------------------------------------------- ADCは、Analog to Digital Converter の意味です。 ``analogRead(PIN)`` は、PIN番ピンの電圧(0~3.3V)を、0〜4095 の値で返します。一般に、抵抗値が変化するタイプのセンサは、この方法をつかって、読み取ることができます。 @@ -256,21 +247,21 @@ 加速度センサ ----------------------------------------- -:numref:`accgyro01` は、内蔵されている加速度センサ(MPU6886) の値を表示するサンプルです。ちなみに、IMUとは、Inertial Measurement Unit: 慣性計測装置 の略です。 +:numref:`imu01` は、内蔵されている加速度センサ(MPU6886) の値を表示するサンプルです。ちなみに、IMUとは、Inertial Measurement Unit: 慣性計測装置 の略です。 「ツール」→「シリアルプロッタ」をひらくと、値をグラフでみることができます。(通信速度設定を、115200bps に設定してください) ジャイロセンサの値も取得可能です。 -.. literalinclude:: src/accgyro.ino +.. literalinclude:: src/imu01.ino :caption: - :name: accgyro01 + :name: imu01 :language: arduino :linenos: - :emphasize-lines: 11,16-17 + :emphasize-lines: 14,16 -赤外(InfraRed)リモコン ------------------------------------------- +赤外(InfraRed)リモコン(Plus2未確認) +------------------------------------------------------------------------------ .. note:: 実験時間中に、送信のみを手軽に試したい場合は、付録の :numref:`irsend02` を書き込んで、教員を呼んでください。 @@ -313,14 +304,14 @@ スプライト表示(TFT_eSprite クラス) -------------------------------------------------------------- +------------------------------------------------------------------------------------------------- -M5.Lcd ではじまる画面描画命令は、表示されている画面に対して、直接描画するため、画面のちらつきが生じることがあります。 -TFT_eSprite クラスを用いると、画面に表示されていない仮想画面(オフスクリーン)を作成して、そこに対して描画を行っておき、さいごにまとめて仮想画面の内容をメインの画面(Lcd)に描画することができます。 +M5.Display ではじまる画面描画命令は、表示されている画面に対して、直接描画するため、画面のちらつきが生じることがあります。 +LGFX_Sprite クラスを用いると、画面に表示されていない仮想画面(オフスクリーン)を作成して、そこに対して描画を行っておき、さいごにまとめて仮想画面の内容をメインの画面(Lcd)に描画することができます。 これにより、画面のちらつきが抑制できます(ダブルバッファリング)。 ちらつき防止のほかに、なめらかに画面スクロールする目的で、実画面よりも大きい仮想画面を作成しておき、その一部の領域のみを実画面に描画するといった用途にも使われます。 -TFT_eSprite クラスは、Lcdクラスとほぼ同様の描画関数を備えています。:numref:`sprite01` は、スプライトの効果あり/なしをAボタンで切り替えて確認できるサンプルプログラムです。 +LGFX_Sprite クラスは、M5.Displayクラスとほぼ同様の描画関数を備えています。:numref:`sprite01` は、スプライトの効果あり/なしをAボタンで切り替えて確認できるサンプルプログラムです。 `→動画 sprite01 `_ .. literalinclude:: src/sprite01.ino @@ -341,23 +332,10 @@ :name: wifi01 :language: arduino :linenos: - :emphasize-lines: 4-5,13-18 + :emphasize-lines: 4-5,17-21 -Wifi接続するだけでは、あまり意味がないので、Telnetサーバを起動する例を :numref:`telnet01` に示します。 -シリアルモニタを開いて、IPアドレス(10.85.xxx.xxx)を確認したら、ターミナル(コマンドプロンプト)で、``telnet 10.85.xxx.xxx`` と入力して、接続します。(Windowsでは https://www.imamura.biz/blog/27493 を参照し、telnetを有効にしてください。) -telnet から文字を入力すると、シリアルモニタに表示されます。 -逆に、シリアルモニタから文字を入力すると、Telnet接続しているターミナルに、文字が表示されます。 -``WiFiServer server(23)`` で、23番ポートで待ち受けるサーバを、作成しています。 -ちなみに、``WiFiMulti`` は、複数のアクセスポイントに対して、Wifi接続を試みることができる機能(クラス)です。ただし、最終的に繋がるのは1つのアクセスポイントになります。 +注:以前掲載していた、`Telnetサーバを起動する例 `_ については省略しました。 -.. note:: Telnet接続を切断するときは、まずControlキーをおしながら ``]`` をおしてください。プロンプトに ``telnet>`` と表示されますので、``quit`` と打ち込むと終了します。 ``Escape character is '^]'.`` の ``^`` は、Controlキーのことです。 - -.. literalinclude:: src/telnet01.ino - :caption: - :name: telnet01 - :language: arduino - :linenos: - :emphasize-lines: 29-30, 32 NTPサーバ (Network Time Protocol) と時刻の取得 @@ -365,7 +343,7 @@ M5StickCPlusには、システム時間(localTime)と、RTC(リアルタイムクロック:時計の機能を備えたICのこと)の2種類の時計があります。システム時間は、システムリセット(再起動)のたびに、時刻もリセットされますが、後者のRTCはリセットされません。 -:numref:`ntp01` に、NTPサーバを使ってシステム時間の修正をしたのち、システム時間を1秒ごとに取得して、シリアルモニタに表示する例を示します。こちらは、M5のライブラリは不要です。configTime()でNTPサーバを設定しておくと、1時間に1回、NTPサーバに接続して、時刻修正します。 +:numref:`ntp01` に、NTPサーバを使ってシステム時間の修正をしたのち、システム時間を1秒ごとに取得して、シリアルモニタに表示する例を示します。configTime()でNTPサーバを設定しておくと、1時間に1回、NTPサーバに接続して、時刻修正します。 `→動画 ntp01 `_ @@ -374,30 +352,30 @@ :name: ntp01 :language: arduino :linenos: - :emphasize-lines: 13 + :emphasize-lines: 24-25 .. warning:: configTime() を行わない状況で、システム時間(localTime)を取得しようとすると、取得に数秒ほど時間がかかります。 -:numref:`rtc01` は、RTCの時刻を表示するサンプルです。なお、5行目で ``USE_NTP`` に 1 が設定してあれば、RTCに時刻を設定します。常時Wifiネットワークに接続できない場合は、RTCを利用することが望ましいです。 +:numref:`rtc01` は、RTCに時刻を設定し、表示するサンプルです。ここではWifi&NTPで時刻同期してから、RTCに設定していますが、Wifiネットワークに接続できない場合は、RTCを利用することが望ましいです。 .. literalinclude:: src/rtc01.ino :caption: :name: rtc01 :language: arduino :linenos: - :emphasize-lines: 5 +.. :emphasize-lines: 5 .. note:: RTCに一旦時刻を設定しておくと、初期状態で書き込まれているプログラムFactoryTest の「BMP8563 RTC Time」でも、その時刻が表示されるようになります。 WebClient --------------------------------------- -:numref:`httpclient01` は、HTTP通信で天気予報Web APIに接続するサンプルです。HTTPClientクラスを用いると、ブラウザでURLを指定してWebページを開くように、WebサーバにGETメソッドやPOSTメソッドでリクエストを送信して、ステータスコードやレスポンスを取得することができます。このサンプルでは、シリアルコンソールに、天気予報をJSON形式で表示します。JSON(ジェイソン)とは、Javascriptのオブジェクトの形式でデータを表現する記法です。 +:numref:`webclient01` は、HTTP通信で天気予報Web APIに接続するサンプルです。HTTPClientクラスを用いると、ブラウザでURLを指定してWebページを開くように、WebサーバにGETメソッドやPOSTメソッドでリクエストを送信して、ステータスコードやレスポンスを取得することができます。このサンプルでは、シリアルコンソールに、天気予報をJSON形式で表示します。JSON(ジェイソン)とは、Javascriptのオブジェクトの形式でデータを表現する記法です。 -.. literalinclude:: src/httpclient01.ino +.. literalinclude:: src/webclient01.ino :caption: - :name: httpclient01 + :name: webclient01 :language: arduino :linenos: .. :emphasize-lines: 5 @@ -405,51 +383,26 @@ .. role:: strike -.. warning:: https (SSL) 通信でPOSTメソッドで送信する場合は、付録→LINE Notify (:numref:`line01`)を参考にしてください。以前は「スケッチ例→HTTPClient→BasicHttpsClient を参照して、WiFiClientSecure クラスを使用してください。」と書いていましたが、WifiClientSecureは必要ありません。 +.. warning:: https (SSL) 通信でPOSTメソッドで送信する場合は、付録→LINE Notify (:numref:`line01`)を参考にしてください。(注:Plus2未確認) -Google Spreadsheet にデータを送信する --------------------------------------------------------- - -HTTP通信で、サーバにデータを送信して格納したいとおもっても、適当なサーバを準備するのは手間がかかることがあります。 - -Google Apps Scriptを用いると、HTTP通信で Google Spreadsheet にデータを書き込んだり、読み取ったりするWebサービスを作成し、WebAPIとして公開することができます。 - -(Google Spreadsheetのメニューで) 拡張機能→Apps Script で、:numref:`doget` を「コード.gs」に書き込みます。14行目で「シート1」の一番下の行に、配列array の要素を追加します。18行目のgetRange(1,3).getValue()は、スプレッドシートのC1(3列1行)の値を取得しています。ここに「=average(C2:C200)」のようにしておくと、データの平均値を取得することもできます。 - -作成した「コード.gs」について、「デプロイ」→「新しいデプロイ」で、アクセスできるユーザを「全員」にし、「デプロイ」を押します。すると、ウェブアプリのURLが表示されますのでコピーします。**このあと、Googleアカウント権限について聞かれる場合があります。** - -作成できたかどうかをパソコンから確認するには、コマンドラインから、以下のように入力します(ただし、curlが必要です。val1=10 と val2=20 のあいだは&記号ですので、シェルでバックグラウンド処理されないように、URLをシングルクォートで囲っています。-L (--location)は、リダイレクト先にリクエストを発行するcurlのオプションです。) exec のあとに ? をいれて、名前1=値1&名前2=値2 のようにしてデータを渡します。 :: - - curl -L 'https://script.google.com/macros/s/XxXxXxXxXx/exec?val1=10&val2=20' - - -.. literalinclude:: src/doget.js - :caption: - :name: doget - :language: javascript - :linenos: - :emphasize-lines: 14,18 - -.. warning:: doGet関数の返却値は、本来はHTTPのレスポンスとして受け取れるのですが、現状の ``HTTPClient`` ではリダイレクトをうまく処理できない?ため、Google App Scriptの出力を受け取れない可能性があります。 - WebServer ---------------------------------------- -すこし長いですが、:numref:`httpserver01` は、80番ポートでHTTPでの通信を待ち受け(listenし)て、クライアントからの接続情報(ヘッダ情報)を返すWebサーバのシンプルな例です。クライアント(ブラウザ)からのリクエスト行のうち、 ``GET`` または ``POST`` ではじまる行があれば、変数 ``meth`` に格納します。つまり、変数 ``meth`` には、ブラウザで発行したリクエストのURLが含まれることになります。(methはmethodの略。)POSTメソッドで送信されていれば、リクエストボディに記述されたデータを変数 ``post`` に格納します。 クライアント(ブラウザ)に返す「レスポンス」は、 ``client.println()`` で送信します。最後に、``client.stop()`` で、サーバ側から接続を切断します。 +:numref:`webserver01` は、80番ポートでHTTPでの通信を待ち受け(listenし)て、クライアントからの接続情報(ヘッダ情報)を返すWebサーバの例です。クライアント(ブラウザ)からのリクエスト行のうち、 ``GET`` または ``POST`` ではじまる行があれば、変数 ``meth`` に格納します。つまり、変数 ``meth`` には、ブラウザで発行したリクエストのURLが含まれることになります。(methはmethodの略。)POSTメソッドで送信されていれば、リクエストボディに記述されたデータを変数 ``post`` に格納します。 クライアント(ブラウザ)に返す「レスポンス」は、 ``client.println()`` で送信します。最後に、``client.stop()`` で、サーバ側から接続を切断します。 `→動画 httpserver01 `_ -.. literalinclude:: src/httpserver01.ino +.. literalinclude:: src/webserver01.ino :caption: - :name: httpserver01 + :name: webserver01 :language: arduino :linenos: - :emphasize-lines: 18,22,26,43,80 + :emphasize-lines: 33,38,42,59,96 センサデータを返すだけなら問題ありませんが、クライアントからのデータを GET / POST で受信して処理する場合は、 ``key1=val1&key2=val2`` のような文字列を要素に分解する必要がでてきます。あまり深入りしませんが、正規表現で文字列を照合・抽出する ``Regexp`` や、抽出した結果をハッシュ/辞書として保存する ``Dictionary`` ライブラリを導入すると、複雑なリクエストやデータを扱いやすくなるでしょう。 -:numref:`regexp01` に、RGBの色指定文字列などのリクエスト文字列をパースして辞書に追加するプログラムの断片を示します。**注意:このプログラム(** :numref:`regexp01` **)は、単体では動作しません** +:numref:`regexp01` に、RGBの色指定文字列などのリクエスト文字列をパースして辞書に追加するプログラムの断片を示します。**注意:このプログラム(** :numref:`regexp01` **)は、単体では動作しません。また、Plus2未確認です。** .. literalinclude:: src/regexp01.ino :caption: @@ -474,7 +427,7 @@ MQTT Publish ~~~~~~~~~~~~~~~~~~~~~~~~ -:numref:`mqtt01pub` は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ``office/temp`` というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 +:numref:`mqtt01pub` は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ``jikken`` というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 .. literalinclude:: src/mqtt01pub.ino @@ -484,12 +437,10 @@ :linenos: -.. warning:: 学内ネットワークからは、ポート制限のため、実験用ブローカ(mqtt.istlab.info) に接続できません。実験室に仮設するWifi基地局を利用してください。 - MQTT Subscribe ~~~~~~~~~~~~~~~~~~~~~~~~ -:numref:`mqtt01sub` は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ワイルドカード文字 ``+`` (プラス) は、任意の単一トピック階層にマッチするすべてのトピックを購読します。ワイルドカード文字 ``#`` は / で区切られた下位トピック階層も含めてマッチします。 JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング(deserialize) すると便利です(76行目以降にサンプルがあります)。 +:numref:`mqtt01sub` は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 ワイルドカード文字 ``+`` (プラス) は、任意の単一トピック階層にマッチするすべてのトピックを購読します。ワイルドカード文字 ``#`` は / で区切られた下位トピック階層も含めてマッチします。 JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング(deserialize) すると便利です(90行目以降にサンプルがあります)。 .. literalinclude:: src/mqtt01sub.ino :caption: @@ -523,8 +474,9 @@ .. note:: サンプルでは文字列(ASCII)データを送受信していますが、値をbyte配列・バイナリで送受信することもできます。 -Bluetooth Serial Protocol Profile (SPP) --------------------------------------------- + +Bluetooth Serial Protocol Profile (SPP) (Plus2未確認) +--------------------------------------------------------------------------------------------------- 「Serial通信」では、開発用PCのシリアルコンソールをつかって、USB接続を介して、文字列を送受信しました。 「Wifi接続」のTelnetサーバでは、TCP/IP通信上でのTelnet接続を介して、文字列を送受信しました。 @@ -571,7 +523,7 @@ https://lang-ship.com/blog/work/m5stickc-esp-now-1/ を参照してください。 :numref:`espnow02` に、MACアドレスにFF:FF:FF:FF:FF:FF を指定し、ブロードキャストする例を示します。 -ブロードキャストの場合、送信先のMACアドレスを指定しなくてよいので楽ですが、他の班のデバイスからも受信できます。espnow02.ino は、数値データのみを送受信する例です。espnow03.ino は、整数・小数・文字列をまとめてbyte (uint8_t) 配列に埋め込んで送受信する例です。 +ブロードキャストの場合、送信先のMACアドレスを指定しなくてよいので楽ですが、他の班のデバイスからも受信できます。``espnow02`` は、数値データのみを送受信する例です。 .. literalinclude:: src/espnow02.ino :caption: @@ -579,31 +531,31 @@ :language: arduino :linenos: +なお、``espnow03`` は、整数・小数・文字列をまとめてbyte (uint8_t) 配列に埋め込んで送信し、あとで取り出して利用する例です。(講義システムで確認してください。) -Preference +Preference・電源制御 ------------------------------------------- -再起動をすると、プログラムがリセットされて、通常の変数や配列データは消えてしまいます。Preferenceを用いると、不揮発性のフラッシュ領域を使ってデータを保存・復元することができます。 +再起動をすると、プログラムがリセットされて、通常の変数や配列データは消えてしまいますが、Preferenceを用いると、不揮発性のフラッシュ領域を使ってデータを保存・復元することができます。 +すこし下にある ``pref01`` (:numref:`pref01`)を参照してください。ボタンを押した回数が、本体に記録され、再起動しても継続されます。 -https://github.com/espressif/arduino-esp32/blob/master/libraries/Preferences/examples/StartCounter/StartCounter.ino - - -電源制御・電力制御 ------------------------------------ +以下に、電源に関連する命令を示します。 - ``ESP.restart()`` で、再起動します。 -- ``M5.Axp.Write1Byte(0x32, M5.Axp.Read8bit(0x32) | 0x80);`` で、電源OFFします。 +- ``M5.Power.powerOff()`` で、電源OFFします。(ただし、USB給電中だとフリーズします) +- ``esp_sleep_enable_timer_wakeup(60*60*24 * 1000000ULL); // 1日後に復帰`` のようにしたうえで、 ``esp_deep_sleep_start()`` で、タイマー設定Deep Sleepします。こちらはUSB給電中でも大丈夫です。 - ``setCpuFrequencyMhz(240)`` で、CPUのクロック数を変更できます。設定できる値は、240、160、80、40、20、10ですが、無線通信するなら80以上を設定する必要があります。 -- ``M5.Axp.ScreenBreath(8)`` で、画面の明るさを調整できます。8〜15が標準的ですが、7でも微かに読めます。 +- ``M5.Display.setBrightness(255)`` で、画面の明るさを調整できます。 -:numref:`pref01` に、Preferenceと電源制御のサンプルを示します。Aボタンでcountを増やし、Aボタン長押しでcountをリセットします。Bボタンで再起動、電源ボタンで電源OFFします。 +:numref:`pref01` に、Preferenceと電源制御のサンプルを示します。Aボタンでcountを増やし、Aボタン長押しでcountをリセットします。Bボタンで再起動、電源ボタンで電源OFFします。 **ただし、35行目のM5.Power.isCharging() はPlus2の場合、充電中かどうかを正しく検出できませんので注意してください。** (一応、Plus用に残しておきます。) .. literalinclude:: src/pref01.ino :caption: :name: pref01 :language: arduino :linenos: + :emphasize-lines: 35 .. その他 diff --git a/week2.rst b/week2.rst index d0dc4b1..f5f1709 100755 --- a/week2.rst +++ b/week2.rst @@ -30,7 +30,7 @@ :name: task01 :language: arduino :linenos: - :emphasize-lines: 4,63-65 + :emphasize-lines: 4,64-66 .. note:: 参考: `FreeRTOSでマルチタスク (on ESP32) `_ @@ -41,7 +41,7 @@ :name: task02 :language: arduino :linenos: - :emphasize-lines: 1,6,8,20,21,33,41 + :emphasize-lines: 3,8,10,26,27,46,54 .. warning:: 引数をアドレスで渡すとき、関数内で宣言したローカル変数は使えません。グローバルな変数を使用する必要があります。