M5StampS3 BATの内蔵LEDは、普通のGPIO直結LEDではなくM5PM1経由でWS2812/NeoPixelが接続されている。なので、neopixcel系のLED制御ドライバでは制御できない。不便ではある。
M5PM1は、M5Stack謹製のPMICで、前にtksさんが言っていた独自開発品。ただのPMICではなく、小型PMIC+I/O拡張+低電力制御ICといった構成で、電源ポート制御、充電制御、タイマー復帰などを固定機能として提供している。M5Stack製品に必要な機能をてんこ盛りにした感じだ。
電源管理: 3.3V DCDC、3.3V LDO、5V出力、充電ON/OFFなど
バッテリー監視: BAT電圧、5V入力、5V出力などのADC測定
充電制御: CHG_ENなどで充電系を制御
GPIO拡張: 5本の多機能GPIO
ADC: GPIOのうち2chを12bit ADCとして使用可能
PWM: GPIOのうち2chをPWMとして使用可能
NeoPixel制御: 最大32個のNeoPixel RGB LEDを駆動可能
低電力制御: スリープ、PWRボタン復帰、外部IO復帰、タイマー復帰
I2C制御: I2Cアドレス 0x6E、100kHz/400kHz対応
その他: Watchdog、32byte RAM、内部温度/基準電圧読み取り
M5Stack製品には、今後はこれが普通に使われてくるのだと思われる。Lチカくらいはできるようにしておいたほうが良さげ。
ESP32-S3側からはI2CでM5PM1を制御する。M5PM1はI2Cアドレス0x6E、ESP32-S3側のI2CはSCL=GPIO47, SDA=GPIO48になっている。
ESP-IDFから使うには、M5Stack製のM5PM1コンポーネントが公開されているので、それを使う。このライブラリはArduino/ESP-IDF両対応になっている。
GitHub - m5stack/M5PM1: M5Stack PMIC chip PM1 driver library · GitHub
https://github.com/m5stack/M5PM1
M5PM1/README_FUNCTION_EN.md at main · m5stack/M5PM1 · GitHub
https://github.com/m5stack/M5PM1/blob/main/README_FUNCTION_EN.md
使用上の注意点としては、M5Unifiedと併用するときには、i2c_config_tがコンフリクトするので、M5Unified.hの後でincludeする必要がある。
#include <M5Unified.h>
#include <M5PM1.h>
プロジェクトを作成してLチカしてみる。
% idf.py create-project m5stamps3bat_blink
Executing action: create-project
The project was created in /Users/kinneko/Downloads/esp/m5stamps3bat_blink
% cd m5stamps3bat_blink
% idf.py set-target esp32s3
(snip)
基本的な構成はこんなところ。
m5stamps3bat_blink/
├── CMakeLists.txt
├── main
│ ├── CMakeLists.txt
│ └── m5stamps3bat_blink.c
└── sdkconfig
idf_component.ymlがないな。
M5PM1コンポーネントを登録する。
% idf.py add-dependency "m5stack/M5PM1"
Executing action: add-dependency
NOTICE: Created "/Users/kinneko/Downloads/esp/m5stamps3bat_blink/main/idf_component.yml"
NOTICE: Successfully added dependency "m5stack/M5PM1": "*" to component "main"
NOTICE: If you want to make additional changes to the manifest file at path /Users/kinneko/Downloads/esp/m5stamps3bat_blink/main/idf_component.yml manually, please refer to the documentation: https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html
こんなidf_component.ymlが生成された。
% cat main/idf_component.yml
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf:
version: '>=4.1.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies public flag can be set.
# # public flag doesn't have an effect dependencies of the main component.
# # All dependencies of main are public by default.
# public: true
m5stack/M5PM1: '*'
あとは、ビルド時に依存関係で自動インストールされる。
sdkconfigをM5StampS3 BATに合わせて調整する。Flashサイズと、PSRAMの設定だけでよさそう。光らせるだけなので、パーティションの設定変更はしない。
% idf.py menuconfig
Serial flasher config --->

Flash size: 8 MBに設定する。



Component config --->

ESP PSRAM --->


SPI RAM config --->

Mode (QUAD/OCT) of SPI RAM chip in use --->


Octalを選ぶ。サイズは自動認識してくれる。

保存して終了。
Lチカのプログラムはこんな感じ。
% vi main/m5stamps3bat_blink.cpp
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "M5PM1.h"
static const char *TAG = "stamps3bat";
#define M5PM1_I2C_PORT I2C_NUM_0
#define M5PM1_I2C_ADDR 0x6E
#define M5PM1_I2C_SDA 48
#define M5PM1_I2C_SCL 47
#define M5PM1_I2C_FREQ 100000
extern "C" void app_main(void)
{
M5PM1 pm1;
auto ret = pm1.begin(
M5PM1_I2C_PORT,
M5PM1_I2C_ADDR,
M5PM1_I2C_SDA,
M5PM1_I2C_SCL,
M5PM1_I2C_FREQ
);
if (ret != M5PM1_OK) {
ESP_LOGE(TAG, "M5PM1 begin failed: %d", ret);
return;
}
ESP_LOGI(TAG, "M5PM1 initialized");
// M5PM1 GPIO0をNeoPixel出力にする
pm1.gpioSetFunc(M5PM1_GPIO_NUM_0, M5PM1_GPIO_FUNC_OTHER);
pm1.gpioSetDrive(M5PM1_GPIO_NUM_0, M5PM1_GPIO_DRIVE_PUSHPULL);
m5pm1_rgb_t red = {255, 0, 0};
m5pm1_rgb_t green = {0, 255, 0};
m5pm1_rgb_t blue = {0, 0, 255};
m5pm1_rgb_t off = {0, 0, 0};
while (true) {
ESP_LOGI(TAG, "LED RED");
pm1.setLeds(&red, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
ESP_LOGI(TAG, "LED OFF");
pm1.setLeds(&off, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
ESP_LOGI(TAG, "LED GREEN");
pm1.setLeds(&green, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
ESP_LOGI(TAG, "LED OFF");
pm1.setLeds(&off, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
ESP_LOGI(TAG, "LED BLUE");
pm1.setLeds(&blue, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
ESP_LOGI(TAG, "LED OFF");
pm1.setLeds(&off, 1, 1, true);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
M5PM1は最大32個のNeoPixelを駆動できる仕様で駆動する個数を指定できる。
pm1.setLeds(色配列, 色配列の個数, 繰り返し回数, 反映するか);
trueは即時反映。falseを指定するのは、複数LEDを個別に設定してから一括更新したい場合になる。refreshLeds()でまとめて反映できる。
今回はオンボードのLEDが1つしかないので、数値はどちらも1になる。
明るさを変えたい場合は、色配列で指定したRGB値を下げる。
メインプログラムをcppにしたので、CMakeListsを書き換えておく。
% vi main/CMakeLists.txt
idf_component_register(SRCS "m5stamps3bat_blink.cpp"
INCLUDE_DIRS ".")
ビルドして書き込んでみる。
% idf.py build flash monitor
(snip)
I (1049) main_task: Calling app_main()
I (1069) M5PM1_SYS: Device: ID=0x50 MODEL=0x20 HW=0x05 SW=0x53(S)
I (1069) M5PM1_I2C: I2C config set and verified: sleep=0, speed=100K
I (1099) M5PM1_I2C: M5PM1 initialized at address 0x6E (I2C: 100000 Hz)
I (1099) stamps3bat: M5PM1 initialized
I (1159) stamps3bat: LED RED
I (1159) M5PM1_LED: LED count set and verified: 1
I (1169) M5PM1_LED: Set 1 LEDs successfully (refreshed)
I (1669) stamps3bat: LED OFF
I (1669) M5PM1_LED: LED count set and verified: 1
I (1669) M5PM1_LED: Set 1 LEDs successfully (refreshed)
I (2169) stamps3bat: LED GREEN
I (2169) M5PM1_LED: LED count set and verified: 1
I (2169) M5PM1_LED: Set 1 LEDs successfully (refreshed)
I (2669) stamps3bat: LED OFF
I (2669) M5PM1_LED: LED count set and verified: 1
I (2669) M5PM1_LED: Set 1 LEDs successfully (refreshed)
I (3169) stamps3bat: LED BLUE
I (3169) M5PM1_LED: LED count set and verified: 1
I (3169) M5PM1_LED: Set 1 LEDs successfully (refreshed)
I (3669) stamps3bat: LED OFF
I (3669) M5PM1_LED: LED count set and verified: 1
I (3669) M5PM1_LED: Set 1 LEDs successfully (refreshed)
(snip)
まぁ、普通にLチカできるよね。
M5StampS3 BATでLチカ - YouTube
https://www.youtube.com/watch?v=oG63GWNa09k
オリジナル投稿:
M5StampS3 BATでLチカ|kinneko|pixivFANBOX
https://kinneko.fanbox.cc/posts/11870461



