M5Stackで遊んでみた

こんにちは、最近M5Stackを買って遊んでみました。せっかくなので作ったものを紹介します

お手軽雨雲レーダー

自宅に雨が降り始める前に、M5Stackが降雨をアラームで教えてくれます🔊
洗濯物を取り込み忘れないようにするために作ってみました。

仕組みとしてはこう言う感じです。

  1. 自宅のWifiに接続
  2. Yahoo!の気象情報APIを呼び出して自宅付近の1時間後の予想降水量を取得
  3. その値を元に画面表示・値が閾値を超えているとアラーム
  4. Wifiを切断
  5. 15分wait

ちなみに、アラームには呼び込み君っぽいメロディを設定してみました。イオンでよく流れてるやつです

メロディの実装についてはこちらのブログを参考にさせていただきました。大変感謝しております🙏
また、残念だったこととして、M5Stackにはバッテリーが備わっているので充電は数日に一度程度の前提でこのプログラムを作ってましたが、実際に動かすと3時間ほどでバッテリーがなくなってしまいました…1日に何回も充電するのは現実的ではないので実戦投入は断念しました🙄
そして後から知ったんですが、M5Stackをdelay()させるのではなくディープスリープさせることで飛躍的にバッテリーの持続時間が伸びるらしいです。また気が乗ればチャレンジしたい

できたものはこんな感じです。この動画は予想降水量が0.0を上回ってる場合です
音が出るので注意して下さい

▼ソースコード
/*
MIT License

Copyright (c) 2023 morifuji-is.ninja

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Copyright (c) 2020 shikarunochi
https://github.com/shikarunochi/M5CoreInkYobukomiKun/blob/main/LICENSE
*/
#include <M5Stack.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include "pitches.h"
#include "time.h"

const char* ssid = "xxxxx";
const char* password = "xxxxxx";

#define JST 3600 * 9

void setup() {

  M5.begin();
  M5.Power.begin();

  M5.Lcd.setTextSize(2);
}

void loop() {
  M5.Lcd.clear(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(WHITE);
  
  int batteryLevel = M5.Power.getBatteryLevel();
  M5.Lcd.printf("%3d%%",batteryLevel);

  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(3000);
    return;
  }
  M5.Lcd.print("/WiFi");

  printLocalTime();

  if (checkRainfail() == -1) {
    delay(3000);
    return;
  }

  WiFi.disconnect();

  delay(5 * 60 * 1000);
}

int checkRainfail() {
  HTTPClient httpClient;

  // URL 設定
  httpClient.begin("https://map.yahooapis.jp/weather/V1/place?appid=XXXXXXXXXXXX&coordinates=135.111111,34.77777777&output=json");

  int status_code = httpClient.GET();
  if (status_code != 200) {
    M5.Lcd.print("Error, status code is not 200!");
    M5.Lcd.println(status_code);
    httpClient.end();
    return -1;
  }

  M5.Lcd.println("/HTTP");

  String response = httpClient.getString();
  httpClient.end();

  // JSON形式データ格納用メモリの確保
  StaticJsonDocument<1536> n_jsondata;

  // JSON形式データの読み込み
  DeserializationError error = deserializeJson(n_jsondata, response);

  if (error) {
    M5.Lcd.print(F("deserializeJson() failed: "));
    M5.Lcd.println(error.f_str());
    return -1;
  }
  const double rainFallInOneHour = n_jsondata["Feature"]["Property"]["WeatherList"]["Weather"][6]["Rainfall"];

  if (rainFallInOneHour == 0.0) {
    M5.Lcd.setTextColor(GREEN);
  } else if (rainFallInOneHour < 1.0) {
    M5.Lcd.setTextColor(YELLOW);
  } else {
    M5.Lcd.setTextColor(RED);
  }

  M5.Lcd.print("rainfall in 1 hour is ...");
  M5.Lcd.setTextSize(4);
  M5.Lcd.printf(" %f mm/h", rainFallInOneHour);
  M5.Lcd.setTextSize(2);

  if (rainFallInOneHour != 0.0) {
    playYobikomi();
  } else {
    playBeep();
  }

  return 0;
}


void playBeep() {
  int i;
  for (i = 0; i < 3; i++){
    M5.Speaker.tone(NOTE_E4, 150);
    delay(150);
    M5.Speaker.mute();
    delay(150);
  }
}

#define NOTE_1 2000
#define NOTE_2 NOTE_1 / 2
#define NOTE_4 NOTE_1 / 4
#define NOTE_4P NOTE_1 / 4 + NOTE_1 / 8
#define NOTE_8 NOTE_1 / 8

#define NUMPIXELS 10
#define PIN 15


int musicData[][2] = {
  { NOTE_G5, NOTE_8 },
  { NOTE_G5, NOTE_4 },
  { NOTE_A5, NOTE_8 },
  { NOTE_G5, NOTE_8 },
  { NOTE_E5, NOTE_8 },
  { NOTE_G5, NOTE_4 },
  { NOTE_G5, NOTE_8 },
  { NOTE_G5, NOTE_4 },
  { NOTE_A5, NOTE_8 },
  { NOTE_G5, NOTE_8 },
  { NOTE_E5, NOTE_8 },
  { NOTE_G5, NOTE_4 },

  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_D5, NOTE_8 },
  { NOTE_E5, NOTE_4P },
  { NOTE_C5, NOTE_8 },

  { NOTE_E5, NOTE_4P },
  { NOTE_G5, NOTE_8 },
  { NOTE_G5, NOTE_2 },

  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_D5, NOTE_8 },
  { NOTE_E5, NOTE_2 },

  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_D5, NOTE_8 },
  { NOTE_E5, NOTE_2 },

  { NOTE_D5, NOTE_8 },
  { NOTE_D5, NOTE_8 },
  { NOTE_D5, NOTE_8 },
  { NOTE_C5, NOTE_8 },
  { NOTE_D5, NOTE_4 },
  { NOTE_E5, NOTE_4 },

  { NOTE_G5, NOTE_4 },
  { NOTE_F5, NOTE_4 },
  { NOTE_E5, NOTE_4 },
  { NOTE_D5, NOTE_4 },

  { NOTE_G5, NOTE_8 },
  { NOTE_G5, NOTE_4 },
  { NOTE_A5, NOTE_8 },
  { NOTE_G5, NOTE_8 },
  { NOTE_E5, NOTE_8 },
  { NOTE_G5, NOTE_4 },

  { NOTE_G5, NOTE_8 },
  { NOTE_G5, NOTE_4 },
  { NOTE_A5, NOTE_8 },
  { NOTE_G5, NOTE_8 },
  { NOTE_E5, NOTE_8 },
  { NOTE_G5, NOTE_4 },

  { NOTE_C5, NOTE_1 },
  { 0, NOTE_1 },
};


void playYobikomi() {
  int musicSize = sizeof(musicData) / sizeof(*musicData);
  for (int index = 0; index < musicSize; index++) {
    if (musicData[index][0] > 0) {
      M5.Speaker.tone(musicData[index][0], musicData[index][1]);
    }
    delay(musicData[index][1] - 100);
    M5.Speaker.mute();
    delay(100);

    M5.update();
    if (M5.BtnA.wasPressed()) {
      break;
    }
  }
  M5.Speaker.mute();
}

int printLocalTime() {

  configTime(JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");

  struct tm timeinfo;

  // 時刻を取得できなかった場合
  if (!getLocalTime(&timeinfo)) {
    M5.Lcd.print("/?");
    return -1;
  }

  // 現在時刻を表示
  M5.Lcd.printf("/%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);

  return 0;
}

DVDプレーヤー待機画面のやつ

こう言うやつです。同世代の人はめちゃくちゃ馴染みあると思うんですよね〜この映像。M5StackのLCDの操作がわからなかったので試しに作ってみました。

できたものはこんな感じです。DVDのロゴ画像があまりネットになくて適当な画像になってしまいました。。
画像をM5Stackに表示するには結構大変で、画像をこちらのツールuint8に変換してコードとして添付する必要がありました。microSDを用意すればもっと簡単らしいんですが空いてるmicroSDがなかったのでこうせざるを得ませんでした。

▼ソースコード
#include <M5Stack.h>
#include "dvd_image.c"

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.Power.begin();

  M5.Lcd.fillScreen(BLACK); 

  // 64px, 28px
  M5.Lcd.drawJpg(dvd_image, 1473);
}

const int width = 64;
const int height = 28;

double previous_millis = 0;
double x = 0;
double y = 0;

// SELECT_ANGLE, IN_GAME
char* status = "SELECT_ANGLE";

int angle_pattern = 5;

int angle_patterns[11][2] = {
  {100,0},
  {98,16},
  {95,32},
  {89,45},
  {81,59},
  {71,71},
  {59,81},
  {45,89},
  {32,95},
  {16,98},
  {0,100}
};


void loop() {
  M5.update();
  M5.Lcd.clear(BLACK);
  M5.Lcd.setCursor(20, 20);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextColor(WHITE);

  if (status == "SELECT_ANGLE") {
    mode_select();
    return;
  }

  if (previous_millis==0) {
    previous_millis = millis();
  }
  
  long diff = millis() - previous_millis;

  float diff_x = diff*angle_patterns[angle_pattern][0]/1000;
  float diff_y = diff*angle_patterns[angle_pattern][1]/1000;

  x += diff_x;
  y += diff_y;

  double distance_x = fmod(x, 2*(320-width));
  double distance_y = fmod(y, 2*(240-height));

  if (distance_x > (320-width)) {
    distance_x -= 2*(distance_x-(320-width));
  }
  if (distance_y > (240-height)) {
    distance_y -= 2*(distance_y-(240-height));
  }

  M5.Lcd.drawJpg(dvd_image, 1473, distance_x,distance_y);

  previous_millis = millis();

  delay(100);
}

void mode_select() {
  M5.Lcd.drawLine(0, 0, angle_patterns[angle_pattern][0], angle_patterns[angle_pattern][1], YELLOW);

  if (M5.BtnA.wasPressed()) {
    angle_pattern+=1;
  }
  if (M5.BtnB.wasPressed()) {
    angle_pattern-=1;
  }

  if (M5.BtnC.wasPressed()) {
    status = "IN_GAME";
  }
  delay(100);
}
// dvd_image.c

// DVD_logo.svg.jpg
// https://lang-ship.com/tools/image2data/

// RGB565 Dump(little endian)
const unsigned char dvd_image[1473] = {
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x48, 
0x00, 0x48, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x80, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d, 
0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 
0x00, 0x01, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 
0x01, 0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x87, 0x69, 0x00, 0x04, 
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0xa0, 0x01, 
0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 
0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x1c, 0x00, 0x40, 0x03, 
0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 
0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 
0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 
0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 
0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 
0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 
0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 
0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 
0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 
0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 
0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 
0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 
0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 
0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 
0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 
0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 
0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 
0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x0b, 0x0b, 
0x0b, 0x0b, 0x0b, 0x0b, 0x12, 0x0b, 0x0b, 0x12, 0x1a, 0x12, 0x12, 0x12, 0x1a, 0x23, 0x1a, 0x1a, 
0x1a, 0x1a, 0x23, 0x2c, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2c, 0x35, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 
0x2c, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 
0x4a, 0x4a, 0x4a, 0x4a, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0xff, 0xdb, 
0x00, 0x43, 0x01, 0x0d, 0x0e, 0x0e, 0x15, 0x14, 0x15, 0x24, 0x14, 0x14, 0x24, 0x57, 0x3b, 0x30, 
0x3b, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 
0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 
0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 
0x57, 0x57, 0x57, 0xff, 0xdd, 0x00, 0x04, 0x00, 0x04, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 
0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xe8, 0x7c, 0x75, 0x79, 0xa7, 0x47, 0x69, 0x05, 0x8e, 
0xa0, 0x67, 0xdb, 0x33, 0xef, 0x02, 0x02, 0x80, 0xfc, 0x98, 0xeb, 0xbf, 0x8c, 0x64, 0x8a, 0xc2, 
0xd2, 0xbc, 0x0f, 0xa3, 0xea, 0xda, 0x7c, 0x7a, 0x84, 0x13, 0x5d, 0xc4, 0xb2, 0x82, 0x54, 0x48, 
0x50, 0x9c, 0x03, 0x8c, 0x90, 0x17, 0x1c, 0xd6, 0x77, 0x8f, 0x85, 0xed, 0xf6, 0xb4, 0x22, 0xb7, 
0x8a, 0x47, 0x4b, 0x78, 0xd5, 0x41, 0x08, 0xc4, 0x6e, 0x6f, 0x98, 0xe0, 0x80, 0x41, 0xed, 0x5a, 
0x76, 0x7e, 0x2a, 0xd4, 0xed, 0x74, 0xe8, 0x34, 0xdd, 0x37, 0x48, 0x9c, 0xbc, 0x31, 0xac, 0x61, 
0x9d, 0x5b, 0x19, 0x03, 0x19, 0xc0, 0x5f, 0x5f, 0x52, 0x28, 0x03, 0xce, 0xb5, 0xbd, 0x26, 0x5d, 
0x17, 0x53, 0x96, 0xc2, 0x47, 0xf3, 0x04, 0x78, 0x3b, 0x87, 0x1b, 0x94, 0x8c, 0x83, 0x8e, 0x71, 
0x5b, 0xfa, 0x1b, 0xbf, 0x87, 0x3c, 0x56, 0x90, 0x4a, 0xdf, 0x2e, 0xff, 0x00, 0x29, 0xb3, 0xc9, 
0xd9, 0x28, 0x05, 0x49, 0xfc, 0x4a, 0xfe, 0xb5, 0xd1, 0xe9, 0x5e, 0x0e, 0xd4, 0xb5, 0x4d, 0x45, 
0xb5, 0x6f, 0x12, 0x61, 0x43, 0xb6, 0xf3, 0x19, 0xc1, 0x67, 0x3d, 0x81, 0x03, 0x21, 0x57, 0x81, 
0xc6, 0x49, 0xc7, 0x1e, 0xb9, 0xaf, 0xf1, 0x23, 0x4e, 0x78, 0x6e, 0xed, 0xb5, 0x48, 0x06, 0x3c, 
0xc1, 0xe5, 0xb6, 0x3b, 0x32, 0x72, 0xbf, 0xa6, 0x7f, 0x2a, 0x00, 0xe8, 0x7c, 0x6b, 0xe2, 0x91, 
0xa5, 0xc4, 0x74, 0xcb, 0x26, 0xff, 0x00, 0x49, 0x91, 0x7e, 0x76, 0x1f, 0xf2, 0xcd, 0x4f, 0xfe, 
0xcc, 0x7b, 0x7a, 0x0e, 0x7d, 0x2b, 0xce, 0x1b, 0x4a, 0xd3, 0xf4, 0xd8, 0x21, 0x7d, 0x7b, 0xed, 
0x29, 0x35, 0xca, 0x99, 0x16, 0x38, 0x4a, 0x29, 0x54, 0xce, 0x01, 0x7d, 0xfd, 0xcf, 0x5c, 0x76, 
0xef, 0xcd, 0x75, 0xde, 0x0e, 0xf0, 0xec, 0xda, 0x84, 0xdf, 0xf0, 0x91, 0x6b, 0x39, 0x93, 0x7b, 
0x6f, 0x88, 0x3f, 0x57, 0x3f, 0xdf, 0x3e, 0xdf, 0xdd, 0xfc, 0xfa, 0x62, 0xb0, 0x7c, 0x69, 0x15, 
0xf6, 0xa1, 0xaf, 0xce, 0xf1, 0x41, 0x23, 0x24, 0x41, 0x62, 0x56, 0x08, 0xe4, 0x10, 0x07, 0x3c, 
0x81, 0x8e, 0xa4, 0xfe, 0x54, 0x01, 0xd1, 0xd8, 0xf8, 0x07, 0x49, 0xd4, 0x2c, 0x22, 0xbe, 0x82, 
0xe2, 0xea, 0x3f, 0x3d, 0x03, 0xa8, 0x90, 0xa3, 0x60, 0x37, 0x23, 0x20, 0x2d, 0x73, 0x56, 0x1a, 
0xa6, 0xad, 0xe1, 0x6d, 0x6c, 0xe9, 0xcd, 0x31, 0x96, 0x28, 0xe4, 0x11, 0xbc, 0x79, 0x25, 0x48, 
0xc8, 0xe4, 0x03, 0x9c, 0x1c, 0x30, 0x3c, 0x7d, 0x0e, 0x6b, 0xab, 0xff, 0x00, 0x84, 0xbf, 0x59, 
0x92, 0x14, 0xb4, 0xd2, 0x74, 0x89, 0x95, 0x82, 0x84, 0x53, 0x22, 0xb1, 0xc6, 0x06, 0x33, 0x8c, 
0x01, 0xf9, 0x91, 0x51, 0xf8, 0x7f, 0xc1, 0x97, 0xcf, 0x7e, 0x35, 0x8d, 0x7d, 0xbe, 0x70, 0xfe, 
0x67, 0x97, 0x90, 0x59, 0x9f, 0x39, 0x05, 0xc8, 0xe0, 0x60, 0xf3, 0x81, 0xed, 0xd8, 0x62, 0x80, 
0x3f, 0xff, 0xd0, 0xeb, 0x6f, 0xbc, 0x71, 0xe1, 0xfb, 0x22, 0xea, 0x25, 0x6b, 0x86, 0x4e, 0xa2, 
0x15, 0x2c, 0x33, 0xe9, 0xbb, 0x85, 0xfd, 0x6b, 0x02, 0x6f, 0x89, 0xb6, 0x2a, 0x3f, 0x73, 0x69, 
0x23, 0x7f, 0xbc, 0xea, 0x3f, 0x91, 0x35, 0xd6, 0x5f, 0x78, 0x4f, 0x40, 0xd4, 0x1c, 0xcb, 0x3d, 
0xaa, 0x89, 0x09, 0xc9, 0x78, 0xc9, 0x42, 0x4f, 0xbe, 0xdc, 0x66, 0xb9, 0x6b, 0xff, 0x00, 0x01, 
0x68, 0xa8, 0x77, 0xc6, 0xf3, 0xaf, 0xb6, 0xe0, 0xc3, 0xff, 0x00, 0x1e, 0x53, 0x40, 0x14, 0x60, 
0xf8, 0x91, 0x7b, 0x77, 0x2a, 0xc1, 0x69, 0xa6, 0x87, 0x91, 0xce, 0x15, 0x44, 0x8c, 0xc4, 0x9f, 
0xc1, 0x2a, 0xf6, 0xa1, 0x77, 0xe2, 0x5d, 0x5a, 0x05, 0x82, 0xf7, 0x40, 0x12, 0x46, 0xae, 0xaf, 
0xb4, 0xca, 0x3a, 0xaf, 0x3f, 0xfe, 0xba, 0xe5, 0x6e, 0x7c, 0x3d, 0x6b, 0x62, 0xde, 0x6d, 0xb4, 
0xd3, 0x23, 0xaf, 0x46, 0x05, 0x41, 0x1f, 0x42, 0x14, 0x1a, 0xa2, 0xda, 0xde, 0xb9, 0x06, 0x62, 
0x4d, 0x42, 0x7d, 0xab, 0xc7, 0x2c, 0x09, 0xfc, 0xc8, 0xcd, 0x00, 0x76, 0x37, 0xbe, 0x3a, 0xd6, 
0x34, 0x96, 0x58, 0xb5, 0x0d, 0x28, 0x5b, 0x92, 0x3e, 0x50, 0x5c, 0x80, 0x40, 0xf4, 0x21, 0x48, 
0xe2, 0xab, 0xc5, 0xf1, 0x41, 0x4b, 0x62, 0x6b, 0x1c, 0x0f, 0x55, 0x93, 0xfc, 0x54, 0x57, 0x1d, 
0x14, 0x32, 0xea, 0xf2, 0x07, 0xd4, 0x2e, 0x26, 0x95, 0x81, 0x38, 0x2c, 0xdb, 0xb1, 0x9f, 0x4d, 
0xc0, 0xe3, 0xf0, 0xae, 0x9a, 0xcf, 0xc1, 0xba, 0x65, 0xce, 0x03, 0xc9, 0x30, 0xcf, 0xa6, 0xcf, 
0xfe, 0x22, 0x80, 0x3a, 0x2b, 0x7f, 0x89, 0x1a, 0x3c, 0xae, 0x12, 0x68, 0x66, 0x8f, 0x3d, 0xc0, 
0x57, 0x1f, 0xf8, 0xe9, 0xcf, 0xe9, 0x5d, 0x7e, 0x99, 0xad, 0x69, 0xba, 0xc2, 0x33, 0xe9, 0xf3, 
0x09, 0x36, 0x7d, 0xe5, 0xc1, 0x0c, 0xb9, 0xf5, 0x53, 0x82, 0x2b, 0x9b, 0xb5, 0xf0, 0x17, 0x87, 
0x91, 0x07, 0x9a, 0x92, 0xcd, 0x8f, 0xef, 0xc8, 0x7f, 0x92, 0xe0, 0x57, 0x57, 0x63, 0xa6, 0xd8, 
0x69, 0xb1, 0x98, 0xac, 0x20, 0x48, 0x54, 0x9c, 0x90, 0x83, 0x19, 0x3e, 0xfe, 0xb4, 0x01, 0xff, 
0xd9, };

所感

  • C言語について
    • C言語難しい…🤮
    • ArudinoIDEの補完がうまく効かないのもあって完全に雰囲気でしか実装してなかった..
  • デバッグしにくい
    • M5Stackに載っているESP32というマイコンではデバッグが簡単にできない?らしい
    • ソースコード修正してコンパイルしてアップロードして動作確認、という回りくどい方法でしかデバッグできなかった
  • 一つ一つの命令が細かくて大変
  • それら踏まえても面白い
    • 無駄なものって作るのっておもしろいですよね
      • 作ってる時が一番面白い説
    • Rustでなんかやりたいと思ってたけどArudino触ってる方が地味に面白い
  • M5Stackの活用例をIoT詳しい人に聞いたら、BlueToothを使ったトランシーバーにするのがオススメって言われた
    • トランシーバーは初学者にはハードル高いけどいつか作れたら面白いやろなぁと思った
      • 家の中でAlexa同士で音声通話してるのを代替させたい

See also