M5Unified入門 その1 概要確認

概要

M5Stackシリーズ共通ライブラリであるM5Unifiedについてちゃんと使い方を調べてみたいと思います。まずはボードが持っている機能をどの程度カバーしているのかを確認してきたいと思います。

M5Unifiedとは?

これまでM5Stack社はボード別に開発ライブラリを作成しており、似たようなライブラリがたくさんあり、そして微妙に仕様が異なるという状況になっていました。グラフィックライブラリであるLovyanGFXが登場したことで搭載している液晶画面などの判定や、標準ライブラリより高速描画が可能になりました。

その後、LovyanGFXを元にM5Stack公式ライブラリとしてM5GFXが作成され、各種ボードの制御コードが追加されたものがM5Unifiedとなります。

気をつけないといけないことは、もともとの個別ライブラリとM5Unifiedは完全コンパチではありません。ほぼそのまま動かすことができるのですが、ボードごとに異なっていたライブラリの関数などを整理する段階で微妙にクラスや関数名などが変わっていることがありますし、M5Unifiedでかなり強化された機能もある一方、まだサポートされていない機能もあります。

GitHub - m5stack/M5Unified: Unified library for M5Stack series
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

上記がリポジトリになります。ライブラリ自体はライブラリマネージャに登録してあるのでM5Unifiedで検索して、すぐに導入することが可能です。

公式ドキュメント

m5-docs
The reference docs for M5Stack products. Quick start, get the detailed information or instructions such as IDE,UIFLOW,Ar...

上記にあるドキュメントが公式ドキュメントとなります。いろいろ準備中のようですので、今後充実していくはずです。

m5-docs
The reference docs for M5Stack products. Quick start, get the detailed information or instructions such as IDE,UIFLOW,Ar...

先程のページからリンクされている「M5Unifiedへの移植のポイント」のページが使い方がまとまっていて参考になると思います。

m5-docs
The reference docs for M5Stack products. Quick start, get the detailed information or instructions such as IDE,UIFLOW,Ar...

上記がPlatformIOを利用したM5Unifiedの導入方法です。

また、らびやんさんの紹介スライドがありますのでこちらで概要が把握できると思います。

複数ボードでのプログラム共通化

M5UnifiedはM5Stackの共通ライブラリであり、ボード自動判定がありますのでまったく同じプログラムを複数のボードで使い回すことが可能です。

条件があえばボード別にビルドする必要もなく、同じバイナリファイルを複数のボードに転送するだけで動作することも可能ですが、最初は機種別にビルドしたほうが安全だと思います。

共通化をする場合には以下の違いを注意してみてください。

MCU(ESP32/ESP32-C3/ESP32-S3)の違い

M5Stackに搭載されているESP32には無印ESP32、廉価版のESP32-C3、高性能版のESP32-S3の3シリーズあります。M5Unifiedはすべてに対応していますが、ビルドするオプションや出来上がったバイナリがシリーズごとに違うので対応ボードを選び直してビルドし直す必要があります。

ただし同じMCUシリーズを採用している場合には、同一バイナリをそのまま動かすことも可能です。

フラッシュメモリ容量の違い

同じ無印ESP32シリーズを採用しているボードでもCore2はフラッシュが16MB、M5StickC Plusは4MBと搭載しているフラッシュ容量が違います。4MBでビルドしたものは16MBのボードにも転送して動かすことは可能ですが、逆はできませんのでビルドし直しが必要になります。

PSRAMの違い

Core2のようにPSRAMを搭載しているボードと、M5StickC Plusのように搭載していないボードで共通プログラム化をする場合にはPSRAMを無効にしたほうが好ましいです。

PSRAMを有効にしてビルドするとArduinoのバージョンによってはPSRAMの初期化エラーで起動失敗する場合があるのでPSRAM非搭載ボードで動かすプログラムについてはPSRAMを無効化にするか、PSRAM搭載機種のみサポートするプログラムにするのかが好ましいです。

機種判定

#include <Arduino.h>
#include <M5Unified.h>

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

  const char* name;
  switch (M5.getBoard()) {
    case m5::board_t::board_M5StackCoreS3:  name = "StackS3";     break;
    case m5::board_t::board_M5AtomS3Lite:   name = "ATOMS3Lite";  break;
    case m5::board_t::board_M5AtomS3:       name = "ATOMS3";      break;
    case m5::board_t::board_M5StampC3:      name = "StampC3";     break;
    case m5::board_t::board_M5StampC3U:     name = "StampC3U";    break;
    case m5::board_t::board_M5Stack:        name = "Stack";       break;
    case m5::board_t::board_M5StackCore2:   name = "StackCore2";  break;
    case m5::board_t::board_M5StickC:       name = "StickC";      break;
    case m5::board_t::board_M5StickCPlus:   name = "StickCPlus";  break;
    case m5::board_t::board_M5StackCoreInk: name = "CoreInk";     break;
    case m5::board_t::board_M5Paper:        name = "Paper";       break;
    case m5::board_t::board_M5Tough:        name = "Tough";       break;
    case m5::board_t::board_M5Station:      name = "Station";     break;
    case m5::board_t::board_M5Atom:         name = "ATOM";        break;
    case m5::board_t::board_M5AtomPsram:    name = "ATOM PSRAM";  break;
    case m5::board_t::board_M5AtomU:        name = "ATOM U";      break;
    case m5::board_t::board_M5TimerCam:     name = "TimerCamera"; break;
    case m5::board_t::board_M5StampPico:    name = "StampPico";   break;
    default:                                name = "Who am I ?";  break;
  }
  M5.Display.println(name);
}

void loop(void) {
  delay(1);
}

M5.getBoard()にてボードの種類が取得可能です。

M5GFX/boards.hpp at master · m5stack/M5GFX
Graphics library for M5Stack series. Contribute to m5stack/M5GFX development by creating an account on GitHub.

上記に対応しているボード一覧があります。

CoreシリーズStickシリーズATOMシリーズSTAMPシリーズその他シリーズ
ESP32
搭載ボード
BASIC
GRAY
FIRE
M5GO
CORE2
CORE2 FOR AWS
M5Stick
M5StickC
M5StickC PLUS
M5StickT
M5StickT2
ATOM LITE
ATOM MATRIX
ATOM ECHO
ATOM U
STAMP PICOCORE.INK
M5PAPER
TOUGH
STATION 485
STATION BAT
ESP32-C3
搭載ボード
STAMP C3
STAMP C3U
ESP32-S3
搭載ボード
CORES3AtomS3
AtomS3 Lite
StampS3

かなり昔に販売終了し日本未発売のM5Stickと、サーモグラフィーカメラを搭載した8万円ぐらいするM5StickT系が未対応になります。

M5Stack用サーマルカメラユニット2(MLX90640)視野角110°版
MLX90640赤外線アレイモジュールを採用したM5Stack用熱画像ユニットです。32 x 24配列の赤外線アレイ、広い視野角(110 ° × 75 °)、-40 ℃ ~ 300 ℃の温度測定範囲を持ち、ホストMCUとはI2Cで通信します...

M5StickTは非常に高いので、サーマルカメラユニットやハットを使うことが推奨されていると思います。

また、ボード以外にも外付けLCDやAtom Displayなどにも対応しています。

画面周り

LovyanGFXと使い方はほぼ変わりません。ただしM5.Displayクラスに集約されていますので、ボードによってM5.LcdからM5.Displayクラスに修正する必要があります。

#include <Arduino.h>
#include <M5Unified.h>

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

void loop(void) {
  M5.Display.startWrite();
  M5.Display.setCursor(0, 0);
  M5.Display.print(millis());
  M5.Display.endWrite();

  delay(1);
}

特徴的なのが初期化方法です。初期化オプションが増えたのでM5.config()でデフォルトの設定を取得してから初期化しています。

M5Unified/HowToUse.ino at master · m5stack/M5Unified
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

初期化オプションについては上記のスケッチ例が参考になると思います。

描画周りはM5.Displayに集約されているのと、LovyanGFXのテクニックとしてstartWrite()とendWrite()で描画まわりを囲ってあげることで描画速度があがります。ただし、E-INK系は特殊なんですが、基本はこの囲いはなくても動きますし、標準ライブラリよりは描画が早いです。

タッチパネル

#include <Arduino.h>
#include <M5Unified.h>

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

void loop(void) {
  M5.update();

  M5.Display.startWrite();
  if (M5.Touch.isEnabled()) {
    auto t = M5.Touch.getDetail();
    auto x = t.distanceX();
    auto y = t.distanceY();
    auto p = t.isPressed();
    M5.Display.setCursor(0, 0);
    M5.Display.printf("x = %4d, y = %4d, press = %d", x, y, p);
  }
  M5.Display.endWrite();

  delay(1);
}

タッチパネルはM5.update()を呼び出すことで情報が更新されるので注意してください。タッチパネルもボードにより仕様が異なりますが、M5Unifiedであればとくに違いを意識する必要がありません。

M5Unified/Touch.ino at master · m5stack/M5Unified
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

マルチタッチなど詳しい使い方は上記のスケッチ例を参考にしてください。

LED

#include <Arduino.h>
#include <M5Unified.h>

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

uint8_t led = 0;

void loop(void) {
  led++;
  M5.Power.setLed(led);
  delay(1);
}

Core2、Core3、CoreInk、M5StickC、M5StickC Plusには赤もしくは緑のLEDがあります。ボードによりアクセス方法が本来異なるのですがM5.Power.setLed()に0から255までの明るさを入れることで制御が可能です。

RGB LED

#include <Arduino.h>
#include <M5Unified.h>
#include <EspEasyLED.h>

EspEasyLED *rgbled;

void setup(void) {
  auto cfg = M5.config();
  M5.begin(cfg);
  switch (M5.getBoard()) {
    case m5::board_t::board_M5StampS3:
      rgbled = new EspEasyLED(GPIO_NUM_21, 1, 20);
      break;
    default:
      rgbled = NULL;
      break;
  }
}

void loop(void) {
  if (rgbled) {
    rgbled->showColor(255, 0, 0);  // RED
    delay(1000);

    rgbled->showColor(EspEasyLEDColor::GREEN);
    delay(1000);

    rgbled->showColor(EspEasyLEDColor::BLUE);
    delay(1000);

    rgbled->showColor(EspEasyLEDColor::WHITE);
    delay(1000);
  }
}

ATOM系、Fire、Core2 for AWS、Stamp系などにはRGB LEDが搭載されています。現在のところRGB LEDはM5Unifiedではサポートしていません。何らかのライブラリなどを利用して、自分で制御する必要があります。

上記の例では自作のEspEasyUtilsライブラリの中のEspEasyLEDを利用したサンプルです。1つだけ搭載している場合にはライブラリを利用せずにneopixelWrite(GPIO_NUM_21, 20, 0, 0)などのように直接制御することも可能です。

ライブラリとしてはFastLEDがよく使われていると思います。

スピーカー

M5Unified/Speaker.ino at master · m5stack/M5Unified
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

上記にスケッチ例があります。M5StackのボードだとDACと呼ばれるアナログ方式の他にI2Sのデジタル方式、そして音のオンオフだけ可能なブザーの3種類があります。

M5Unifiedではその方式でも同じ方法で音を鳴らすことが可能です。音質的にはI2Sがよく、DACが若干ノイズがまじり、ブザーがなんとか効果音が鳴らせるぐらいのものになります。

取り扱いは結構難しいですのでここでは深く取り上げません。

マイク

M5Unified/Microphone.ino at master · m5stack/M5Unified
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

マイクもI2Sのデジタル方式と、ADCのアナログ方式がありますがM5Unifiedでは同じように取り扱うことができます。詳しくは上記のスケッチ例を見てください。

ボタン

#include <M5Unified.h>

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

void loop(void) {
  M5.update();

  M5.Display.startWrite();
  M5.Display.setCursor(0, 0);

  int state = M5.BtnA.wasHold()               ? 1
              : M5.BtnA.wasClicked()          ? 2
              : M5.BtnA.wasPressed()          ? 3
              : M5.BtnA.wasReleased()         ? 4
              : M5.BtnA.wasDecideClickCount() ? 5
                                              : 0;
  M5.Display.print("BtnA   :");
  if (state) {
    M5.Display.print(state);
  }
  M5.Display.println();

  state = M5.BtnB.wasHold()               ? 1
          : M5.BtnB.wasClicked()          ? 2
          : M5.BtnB.wasPressed()          ? 3
          : M5.BtnB.wasReleased()         ? 4
          : M5.BtnB.wasDecideClickCount() ? 5
                                          : 0;
  M5.Display.print("BtnB   :");
  if (state) {
    M5.Display.print(state);
  }
  M5.Display.println();

  state = M5.BtnC.wasHold()               ? 1
          : M5.BtnC.wasClicked()          ? 2
          : M5.BtnC.wasPressed()          ? 3
          : M5.BtnC.wasReleased()         ? 4
          : M5.BtnC.wasDecideClickCount() ? 5
                                          : 0;
  M5.Display.print("BtnC   :");
  if (state) {
    M5.Display.print(state);
  }
  M5.Display.println();

  state = M5.BtnEXT.wasHold()               ? 1
          : M5.BtnEXT.wasClicked()          ? 2
          : M5.BtnEXT.wasPressed()          ? 3
          : M5.BtnEXT.wasReleased()         ? 4
          : M5.BtnEXT.wasDecideClickCount() ? 5
                                            : 0;
  M5.Display.print("BtnEXT :");
  if (state) {
    M5.Display.print(state);
  }
  M5.Display.println();

  state = M5.BtnPWR.wasHold()               ? 1
          : M5.BtnPWR.wasClicked()          ? 2
          : M5.BtnPWR.wasPressed()          ? 3
          : M5.BtnPWR.wasReleased()         ? 4
          : M5.BtnPWR.wasDecideClickCount() ? 5
                                            : 0;
  M5.Display.print("BtnPWR :");
  if (state) {
    M5.Display.print(state);
  }
  M5.Display.println();

  M5.Display.endWrite();
  delay(1);
}

M5UnifiedではBtnA、BtnB、BtnC、BtnEXT、BtnPWRに対応しています。Core2などのタッチパネル系のボタンも同じように取得可能です。ボタン系はM5.update()を呼び出すことで状態を更新するので、判定をするまえに必ず呼び出すようにしてください。あと電源ボタンは押すとリセットするボードや長押しが取得できない場合があるので、なるべく使わないほうが安全です。

また、ToughやCoreS3などのタッチパネルであり、Core2のようにボタン用エリアが定義されていないものはボタンも利用できないので注意してください。この場合には自前でタッチパネルの座標などを処理してボタン的な制御をする必要があります。

M5Unified/Button.ino at master · m5stack/M5Unified
Unified library for M5Stack series. Contribute to m5stack/M5Unified development by creating an account on GitHub.

上記が公式のスケッチ例になります。

IMU

#include <M5Unified.h>

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

void loop(void) {
  M5.Display.startWrite();

  M5.Display.setCursor(0, 0);

  float ax, ay, az;
  float gx, gy, gz;
  M5.Imu.getAccel(&ax, &ay, &az);
  M5.Imu.getGyro(&gx, &gy, &gz);

  M5.Display.printf("Accel X = %12.6f\n", ax);
  M5.Display.printf("Accel Y = %12.6f\n", ay);
  M5.Display.printf("Accel Z = %12.6f\n", az);
  M5.Display.printf("Gyro  X = %12.6f\n", gx);
  M5.Display.printf("Gyro  Y = %12.6f\n", gy);
  M5.Display.printf("Gyro  Z = %12.6f\n", gz);

  M5.Display.endWrite();
  delay(1);
}

IMUも世代やボードで複数の種類がありますが、M5Unifiedでは自動判定してくれ同じ処理でデータの取得が可能です。

RTC

#include <M5Unified.h>

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

void loop(void) {
  M5.Display.startWrite();

  M5.Display.setCursor(0, 0);

  static constexpr const char* const wd[7] = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

  auto dt = M5.Rtc.getDateTime();
  M5.Display.printf("RTC : %04d/%02d/%02d (%s)  %02d:%02d:%02d", dt.date.year, dt.date.month, dt.date.date, wd[dt.date.weekDay], dt.time.hours, dt.time.minutes, dt.time.seconds);

  M5.Display.endWrite();
  delay(500);
}

M5StackのRTCはほぼ同じRTCチップを採用していますがM5Unifiedでも中身を意識することなく取得可能です。ただし、事前にWi-Fiなどに接続してNTPから時間合わせをしておかないとRTCの意味はありません。

そしてWi-Fiが使える環境の場合にはRTCを使わずに直接時間合わせをすればよいので、スリープなどを使う環境以外ではあまり利用機会はないかもしれません。

赤外線送信(IR)

#include <M5Unified.h>
#include <IRsend.h>

IRsend *irsend;

void setup(void) {
  auto cfg = M5.config();
  M5.begin(cfg);
  switch (M5.getBoard()) {
    case m5::board_t::board_M5StickC:
    case m5::board_t::board_M5StickCPlus:
      irsend = new IRsend(GPIO_NUM_9);
      break;
    case m5::board_t::board_M5Atom:
      irsend = new IRsend(GPIO_NUM_12);
      break;
    default:
      irsend = NULL;
      break;
  }
}

void loop(void) {
  if (irsend) {
    uint64_t send = irsend->encodeNEC(0x0000, 22);
    irsend->sendNEC(send);
  }
  delay(500);
}

ATOM系やM5StickC系はIR送信が可能です。標準的に利用されているライブラリがあるため、M5Unifiedでは直接サポートをしていません。自分でライブラリを組み込んで利用することになります。

細かい使い方はライブラリの説明か、上記の記事などを参考にしてください。

バイブ

M5.Power.Axp192.setLDO3(3000); // On 1800-3300
delay(1000);
M5.Power.Axp192.setLDO3(0); // Off

Core2とCore2 for AWSには振動モーターと搭載しており、バイブレーションをすることが可能です。ただし呼び出し方がちょっと面倒です。Core2以外のM5StickCなどはこのLDO3には画面の回路が接続されているので、間違えて呼び出すと画面が消えたりします。

SD(TF)

#include "SD.h"
#include <M5Unified.h>

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

  while (false == SD.begin(GPIO_NUM_4, SPI, 25000000)) {
    M5.Display.println("SD Wait...");
    delay(500);
  }

  M5.Display.setCursor(0, 0);
  File root = SD.open("/");
  if (root) {
    File file = root.openNextFile();
    while (file) {
      if (file.isDirectory()) {
        // Dir skip
      } else {
        // File
        String filename = file.name();
        M5.Display.println(filename);
      }
      file = root.openNextFile();
    }
  }
}

void loop() { 
  delay(1);
}

M5UnifiedはArduino環境だけではなく、広い環境で使えるように作られているライブラリです。そのため非常に移植性が高いのですが、Arduino用の便利な関数やライブラリが標準では利用しないようになっています。

特にSDを利用する場合にはM5Unified.hよりも前にSD.hを読み込むようにしてください。また、SDカードの自動マウントも行われませんので、利用する場合には明示的にマウントをする必要があります。

I2C(PortA)

#include <Wire.h>
#include <M5Unified.h>

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

  Wire.begin(M5.Ex_I2C.getSDA(), M5.Ex_I2C.getSCL());
}

void loop() {
  M5.Display.startWrite();

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

  M5.Display.printf("I2C Scan\n");
  M5.Display.printf("SDA:%2d SCL:%2d\n", M5.Ex_I2C.getSDA(), M5.Ex_I2C.getSCL());

  for (byte address = 0; address <= 127; address++) {
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();
    if (error == 0) {
      M5.Display.printf("%02X ", address);
    } else {
      M5.Display.print(".. ");
      if (address % 8 == 7) {
        M5.Display.println();
      }
    }
    delay(1);
  }

  M5.Display.endWrite();

  delay(3000);
}

I2CもM5UnifiedはArduinoのWireクラスをサポートしていません。内部に独自のI2C_Classがあるので、一般的なArduinoライブラリを利用する場合にはWireクラスで初期化しなおす必要があります。

まず最初にWire.hを読み込んで、M5.begin()後にWire.begin()で初期化してください。PortAのI2Cを利用する場合にはM5.Ex_I2Cがすでに初期化済みですのでgetSDA()とgetSCL()でピン番号をもらって初期化することでPortAのピン番号をボード別に設定する必要がなくなります。

開発ボード

ボードarduino-esp32 2.0.9M5Stack 2.0.7PlatformIO
ATOM LITEM5Stack-ATOMM5Stack-ATOMm5stack-atom
ATOM MATRIXM5Stack-ATOMM5Stack-ATOMm5stack-atom
ATOM ECHOM5Stack-ATOMM5Stack-ATOMm5stack-atom
ATOM UM5Stack-ATOMM5Stack-ATOMm5stack-atom
BASICM5Stack-Core-ESP32M5Stack-Core-ESP32m5stack-core-esp32
GRAYM5Stack-Core-ESP32M5Stack-Core-ESP32m5stack-grey
M5GOM5Stack-Core-ESP32M5Stack-Core-ESP32m5stack-core-esp32
FIREM5Stack-FIREM5Stack-FIREm5stack-fire
CORE2M5Stack-Core2M5Stack-Core2m5stack-core2
CORE2 for AWSM5Stack-Core2M5Stack-Core2m5stack-core2
CORE.INKM5Stack-CoreInkM5Stack-CoreInkm5stack-coreink
M5PAPER(M5Stick-C)M5Stack-Paper(m5stick-c)
M5StickCM5Stick-CM5Stick-Cm5stick-c
M5StickC PLUS(M5Stick-C)M5Stick-C-Plus(m5stick-c)
TOUGH(M5Stack-Core2)M5Stack-Tough(m5stack-core2)
STATION 485M5Stack-StationM5Stack-Stationm5stack-station
STATION BATM5Stack-StationM5Stack-Stationm5stack-station
AtomS3M5Stack-ATOMS3M5Stack-ATOMS3m5stack-atoms3
AtomS3 LiteM5Stack-ATOMS3M5Stack-ATOMS3m5stack-atoms3
CORES3(ESP32S3 Dev Module)M5Stack-CoreS3(esp32-s3-devkitc-1)
STAMP PICO(M5Stick-C)STAMP-PICO(m5stick-c)
STAMP C3(ESP32C3 Dev Module)STAMP-C3(esp32-c3-devkitc-02)
STAMP C3U(ESP32C3 Dev Module)STAMP-C3(esp32-c3-devkitc-02)
StampS3STAMP-S3STAMP-S3m5stack-stamps3
Atom DisplayM5Stack-ATOMM5Stack-ATOMm5stack-atom
Atom Display LiteM5Stack-ATOMM5Stack-ATOMm5stack-atom
Timer CAMM5Stack-Timer-CAMM5Stack-Timer-CAM(m5stick-c)
Unit CAM(M5Stick-C)M5Stack-Unit-CAM(m5stick-c)
PoE CAM(M5Stack-Timer-CAM)M5Stack-PoE-CAM(m5stick-c)

開発環境ごとにどのボードを選択するかの表になります。カッコに入っているものは専用のものがありませんが、なるべく近いものを書いてあります。

arduino-esp32は次回のバージョンでM5Stack-CoreS3が利用できるはずです。

まとめ

全般的に知っておいたほうがよいことは説明できたと思います。これだけだとちょっと情報が足りないので、ボード別に使い方の説明なども今後記事を書いてみる予定です。

続編

コメント

  1. はじめ より:

    M5Unifiedに乗り換えをしたのですがM5.Axpが使えなくなってしまいました。まだ情報が少なく対応方法
    がみつかりません。
    ご教授頂けると幸いです

    • たなかまさゆき より:

      M5.Power.Axp192

      に移動しているはずです
      どこかに書いてないか確認中ですが、M5Stackの公式ドキュメントがエラーで見えない。。。

      • はじめ より:

        M5.Power.Apx192.~が使用できました、ありがとうございます。
        M5Unifiedがリリースされて使いやすい環境になりつつも昔のライブラリを使用している情報が多いため新規ではじめる初心者やライトユーザーには理解しずらい状況になってしまっていると感じています。
        公式ドキュメントが早く整理され充実することを願っています。

        • たなかまさゆき より:

          動いてよかったです
          日本人のドキュメント整備メンバーが増えたみたいなので、今後に期待ですね!

  2. めい より:

    初めて電子工作的なものをやってみたいと思い、とりあえず最新機種を買えばいいだろうとCoreS3を買ったのですが、CoreS3の情報が少なくてとても困っていました。
    この記事にも書かれていましたが、ボタンがないので、まず画面にボタンを作りたいと思ったのですが、GitでもCoreS3のサンプルがなくてまったくわからず…M5Unifiedが、どうやら汎用に使えるライブラリらしい、というところまでは想像できたのですが、そこから先に進めなかったところ、M5Unifiedで検索してこちらの記事にたどり着きました。
    まだボタン出来ていませんが、タッチパネルのタッチ情報を取得することができたので、先に進めそうです。この記事、最高です。すごく助かりました、ありがとうございました。
    (一緒にM5のSCALES KITを買ってあって体重計を作る予定です、先が長そうですけど。)

    • たなかまさゆき より:

      なかなか情報ないですよね
      私もまだちゃんと触っていないので記事書いていません。。。

      画面の部品とかボタンとかの制御をするサンプルって少ないんですよね
      ちょっとずつまとめてはいるのですが、全然進んでいないので公開までもう少し時間かかりそうです

      まずはM5Unifiedのサンプルを眺めてみて、使えそうな機能がないのかを確認するのがよいと思います

      • めい より:

        返信ありがとうございます。さらに調べていたら、まず公式ドキュメントのp7に下記の記載を見つけました。

        On the front of the Core S3 we have the
        320X240 pixel (2.0”) IPS LCD. Covering most
        of the from is the capacitive multitouch screen
        sensor with three dedicated touch zones
        available in code as buttons A, B and C.
        These are not clearly marked as zone A shares
        the same location and the left microphone,
        Zone B shares the same location as the
        camera and zone C shares the same location
        as the right microphone.

        これを読むと、CoreS3の画面下部のマイク穴やカメラの部分には、Core2と同様に静電容量式のボタンが装備されていると読めます。
        でもM5UnifiedのButtonは動作しませんでした。(ソース中のコメントにもCoreS3は記載がないです)

        そこで本記事のタッチパネルの項目にあるテストプログラムを少し変更して試してみたところ、ZoneAだけ反応しました。
        本記事では、
        auto x = t.distanceX();
        auto y = t.distanceY();
        としてフリックの移動距離を表示していますが、ここを
        auto x = t.base_x;
        auto y = t.base_y;
        としてみたところ、LCDの表示領域を触ると画面左上はx=0,y=0ですし、右下はx=319,y=239が表示されます(ここまでは当たり前)。
        ところが、画面左下のマイク穴あたりをタッチすると、x=80,y=2000が表示されます。
        つまり少なくともZoneAにはボタンが装備されていると思われます。
        これで、ZoneBがx=160,y=2000, ZoneCがx=240,y=2000だったら完璧だったのですが、
        ZoneB(カメラレンズのあたり)、ZoneC(右マイク穴)は全く反応しません。

        どういうことなのでしょう…とりあえず拙い英語でM5のForumに質問を投げてみました。