2025年5月13日火曜日

iOS 18.5リリース

iOS 18.5がリリースされました

対象デバイスは、iPhone XS以降, iPad(7代目), iPad mini(5代目以降), iPad Air(3代目), iPad Pro(13インチ、12.9インチ 3代目以降、11インチ 初代以降)になります

アップデート内容は、以下の様になっています

  • 新しいプライドハ一モニーの壁紙
  • お子様のデバイスでスクU一ンタイムパスコードが使用されると、親/保護者に通知が届くようになりました
  • 他社製デバイス上のApple TVアフリでコンテンツを購入するときに、"iPhoneで購入"を使用できます
  • Apple Vision Proアブリで黒い画面が表示されるごとがある問題を修正しました
  • iPhone 13(すべてのモデル)で通信事業者から提供される衛星通信の機能に対応しました。詳しい情報: http;//support.apple.com/ja-jp/122339

Apple セキュリティアップデートを確認すると以下のセキュリティアップデート内容が記載されています

AppleJPEG

CVE-2025-31251: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

Baseband

CVE-2025-31214: 秦若涵, 崔志伟, and 崔宝江

Call History

CVE-2025-31225: Deval Jariwala

Core Bluetooth

CVE-2025-31212: Guilherme Rambo of Best Buddy Apps (rambo.codes)

CoreAudio

CVE-2025-31208: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreGraphics

CVE-2025-31209: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreMedia

CVE-2025-31239: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CVE-2025-31233: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

FaceTime

CVE-2025-31253: Dalibor Milanovic

CVE-2025-31210: Andrew James Gonzalez

FrontBoard

CVE-2025-31207: YingQi Shi (@Mas0nShi) of DBAppSecurity's WeBin lab, Duy Trần (@khanhduytran0)

iCloud Document Sharing

CVE-2025-30448: Dayton Pidhirney of Atredis Partners, Lyutoon and YenKoc

ImageIO

CVE-2025-31226: Saagar Jha

Kernel

CVE-2025-31219: Michael DePlante (@izobashi) and Lucas Leong (@_wmliang_) of Trend Micro Zero Day Initiative

CVE-2025-31241: Christian Kohlschütter

libexpat

CVE-2024-8176

Mail Addressing

CVE-2025-24225: Richard Hyunho Im (@richeeta)

mDNSResponder

CVE-2025-31222: Paweł Płatek (Trail of Bits)

Notes

CVE-2025-31228: Andr.Ess

CVE-2025-31227: Shehab Khan

Pro Res

CVE-2025-31245: wac

CVE-2025-31234: CertiK (@CertiK)

Security

CVE-2025-31221: Dave G.

WebKit

CVE-2025-24213: Google V8 Security Team

CVE-2025-31223: Andreas Jaegersberger & Ro Achterberg of Nosebeard Labs

CVE-2025-31238: wac working with Trend Micro Zero Day Initiative

CVE-2025-24223: rheza (@ginggilBesel) and an anonymous researcher

CVE-2025-31204: Nan Wang(@eternalsakura13)

CVE-2025-31217: Ignacio Sanmillan (@ulexec)

CVE-2025-31215: Jiming Wang and Jikai Ren

CVE-2025-31206: an anonymous researcher

CVE-2025-31205: Ivan Fratric of Google Project Zero

CVE-2025-31257: Juergen Schmied of Lynck GmbH

なおアップデートファイルの大きさは、iOS 18.4.1をインストールしているiPhone 11 proで1.17GB、iPhone 11で1.15GBになります


スマホ・携帯ランキング

2025年5月10日土曜日

Timer Camera X(ジャンク)、WiFiに繋がるか...

 先の記事で記載したWiFiに接続できないM5STACK ESP32 PSRAM Timer Camera XでWiFi関連をチェックしてみました。結論を先に言ってしまうと、繋がりませんでした。

最初にM5Burnerを使用してTimerCamForUIFlowを書き込んで、CameraToolsに接続しました。残念ながら、USB経由では問題なく接続できましたが、WiFiにすると接続がエラーになります。やはり、問題があることは確かです。

ESP32 Wifi接続できない"をキーワードに検索をしてみた結果、いろいろと出てきました。そこで、それらを踏まえたチェック用のスケッチを作成しました。内容としてはMACアドレス表示、セキュリティ設定の変更、電波強度変更、WiFiスキャン(ファクトリテストで行っていました)を行うようにしています

Unitに映像を表示させることにしました。なお、JEPEGモード、320x240で撮影し、それをLCD Unitに表示する簡単な記述になります。

#include <M5TimerCAM.h>
#include <M5GFX.h>
#include <M5UnitLCD.h>
#include <WiFi.h>
#include "wifi_chk.h"

// M5UnitLCD display
M5UnitLCD display(4, 13, 400000);  // SDA, SCL, FREQ

int tx_power;     // 送信出力値格納用
char msgbuf[64];  // メッセージ表示用

// WiFi Power CHeck
void wifi_power_chk() {
  Serial.println("WiFi Power CHeck");
  display.println("WiFi Power CHeck");

  wifi_power_t wifiPWR[11];
  wifiPWR[0] = WIFI_POWER_19_5dBm;  // 78
  wifiPWR[1] = WIFI_POWER_19dBm;    // 76
  wifiPWR[2] = WIFI_POWER_18_5dBm;  // 74
  wifiPWR[3] = WIFI_POWER_17dBm;    // 68
  wifiPWR[4] = WIFI_POWER_15dBm;    // 60
  wifiPWR[5] = WIFI_POWER_13dBm;    // 52
  wifiPWR[6] = WIFI_POWER_11dBm;    // 44
  wifiPWR[7] = WIFI_POWER_8_5dBm;   // 34
  wifiPWR[8] = WIFI_POWER_7dBm;     // 28
  wifiPWR[9] = WIFI_POWER_5dBm;     // 20
  wifiPWR[10] = WIFI_POWER_2dBm;    // 8

  WiFi.disconnect(true, true);
  WiFi.mode(WIFI_STA);
  WiFi.setMinSecurity(WIFI_AUTH_WPA2_PSK);  // Lower min security to WPA.
  for (int i = 0; i < 11; ++i) {
    WiFi.begin(ssid, password);
    wl_status_t status = WiFi.begin(ssid, password);
    WiFi.setTxPower(wifiPWR[i]);
    sprintf(msgbuf, "Try WiFi connection by %d...", WiFi.getTxPower());
    Serial.printf(msgbuf);
    display.println(msgbuf);

    delay(10000);
    if (status != WL_CONNECTED) {
      status = WiFi.status();
      sprintf(msgbuf,
              status == WL_NO_SHIELD ? "no shield\n" : status == WL_IDLE_STATUS     ? "idle\n"
                                                     : status == WL_NO_SSID_AVAIL   ? "no ssid available\n"
                                                     : status == WL_SCAN_COMPLETED  ? "scan completed\n"
                                                     : status == WL_CONNECT_FAILED  ? "connect failed\n"
                                                     : status == WL_CONNECTION_LOST ? "connection lost\n"
                                                     : status == WL_DISCONNECTED    ? "disconnected\n"
                                                                                    : "connected\n");
    } else sprintf(msgbuf, "conncted\n");
    Serial.printf(msgbuf);
    display.println(msgbuf);
    WiFi.disconnect(true, true);
    WiFi.reconnect();
  }
}

// WiFi Security CHeck
void wifi_sec_chk() {
  Serial.println("WiFi Security CHeck");
  display.println("WiFi Security CHeck");

  wifi_auth_mode_t wifiSEC[6];
  wifiSEC[0] = WIFI_AUTH_OPEN;            /**< authenticate mode : open */
  wifiSEC[1] = WIFI_AUTH_WEP;             /**< authenticate mode : WEP */
  wifiSEC[2] = WIFI_AUTH_WPA_PSK;         /**< authenticate mode : WPA_PSK */
  wifiSEC[3] = WIFI_AUTH_WPA2_PSK;        /**< authenticate mode : WPA2_PSK */
  wifiSEC[4] = WIFI_AUTH_WPA_WPA2_PSK;    /**< authenticate mode : WPA_WPA2_PSK */
  wifiSEC[5] = WIFI_AUTH_WPA2_ENTERPRISE; /**< authenticate mode : WPA2_ENTERPRISE */

  WiFi.disconnect(true, true);
  WiFi.mode(WIFI_STA);
  for (int i = 0; i < 6; ++i) {
    WiFi.begin(ssid, password);
    wl_status_t status = WiFi.begin(ssid, password);
    WiFi.setMinSecurity(wifiSEC[i]);
    switch (wifiSEC[i]) {
      case WIFI_AUTH_OPEN:
        sprintf(msgbuf, "Try WiFi connection by open ...\n");
        break;
      case WIFI_AUTH_WEP:
        sprintf(msgbuf, "Try WiFi connection by WEP ...\n");
        break;
      case WIFI_AUTH_WPA_PSK:
        sprintf(msgbuf, "Try WiFi connection by WPA ...\n");
        break;
      case WIFI_AUTH_WPA2_PSK:
        sprintf(msgbuf, "Try WiFi connection by WPA2 ...\n");
        break;
      case WIFI_AUTH_WPA_WPA2_PSK:
        sprintf(msgbuf, "Try WiFi connection by WPA+WPA2 ...\n");
        break;
      case WIFI_AUTH_WPA2_ENTERPRISE:
        sprintf(msgbuf, "Try WiFi connection by WPA2-EAP ...\n");
        break;
      default:
        sprintf(msgbuf, "Setting error!\n");
    }
    Serial.printf(msgbuf);
    display.println(msgbuf);

    delay(10000);
    if (status != WL_CONNECTED) {
      status = WiFi.status();
      sprintf(msgbuf,
              status == WL_NO_SHIELD ? "no shield\n" : status == WL_IDLE_STATUS     ? "idle\n"
                                                     : status == WL_NO_SSID_AVAIL   ? "no ssid available\n"
                                                     : status == WL_SCAN_COMPLETED  ? "scan completed\n"
                                                     : status == WL_CONNECT_FAILED  ? "connect failed\n"
                                                     : status == WL_CONNECTION_LOST ? "connection lost\n"
                                                     : status == WL_DISCONNECTED    ? "disconnected\n"
                                                                                    : "connected\n");
    } else sprintf(msgbuf, "conncted\n");
    Serial.printf(msgbuf);
    display.println(msgbuf);
    WiFi.disconnect(true, true);
    WiFi.reconnect();
  }
}

void setup() {
  TimerCAM.begin();
  display.begin();
  WiFi.begin();

  Serial.begin(115200);
  display.setTextSize(2);
  display.setRotation(3);
  display.setTextScroll(true);
  display.clear(TFT_BLACK);

  // Show MacAddress
  byte mac[6];
  WiFi.macAddress(mac);
  sprintf(msgbuf, "MAC Address : \n %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.printf(msgbuf);
  display.println(msgbuf);

  // Show WiFi Power (Default)
  WiFi.disconnect(true, true);
  tx_power = WiFi.getTxPower();  // デフォルトの送信出力取得 19.5dBmだと78
  sprintf(msgbuf, "Default TxPower: %d\n", tx_power);
  Serial.printf(msgbuf);
  display.println(msgbuf);
  delay(5000);

  display.clear(TFT_BLACK);
  wifi_sec_chk();
  display.clear(TFT_BLACK);
  wifi_power_chk();
}

void loop() {
  //WiFi スキャン
  Serial.println("WiFi Scan start");
  display.println("WiFi Scan start");

  // WiFi.scanNetworks will return the number of networks found.
  int n = WiFi.scanNetworks();
  Serial.println("WiFi Scan done");
  display.println("WiFi Scan done");
  if (n == 0) {
    Serial.println("no networks found\n");
    display.println("no networks found\n");
  } else {
    sprintf(msgbuf, "%2d networks found\n", n);
    Serial.printf(msgbuf);
    display.println(msgbuf);
    Serial.println("Nr | SSID                             | RSSI | CH | Encryption");
    display.println("Nr | SSID                             | RSSI | CH | Encryption");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      sprintf(msgbuf, "%2d | %-32.32s | %4d | %2d | ", i + 1, WiFi.SSID(i).c_str(), WiFi.RSSI(i), WiFi.channel(i));
      Serial.printf(msgbuf);
      display.println(msgbuf);
      switch (WiFi.encryptionType(i)) {
        case WIFI_AUTH_OPEN:
          sprintf(msgbuf, "open\n");
          break;
        case WIFI_AUTH_WEP:
          sprintf(msgbuf, "WEP\n");
          break;
        case WIFI_AUTH_WPA_PSK:
          sprintf(msgbuf, "WPA\n");
          break;
        case WIFI_AUTH_WPA2_PSK:
          sprintf(msgbuf, "WPA2\n");
          break;
        case WIFI_AUTH_WPA_WPA2_PSK:
          sprintf(msgbuf, "WPA+WPA2\n");
          break;
        case WIFI_AUTH_WPA2_ENTERPRISE:
          sprintf(msgbuf, "WPA2-EAP\n");
          break;
        case WIFI_AUTH_WPA3_PSK:
          sprintf(msgbuf, "WPA3\n");
          break;
        case WIFI_AUTH_WPA2_WPA3_PSK:
          sprintf(msgbuf, "WPA2+WPA3\n");
          break;
        case WIFI_AUTH_WAPI_PSK:
          sprintf(msgbuf, "WAPI\n");
          break;
        default:
          sprintf(msgbuf, "unknown\n");
      }
      Serial.printf(msgbuf);
      display.println(msgbuf);
      delay(10);
    }
  }
  Serial.printf("");
  display.println("");

  // Delete the scan result to free memory for code below.
  WiFi.scanDelete();

  // Wait a bit before scanning again.
  delay(5000);
  TimerCAM.Power.powerOff();
}

調べては継ぎ足しして作成したので、冗長な記述が多いです(汗

なおwifi_chk.hは、ssidとpasswordのみを宣言しています。 wifi_sec_chk()がセキュリティ設定を変更して接続チェックを行っています。wifi_power_chk()は電波強度を変更して接続チェックを行っています。なお、loop()ないでWiFiスキャンを行っています。

実行した結果は下記になります:

MAC Address : 
 **:**:**:**:**:**
Default TxPower: 78
WiFi Security CHeck
Try WiFi connection by open ...
disconnected
Try WiFi connection by WEP ...
disconnected
Try WiFi connection by WPA ...
disconnected
Try WiFi connection by WPA2 ...
disconnected
Try WiFi connection by WPA+WPA2 ...
disconnected
Try WiFi connection by WPA2-EAP ...
no ssid available
WiFi Power CHeck
Try WiFi connection by 72...disconnected
Try WiFi connection by 72...disconnected
Try WiFi connection by 72...disconnected
Try WiFi connection by 66...disconnected
Try WiFi connection by 60...disconnected
Try WiFi connection by 50...disconnected
Try WiFi connection by 38...disconnected
Try WiFi connection by 28...disconnected
Try WiFi connection by 28...disconnected
Try WiFi connection by 14...disconnected
Try WiFi connection by 2...disconnected
WiFi Scan start
WiFi Scan done
 3 networks found
Nr | SSID                             | RSSI | CH | Encryption
 1 | ***********                      |  -85 | 11 | WPA+WPA2
 2 | ***********                      |  -89 |  4 | WPA2
 3 | ***********                      |  -93 |  4 | WPA2

MACアドレスは正常に表示され、WiFiスキャンも実行されました。しかし、セキュリティや電波強度の変更を行ってもまったく繋がる様子がありません。スキャンは正常なのに何で?!って感じです。また、電波強度は設定した値と読み取った値が異なることも良くわかりません。今度、M5STAMP Picoで試してみたいと思います

最終手段でフラッシュメモリをクリアして、工場出荷状態に戻して上記テストを再度行ってみました(フラッシュメモリのクリアは自己責任でお願いします)。クリアにはesptool.pyを使用します。入手先はEspressifのGithubになります

https://github.com/espressif/esptool

下記コマンドにて、フラッシュをクリアできます

”esptool.py -p シリアルポート名 erase_flash"

残念ながら フラッシュメモリをクリアでも問題は改善しませんした。と言うわけで最初に記載した通り、結果はWiFiには何をやっても繋がりませんでした。

念のため、蓋を開けて確認しましたが老いた目では問題があるようには見えません


当初の予定通りカメラボードとして、余生を過ごしてもらう結果になりました

参考にさせて頂きましたサイト:

2025年5月9日金曜日

Timer Camera X(ジャンク)で画像をLCDで表示

M5STACK ESP32 PSRAM Timer Camera Xのジャンク品を購入しました。ジャンク理由はWiFiに接続できたことが無いとなっていましたが、とりあえずカメラが使えればと購入しました

最初にカメラがちゃんと動作するかをテストします。と言っても液晶は付いていないんので、Groveコネクタ経由でLCD Unitに映像を表示させることにしました。なお、JEPEGモード、320x240で撮影し、それをLCD Unitに表示する簡単な記述になります。

#include <M5TimerCAM.h>
#include <M5GFX.h>
#include <MUnitLCD.h>

// M5UnitLCD display;                 // default setting
M5UnitLCD display(4, 13, 400000);  // SDA, SCL, FREQ

void setup() {
  TimerCAM.begin();
  display.begin();

  // display setting
  display.setRotation(0);
  display.clear(TFT_BLACK);

  if (!TimerCAM.Camera.begin()) {
    Serial.println("Camera Init Fail");
    return;
  }
  Serial.println("Camera Init Success");

  // Cammera setting
  TimerCAM.Camera.sensor->set_pixformat(TimerCAM.Camera.sensor, PIXFORMAT_JPEG);  // 画像フォーマット
  TimerCAM.Camera.sensor->set_framesize(TimerCAM.Camera.sensor, FRAMESIZE_QVGA);  // 画像サイズ:320x240

  TimerCAM.Camera.sensor->set_vflip(TimerCAM.Camera.sensor, 1);    //上下反転 0無効 1有効
  TimerCAM.Camera.sensor->set_hmirror(TimerCAM.Camera.sensor, 0);  //左右反転 0無効 1有効
}

void loop() {
  while(true) {
    if (TimerCAM.Camera.get()) {
      TimerCAM.Power.setLed(255);  // LED点灯
      Serial.printf("pic size: %d\n", TimerCAM.Camera.fb->len);

      int32_t data_size = TimerCAM.Camera.fb->len;
      uint8_t* sata_buf = TimerCAM.Camera.fb->buf;

      if (data_size != 0) {
        display.drawJpg(sata_buf, data_size, 0, 0, 320, 240);
        data_size = 0;
      }

      TimerCAM.Camera.free();
      TimerCAM.Power.setLed(0);
    }
  }
  TimerCAM.Camera.free();
  TimerCAM.Power.setLed(0);
  TimerCAM.Power.setLed(0);
}

簡単な記述なので、サクッと動作しました

カメラの詳細設定に関しては、今後いろいろと試したいと思います。

記述してから気が付きましたが、動作チェックが目的であればcameraToolsを使用すれば、もっと簡単にできました。やはり、ドキュメントは見ないといけませんね

2025年5月8日木曜日

LCD Unitを使ってみよう!

先日、LCD Unitのファームウェアをアップデートしましたが実際に使用していなかったので、M5StickC Plus2に接続して表示させてみました

基本的にはサンプルデザインを流用して記述しました。サンプル記述では、メッセージ表示後に丸と四角のランダムパターンを表示します

// #include <M5StickCPlus2.h>
// #include <M5GFX.h>
#include <Arduino.h>
#include <M5UnitLCD.h>
#include <M5Unified.h>

void setup(void) {
  auto cfg = M5.config();

  // M5 UnitLCD display setting.
  // cfg.external_display.unit_lcd = true;

  #if defined(__M5GFX_M5UNITLCD__)       // setting for Unit LCD.
    cfg.unit_lcd.pin_sda = GPIO_NUM_32;  // Grove I2C SDA pin
    cfg.unit_lcd.pin_scl = GPIO_NUM_33;  // Grove I2C SCL pin
    cfg.unit_lcd.i2c_addr = 0x3E;        // I2C Adress
    cfg.unit_lcd.i2c_freq = 400000;
    cfg.unit_lcd.i2c_port = I2C_NUM_0;
  #endif

  M5.begin(cfg);

  // Get the number of available displays
  int display_count = M5.getDisplayCount();

  for (int i = 0; i < display_count; ++i) {
    M5.Displays(i).setRotation(3);
    int textsize = M5.Displays(i).height() / 60;
    if (textsize == 0) { textsize = 1; }
    M5.Displays(i).setTextSize(textsize);
    Serial.printf("No.%d\n", i);
    M5.Displays(i).printf("No.%d\n", i);
  }


  // If an external display is to be used as the main display, it can be listed in order of priority.
  //  M5.setPrimaryDisplayType( m5::board_t::board_M5UnitLCD );
  M5.Display.print("primary display\n");


  int index_unit_lcd = M5.getDisplayIndex(m5::board_t::board_M5UnitLCD);
  M5.Displays(index_unit_lcd).print("This is  M5 UnitLCD display\n");
  M5.delay(10000);
}


// When creating a function for drawing, it can be used universally by accepting a LovyanGFX type as an argument.
void draw_function(LovyanGFX* gfx) {
  int x = rand() % gfx->width();
  int y = rand() % gfx->height();
  int r = (gfx->width() >> 4) + 2;
  uint16_t c = rand();
  gfx->fillRect(x - r, y - r, r * 2, r * 2, c);
}


void loop(void) {
  M5.delay(1);

  for (int i = 0; i < M5.getDisplayCount(); ++i) {
    int x = rand() % M5.Displays(i).width();
    int y = rand() % M5.Displays(i).height();
    int r = (M5.Displays(i).width() >> 4) + 2;
    uint16_t c = rand();
    M5.Displays(i).fillCircle(x, y, r, c);
  }

  for (int i = 0; i < M5.getDisplayCount(); ++i) {
    draw_function(&M5.Displays(i));
  }
}

なお、#include <Arduino.h>を宣言していないと、上記記述の14行目~17行名で構造体 config_tにunit_lcdが無いといった趣旨のエラーが発生します。勉強不足で、嵌まってしましいましたよ。

参考にさせて頂きましたサイト:

2025年5月2日金曜日

M5StickC Plus2でWifi接続

 M5STACK 製品をいくつか購入していますが、いまだWifiに接続したことが無かったので試してみました。調べてみたところ、WiFi.hを使用すれば簡単に接続できるようです

#include <M5StickCPlus2.h>
#include <M5Unified.h>
#include <WiFi.h>

const char* ssid = "********";        // 接続先WiFiのSSID
const char* password = "********";    // 接続先WiFiのパスワード

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setBrightness(5);
  M5.Lcd.setRotation(3);                           // 画面向き
  M5.Lcd.setTextSize(2);                           // フォントサイズ

  M5.Lcd.print("SSID : ");
  M5.Lcd.println(ssid);

  WiFi.begin(ssid, password);  // WiFi接続

  M5.Lcd.print("Connecting");

  while (WiFi.status() != WL_CONNECTED) {  // 接続チェック
    delay(500);
    M5.Lcd.print(".");
  }

  M5.Lcd.println("");
  M5.Lcd.print("IP Adress : \n");
  M5.Lcd.println(WiFi.localIP());  // IPアドレス表示
}

void loop() {}

wifi.begin()で接続して、Wifi.status()で接続チェックを行うだけでと簡単でした。実行も問題なくでき簡単です。

折角、Wifiに接続できましたので、APIなどを使用しないで使えるNTPサーバーに接続して日時を取得して表示するスケッチを作成しました

#include <M5StickCPlus2.h>
#include <M5Unified.h>
#include <WiFi.h>

#define JST 9 * 3600L

const char* ssid = "********";        // 接続先WiFiのSSID
const char* password = "********";    // 接続先WiFiのパスワード

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setBrightness(5);
  M5.Lcd.setRotation(3);  // 画面向き
  M5.Lcd.setTextSize(2);  // フォントサイズ

  M5.Lcd.print("SSID : ");
  M5.Lcd.println(ssid);

  WiFi.begin(ssid, password);  // WiFi接続

  M5.Lcd.print("Connecting");

  while (WiFi.status() != WL_CONNECTED) {  // 接続チェック
    delay(500);
    M5.Lcd.print(".");
  }

  M5.Lcd.println("");
  M5.Lcd.print("IP Adress : \n");
  M5.Lcd.println(WiFi.localIP());  // IPアドレス表示

  // NTPサーバと、ローカルのタイムゾーンを設定
  // タイムゾーン:日本、夏時間無し、PUBLIC NTPと日本標準時グループに接続
  configTime(JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp"); 
}

void loop() {
  M5.Lcd.clear(BLACK);
  M5.Lcd.setCursor(0, 0);
  struct tm tm;
  /*
    tm構造体の要素:
    int tm_sec    秒:(0~61)
    int tm_min    分:(0~59)
    int tm_hour   時:(0~23)
    int tm_mday   日:(1~31)
    int tm_mon    1月からの月数:(0~11)
    int tm_year   1900年からの年数
    int tm_wday   日曜日からの日数:(0~6)
    int tm_yday   1月1日からの日数:(0~365)
    int tm_isdst  夏時間フラグ
 */
  getLocalTime(&tm);
  M5.Lcd.printf(" %04d/%02d/%02d %02d:%02d:%02d",
               tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,  // 年、月、日
               tm.tm_hour, tm.tm_min, tm.tm_sec);             // 時、分、秒
  delay(1000);
}

#define JSTは日本時間にするための設定で、configTime()でPUBLIC NTPと日本標準時グループに接続して時間を取得しています、なお、メモとして構造体 tmの内容をコメントとして記載しています。ま、使用するたびに調べるのが面倒なだけですが...

無事に動作し、時間を取得できました。

NTPサーバーへの接続は、WEBサービスを使用するスケッチの最初の一歩ですね

2025年4月23日水曜日

I2C OLEDを試してみた

M5STACK LCD Unitのファームウェアアップデート」の記事の際に記載した I2C OLEDディスプレイを動かしてみました。

本製品はタイトルや製品説明では、ドライバICはSSD1315 を使用しているとありましたが、詳細説明ではSSD1306を使用と記載されています。購入してから気が付きました...



詳しくは調べていませんが、SSD1315 はSSD1306  の上位互換らしいので、SSD1306として使用してみました。なお、OLEDのライブラリはAdafruit_SSD1306を使用して記述しました

#include <Wire.h>
#include <Adafruit_GFX.h>      // Ver 1.12.1
#include <Adafruit_SSD1306.h>  // Ver 2.5.13

#define SCREEN_WIDTH 128 // OLED 横設定
#define SCREEN_HEIGHT 64 // OLED 高さ設定
#define OLED_RESET    -1 // OLEDリセット(未使用:-1)
#define SCREEN_ADDRESS 0x3C // ボード上の設定:0x78に接続:0x3C、0x7Aに接続:0x3D

// ディスプレイの宣言
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup() {

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);

}

void loop() {

  display.clearDisplay();      // 表示クリア
  display.setTextSize(2);      // テキストサイズ
  display.setTextColor(WHITE); // テキストカラー
  display.setCursor(0, 10);    // テキストの表示位置

  display.println("Hello World");
  display.display();           // テキスト表示

  delay(1000);

}

サクッと動いてしまいました。3ボードセットなので各ボードで動作チェックを行い、不良が無いことを先に確認しました

折角なのでスタックチャンアバターを表示しようと調べてみると、M5 GLASS2 unitで使用されているSSD1309はSSD1306と互換性があるという情報を見つけました。早速、ライブラリを変更して試してみます。予定通りスタックチャンを表示しますが、折角なので10秒ごとに表情が変わるようにしました

#include &ltM5UnitGLASS2.h>
#include &ltM5Unified.h>
#include &ltAvatar.h>

using namespace m5avatar;
m5avatar::Avatar avatar;

const Expression expressions[] = {
  Expression::Angry,
  Expression::Sleepy,
  Expression::Happy,
  Expression::Sad,
  Expression::Doubt,
  Expression::Neutral
};

const int expressionsSize = sizeof(expressions) / sizeof(Expression);
int idx = 0;

void setup() {
  auto cfg=M5.config();
  cfg.unit_glass2.pin_sda = 21; // SDA ピン設定
  cfg.unit_glass2.pin_scl = 22; // SCL ピン設定
  M5.begin(cfg);

  // OLED ディスプレイサイズ:128 x 64
  avatar.setScale(.4);         // 縮尺:.4 = 128/320
  avatar.setPosition(-88,-96); // ポジション:88 = (240-64)/2, 96 = (340-128)/2
  avatar.init();               // アバターの初期化
}

void loop() {
  M5.update();

  idx = rand() % expressionsSize;
  avatar.setExpression( expressions[idx] );
  
  delay(10000);

}

スタックチャンアバターは、320x240ディスプレイ用に準備されていますので、小さい液晶で表示する際は縮尺(avatar.setScale())やポジション(avatar.setPosition())の設定を変更する必要があります



とりあえず、動作したので良しとしました。結局、このOLED のディスプレイドライバは不明ですが、SSD1306、SSD1309、SSD1315は互換性があるようですね

参考にさせて頂きましたサイト:

2025年4月21日月曜日

iOS 18.4.1リリース

  iOS 18.4.1がリリースされました

対象デバイスは、iPhone XS以降, iPad(7代目), iPad mini(5代目以降), iPad Air(3代目), iPad Pro(13インチ、12.9インチ 3代目以降、11インチ 初代以降)になります

アップデート内容は、以下の様になっています

このアップデートには重要なバグ修正とセキュリティアップデートが含まれ、特定の車両でまれにCarPlayのワイヤレス接続が出来なくなる問題に対処しています。

Apple セキュリティアップデートを確認すると以下のセキュリティアップデート内容が記載されています

CoreAudio

CVE-2025-31200: Apple and Google Threat Analysis Group

RPAC

CVE-2025-31201: Apple

なおアップデートファイルの大きさは、iOS 18.4をインストールしているiPhone 11で211.3MBになります


スマホ・携帯ランキング

2025年4月10日木曜日

ケチって互換DFplayer mini を買ったばかりに...

本来であれば、DFRobot のDFplayer mini を購入すればよいのですが、価格に負けて互換品を購入しました。使用方法は、UART制御でSD内のMP3を再生し、BUSY信号をチェックして再生の完了を確認するようにします。それぞれの接続は基本通りですね

早速、スケッチを記述しますが、動きません。ライブラリは”DFRobotDFPlayerMini”を最初使用していましたが動く気配がありません。調べていくと互換機は、このライブラリでは正常に動作しないという記述を見つけ、”DFPlayer Mini Mp3 by Makuna”などの別ライブラリも試しましたがやはり動作しませんでした。DFplayerのIO_1やIO_2をGNDに接続して、試したところ再生されましたのでモジュールが壊れている可能性は低そうです

そこで互換機に関する内容をネットで検索しまくったところ、初期の互換機と現在の物ではチップが異なっているという記載を見つけました。そこで、互換機のチップを確認するとTD5580Aと記載されていました

ちなみにDFRobot のDFplayer miniは下記になります

そこで互換品のTD5580Aで調べたところ、 SerialMP3と言うライブラリを見つけました。このライブラリは、互換品のチップに合わせて作られているようです。早速、このライブラリを使用してスケッチを記述したところ、簡単に動作しました(5Vを供給しないと再生しません)。なお、MP3ファイルはSDカードの直下に保存して使用しています

#include <M5unified .h>
#include <SerialMP3.h>

#define RX_PIN 22   // RX pin   22
#define TX_PIN 21   // TX pin   21
#define BUSY_PIN 36 // BUSY pin 36

SerialMP3 mp3(RX_PIN, TX_PIN);

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  pinMode(BUSY_PIN, INPUT);

  // put your setup code here, to run once:
  mp3.showDebug(true); // print command send to Serial MP3 Player
  Serial.begin(9600);  // Start serial interface
  mp3.init();          // MP3 Player の祖帰化  
  mp3.setVolume(20);   // ボリューム設定(0-30)
  mp3.play(2); // play exam.mp3
  while(digitalRead(BUSY_PIN) == LOW){
    delay(100);
  }
}

void loop() {
  M5.update(); 
  if (M5.BtnA.isPressed()) {
    mp3.play(1); // play exam.mp3
    while(digitalRead(BUSY_PIN) == LOW){
      delay(100);
    }
  }
  //delay(5000); // wait 2 second
}

正規品を購入していればサクッと動いたのに、ケチったばかりにいらぬ苦労してしまいましたよ

2025年4月8日火曜日

M5STACK LCD Unitのファームウェアアップデート

M5Stamp Picoを弄っていますが、やはり液晶が欲しいなって思っちゃいました。そこで、良く使用されるI2C OLEDディスプレイM5STACK LCD Unitを購入しました。今回は、M5STACK LCD Unitのファームウェアアップデートを行います(写真はアップデート済み)

M5STACK LCD Unitを検索するとファームウェアアップデートに関する情報が出てきます。と言うか、あまり使用例が出てこないんですよねぇ

M5STACKのUnit LCDサイト

上記を確認すると、I2C経由でのアップデート、または裏蓋開けてESP32ダウンローダを使用してアップデートの2つの方法がありました。蓋開けるのは面倒なので、I2C経由でのアップデートしてみようかと思います。GitHubのM5Stack Unit LCD FirmWareを確認するとマニュアルには、M5StickC Plus2は明記されていませんが、スケッチ内には記載があるので大丈夫そうです

GitHubのM5Stack Unit LCD FirmWare

早速、M5StickC Plus2に書き込んで実行してみましたが、searchUnitLCD()の応答待ちでスタックしているように見受けられました(LCD Unitの応答がない?!)

そこで勉強がてら、I2Cスキャナーのスケッチを作成して確認したところ、GroveコネクタのI2Cバス上にアドレスは存在していることは確認できました(スケッチは後述)

    • 内部I2Cバス:0x51(RTC), 0x61(6-axis IMU)
    • Grove I2Cバス:0x3E(LCD Unit)
    • ピンヘッダ I2Cバス:なし

流石にメーカー製のスケッチを解析する気にはなりませんでしたので、I2C経由は諦めてESP32ダウンローダ(Stamp ISPを使用)を使用することにしました

接続したら、M5Burnerから書き込んで終了(書き込む際、ESP32ダウンローダを抑えた方が接触不良なく書き込めます)。無事にアップロードできました

なお、M5STACKのUnit LCDサイト内にあるサンプル記述をM5StickC Plus2に書き込んで動作確認できました。次は、M5Stamp Picoで試したいと思います

参考までにI2Cスキャンのスケッチを下記に乗せておきます:

#include <M5unified .h>
#include <M5StickCPlus2.h>
#include <M5Unified.h>
#include "wire.h"

TwoWire *i2cWire;

uint8_t sda = -1;
uint8_t scl = -1;
uint8_t I2C_SEL = 0;

void I2C_Setting() {
  if (I2C_SEL == 1) {        // GROVEコネクタ
    sda = 32;
    scl = 33;
    Wire.begin(sda, scl);
    i2cWire = &Wire;
  } else if (I2C_SEL == 2) {  // ピンヘッダー
    Wire1.end();              // Wire1を終了し再割り当て
    sda = 0;
    scl = 26;
    Wire1.begin(sda, scl);
    i2cWire = &Wire1;
  } else {                    // 内部I2C
    Wire1.end();
    sda = 21;
    scl = 22;
    Wire1.begin(sda, scl);    // Wire1:通常内部I2C
    i2cWire = &Wire1;
  }
}

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setBrightness(5);
  M5.Lcd.setRotation(3);                          // 画面向き
  M5.Lcd.setTextSize(2);                          // フォントサイズ
  M5.Lcd.setTextFont(&fonts::lgfxJapanGothic_8);  // フォント
}

void loop() {
  int device_cnt = 0;

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);

  M5.Lcd.printf("I2Cスキャン:\n");

  I2C_SEL = 0;
  while (I2C_SEL < 3) {
    I2C_Setting();

    if (I2C_SEL == 1) {
      M5.Lcd.printf("Groce: SDA:%2d SCL:%2d\n", sda, scl);
    } else if (I2C_SEL == 2) {
      M5.Lcd.printf("ピン : SDA:%2d SCL:%2d\n", sda, scl);
    } else {
      M5.Lcd.printf("内部 : SDA:%2d SCL:%2d\n", sda, scl);
    }

    device_cnt = 0;
    for (byte address = 0; address <= 127; address++) {
      i2cWire->beginTransmission(address);
      byte error = i2cWire->endTransmission();
      if (error == 0) {
        M5.Lcd.printf("0x%02X ", address);
        device_cnt++;
      }
      delay(1);
    }
    I2C_SEL++;
    if (device_cnt == 0) {
      M5.Lcd.printf("I2Cデバイスが見つからない!");
    }
    M5.Lcd.println();
  }
  delay(3000);
}


参考にさせて頂きましたサイト:

2025年4月5日土曜日

M5Stamp PicoでLチカ(WS2812)

Aliexpressで面白うそうなLEDモジュールを見つけたので、M5Stamp PicoでLチカ 第2弾をしました。なお、このLEDモジュールはアマゾンでも販売していました

このLEDモジュールはWS2812 5050を8個搭載しており、1本のデータ信号でこれらを制御することが出来ます。それにより1モジュール1ピンとなるため、GPIOピンの節約が出来そうです。今回もナイトライダー風にしますが、折角なのでパターン違いで2モジュール制御したいと思います。回路は非常に簡単です


本モジュールの制御には、Adafruit_NeoPixelライブラリを使用しました。ArduinoIDEのライブラリマネージャーで簡単に追加できます

// LED 制御(WS2812B)

#include <M5unified .h>
#include <dafruit_NeoPixel.h>
#define PIN1 18                 // LEDのデータを接続するGPIO
#define PIN2 19                 // LEDのデータを接続するGPIO
#define LED_NUM  8              // 接続LED数(4の倍数)
#define LED_MSK (LED_NUM/2) -1
#define LED_DLY 50              // 点灯時間
#define MAX_LED 128             // 明るさ

// LED config
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(LED_NUM, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(LED_NUM, PIN2, NEO_GRB + NEO_KHZ800);


void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);
  
  // LED setup
  strip1.begin();
  strip2.begin();
}


int z = 0;
void loop() {
  int x = 0;
  int y = 0;

  for (int i = 0; i < LED_NUM; i++ ){

    // LED1 設定
    strip1.clear();  // LED1 消灯
    x = i & LED_MSK;
    y = ~x & (LED_NUM-1);
    strip1.setPixelColor(x, strip1.Color(0, MAX_LED, 0)); 
    strip1.setPixelColor(y, strip1.Color(0, MAX_LED, 0)); 
    strip1.show();

    // LED2 設定
    strip2.clear();  // LED2 消灯
    if ((z % 2) == 0) {
      strip2.setPixelColor((i), strip2.Color(0, MAX_LED, 0)); 
    } else {
      strip2.setPixelColor(((LED_NUM-1)-i), strip2.Color(0, MAX_LED, 0));
    }
    strip2.show();

    delay(LED_DLY);
  }
  z++;
}

13行目、14行目のAdafruit_NeoPixel宣言は、モジュール内のLED総数、割当てピン、蘇秦データのカラー順序(今回はRGB)、駆動周波数は800KHzで設定しています

22行目、23行目の.begin()でGPIOの出力設定が行われます

25行目、43行目の.clean()で全てのLEDを消灯しています

38,39行目、45,47行目の.setPixelColor()で表示するLEDとカラー(RGB順)を設定します(今回は緑色にしています)

なお、strip1はLED 0 → 3、LED 7 → 4の順で2個づつ表示、strip2はLED 0 → 7 → 0の順で表示しています

カラー設定値を半分にして明るさが変わるか試しましたが、これでも眩しいです


次は何をしてみようかな...

iOS 18.4 リリース

 iOS 18.4に合わせて、watchOS 11.4がリリースされました

なお、Apple Watch Series 6 以降が対象になります

アップデートには、以下の新機能と機能改善、およびバグ修正が含まれます:

  • Matter対応のロボット掃除機をホームアプリで操作でき、シーンやオートメーションに追加することもできます。
  • 消音モードで睡眠/起床アラームを強化するオプション
  • 文字盤の切り替え時に文字盤の選択が応答しなくなる問題

Apple セキュリティアップデートを確認すると以下のセキュリティアップデート内容が記載されています

AirDrop

CVE-2025-24097: Ron Masas of BREAKPOINT.SH

Audio

CVE-2025-24244: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CVE-2025-24243: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

Authentication Services

CVE-2025-30430: Dominik Rath

CVE-2025-24180: Martin Kreichgauer of Google Chrome

BiometricKit

CVE-2025-24237: Yutong Xiu

Calendar

CVE-2025-30429: Denis Tokarev (@illusionofcha0s)

CVE-2025-24212: Denis Tokarev (@illusionofcha0s)

CoreAudio

CVE-2025-24163: Google Threat Analysis Group

CVE-2025-24230: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreMedia

ACVE-2025-24190: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreMedia Playback

CVE-2025-30454: pattern-f (@pattern_F_)

CoreServices

CVE-2025-31191: Jonathan Bar Or (@yo_yo_yo_jbo) of Microsoft, and an anonymous researcher

CoreText

CVE-2025-24182: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

curl

CVE-2024-9681

Focus

CVE-2025-30439: Andr.Ess

CVE-2025-24283: Kirin (@Pwnrin)

Foundation

CVE-2025-30447: LFY@secsys from Fudan University

ImageIO

CVE-2025-24210: Anonymous working with Trend Micro Zero Day Initiative

IOGPUFamily

CVE-2025-24257: Wang Yu of Cyberserval

Kernel

CVE-2025-30432: Michael (Biscuit) Thomas - @biscuit@social.lol

libarchive

CVE-2024-48958

libnetcore

CVE-2025-24194: an anonymous researcher

libxml2

CVE-2025-27113

CVE-2024-56171

libxpc

CVE-2025-24178: an anonymous researcher

CVE-2025-31182: Alex Radocea and Dave G. of Supernetworks, 风沐云烟(@binary_fmyy) and Minghao Lin(@Y1nKoc)

CVE-2025-24238: an anonymous researcher

Maps

CVE-2025-30470: LFY@secsys from Fudan University

NetworkExtension

CVE-2025-30426: Jimmy

Power Services

CVE-2025-24173: Mickey Jin (@patch1t)

Safari

CVE-2025-24113: @RenwaX23

CVE-2025-30467: @RenwaX23

CVE-2025-24167: Syarif Muhammad Sajjad

Security

CVE-2025-30471: Bing Shi, Wenchao Li, Xiaolong Bai of Alibaba Group, Luyi Xing of Indiana University Bloomington

Share Sheet

CVE-2025-30438: Halle Winkler, Politepix theoffcuts.org

Shortcuts

CVE-2025-30433: Andrew James Gonzalez

Siri

CVE-2025-31183: Kirin (@Pwnrin), Bohdan Stasiuk (@bohdan_stasiuk)

CVE-2025-24217: Kirin (@Pwnrin)

CVE-2025-24214: Kirin (@Pwnrin)

WebKit

CVE-2025-24264: Gary Kwong, and an anonymous researcher

CVE-2025-24216: Paul Bakker of ParagonERP

CVE-2025-24213: Google V8 Security Team

CVE-2025-24209: Francisco Alonso (@revskills), and an anonymous researcher

CVE-2025-30427: rheza (@ginggilBesel)

CVE-2025-30425: an anonymous researcher


スマホ・携帯ランキング 

2025年4月4日金曜日

iOS 18.4リリース

先日、iOS 18.4がリリースされました

対象デバイスは、iPhone XS以降, iPad(7代目), iPad mini(5代目以降), iPad Air(3代目), iPad Pro(13インチ、12.9インチ 3代目以降、11インチ 初代以降)になります

アップデート内容は、以下の様になっています。なお、英語でのリリース情報でしたので、日本語に翻訳しています

Apple lntelligence(iPhone16全モデル、iPhone15 Pro、iPhone15 Pro Max)

  • 優先通知は通知の最上部に表示され、すぐに注意を払う必要がある重要な通知をハイライトします。
  • lmage Playgroundの追加スタイルオプションにSketchが追加されました。
  • Apple lntelligence機能は、英語(インド、シンガポール)、フランス語(フランス、カナダ)、ドイツ語(ドイツ)、イタリア語(イタリア)、日本語(日本)、韓国語(韓国)、ポルトガル語(ブラジル)、簡体字中国語、スペイン語(スペイン、ラテンアメリカ、米国)を含む、8つの追加言語と2つの追加英語ロケールに対応しています。

Apple Vision Proアプリ

  • 新しいApple Vision Proアプリケーションは、Apple Vision Proを搭載しているユーザー向けに自動的に起動し、新しいコンテンツや空間体験の発見、デバイスに関する情報への素早いアクセスをサポートします。

Apple News+

  • 世界有数のレシピ出版社のレシピがApple News+に登場
  • レシピカタログでは、ブラウズや検索でぴったりの料理を見つけて、保存したレシピに保存できます。
  • クッキングモードでは、ステップバイステップの指示に簡単に従うことができます。
  • フードセクションでは、レストラン、キッチンのコツ、健康的な食事などに関する記事も楽しめます。

Photos 

  • Photosのライブラリビューで、アルバムに含まれていないアイテムや、MacまたはPCから同期されたアイテムの表示/非表示を切り替える新しいフィルタ。
  • Photosの"メディアの種類"および"ユーティリティ"コレクションのアイテムの順序を変更。
  • すべてのコレクションで一貫したフィルタリングオプション。
  • Photosで更新日順にアルバムを並べ替えるオプション。
  • Photosの設定で、"最近閲覧した"コレクションと"最近共有した"コレクションを無効にする機能。。
  • Photos設定で"Face IDを使用"が有効になっている場合、MacまたはPCへのインポート時に非表示の写真が除外されます。

このアップデートには、以下の機能強化とバグ修正も含まれています:

  • 絵文字キーボードに、オブジェクト、植物、スマイリーフェイスを含む8つの新しい絵文字が追加されました。
  • Safariの最近の検索候補により、新しいクエリを開始する際に以前の検索トピックにすばやく戻ることができます。
  • セットアップアシスタントは、保護者が家族の子供のためにチャイルドアカウントを作成するために必要な手順を合理化し、あとでチャイルドアカウントの設定を完了したい場合は、子供に適したデフォルト設定を有効にします。
  • 子どもがアプリをアンインストールし、再インストールしても、Screen Timeアプリの制限は継続されます。
  • App Storeにはユーザーレビューの要約が含まれているため、他のユーザーからの有益な情報を一目で得ることができます。
  • 進行状況を失うことなく、App Storeでアプリのダウンロードやアップデートを一時停止したり再開したりできます。
  • ポッドキャスト用の新しいウィジェットには、お気に入りの番組を追跡するためのフォロー中の番組ウィジェットや、最新のエピソード、保存済み、ダウンロード済みなどの最もよく使用するセクションにアクセスできるライブラリウィジェットが含まれます。
  • アンビエントミュージックは、コントロールセンターから即座に音楽を再生する機能を提供し、日常生活のためのサウンドトラックを提供する手作りのプレイリストのセットへのアクセスを提供します。
  • Apple Fitness+コレクションをライブラリに追加できるようになりました。
  • Matter対応のロボット掃除機をホームアプリで操作でき、シーンやオートメーションに追加することもできます。
  • バングラ語、グジャラート語、カンナダ語、マラヤーラム語、マラーティー語、オディア語、パンジャブ語、タミル語、テルグ語、ウルドゥー語を含む10の新しいシステム言語に対応。
原文:

Apple lntelligence (All iPhone 16 models, iPhone 15 Pro, iPhone 15 Pro Max)

  • Priority notifications appear at the top of your notifications, highlighting important notifications that may require your immediate attention
  • Sketch is now available as an additional style optionin in lmage Playground, allowing you to create gorgeous sketch drawings
  • Apple lntelligence features support 8 additional languages and 2 additional English locales, including English (lndia, Singapore), French (France, Canada), German (Germany), ltalian (ltaly), Japanese (Japan), Korean (South Korea), Portuguese (Brazil), Sim plified Chinese, and Spanish (Spain, Latin America, US)

Apple Vision Pro App

  • The new Apple Vision Pro app, automatically in stalled for users with Apple Vision Pro, helps you discover new content, spatial experiences, and quickly access information about your device

Apple News+

  • Recipes from some of the world's best recipe publishers are now available on Apple News+
  • Recipe Catalog allows you to browse or search to find the perfect dish and save it to your Saved Recipes
  • Cooking mode lets you easily follow step- by- step directio ns
  •   The Food section also includes stories about restaurants, kitchen tips, healthy eating, and more 

Photos 

  • New filters to show or hide items that are not contained in an album, or synced froma Mac or PC,in the Library view in Photos
  • Reorder items in the Media Types and Utilities collections in Photos
  • Consistent filtering options in all collections, including the ability to sort by oldest or newest first in Photos
  • Option to sort albums by Date Modified in Photos
  • Ability to disable "Recently Viewed" and "Recently Shared" collections in Photos Settings
  • Hidden photos are no longer in cluded for import to Mac or a PC if Use Face ID is enabled in Photos settings

This update also includes the following enhancements and bug fixes:

  • 8 new emoji including objects, plants, and a smiley face are now available in the emoji keyboard
  • Safari recent search suggestions help you quickly get back to previous search topics when starting a new query
  • Setup Assistant streamlines steps parents need to take to create a Child Account for a kid in their family, and enables child-appropriate default settings if parents prefer to complete setting up a Child Account later
  • Screen Time App Limits persist even after a child uninstalls and reinstalls an app
  • App Storeincludes summariesforuser reviews so you can get helpfulinsights from other users at a glance
  • Pause and resume of an app download or update on App Store without losing progress
  • New widgets for Podcasts including a Followed Shows  widget to track your favorite shows and a Library widget to get to your most used sections, such as Latest Episodes, Saved, and Downloaded
  • Ambient Music offers the ability to instantly play music from Control Center, giving access to a set of hand-curated playlists that offer soundtracks for daily life
  • Apple Fitness+ Collections can now be added to Library
  • Matter-compatible robot vacuum cleaners can be controlled in the Home app as well as be added to scenes and automatlons
  • Support for 10 new system languages including Bangla, Gujarati, Kannada, Malayalam, Marathi, Odia, Punjabi, Tamil, Telugu, and Urdu

Apple セキュリティアップデートを確認すると以下のセキュリティアップデート内容が記載されています

Accessibility

CVE-2025-24202: Zhongcheng Li from IES Red Team of ByteDance

Accounts

CVE-2025-24221: Lehan Dilusha @zorrosign Sri Lanka, and an anonymous researcher

AirDrop

CVE-2025-24097: Ron Masas of BREAKPOINT.SH

Audio

CVE-2025-24244: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CVE-2025-24243: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

Authentication Services

CVE-2025-30430: Dominik Rath

CVE-2025-24180: Martin Kreichgauer of Google Chrome

BiometricKit

CVE-2025-24237: Yutong Xiu

Calendar

CVE-2025-30429: Denis Tokarev (@illusionofcha0s)

CVE-2025-24212: Denis Tokarev (@illusionofcha0s)

CoreAudio

CVE-2025-24163: Google Threat Analysis Group

CVE-2025-24230: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreMedia

CVE-2025-24211: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CVE-2025-24190: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

CoreMedia Playback

CVE-2025-30454: pattern-f (@pattern_F_)

CoreServices

CVE-2025-31191: Jonathan Bar Or (@yo_yo_yo_jbo) of Microsoft, and an anonymous researcher

CoreText

CVE-2025-24182: Hossein Lotfi (@hosselot) of Trend Micro Zero Day Initiative

curl

CVE-2024-9681

DiskArbitration

CVE-2025-30456: Gergely Kalman (@gergely_kalman)

Focus

CVE-2025-30439: Andr.Ess

CVE-2025-24283: Kirin (@Pwnrin)

Foundation

CVE-2025-30447: LFY@secsys from Fudan University

Handoff

CVE-2025-30463: mzzzz__

ImageIO

CVE-2025-24210: Anonymous working with Trend Micro Zero Day Initiative

IOGPUFamily

CVE-2025-24257: Wang Yu of Cyberserval

Journal

CVE-2025-30434: Muhammad Zaid Ghifari (Mr.ZheeV) and Kalimantan Utara

Kernel

CVE-2025-30432: Michael (Biscuit) Thomas - @biscuit@social.lol

libarchive

CVE-2024-48958

libnetcore

CVE-2025-24194: an anonymous researcher

libxml2

CVE-2025-27113

CVE-2024-56171

libxpc

CVE-2025-24178: an anonymous researcher

CVE-2025-31182: Alex Radocea and Dave G. of Supernetworks, 风沐云烟(@binary_fmyy) and Minghao Lin(@Y1nKoc)

CVE-2025-24238: an anonymous researcher

Maps

CVE-2025-30470: LFY@secsys from Fudan University

MobileLockdown

CVE-2025-24193: Florian Draschbacher

NetworkExtension

CVE-2025-30426: Jimmy

Photos

CVE-2025-30428: Jax Reissner

CVE-2025-30469: Dalibor Milanovic

Power Services

CVE-2025-24173: Mickey Jin (@patch1t)

RepairKit

CVE-2025-24095: Mickey Jin (@patch1t)

Safari

CVE-2025-24113: @RenwaX23

CVE-2025-30467: @RenwaX23

CVE-2025-31192: Jaydev Ahire

CVE-2025-24167: Syarif Muhammad Sajjad

Security

CVE-2025-30471: Bing Shi, Wenchao Li, Xiaolong Bai of Alibaba Group, Luyi Xing of Indiana University Bloomington

Share Sheet

CVE-2025-30438: Halle Winkler, Politepix theoffcuts.org

Shortcuts

CVE-2025-30433: Andrew James Gonzalez

Siri

CVE-2025-31183: Kirin (@Pwnrin), Bohdan Stasiuk (@bohdan_stasiuk)

CVE-2025-24217: Kirin (@Pwnrin)

CVE-2025-24214: Kirin (@Pwnrin)

CVE-2025-24205: YingQi Shi(@Mas0nShi) of DBAppSecurity's WeBin lab and Minghao Lin (@Y1nKoc)

CVE-2025-24198: Richard Hyunho Im (@richeeta) with routezero.security

Web Extensions

CVE-2025-31184: Alexander Heinrich (@Sn0wfreeze), SEEMOO, TU Darmstadt & Mathy Vanhoef (@vanhoefm) and Jeroen Robben (@RobbenJeroen), DistriNet, KU Leuven

Web Extensions

CVE-2025-24192: Vsevolod Kokorin (Slonser) of Solidlab

WebKit

CVE-2025-24264: Gary Kwong, and an anonymous researcher

CVE-2025-24216: Paul Bakker of ParagonERP

CVE-2025-24213: Google V8 Security Team

CVE-2025-24209: Francisco Alonso (@revskills), and an anonymous researcher

CVE-2025-24208: Muhammad Zaid Ghifari (Mr.ZheeV) and Kalimantan Utara

CVE-2025-30427: rheza (@ginggilBesel)

CVE-2025-30425: an anonymous researcher

なおアップデートファイルの大きさは、iOS 18.3.2をインストールしているiPhone 11 proで3.26GB、iPhone 11で3.24GBになります


スマホ・携帯ランキング











2025年3月31日月曜日

M5Stamp Picoを買っちゃった

M5StickC Plus2を弄ってみて、玩具などの改造など色々と使い道ありそうです。そこで、組み込みし易そうな、M5Stamp Pico Mateを購入してみました。このサイズであれば、ゴチゾウからはみ出さずに出来そうな気がしますが、バッテリーや液晶などを考えると難しいかな...

内容物は本体、端子引き出し用のジャンパ端子、シール、六角レンジとなっています。サクッとジャンパ端子を半田付けして使用しみます。

なお、ArduinoIDEはM5StickC Plus2で設定していますので、ライブラリインストールのみで使用できました

とりあえず、初めに行うのはLチカと勝手に決めてGPIOにLEDを接続して試します(普通はオンボードのLEDだとは主マスが、きっと使う機会は少ないのでGPIO経由で試します)。あと、LED 1個じゃつまらないのでナイトライダー風にします


// LED 制御(PWM)

#include <M5unified .h>
#define LED_NUM 6
#define LED_DLY 50
#define MAX_LED 256
#define LOW_LED 64
byte  leds   [LED_NUM] = {26, 18, 19, 21, 22, 25};
byte  pwmchs [LED_NUM] = {1, 2, 3, 4, 5, 6};

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);
  
  // set pin to OUTPUT & LED off
  for (byte i = 0 ; i < LED_NUM ; i++) {
    pinMode(leds[i], OUTPUT);
    ledcSetup(pwmchs[i], 12000, 8);       //周波数:12KHz、分解能:8ビット
    ledcAttachPin(leds[i], pwmchs[i]);
  }
}

void loop() {
  int y = 0;
  // 左から右
  for (int i = 0; i < LED_NUM*2-1; i++ ){
    if ((i % 2) == 0) {
      ledcWrite(pwmchs[y], MAX_LED);        //  100%(3.3V)
      delay(LED_DLY);
      ledcWrite(pwmchs[y], 0);              //  0%(0V)
    } else {
      ledcWrite(pwmchs[y], LOW_LED);        //  25%(0.9V)
      ledcWrite(pwmchs[y+1], LOW_LED);      //  25%(0.9V)
      delay(LED_DLY);
      ledcWrite(pwmchs[y], 0);              //  0%(0V)
      ledcWrite(pwmchs[y+1], 0);            //  0%(0V)
      y++;
    }
  }
  
  for (int i = LED_NUM*2-3; i >= 0; i-- ){
    if ((i % 2) == 0) {
      ledcWrite(pwmchs[y], MAX_LED);        //  100%(3.3V)
      delay(LED_DLY);
      ledcWrite(pwmchs[y], 0);              //  0%(0V)
    } else {
      ledcWrite(pwmchs[y], LOW_LED);        //  25%(0.9V)
      ledcWrite(pwmchs[y-1], LOW_LED);      //  25%(0.9V)
      delay(LED_DLY);
      ledcWrite(pwmchs[y], 0);              //  0%(0V)
      ledcWrite(pwmchs[y-1], 0);            //  0%(0V)
      y--;
    }
  }
}

なお、残像を残すようにするため、ループ変数 iから変数 yを作成しています(変数 iが偶数の時はLED 1個を最大輝度、基数の時はLED 2個を25%輝度)

書き込みにはStamp ISPを使用しています(ドライバはCH9102_VCP_SER_Windowsを使用)。なお、LED点灯だけであれば5Vが無くても動作するようです。とりあえず、無事に動作しました



PWM制御で作成していますが、本来はGPIOをアンログ出力(dacWrite)を使用すると思いますが、将来的にモーターを制御したいと思いますのでPWM制御にしています

2025年3月27日木曜日

mini MAG LITE(2AA)のLED化

作業机の引き出しを整理していたところ、mini MAG LITE用のLEDモジュールが出てきました。記憶が定かではありませんが、20年位前に友人からジャンクとして貰って、後回しで引き出しに放り込んでいたんだと思います

LEDの横が溶けており修理した後がありますが、よく見ると足が折れています。ま、ダメ元と言うことでいいやと思い、手持ちのLEDと変えてみました


何とかLED交換できましたが、パターンのランドもダメになっており半田で無理やり繋いでいます(LEDを取り外した際の写真は撮り忘れ...ランドが剥がれたので焦ってしまいました)。これで点くのかとドキドキしながら、装着してみたところ無事に点灯しました

やはり電球と比べると明るいです。写真では青っぽく見えますが、白色LEDを使用しています。これでしばらく使用しみます

ま、3Vで点灯するLEDもありますので、電球の代わりに付け替える方法もあるんですがね

2025年3月25日火曜日

デジタルゴチゾウを作ってみよう:ハードウェア編

前回の記事でソフトウェアの準備が出来ましたので、今度はハードウェア面を作成します

最初にヒダカヒロジさんの「デジタルゴチゾウをつくる | MUDAなことをしよう。」サイトを参考にしてか回路を作成します。当初は、サイズが小さい点からMCP4661を単体で購入して作成するつもりでしたが、部品サイトを検索しても見つからなかったため同じモジュールを使用することにしました。なので、ヒダカヒロジさんの紹介している回路と全く同じ構成になりますので、回路詳細は「デジタルゴチゾウをつくる | MUDAなことをしよう。」サイトをご覧ください

上側の6角形にした基板には、M5STICKC Plus2を接続するためのピンヘッダーを搭載しています。下側のピンヘッダはゴチゾウ側の基板、およびスイッチを接続します。配線が切れない様にホットボンドで固定してあります

さて、ケースですが我が家には3Dプリンタはありません。たとえ、合ったとしてもデータが作れないので、ゴチゾウを切った貼ったして加工しました。途中で、タイクーンはてれびくんの付録ゴチゾウだったことを思い出し、違うのを試用すればよかったと後悔することになりました

ゴチゾウ側の基板からの配線になります。こちらも断線防止のためにホットボンドで固定しています。ゴチゾウの下部スイッチは再利用して、中にマイクロスイッチ(uxcell 20pcs 4mm x 2mm SPST 瞬間押しボタン パネルPCB)を付けています。なお、株スイッチは奥まで押し込まれますので、それに合わせてください(スイッチを貼り付けるためにスイッチの出っ張りを切り落としています)


で、組み立てるとこんな感じになります。ホットボンドやレジンで補強しまくっています

ピンヘッダーに合わせて、M5STICKC Plus2を刺すことができます

この状態でガヴベルトに接続してテストを行いました。特に高さがありませので、動作テストとベルトとの干渉をチェックしています(少し余裕があるていどで使用できます)

ここで、我が家のちびちゃんにみつかりました。遊びたいオーラ出しまくりですが、M5STICKC Plus2が不安定なので渡せません。急いで上部を作成することにしました

いらない穴をふさいで、スクリーン用の穴を空けて、次は細かい傷を消そうというところで、ちびちゃんの玩具になりました。とりあえず、不安定では無いのでちびちゃんが遊んでも簡単には壊れないと思います

とりあえず、動作画面を載せておきます




レジェンドライダーを選択した時は、ライダーズクレストが表示されます

強奪されたので、これで完成にしました。気が向いたら細かい傷取りや塗装もしたいと思ってます...

2025年3月24日月曜日

デジタルゴチゾウを作ってみよう:ソフトウェア編

現在、我が家のちびちゃんは仮面ライダーガヴにはまっており、色々なゴチゾウに興味があります。一時期よりは手に入るようになりましたが、それでも手に入らない物もありますよね

そんな中、X(旧Twitter)を眺めていたところヒダカヒロジさんの投稿でデジタルゴチゾウが紹介されていました。早速、リンク先の「デジタルゴチゾウをつくる | MUDAなことをしよう。」を拝見したところ、スケッチ(ソースコードをこういう風に言うらしい)を含む制作過程がすべて紹介されていました。

M5STAMP製品どころかArduinoも使用したことありませんが、ここまで情報があればきっと作ることが出来ると見切り発車で~す

ヒダカヒロジさんは、ヴァレンバスターをターゲットにしていますので横向き使用となっておりますが、我が家ではガヴドライバでの使用を想定しています。そのため、ヒダカヒロジさんのソースコードから下記内容を変更しています

  1. 縦型表示
    • select_gochizou 関数内の画面サイズ、およびsetup 関数内のsetRotation()の設定値を変更
    • 各種描画位置、サイズを変更
  2. ゴチゾウのカテゴリ、名称の日本語表示
    ちびちゃんはまだ読めませんが、今後の勉強もかねて
    • M5Unified.h をインクルードし、setup 関数内でsetTextFontでgfxJapanGothic_8 フォントを設定
      縦型、日本語化に伴い、このサイズを選択しています
  3. カテゴリアイコンをゴチゾウ画像化
    ちびちゃんにはこちらの方が判りますので...
    • 85x85 の画像データを作成し、こちらのサイトからバイナリ化してimg_icon.hを作成しています
  4. ゴチゾウの目を丸型化
    横幅が狭いので変更。ま、こっちの方が好みなんですけど
    • ヒダカヒロジさんの瞳作成を参考にし、縦型変更に伴うサイズ、位置設定を変更してます
    • 瞳を閉じている目、初期状態の目も描画で作成したので、img_gochizou.hは使用してません
    • 白目の部分は黒めにしています(ゴチゾウのイメージカラーで白がいるため)
  5. デバッグモードを追加
    描画動作のデバッグの容易化のため
    • 4項のデバッグのため、ボタンBの設定を拡張スイッチと同様の内容に変更
    • デバッグモード時、I2C アクセスは行わない様になっています
  6. その他
    • 75x75でライダーズクレスト画像を作成し、img_crest.hに設定
    • サポートゴチゾウを増やしています(クレーンの丈さんの調査結果を参考にしました)
    • ブンブンジャー選択時もクレスト画像を表示っするようにしています

完成したソースコードは以下になります:

#include <M5StickCPlus2.h>
#include "M5Unified.h" // 日本語フォントを使用するために追加
#include "MCP4661_asukiaaa.hpp"
#include "img_icon.h"
#include "img_crest.h"
#include "Wire.h"

#define PIN_SW 25 // Extra SW
#define ON  LOW
#define OFF HIGH
uint8_t sw = OFF;
uint8_t prev_sw = OFF;

#define STATE_INIT     0
#define STATE_GOCHIZOU 1
#define STATE_CHANGE   2
#define STATE_FINISH   3
uint8_t state = STATE_INIT;
uint8_t prev_state = STATE_INIT;

#define STATE_FINISH_TO_CHANGE_TIME_MS 10000
unsigned long state_change_point_ms = 0;

// #define debug // I2C 通信オフ

void change_state(uint8_t new_state){
  state = new_state;
  Serial.print(F("State: "));
  switch(state){
  case STATE_INIT:     Serial.println(F("INIT"));     break;
  case STATE_GOCHIZOU: Serial.println(F("GOCHIZOU")); break;
  case STATE_CHANGE:   Serial.println(F("CHANGE"));   break;
  case STATE_FINISH:   Serial.println(F("FINISH"));   break;
  default: ;
  }
}

MCP4661_asukiaaa::Core potentio(&Wire, MCP4661_asukiaaa::DeviceAddress::A0H_A1H_A2H);

#define R_VALUE_MAX 256

int RrA_value = 0;
int RrB_value = 0;

// 257ステップで100kΩなので、1ステップあたり0.389Ω。
#define R_62K  162 // 145 ~ 179
#define R_47K  121 // 114 ~ 132
#define R_39K  102 //  95 ~ 108
#define R_30K   78 //  74 ~  82
#define R_24K   63 //  60 ~  65
#define R_20K   52 //  50 ~  54
#define R_16K   42 //  39 ~  44
#define R_12K   31 //  29 ~  32
#define R_10K   26 //  25 ~  27
#define R_8_2K  21 //  20 ~  22
#define R_6_8K  17 //  17 ~  18
#define R_5_6K  14 //  14 ~  15

void printLogAboutWrite(Stream* serial, uint8_t channel, uint16_t valWrote, int result) {
  serial->print("write " + String(valWrote) + " for wiper" + String(channel) +
                " ");
  serial->println(result == 0 ? "succeeded"
                              : "failed by error " + String(result));
}

#define CATEGORY_GUMMY         0
#define CATEGORY_SNACK         1
#define CATEGORY_CHOCOLATE     2
#define CATEGORY_MARSHMALLOW   3
#define CATEGORY_CANDY         4
#define CATEGORY_RAMUNE        5
#define CATEGORY_POPCORN       6
#define CATEGORY_RICE_CRACKER  7
#define CATEGORY_JELLY         8
#define CATEGORY_MACARON       9
#define CATEGORY_DONUT        10
#define CATEGORY_CARAMEL      11
#define CATEGORY_COOKIE       12
#define CATEGORY_PUDDING      13
#define CATEGORY_CAKE         14
#define CATEGORY_SPECIAL      15
#define CATEGORY_LEGEND_RIDER 16
#define CATEGORY_SUPER_SENTAI 17
#define CATEGORY_SWEETS       18

typedef struct {
  char* name_1; // 全角 8文字 
  char* name_2; // 全角 8文字 
  uint32_t color; // 0x000000Uの形で表現
  uint16_t r_A;
  uint16_t r_B;
} gochizou;

#define C_BLACK       0x000000U
#define C_NAVY        0x000080U
#define C_DARKGREEN   0x008000U
#define C_DARKCYAN    0x008080U
#define C_MAROON      0x800000U
#define C_PURPLE      0x800080U
#define C_OLIVE       0x808000U
#define C_LIGHTGREY   0xC0C0C0U
#define C_DARKGREY    0x808080U
#define C_BLUE        0x0000FFU
#define C_GREEN       0x00FF00U
#define C_CYAN        0x00FFFFU
#define C_RED         0xFF0000U
#define C_MAGENTA     0xFF00FFU
#define C_YELLOW      0xFFFF00U
#define C_WHITE       0xFFFFFFU
#define C_ORANGE      0xFFA500U
#define C_GREENYELLOW 0xADFF2FU
#define C_PINK        0xFFC0CBU
#define C_BROWN       0x964B00U
#define C_GOLD        0xFFD700U
#define C_SILVER      0xC0C0C0U
#define C_SKYBLUE     0x87CEEBU
#define C_VIOLET      0xB42EE2U

gochizou selected_gochizou = {"ポッピンググミ", NULL, C_PURPLE, R_62K, R_62K};

gochizou gochizou_gummy[] = {
  {"ポッピンググミ",   NULL, C_PURPLE,   R_62K, R_62K}, //017
  {"キッキンググミ",   NULL, C_ORANGE,   R_62K, R_47K}, //018
  {"パンチンググミ",   NULL, C_SKYBLUE,  R_62K, R_39K}, //019
  {"フィッシンググミ", NULL, C_CYAN,     R_62K, R_30K}, //020
  {"アメージンググミ", NULL, C_PURPLE,    R_62K, R_24K}, //021
  {"スパーキンググミ", NULL, C_DARKGREY, R_62K, R_20K}  //022
};

gochizou gochizou_snack[] = {
  {"ザクザクチップス", NULL,     C_YELLOW, R_62K, R_16K},  //023
  {"ヒリヒリチップス", NULL,     C_RED,    R_62K, R_8_2K}, //026
  {"ショットスナック", NULL,     C_YELLOW,  R_24K, R_10K},  //073
  {"スパイクスナック", NULL,     C_YELLOW, R_24K, R_8_2K}, //074
  {"ショットスナック", "技:シュート", C_YELLOW,  R_20K, R_47K},  //078
  {"スパイクスナック", "技:ニードル", C_YELLOW, R_20K, R_39K},  //079
  {"ポテトチェーン",   NULL,     C_YELLOW, R_20K, R_16K},  //083
  {"シールドスナック", NULL,     C_YELLOW, R_20K, R_12K},  //084
  {"ポテトチェーン",   "技:ストーム",  C_YELLOW, R_20K, R_10K},  //085
  {"シールドスナック", "技:アタック", C_YELLOW, R_20K, R_8_2K}, //086
};

gochizou gochizou_chocolate[] = {
  {"チョコダン",  NULL,           C_RED,       R_62K, R_6_8K}, //027
  {"チョコドン",  "技:バースト", C_BROWN,      R_62K, R_5_6K}, //028
  {"チョコT",     NULL,           C_DARKGREEN, R_47K, R_47K},  //030
  {"チョコホネ" , NULL,           C_DARKGREEN, R_47K, R_39K},  //031
  {"チョコルド",  NULL,           C_DARKGREY,  R_47K, R_30K},  //032
  {"チョコルド",  "技:アタック", C_DARKGREY,   R_47K, R_24K},  //033
  {"チョコスタ" , NULL,           C_BROWN,     R_20K, R_62K},  //077
  {"チョコホネ",  "技:ウォール", C_DARKGREEN,  R_20K, R_30K},  //080
  {"チョコスタ",  "技:シュート", C_BROWN,      R_20K, R_20K}   //082
};

gochizou gochizou_marshmallow[] = {
  {"フワマロ", NULL, C_CYAN, R_47K, R_20K},  //034
  {"マルマロ", NULL, C_PINK, R_47K, R_16K}   //035
};

gochizou gochizou_candy[] = {
  {"ブルキャン", NULL,               C_MAGENTA, R_47K, R_12K},  //036
  {"グルキャン", NULL,               C_SKYBLUE, R_47K, R_10K},  //037
  {"バクキャン", NULL,               C_YELLOW,  R_47K, R_8_2K}, //038
  {"もふパチ",   NULL,               C_PURPLE,  R_39K, R_30K},  //044
  {"もふパチ",   "技:スパーキング", C_PURPLE,  R_30K, R_16K}   //059
};

gochizou gochizou_ramune[] = {
  {"バブルラムネ",  "技:ショック", C_SKYBLUE, R_47K, R_6_8K}, //039
  {"バブルラムネ",  NULL,           C_SKYBLUE, R_47K, R_5_6K}  //040
};

gochizou gochizou_popcorn[] = {
  {"ポップバーン", NULL,         C_SKYBLUE, R_39K, R_16K}, //047
  {"ポップバーン", "技:バーン", C_SKYBLUE, R_30K, R_8_2K} //062
};

gochizou gochizou_rice_cracker[] = {
  {"ビュンベイ", NULL,             C_RED, R_39K, R_10K}, //049
  {"ビュンベイ", "技:ローリング", C_RED, R_30K, R_5_6K} //064
};

gochizou gochizou_jelly[] = {
  {"ぷるゼリー", NULL,            C_MAGENTA, R_39K, R_8_2K}, //050
  {"ぷるゼリー", "技:ショット",  C_MAGENTA, R_24K, R_62K}   //065
};

gochizou gochizou_macaron[] = {
  {"エレガンマカロン", NULL,           C_PINK, R_39K, R_6_8K}, //051
  {"エレガンマカロン", "技:アタック", C_PINK, R_24K, R_47K},  //066
};

gochizou gochizou_donut[] = {
  {"ドーマル", NULL,           C_SKYBLUE, R_39K, R_5_6K}, //052
  {"ドーマル", "技:ショット", C_SKYBLUE, R_24K, R_39K}   //067
};

gochizou gochizou_caramel[] = {
  {"キャラメルメル", NULL,           C_GOLD, R_30K, R_62K}, //053
  {"キャラメルメル", "技:マジック", C_GOLD, R_24K, R_30K}  //068
};

gochizou gochizou_cookie[] = {
  {"クッキッキー", NULL,           C_BLUE, R_30K, R_47K}, //054
  {"クッキッキー", "技:ラッシュ", C_BLUE, R_24K, R_24K}  //069
};

gochizou gochizou_pudding[] = {
  {"どっプリン", NULL,             C_ORANGE, R_30K, R_30K}, //056
  {"どっプリン", "技:インパクト", C_ORANGE, R_24K, R_16K}  //071
};

gochizou gochizou_cake[] = {
  {"ケーキング", NULL,      C_WHITE, R_5_6K, R_39K}, //151
  {"ブッシュ",  "ドノエル", C_GREEN, R_5_6K, R_30K}  //152
};

gochizou gochizou_special[] = {
  {"スペシャル",   NULL,            C_WHITE, R_16K, R_62K}, //089
  {"おめでとう",   NULL,            C_WHITE, R_16K, R_47K}, //090
  {"クリスマス",   NULL,            C_GREEN, R_16K, R_39K}, //091
  {"ハッピー",     "ニューイヤー",  C_RED,   R_16K, R_30K}, //092
  {"ミュージック", NULL,            C_WHITE, R_16K, R_24K}, //093
  {"おめでとう",   "誕生日Ver.",    C_WHITE, R_16K, R_20K}  //094
};

gochizou gochizou_legend_rider[] = {
  {"クウガ",      NULL,       C_RED,     R_16K, R_16K},  //095
  {"アギト",      NULL,       C_GOLD,    R_16K, R_12K},  //096
  {"竜騎",        NULL,       C_RED,     R_16K, R_10K},  //097
  {"ファイズ",    NULL,       C_RED,     R_16K, R_8_2K}, //098
  {"ブレード",    NULL,       C_BLUE,    R_16K, R_6_8K}, //099
  {"響",          NULL,       C_PURPLE,  R_16K, R_5_6K}, //100
  {"カブト",      NULL,       C_RED,     R_12K, R_62K},  //101
  {"電王",        NULL,       C_RED,     R_12K, R_47K},  //102
  {"キバ",        NULL,       C_RED,     R_12K, R_39K},  //103
  {"ディケード",  NULL,       C_MAGENTA, R_12K, R_30K},  //104
  {"ダブル",      NULL,       C_PURPLE,   R_12K, R_24K}, //105
  {"オーズ",      NULL,       C_GREEN,   R_12K, R_20K},  //106
  {"フォーゼ",    NULL,       C_WHITE,   R_12K, R_16K},  //107
  {"ウィザード",  NULL,       C_RED,     R_12K, R_12K},  //108
  {"鎧武",        NULL,       C_ORANGE,  R_12K, R_10K},  //109
  {"ドライブ",    NULL,       C_RED,     R_12K, R_8_2K}, //110
  {"ゴースト",    NULL,       C_ORANGE,  R_12K, R_6_8K}, //111
  {"エグゼイド",  NULL,       C_PURPLE,  R_12K, R_5_6K}, //112
  {"ビルド",      NULL,       C_RED,     R_10K, R_62K},  //113
  {"ジオウ"  ,    NULL,       C_PURPLE,  R_10K, R_47K},  //114
  {"ゼロワン",    NULL,       C_YELLOW,  R_10K, R_39K},  //115
  {"セイバー",    NULL,       C_RED,     R_10K, R_30K},  //116
  {"リバイ",      "REVICE",   C_PINK,    R_10K, R_24K},  //117
  {"バイス",      "REVICE",   C_PINK,    R_10K, R_20K},  //118
  {"ギーツ",      NULL,       C_WHITE,   R_10K, R_16K},  //119
  {"タイクーン",  "GEATS",    C_GREEN,   R_10K, R_12K},  //120
  {"バッファ",    "GEATS",    C_PURPLE,  R_10K, R_10K},  //121
  {"ナーゴ",      "GEATS",    C_GOLD,    R_10K, R_8_2K}, //122
  {"ガッチャード", NULL,       C_SKYBLUE, R_10K, R_6_8K}, //123
  {"レジェンド",   "GOTCHARD", C_GOLD,    R_10K, R_5_6K}, //124
  {"マジェード",   "GOTCHARD", C_WHITE,   R_8_2K, R_62K}, //125
  {"ジーン",       "GEATS",    C_BLUE,    R_8_2K, R_47K}, //126
  {"ヴァルバラド", "GOTCHARD", C_PURPLE,  R_8_2K, R_39K}, //127
  {"1号",         NULL,       C_GREEN,   R_8_2K, R_30K}, //128
  {"バルカン",     "ZERO-ONE", C_BLUE,    R_8_2K, R_24K}, //129
  {"ブレイズ",     "SABER",    C_BLUE,    R_8_2K, R_20K}, //130
  {"ライブ",       "REVICE",   C_GOLD,    R_8_2K, R_16K}, //131
  {"ガヴ",         NULL,       C_PURPLE,  R_5_6K, R_24K}, //153
  {"Nextライダー", NULL,       C_GREEN,   R_5_6K, R_20K}, //154
  {"Newヒーロー",  NULL,       C_GREEN,   R_5_6K, R_16K}, //155
  {"仮面ライダー", NULL,       C_GREEN,   R_5_6K, R_12K}  //156
};

gochizou gochizou_super_sentai[] = {
  {"戦隊",     NULL,            C_RED, R_8_2K, R_12K},  //132
  {"ヒーロー", NULL,            C_RED, R_8_2K, R_10K},  //133
  {"爆上戦隊", "ブンブンジャー", C_RED, R_8_2K, R_8_2K}  //134
};

gochizou gochizou_sweets[] = {
  {"おやつ", NULL, C_WHITE, R_24K,  R_6_8K}, // 078
  {"おかし", NULL, C_WHITE, R_24K,  R_5_6K}, // 079
  {"??????", NULL, C_WHITE, R_20K,  R_24K},
  {"??????", NULL, C_WHITE, R_8_2K, R_6_8K},
  {"??????", NULL, C_WHITE, R_8_2K, R_5_6K},
  {"??????", NULL, C_WHITE, R_6_8K, R_62K},
  {"??????", NULL, C_WHITE, R_6_8K, R_47K},
  {"??????", NULL, C_WHITE, R_6_8K, R_39K},
  {"??????", NULL, C_WHITE, R_6_8K, R_30K},
  {"??????", NULL, C_WHITE, R_6_8K, R_24K},
  {"??????", NULL, C_WHITE, R_6_8K, R_20K},
  {"??????", NULL, C_WHITE, R_6_8K, R_16K},
  {"??????", NULL, C_WHITE, R_6_8K, R_12K},
  {"??????", NULL, C_WHITE, R_6_8K, R_10K},
  {"??????", NULL, C_WHITE, R_6_8K, R_8_2K},
  {"??????", NULL, C_WHITE, R_6_8K, R_6_8K},
  {"??????", NULL, C_WHITE, R_6_8K, R_5_6K},
  {"??????", NULL, C_WHITE, R_6_8K, R_62K},
  {"??????", NULL, C_WHITE, R_6_8K, R_47K},
  {"??????", NULL, C_WHITE, R_6_8K, R_39K},
  {"??????", NULL, C_WHITE, R_6_8K, R_30K},
  {"??????", NULL, C_WHITE, R_6_8K, R_24K},
  {"??????", NULL, C_WHITE, R_6_8K, R_20K},
  {"??????", NULL, C_WHITE, R_6_8K, R_16K},
  {"??????", NULL, C_WHITE, R_6_8K, R_12K},
  {"??????", NULL, C_WHITE, R_6_8K, R_10K},
  {"??????", NULL, C_WHITE, R_6_8K, R_8_2K},
  {"??????", NULL, C_WHITE, R_6_8K, R_6_8K},
  {"??????", NULL, C_WHITE, R_6_8K, R_5_6K},
  {"??????", NULL, C_WHITE, R_5_6K, R_62K},
  {"??????", NULL, C_WHITE, R_5_6K, R_47K}
};

int8_t  gochizou_index = 0;
uint8_t gochizou_category = CATEGORY_GUMMY;
uint8_t gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);

void change_gochizou_category(){
  // カテゴリー順を編集しやすいよう、この形にする
  switch(gochizou_category){
  case CATEGORY_GUMMY:
    gochizou_category = CATEGORY_SNACK;
    gochizou_category_size = sizeof(gochizou_snack) / sizeof(gochizou);
    break;
  case CATEGORY_SNACK:
    gochizou_category = CATEGORY_CHOCOLATE;
    gochizou_category_size = sizeof(gochizou_chocolate) / sizeof(gochizou);
    break;
  case CATEGORY_CHOCOLATE:
    gochizou_category = CATEGORY_MARSHMALLOW;
    gochizou_category_size = sizeof(gochizou_marshmallow) / sizeof(gochizou);
    break;
  case CATEGORY_MARSHMALLOW:
    gochizou_category = CATEGORY_CANDY;
    gochizou_category_size = sizeof(gochizou_candy) / sizeof(gochizou);
    break;
  case CATEGORY_CANDY:
    gochizou_category = CATEGORY_RAMUNE;
    gochizou_category_size = sizeof(gochizou_ramune) / sizeof(gochizou);
    break;
  case CATEGORY_RAMUNE:
    gochizou_category = CATEGORY_POPCORN;
    gochizou_category_size = sizeof(gochizou_popcorn) / sizeof(gochizou);
    break;
  case CATEGORY_POPCORN:
    gochizou_category = CATEGORY_RICE_CRACKER;
    gochizou_category_size = sizeof(gochizou_rice_cracker) / sizeof(gochizou);
    break;
  case CATEGORY_RICE_CRACKER:
    gochizou_category = CATEGORY_JELLY;
    gochizou_category_size = sizeof(gochizou_jelly) / sizeof(gochizou);
    break;
  case CATEGORY_JELLY:
    gochizou_category = CATEGORY_MACARON;
    gochizou_category_size = sizeof(gochizou_macaron) / sizeof(gochizou);
    break;
  case CATEGORY_MACARON:
    gochizou_category = CATEGORY_DONUT;
    gochizou_category_size = sizeof(gochizou_donut) / sizeof(gochizou);
    break;
  case CATEGORY_DONUT:
    gochizou_category = CATEGORY_CARAMEL;
    gochizou_category_size = sizeof(gochizou_caramel) / sizeof(gochizou);
    break;
  case CATEGORY_CARAMEL:
    gochizou_category = CATEGORY_COOKIE;
    gochizou_category_size = sizeof(gochizou_cookie) / sizeof(gochizou);
    break;
  case CATEGORY_COOKIE:
    gochizou_category = CATEGORY_PUDDING;
    gochizou_category_size = sizeof(gochizou_pudding) / sizeof(gochizou);
    break;
  case CATEGORY_PUDDING:
    gochizou_category = CATEGORY_CAKE;
    gochizou_category_size = sizeof(gochizou_cake) / sizeof(gochizou);
    break;
  case CATEGORY_CAKE:
    gochizou_category = CATEGORY_SPECIAL;
    gochizou_category_size = sizeof(gochizou_special) / sizeof(gochizou);
    break;
  case CATEGORY_SPECIAL:
    gochizou_category = CATEGORY_LEGEND_RIDER;
    gochizou_category_size = sizeof(gochizou_legend_rider) / sizeof(gochizou);
    break;
  case CATEGORY_LEGEND_RIDER:
    gochizou_category = CATEGORY_SUPER_SENTAI;
    gochizou_category_size = sizeof(gochizou_super_sentai) / sizeof(gochizou);
    break;
  case CATEGORY_SUPER_SENTAI:
    //gochizou_category = CATEGORY_SWEETS;
    //gochizou_category_size = sizeof(gochizou_sweets) / sizeof(gochizou);
    gochizou_category = CATEGORY_GUMMY;
    gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);
    break;
  /*  
  case CATEGORY_SWEETS:
    gochizou_category = CATEGORY_GUMMY;
    gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);
    break;
  */
  default:
    ;
  }

  gochizou_index = 0;
}

void select_gochizou(){
  if(gochizou_index >= gochizou_category_size){
    gochizou_index = 0;
  }else if(gochizou_index < 0){
    gochizou_index = gochizou_category_size - 1;
  }

  switch(gochizou_category){
  case CATEGORY_GUMMY:        selected_gochizou = gochizou_gummy[gochizou_index];        break;
  case CATEGORY_SNACK:        selected_gochizou = gochizou_snack[gochizou_index];        break;
  case CATEGORY_CHOCOLATE:    selected_gochizou = gochizou_chocolate[gochizou_index];    break;
  case CATEGORY_MARSHMALLOW:  selected_gochizou = gochizou_marshmallow[gochizou_index];  break;
  case CATEGORY_CANDY:        selected_gochizou = gochizou_candy[gochizou_index];        break;
  case CATEGORY_RAMUNE:       selected_gochizou = gochizou_ramune[gochizou_index];       break;
  case CATEGORY_POPCORN:      selected_gochizou = gochizou_popcorn[gochizou_index];      break;
  case CATEGORY_RICE_CRACKER: selected_gochizou = gochizou_rice_cracker[gochizou_index]; break;
  case CATEGORY_JELLY:        selected_gochizou = gochizou_jelly[gochizou_index];        break;
  case CATEGORY_MACARON:      selected_gochizou = gochizou_macaron[gochizou_index];      break;
  case CATEGORY_DONUT:        selected_gochizou = gochizou_donut[gochizou_index];        break;
  case CATEGORY_CARAMEL:      selected_gochizou = gochizou_caramel[gochizou_index];      break;
  case CATEGORY_COOKIE:       selected_gochizou = gochizou_cookie[gochizou_index];       break;
  case CATEGORY_PUDDING:      selected_gochizou = gochizou_pudding[gochizou_index];      break;
  case CATEGORY_CAKE:         selected_gochizou = gochizou_cake[gochizou_index];         break;
  case CATEGORY_SPECIAL:      selected_gochizou = gochizou_special[gochizou_index];      break;
  case CATEGORY_LEGEND_RIDER: selected_gochizou = gochizou_legend_rider[gochizou_index]; break;
  case CATEGORY_SUPER_SENTAI: selected_gochizou = gochizou_super_sentai[gochizou_index]; break;
  case CATEGORY_SWEETS:       selected_gochizou = gochizou_sweets[gochizou_index];       break;
  default: ;
  }
}

M5Canvas canvas_0(&StickCP2.Display); // スプライト1
M5Canvas canvas_1(&StickCP2.Display); // スプライト2

#define DISP_WIDTH  135
#define DISP_HEIGHT 240
#define SWEETS_ICON_WIDTH  85
#define SWEETS_ICON_HEIGHT 85

#define EYE_X 35
#define EYE_Y 140

void update_disp_gochizou_name(){
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、上下で帯の色を変える
    switch(gochizou_index){
    case 10: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, C_GREEN); break; // W
    case 18: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, C_BLUE);  break; // Build
    default: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, selected_gochizou.color);
    }
  }else{
    StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, selected_gochizou.color);
  }
  StickCP2.Display.fillRect(0, 215, DISP_WIDTH, 25, selected_gochizou.color);

  StickCP2.Display.fillRect(0, 130, DISP_WIDTH, 85, TFT_BLACK);
  if(selected_gochizou.name_2 == NULL){
    StickCP2.Display.setCursor(0,170);
    StickCP2.Display.print(selected_gochizou.name_1);
  }else{
    StickCP2.Display.setCursor(0,150);
    StickCP2.Display.print(selected_gochizou.name_1);
    StickCP2.Display.setCursor(0,185);
    StickCP2.Display.print(selected_gochizou.name_2);
  }
}

void update_disp_gochizou_category(){
  StickCP2.Display.fillRect(0, 25, DISP_WIDTH, 105, C_BLACK);
  switch(gochizou_category){
  case CATEGORY_GUMMY:        StickCP2.Display.drawPng((std::uint8_t*)gummy,        12425, 25, 35); break;
  case CATEGORY_SNACK:        StickCP2.Display.drawPng((std::uint8_t*)snack,        14633, 25, 35); break;
  case CATEGORY_CHOCOLATE:    StickCP2.Display.drawPng((std::uint8_t*)chocolate,    12294, 25, 35); break;
  case CATEGORY_MARSHMALLOW:  StickCP2.Display.drawPng((std::uint8_t*)marshmallow,  10978, 25, 35); break;
  case CATEGORY_CANDY:        StickCP2.Display.drawPng((std::uint8_t*)candy,        11478, 25, 35); break;
  case CATEGORY_RAMUNE:       StickCP2.Display.drawPng((std::uint8_t*)ramune,       14219, 25, 35); break;
  case CATEGORY_POPCORN:      StickCP2.Display.drawPng((std::uint8_t*)popcorn,      13037, 25, 35); break;
  case CATEGORY_RICE_CRACKER: StickCP2.Display.drawPng((std::uint8_t*)rice_cracker, 12937, 25, 35); break;
  case CATEGORY_JELLY:        StickCP2.Display.drawPng((std::uint8_t*)jelly,        15142, 25, 35); break;
  case CATEGORY_MACARON:      StickCP2.Display.drawPng((std::uint8_t*)macaron,      12466, 25, 35); break;
  case CATEGORY_DONUT:        StickCP2.Display.drawPng((std::uint8_t*)donut,        15886, 25, 35); break;
  case CATEGORY_CARAMEL:      StickCP2.Display.drawPng((std::uint8_t*)caramel,      12346, 25, 35); break;
  case CATEGORY_COOKIE:       StickCP2.Display.drawPng((std::uint8_t*)cookie,       12419, 25, 35); break;
  case CATEGORY_PUDDING:      StickCP2.Display.drawPng((std::uint8_t*)pudding,      15329, 25, 35); break;
  case CATEGORY_CAKE:         StickCP2.Display.drawPng((std::uint8_t*)cake,          9209, 25, 35); break;
  case CATEGORY_SPECIAL:      StickCP2.Display.drawPng((std::uint8_t*)special,      12475, 25, 35); break;
  case CATEGORY_LEGEND_RIDER: StickCP2.Display.drawPng((std::uint8_t*)rider,         2467, 25, 35); break;
  case CATEGORY_SUPER_SENTAI: StickCP2.Display.drawPng((std::uint8_t*)sentai,        5287, 25, 35); break;
  //case CATEGORY_SWEETS:
  //  break;
  default: ;
  } 
}


void show_gochizou_face_init(){
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X+7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X-7, EYE_Y-7,  5, C_WHITE);
  canvas_0.pushSprite(0,0);
  
  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
}

void show_gochizou_face_change(){
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  canvas_0.fillCircle(EYE_X, EYE_Y, 6, C_SILVER);
  canvas_0.fillCircle(EYE_X, EYE_Y,  2, C_BLACK);
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y,  6, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y,  2, C_BLACK);
  // 両まぶた
  canvas_0.fillTriangle(EYE_X-24, EYE_Y-26, EYE_X+26, EYE_Y+5, EYE_X+26, EYE_Y-26, C_WHITE);
  canvas_0.fillTriangle(DISP_WIDTH - EYE_X+24, EYE_Y-26, DISP_WIDTH - EYE_X-26, EYE_Y+5, DISP_WIDTH - EYE_X-26, EYE_Y-26, C_WHITE);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X-7, EYE_Y+9,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+7, EYE_Y+9,  5, C_WHITE);

 // canvas_0.drawPng((std::uint8_t*)gochizou_init, 548, 0, 0);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    switch(gochizou_index){
    case 0:  canvas_0.drawPng((std::uint8_t*)kuuga,    2136, 30, 50); break;
    case 1:  canvas_0.drawPng((std::uint8_t*)agito,    1897, 30, 50); break;
    case 2:  canvas_0.drawPng((std::uint8_t*)ryuki,    2100, 30, 50); break;
    case 3:  canvas_0.drawPng((std::uint8_t*)faiz,     1884, 30, 50); break;
    case 4:  canvas_0.drawPng((std::uint8_t*)blade,    1357, 30, 50); break;
    case 5:  canvas_0.drawPng((std::uint8_t*)hibiki,   2128, 30, 50); break;
    case 6:  canvas_0.drawPng((std::uint8_t*)kabuto,   2654, 30, 50); break;
    case 7:  canvas_0.drawPng((std::uint8_t*)deno,     3238, 30, 50); break;
    case 8:  canvas_0.drawPng((std::uint8_t*)kiva,     2509, 30, 50); break;
    case 9:  canvas_0.drawPng((std::uint8_t*)decade,   1612, 30, 50); break;
    case 10: canvas_0.drawPng((std::uint8_t*)w,        1535, 30, 50); break;
    case 11: canvas_0.drawPng((std::uint8_t*)ooo,      4088, 30, 50); break;
    case 12: canvas_0.drawPng((std::uint8_t*)fourze,   4203, 30, 50); break;
    case 13: canvas_0.drawPng((std::uint8_t*)wizard,   4437, 30, 50); break;
    case 14: canvas_0.drawPng((std::uint8_t*)gaim,     2921, 30, 50); break;
    case 15: canvas_0.drawPng((std::uint8_t*)drive,    1850, 30, 50); break;
    case 16: canvas_0.drawPng((std::uint8_t*)ghost,    2158, 30, 50); break;
    case 17: canvas_0.drawPng((std::uint8_t*)exaid,    2450, 30, 50); break;
    case 18: canvas_0.drawPng((std::uint8_t*)build,    1963, 30, 50); break;
    case 19: canvas_0.drawPng((std::uint8_t*)zio,      2045, 30, 50); break;
    case 20: canvas_0.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 21: canvas_0.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 22: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 23: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 24: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    /*
    case 25: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 26: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 27: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    */
    case 28: canvas_0.drawPng((std::uint8_t*)gotchard, 2453, 30, 50); break;
    case 29: canvas_0.drawPng((std::uint8_t*)legend,   3035, 30, 50); break;
    case 30: canvas_0.drawPng((std::uint8_t*)majede,   2743, 30, 50); break;
    // case 31: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 32: canvas_0.drawPng((std::uint8_t*)valvarad, 2630, 30, 50); break;
    case 33: canvas_0.drawPng((std::uint8_t*)ichigo,   3302, 30, 50); break;
    /*
    case 34: canvas_0.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 35: canvas_0.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 36: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    */
    case 37: canvas_0.drawPng((std::uint8_t*)gavv,     2121, 30, 50); break;
    /*
    case 38: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 39: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 40: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    */
    default: ;
    }
  } else if(gochizou_category == CATEGORY_SUPER_SENTAI){
    switch(gochizou_index){
    //case 0:  canvas_0.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    //case 1:  canvas_0.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    case 2:  canvas_0.drawPng((std::uint8_t*)boonboom,    3597, 30, 50); break;
    default: ;
    }
  }
  canvas_0.pushSprite(0,0);

  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
 // canvas_1.drawPng((std::uint8_t*)gochizou_blink, 1070, 0, 0);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    switch(gochizou_index){
    case 0:  canvas_1.drawPng((std::uint8_t*)kuuga,    2136, 30, 50); break;
    case 1:  canvas_1.drawPng((std::uint8_t*)agito,    1897, 30, 50); break;
    case 2:  canvas_1.drawPng((std::uint8_t*)ryuki,    2100, 30, 50); break;
    case 3:  canvas_1.drawPng((std::uint8_t*)faiz,     1884, 30, 50); break;
    case 4:  canvas_1.drawPng((std::uint8_t*)blade,    1357, 30, 50); break;
    case 5:  canvas_1.drawPng((std::uint8_t*)hibiki,   2128, 30, 50); break;
    case 6:  canvas_1.drawPng((std::uint8_t*)kabuto,   2654, 30, 50); break;
    case 7:  canvas_1.drawPng((std::uint8_t*)deno,     3238, 30, 50); break;
    case 8:  canvas_1.drawPng((std::uint8_t*)kiva,     2509, 30, 50); break;
    case 9:  canvas_1.drawPng((std::uint8_t*)decade,   1612, 30, 50); break;
    case 10: canvas_1.drawPng((std::uint8_t*)w,        1535, 30, 50); break;
    case 11: canvas_1.drawPng((std::uint8_t*)ooo,      4088, 30, 50); break;
    case 12: canvas_1.drawPng((std::uint8_t*)fourze,   4203, 30, 50); break;
    case 13: canvas_1.drawPng((std::uint8_t*)wizard,   4437, 30, 50); break;
    case 14: canvas_1.drawPng((std::uint8_t*)gaim,     2921, 30, 50); break;
    case 15: canvas_1.drawPng((std::uint8_t*)drive,    1850, 30, 50); break;
    case 16: canvas_1.drawPng((std::uint8_t*)ghost,    2158, 30, 50); break;
    case 17: canvas_1.drawPng((std::uint8_t*)exaid,    2450, 30, 50); break;
    case 18: canvas_1.drawPng((std::uint8_t*)build,    1963, 30, 50); break;
    case 19: canvas_1.drawPng((std::uint8_t*)zio,      2045, 30, 50); break;
    case 20: canvas_1.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 21: canvas_1.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 22: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 23: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 24: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    /*
    case 25: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 26: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 27: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    */
    case 28: canvas_1.drawPng((std::uint8_t*)gotchard, 2453, 30, 50); break;
    case 29: canvas_1.drawPng((std::uint8_t*)legend,   3035, 30, 50); break;
    case 30: canvas_1.drawPng((std::uint8_t*)majede,   2743, 30, 50); break;
    // case 31: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 32: canvas_1.drawPng((std::uint8_t*)valvarad, 2630, 30, 50); break;
    case 33: canvas_1.drawPng((std::uint8_t*)ichigo,   3302, 30, 50); break;
    /*
    case 34: canvas_1.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 35: canvas_1.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 36: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    */
    case 37: canvas_1.drawPng((std::uint8_t*)gavv,     2121, 30, 50); break;
    /*
    case 38: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 39: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 40: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    */
    default: ;
    }
  } else if (gochizou_category == CATEGORY_SUPER_SENTAI){
    switch(gochizou_index){
    //case 0:  canvas_1.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    //case 1:  canvas_1.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    case 2:  canvas_1.drawPng((std::uint8_t*)boonboom,    3597, 30, 50); break;
    default: ;
    }
  }
}

void show_gochizou_face_finish(){
  // 天使の輪を描く
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X+7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X-7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillEllipse(DISP_WIDTH/2, 70, 50, 30, C_GOLD);
  canvas_0.fillEllipse(DISP_WIDTH/2, 67, 40, 20, C_WHITE);
  canvas_0.pushSprite(0,0);
  
  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
  canvas_1.fillEllipse(DISP_WIDTH/2, 70, 50, 30, C_GOLD);
  canvas_1.fillEllipse(DISP_WIDTH/2, 67, 40, 20, C_WHITE);
}

uint8_t blink_state = 0;
unsigned long prev_eye_change_point_ms = 0;

void update_face(unsigned long now_ms){
  // 状態遷移時
  switch(prev_state){
  case STATE_INIT:
    if(state == STATE_GOCHIZOU){
      show_gochizou_face_init();
    }
    break;
  case STATE_GOCHIZOU:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_CHANGE){
      show_gochizou_face_change();
    }
    break;
  case STATE_CHANGE:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_FINISH){
      show_gochizou_face_change();
    }
    break;
  case STATE_FINISH:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_CHANGE){
      show_gochizou_face_finish();
    }
    break;
  default:
    ;
  }

  // 時間経過時
  if(state == STATE_GOCHIZOU || state == STATE_CHANGE){
    // まばたき動作
    switch(blink_state){
    case 0:
      if(now_ms - prev_eye_change_point_ms >= 3000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 1:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 2:
      if(now_ms - prev_eye_change_point_ms >= 5000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 3:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 4:
      if(now_ms - prev_eye_change_point_ms >= 7000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 5:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 6:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 7:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state = 0;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    default:
      ;
    }
  }
}

void setup(void)
{
  auto cfg = M5.config();
  StickCP2.begin(cfg);

  Wire.end();
  Wire.begin(0, 26); //G0. G26 I2C port

  Serial.begin(115200);

  // 省電力化のため、CPU周波数を少し落とす場合に有効化。最大240MHz。
  setCpuFrequencyMhz(160);

  pinMode(PIN_SW, INPUT_PULLUP);  // 入力として使用する
  gpio_pulldown_dis(GPIO_NUM_36); // 使用しないのでフローティング入力設定
  gpio_pullup_dis(GPIO_NUM_36);   // 使用しないのでフローティング入力設定

  StickCP2.Display.setBrightness(5);
  StickCP2.Display.setRotation(2);  // 画面向き
  StickCP2.Display.setTextSize(2);  // フォントサイズ
  StickCP2.Display.setTextFont(&fonts::lgfxJapanGothic_8);  // フォント
  update_disp_gochizou_name();
  update_disp_gochizou_category();

  // ゴチゾウの表情用スプライトの準備
  canvas_0.createSprite(DISP_WIDTH, DISP_HEIGHT);
  canvas_1.createSprite(DISP_WIDTH, DISP_HEIGHT);
}

void loop(void)
{
  StickCP2.update();
  sw = digitalRead(PIN_SW);

  unsigned long now_ms = millis();

  if(prev_sw == OFF && sw == ON){
    switch(state){
    case STATE_INIT:
      StickCP2.Speaker.tone(5000, 50);
      change_gochizou_category();
      select_gochizou();
      update_disp_gochizou_category();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      change_state(STATE_CHANGE);
      break;
    case STATE_CHANGE:
      change_state(STATE_FINISH);
      state_change_point_ms = now_ms;
      break;
    case STATE_FINISH:
      break;
    default:
      ;
    }
  }

  if(StickCP2.BtnA.wasClicked()){
    StickCP2.Speaker.tone(5000, 50);
    switch(state){
    case STATE_INIT:
      gochizou_index++;
      select_gochizou();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      break;
    case STATE_CHANGE:
    case STATE_FINISH:
    default:
      ;
    }
  }

  if(StickCP2.BtnB.wasClicked()){
    switch(state){
    case STATE_INIT:
      StickCP2.Speaker.tone(5000, 50);
      change_gochizou_category();
      select_gochizou();
      update_disp_gochizou_category();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      change_state(STATE_CHANGE);
      break;
    case STATE_CHANGE:
      change_state(STATE_FINISH);
      state_change_point_ms = now_ms;
      break;
    case STATE_FINISH:
      break;
    default:
      ;
    }
  }


  if(StickCP2.BtnA.wasHold()){
    switch(state){
    case STATE_INIT:
      // 抵抗値をセットする
      int result_a, result_b;

      #ifndef debug
        result_a = potentio.writeWiperRAM(0, selected_gochizou.r_A);
        printLogAboutWrite(&Serial, 0, selected_gochizou.r_A, result_a);
        result_b = potentio.writeWiperRAM(1, selected_gochizou.r_B);
        printLogAboutWrite(&Serial, 1, selected_gochizou.r_B, result_b);
      #else
        result_a = 0;
        result_b = 0;
      #endif

      if(result_a == 0 && result_b == 0){
        StickCP2.Speaker.tone(4000, 50);
        delay(50);
        StickCP2.Speaker.tone(6000, 50);
        change_state(STATE_GOCHIZOU);
      }
      break;
    case STATE_GOCHIZOU:
    case STATE_CHANGE:
    case STATE_FINISH:
      change_state(STATE_INIT);
      break;
    default:
      ;
    }
  }

  // 時間経過処理
  if(state == STATE_FINISH && now_ms - state_change_point_ms >= STATE_FINISH_TO_CHANGE_TIME_MS){
    change_state(STATE_CHANGE);
  }

  update_face(now_ms);

  prev_sw = sw;
  prev_state = state;

  delay(10);
}

完成したスケッチをArduino IDEでコンパイルと検証を行って見たいと思います。その前に準備として、MCP4661_asukiaaaをArduino IDEにインストールしました(関連ライブラリとして、wire_asukiaaa 1.1.13もインストールされました)

コンパイルしたところ、エラーが発生しました

IIn file included from c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.h:3,
                 from c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:3,
                 from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:35: error: 'TwoWire' was not declared in this scope
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                   ^~~~~~~
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:35: note: suggested alternative: 'TwoWire_h'
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                   ^~~~~~~
                                   TwoWire_h
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:42: error: template argument 1 is invalid
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                          ^
In file included from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:131:3: error: 'TwoWire' does not name a type; did you mean 'TwoWire_h'?
   TwoWire* wire;
   ^~~~~~~
   TwoWire_h
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:133:15: error: expected ')' before '*' token
   Core(TwoWire* wire, uint8_t address) : wire(wire), address(address) {}
       ~       ^
               )
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp: In member function 'int MCP4661_asukiaaa::Core::writeToRegister(uint8_t, uint16_t, uint8_t)':
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:189:5: error: 'wire' was not declared in this scope
     wire->beginTransmission(address);
     ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:189:5: note: suggested alternative: 'Core'
     wire->beginTransmission(address);
     ^~~~
     Core
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp: In member function 'int MCP4661_asukiaaa::Core::readFromRegister(uint8_t, uint16_t*, uint8_t)':
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:199:9: error: 'wire' was not declared in this scope
         wire, address, buildFirstByte(registerAddress, command, 0), bytes, 2);
         ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:199:9: note: suggested alternative: 'Core'
         wire, address, buildFirstByte(registerAddress, command, 0), bytes, 2);
         ^~~~
         Core
C:\Tools\M5StickCPlus2\gochizou\gochizou.ino: At global scope:
C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:38:84: error: no matching function for call to 'MCP4661_asukiaaa::Core::Core(TwoWire*, const uint8_t&)'
 MCP4661_asukiaaa::Core potentio(&Wire, MCP4661_asukiaaa::DeviceAddress::A0H_A1H_A2H);
                                                                                    ^
In file included from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note: candidate: 'constexpr MCP4661_asukiaaa::Core::Core(const MCP4661_asukiaaa::Core&)'
 class Core {
       ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note:   candidate expects 1 argument, 2 provided
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note: candidate: 'constexpr MCP4661_asukiaaa::Core::Core(MCP4661_asukiaaa::Core&&)'
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note:   candidate expects 1 argument, 2 provided

exit status 1

Compilation error: no matching function for call to 'MCP4661_asukiaaa::Core::Core(TwoWire*, const uint8_t&)'
エラーメッセージから検索しましたが、さっぱり判りません。そもそもToWireってM5STAMPの標準関数では無いの?!っという疑問しかわきませんでした。記述内容をチェックしても原因が判りません

問題の切り分けのためにMCP4661_asukiaaa.hppにM5StickCPlus2.hのインクルード文を追加したところ同じエラーが発生、さらにwire_asukiaaa.hppにも追加してもエラーが発生しました。
この現象から、ToWireが定義されているwire.hが参照されていないのではなりました。

慣れている人であれば対策を知っているかと思いますが、初めて使用した私からするとこれまたサッパリです。なので、全てのヘッダファイルをローカルにコピーして、インクルード文をローカル参照にすることでコンパイルが正常に終了しました。簡単に書いていますが、一晩悩みましたよ