M5CORE2にはバイブレーション機能として振動モータが搭載されています。このモータをON/OFFするプログラムを作成します。電源マネージメントIC AXP192を操作することによりモータを動作させます。
バイブレーション機能の回路構成とモータ電流
回路構成は、MCU(ESP32)→電源IC(AXP192)→振動モータ(1027DC Motor)、となっています。このコイン型DCコアレス振動モータですが、データシートより定常80mA流れます。ESP32の汎用ポートの許容電流は40mAと足らないため、電流を流せる駆動回路が必要になります。M5CORE2はAXP192という電源ICが搭載されており、モータが接続されているLDO3端子は200mAまで流すことができます。
このLDO3端子出力をプログラムからコントロールしてモータをON/OFFします。AXP192はTWSI通信(Two Wire Serial Interface。I2Cと同じ)によりMCUからON/OFFします。ライブラリにAXP192を操作する関数がありますので、TWSI通信を意識することなくモータ駆動させることができます。
プログラム
M5CORE2本体のボタンAを押している間だけモータがONするプログラムを作成しました。下記API関数によりON/OFFできます。引数のstateにはモータONのときはtrue、OFFのときはfalseを渡します。
関数:M5.Axp.SetVibration(state);
#include <M5Core2.h>
void setup() {
M5.begin();
M5.Lcd.clear();
M5.Lcd.setTextSize(5);
M5.Lcd.setCursor(20, 0);
M5.Lcd.print("VIBRATION");
}
void loop() {
M5.update();
M5.Lcd.setCursor(100, 100);
if(M5.BtnA.isPressed()){
M5.Lcd.print("ON ");
M5.Axp.SetVibration(true); // Motor ON
}
else{
M5.Lcd.print("OFF");
M5.Axp.SetVibration(false); // Motor OFF
}
delay(100);
}
Code language: C++ (cpp)
電源マネージメントIC 「AXP192」を理解する
AXP192は電源マネージメントI Cで下記の機能を持っています。
- 外部ACアダプタ、USB 5V、内蔵Liバッテリなどの電源が混在するシステムで充電や状況に応じて優先する電源を管理します。
- 降圧DCDCレギュレータ×3。各々で出力電圧を設定可能。M5CORE2では、DCDC1は3.3Vを出力し、ESP32やメモリ、スピーカ駆動DアンプIC、IMU、MICなどに、DCDC3はLCDのバックライトに電源供給されています。
- LDO(Low Drop Out)レギュレータ×4。各々で出力電圧を設定可能。LDO1はRTC、LDO2はLCD、LDO3は振動モータに電源供給されています。
- MCUからTWSI(Two Wire Serial Interface。I2Cと同じ)により、AXP192のレジスタにアクセスし、コントロールします。
AXP192のデータシートはこちら↓
https://github.com/m5stack/M5-Schematic/blob/master/Core/AXP192%20Datasheet_v1.1_en_draft_2211.pdf
振動モータのデータシートはこちら↓
https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/core/SY7088-Silergy.pdf
AXP192の操作関数
ArduinoIDEのvibrateというスケッチ例を見ると、振動モータの駆動にSetVibration()という関数があります。引数でtrueを渡すとON、falseを渡すとOFFします。この関数はライブラリのAXP.cppの中で次の関数を実行するように書かれています。stateはSetVibration()のtrue/falseです。
関数:axp192.SetLDOEnable(3, state);
また、上記関数はAXP192.cppの中で以下のようになっています(一部の抜粋)。numberは上記関数の第1引数で「3」です。markの初期値は1です。つまり、1を3bitシフトした値、AXP192のLDO3のレジスタアドレス「0x12」のBit3「LDO3 switch control」をenable(=1)にするとモータ駆動します。disable(=0)で停止です。
mark <<= number;
if (state) {
Write1Byte(0x12, (Read8bit(0x12) | mark));
}
Code language: C++ (cpp)
Write1Byte()はAXP.cppの中で以下のようになっています。0x34はAXP192のI2Cアドレスです。AXP192のデータシートでは0x68となっていますが、おそらく8bit表記なのだと思われます。I2Cアドレスは7bitでLSB(bit0)はR/Wを表します。
void Write1Byte(uint8_t Addr, uint8_t Data) {
Wire1.beginTransmission(0x34);
Wire1.write(Addr);
Wire1.write(Data);
Wire1.endTransmission();
}
Code language: C++ (cpp)
まとめ
AXP192の仕様など理解すべきことは多いのですが、プログラム自体はライブラリのAPI関数SetVibration()を使うことで簡単にON/OFFできます。

