M5StickCのバッテリー管理AXP192を図にまとめる

一覧を列挙したものだと、あとでわかりにくいので使うところだけをまとめた図を作ってみました。

※現時点の情報ですので、最新情報はM5StickC非公式日本語リファレンスを確認してください。

関連図

項目詳細

外部USB電源入力(USB, VBUS)

電圧(mV):GetVusbinData() * 1.7
電流(mA):GetIusbinData() * 0.375

USBからの電源供給ですが、0.0.5では関数が実装されていません。以下の内容を自分で定義すれば取得できます。

uint16_t GetVusbinData(void){
 
    uint16_t vin = 0;
 
    Wire1.beginTransmission(0x34);
    Wire1.write(0x5a);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();
 
    Wire1.beginTransmission(0x34);
    Wire1.write(0x5b);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf2 = Wire1.read();
 
    vin = ((buf << 4) + buf2); // V
    return vin;
 
}
 
uint16_t GetIusbinData(void){
 
    uint16_t iin = 0;
 
    Wire1.beginTransmission(0x34);
    Wire1.write(0x5c);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();
 
    Wire1.beginTransmission(0x34);
    Wire1.write(0x5d);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf2 = Wire1.read();
 
    iin = ((buf << 4) + buf2); // V
    return iin;
 
}

外部電源入力(5V←, ACIN)

電圧(mV):M5.Axp.GetVinData() * 1.7
電流(mA):M5.Axp.GetIinData() * 0.625

外部電源の電圧と電流を取得する。

液晶バックライト電圧(LDO2)

電圧(V):M5.Axp.ScreenBreath( val )

valは0x00(1.8V:暗い)から0x0f(3.3V:明るい)の16段階。

内部供給電圧(ASP)

電圧(mV):M5.Axp.GetVapsData() * 1.4

USBやACINから5Vが供給されているときには5V、バッテリー駆動のときには4V程度になります。0.0.5では実装されていません。GitHubでは実装されていますので、次回リリース時には使えるようになると思います。

内部温度

温度(℃): -144.7 + M5.Axp.GetTempData() * 0.1

40℃から50℃ぐらいが正常値な気がします。

バッテリー充電

充電電流(mA):M5.Axp.GetIchargeData() * 0.5

バッテリーに充電している電流です。この値が0以外の場合が充電中になります。バッテリー残量によりますが10mA前後で充電をしているようです。電源を消すともっと早く充電できるはずです。

バッテリー放電(状態取得)

充電電流(mA):M5.Axp.GetIdischargeData() * 0.5
バッテリー電圧(mV):GetVapsData() * 1.4
バッテリー容量(mHA):M5.Axp.GetCoulombData()

バッテリー残量を表示する場合には、容量ではなく電圧を使ったほうが無難だと思います。容量は使っていくと減っていくので、最大値を保存しておかないと計算できません。バッテリー電圧は3.0Vから4.2Vの間で設定されているので、 3.3V以下で0%、4.1V以上は100%の計算などがかんたんな気がします。

M5StickCのピン配置を調べる

※現時点の情報ですので、最新情報はM5StickC非公式日本語リファレンスを確認してください。

わかりやすいピン配置図がなかったので調べてみました。

ESP32-PICO-D4の配置

データシートから書き起こしました。あまり必要ないですよね。。。

データシート

https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf

ピン配置

NameNo.TypePinMapFunction
VDDA1P Analog power supply (2.3 V ~ 3.6 V)
LNA_IN2I/O RF input and output
VDDA3P33P Analog power supply (2.3 V ~ 3.6 V)
VDDA3P34P Analog power supply (2.3 V ~ 3.6 V)
IO36(SENSOR_VP)5IExtended IO portGPIO36, ADC1_CH0, RTC_GPIO0
IO37(SENSOR_CAPP)6IBUTTON AGPIO37, ADC1_CH1, RTC_GPIO1
IO38(SENSOR_CAPN)7I GPIO38, ADC1_CH2, RTC_GPIO2
IO39(SENSOR_VN)8IBUTTON BGPIO39, ADC1_CH3, RTC_GPIO3
EN9I High: On; enables the module
Low: Off; the module powers off
Note: Do not leave this pin floating.
IO3410IMicrophone SDAADC1_CH6, RTC_GPIO4
IO3511I ADC1_CH7, RTC_GPIO5
IO3212I/OGROVE SDA32K_XP (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
IO3313I/OGROVE SCL32K_XN (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
IO2514I/O GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
IO2615I/OExtended IO portGPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
IO2716I/O GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
IO1417I/O ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
IO1218I/O ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3
VDD3P3_RTC19P Input power supply for RTC IO (2.3 V ~ 3.6 V)
IO1320I/OTFT_CLKADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
IO1521I/OTFT_MOSIADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0, HS2_CMD, SD_CMD, EMAC_RXD3
IO222I/O ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
IO023I/OMicrophone SCL / Extended IO portADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
IO424I/O ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
IO1625I/O GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
VDD_SDIO26P Output power supply: the same voltage as VDD3P3_RTC
IO1727I/O GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
IO9(SD2)28I/OIR transmitterGPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD
IO10(SD3)29I/ORed LEDGPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD
IO11(CMD)30I/O GPIO11, SD_CMD, SPICS0, HS1_CMD, U1RTS
IO16(CLK)31I/O GPIO6, SD_CLK, SPICLK, HS1_CLK, U1CTS
IO7(SD0)32I/O GPIO7, SD_DATA0, SPIQ, HS1_DATA0, U2RTS
IO8(SD1)33I/O GPIO8, SD_DATA1, SPID, HS1_DATA1, U2CTS
IO534I/OTFT_CSGPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
IO1835I/OTFT_RSTGPIO18, VSPICLK, HS1_DATA7
IO2336I/OTFT_DCGPIO23, VSPID, HS1_STROBE
VDD3P3_CPU37P Input power supply for CPU IO (1.8 V ~ 3.6 V)
IO1938I/O GPIO19, VSPIQ, U0CTS, EMAC_TXD0
IO2239I/OIMU & AXP SCLGPIO22, VSPIWP, U0RTS, EMAC_TXD1
IO03(U0RXD)40I/O GPIO3, U0RXD, CLK_OUT2
IO01(U0TXD)41I/O GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
IO2142I/OIMU & AXP SDAGPIO21, VSPIHD, EMAC_TX_EN
VDDA43P Analog power supply (2.3 V ~ 3.6 V)
XTAL_N_NC44 NC
XTAL_P_NC45 NC
VDDA46P Analog power supply (2.3 V ~ 3.6 V)
CAP2_NC47 NC
CAP1_NC48 NC

全部のピン配置です。なぜIO0がMicrophoneに使われているのに、外部に出力されているのだろう?

そして、Wi-Fiを使うと相変わらずADC2が使えないのでIO0とIO26はアナログ入力には使えません。

ピン配置抜粋

ボタン

IO37BUTTON A(HOMEボタン)
IO39BUTTON B(右横ボタン)

赤色LED

IO10Red LED

IR transmitter

IO9IR transmitter

TFT

IO13TFT_CLK
IO15TFT_MOSI
IO5TFT_CS
IO18TFT_RST
IO23TFT_DC

内蔵I2C(ピン配置)

IO21IMU & AXP I2C SDA
IO22IMU & AXP I2C SCL

内蔵I2C(アドレス)

0x34Power Mangement IC(AXP192)
0x51RTC(BM8563)
0x6C6-axis IMU(SH200Q)

Microphone(I2S)

IO34Microphone I2S SDA
IO0Microphone I2S SCL

GROVE端子

IO32I/OGROVE SDAADC1_CH4, TOUCH9
IO33I/OGROVE SCLADC1_CH5, TOUCH8

Extended IO port(お尻の外部接続)

IO26I/ODAC_2, ADC2_CH9
IO36IADC1_CH0
IO0I/OADC2_CH1, TOUCH1, CLK_OUT1

※Wi-Fi利用時はIO0とIO26はアナログ入力として利用できません
※Microphone利用時はIO0を利用できません

M5StickCのバッテリー管理AXP192を調べる

※現時点の情報ですので、最新情報はM5StickC非公式日本語リファレンスを確認してください。

ちょっとAXP192のライブラリの動きが不明だったので、データシートをみて調べてみました。

データシート

英語のデータシートがなんとありません。。。

製造元サイトのは概要のみなので、GitHubにある中国語のデータシートをがんばって解読することが必要です。

I2C通信レジスター P29

グループアドレス説明R/Wデフォルト値
電力制御00電源ステータスレジスタR 
電力制御01電力モード/充電ステータスレジスタR 
電力制御04OTG VBUSステータスレジスタR 
電力制御06-0Bデータキャッシュレジスタ 0-5R/WF0/0F/00/FF/00/00
電力制御10EXTEN & DC-DC2 スイッチ制御レジスタR/WX5H
電力制御12DC-DC1/3 & LDO2/3 スイッチ制御レジスタR/WXFH
電力制御23DC-DC2 電圧設定レジスタR/W16H
電力制御25DC-DC2 電圧勾配パラメータ設定レジスタR/W00H
電力制御26DC-DC1 電圧設定レジスタR/W68H
電力制御27DC-DC3 電圧設定レジスタR/W48H
電力制御28LDO2/3 電圧設定レジスタR/WCFH
電力制御30VBUS-IPSOUT パス設定レジスタR/W60H
電力制御31VOFFシャットダウン電圧設定レジスタR/WX3H
電力制御32シャットダウン、電池検知、CHGLED制御レジスタR/W46H
電力制御33充電制御レジスタ 1R/WC8H
電力制御34充電制御レジスタ 2R/W41H
電力制御35バックアップ電池充電制御レジスタR/W22H
電力制御36PEKパラメータ設定レジスタR/W5DH
電力制御37DCDCコンバータ動作周波数設定レジスタR/W08H
電力制御38バッテリ充電低温警報設定レジスタR/WA5H
電力制御39バッテリ充電高温警報設定レジスタR/W1FH
電力制御3AAPS低電力レベル1設定レジスタR/W68H
電力制御3BAPS低電力レベル2設定レジスタR/W5FH
電力制御3Cバッテリ放電低温警報設定レジスタR/WFCH
電力制御3Dバッテリ放電高温警報設定レジスタR/W16H
電力制御80DCDC動作モード設定レジスタR/WE0H
電力制御82ADCイネーブル設定レジスタ1R/W83H
電力制御83ADCイネーブル設定レジスタ2R/W80H
電力制御84ADCサンプルレート設定、TS端子制御レジスタR/W32H
電力制御85GPIO [3:0]入力範囲設定レジスタR/WX0H
電力制御86GPIO1 ADC IRQ立ち上がりエッジしきい値設定R/WFFH
電力制御87GPIO1 ADC IRQ立ち下がりエッジしきい値設定R/W00H
電力制御8Aタイマ制御レジスタR/W00H
電力制御8BVBUS監視設定レジスタR/W00H
電力制御8F過熱シャットダウン制御レジスタR/W01H
GPIO制御90GPIO0制御レジスタR/W07H
GPIO制御91GPIO0 LDOモード出力電圧設定レジスタR/WA0H
GPIO制御92GPIO1制御レジスタR/W07H
GPIO制御93GPIO2制御レジスタR/W07H
GPIO制御94GPIO [2:0]信号ステータスレジスタR/W00H
GPIO制御95GPIO [4:3]機能制御レジスタR/W00H
GPIO制御96GPIO [4:3]信号ステータスレジスタR/W00H
GPIO制御97GPIO [2:0]プルダウン制御レジスタR/W00H
GPIO制御98PWM1周波数設定レジスタR/W00H
GPIO制御99PWM1デューティサイクル設定レジスタ1R/W16H
GPIO制御9APWM1デューティサイクル設定レジスタ2R/W0BH
GPIO制御9BPWM2周波数設定レジスタR/W00H
GPIO制御9CPWM2デューティサイクル設定レジスタ1R/W16H
GPIO制御9DPWM2デューティサイクル設定レジスタ2R/W0BH
GPIO制御9EN_RSTO (GPIO5) 制御レジスタR/W20H
割込制御40IRQイネーブル制御レジスタ1R/WD8H
割込制御41IRQイネーブル制御レジスタ2R/WFFH
割込制御42IRQイネーブル制御レジスタ3R/W3BH
割込制御43IRQイネーブル制御レジスタ4R/WC1H
割込制御4AIRQイネーブル制御レジスタ5R/W00H
割込制御44IRQステータスレジスタ1R/W00H
割込制御45IRQステータスレジスタ2R/W00H
割込制御46IRQステータスレジスタ3R/W00H
割込制御47IRQステータスレジスタ4R/W00H
割込制御4DIRQステータスレジスタ5R/W00H
ADCデータ56ACIN電圧ADCデータ上位8ビットR 
ADCデータ57ACIN電圧ADCデータ下位4ビットR 
ADCデータ58ACIN電流ADCデータ上位8ビットR 
ADCデータ59ACIN電流ADCデータ下位4ビットR 
ADCデータ5AVBUS電圧ADCデータ上位8ビットR 
ADCデータ5BVBUS電圧ADCデータ下位4ビットR 
ADCデータ5CVBUS電流ADCデータ上位8ビットR 
ADCデータ5DVBUS電流ADCデータ下位4ビットR 
ADCデータ5EAXP192内部温度監視ADCデータ上位8ビットR 
ADCデータ5FAXP192内部温度監視ADCデータ下位4ビットR 
ADCデータ62TS入力ADCデータ上位8ビット、デフォルトのバッテリ温度監視R 
ADCデータ63TS入力ADCデータは4ビット下位、デフォルトモニタバッテリ温度R 
ADCデータ64GPIO0電圧ADCデータ上位8ビットR 
ADCデータ65GPIO0電圧ADCデータ下位4ビットR 
ADCデータ66GPIO1電圧ADCデータ上位8ビットR 
ADCデータ67GPIO1電圧ADCデータ下位4ビットR 
ADCデータ68GPIO2電圧ADCデータ上位8ビットR 
ADCデータ69GPIO2電圧ADCデータ下位4ビットR 
ADCデータ6AGPIO3電圧ADCデータ上位8ビットR 
ADCデータ6BGPIO3電圧ADCデータ下位4ビットR 
ADCデータ70バッテリー瞬時電力上位8ビットR 
ADCデータ71バッテリー瞬時電力中位8ビットR 
ADCデータ72バッテリー瞬時電力下位8ビットR 
ADCデータ78電池電圧上位8ビットR 
ADCデータ79電池電圧下位4ビットR 
ADCデータ7Aバッテリー充電電流上位8ビットR 
ADCデータ7Bバッテリー充電電流下位5ビットR 
ADCデータ7Cバッテリー放電電流上位8ビットR 
ADCデータ7Dバッテリー放電電流下位4ビットR 
ADCデータ7EAPS電圧上位8ビットR 
ADCデータ7FAPS電圧下位4ビットR 
バッテリB0バッテリ充電クーロンカウントデータレジスタ[31:24]R/W00H
バッテリB1バッテリ充電クーロンカウントデータレジスタ[23:16]R/W00H
バッテリB2バッテリ充電クーロンカウントデータレジスタ[15:8]R/W00H
バッテリB3バッテリ充電クーロンカウントデータレジスタ[7:0]R/W00H
バッテリB4バッテリ放電クーロンカウントデータレジスタ[31:24]R/W00H
バッテリB5バッテリ放電クーロンカウントデータレジスタ[23:16]R/W00H
バッテリB6バッテリ放電クーロンカウントデータレジスタ[15:8]R/W00H
バッテリB7バッテリ放電クーロンカウントデータレジスタ[7:0]R/W00H
バッテリB8クーロンカウンタ制御レジスタR/W00H

ここは肝になりますが、基本的にAPI経由だと知らなくてもなんとかなります。

APIでの呼び出し確認

bigin : 利用開始

アドレスアドレス説明
0x10EXTEN & DC-DC2 スイッチ制御レジスタ0xff
0x28LDO2/3 電圧設定レジスタ0xff
0x82ADCイネーブル設定レジスタ10xff
0x33充電制御レジスタ 10xC0
0xB8クーロンカウンタ制御レジスタ0x80
0x12DC-DC1/3 & LDO2/3 スイッチ制御レジスタ0x4d
0x36PEKパラメータ設定レジスタ0x5c
0x90GPIO0制御レジスタ0x02
0x31VOFFシャットダウン電圧設定レジスタ0x04

初期設定をしています。バッテリーは4.2Vまで100mAで充電して、3.0V以下になったらシャットダウンします。

ScreenBreath : 画面の明るさ設定

0x28LDO2/3 電圧設定レジスタ Val

画面の明るさを指定します。0x00(1.8V:暗)から0x0f(3.3V:明)までの値を設定できます。初期化時にはLDO2/3の両方を設定していますが、この関数だと実際にScreenが接続されていると思われるLDO2だけに設定しています。

EnableCoulombcounter : バッテリ残量ゲージ有効

0xB8クーロンカウンタ制御レジスタ0x80

残量ゲージのカウンタを有効にします。通常使うことはないでしょう。

DisableCoulombcounter : バッテリ残量ゲージ無効

0xB8クーロンカウンタ制御レジスタ0x00

残量ゲージのカウンタを無効にします。通常使うことはないでしょう。

StopCoulombcounter : バッテリ残量ゲージ停止

0xB8クーロンカウンタ制御レジスタ0xC0

残量ゲージのカウンタを停止にします。通常使うことはないでしょう。

ClearCoulombcounter : バッテリ残量ゲージクリア

0xB8クーロンカウンタ制御レジスタ0xA0

残量ゲージのカウンタをクリアします。通常使うことはないでしょう。

GetCoulombchargeData : バッテリ充電状態取得

0xB0バッテリ充電クーロンカウントデータレジスタ[31:24] 
0xB1バッテリ充電クーロンカウントデータレジスタ[23:16] 
0xB2バッテリ充電クーロンカウントデータレジスタ[15:8] 
0xB3バッテリ充電クーロンカウントデータレジスタ[7:0] 

この値も直接使うことはないでしょう。

GetCoulombdischargeData : バッテリ放電状態取得

0xB4バッテリ放電クーロンカウントデータレジスタ[31:24] 
0xB5バッテリ放電クーロンカウントデータレジスタ[23:16] 
0xB6バッテリ放電クーロンカウントデータレジスタ[15:8] 
0xB7バッテリ放電クーロンカウントデータレジスタ[7:0] 

この値も直接使うことはないでしょう。

GetCoulombData : バッテリ状態取得

内部で上記の2つの関数を呼び出して計算をしています。戻り値はmAhのfloat型です。

GetVinData : ACIN(外部電源)電圧取得

0x56ACIN電圧ADCデータ上位8ビット 
0x57ACIN電圧ADCデータ下位4ビット 

お尻の端子からの5V外部電源の電圧取得です。取得するのはADCのステップ数なので、ステップ数 × 1.7mVで実際の電圧に変換する必要があります。

GetIinData : ACIN(外部電源)電流取得

0x58ACIN電流ADCデータ上位8ビット 
0x59ACIN電流ADCデータ下位4ビット 

お尻の端子からの5V外部電源の電流取得です。取得するのはADCのステップ数なので、ステップ数 × 0.625mAで実際の電流に変換する必要があります。

GetIchargeData : バッテリー充電電流取得

0x7aバッテリ充電電流上位8ビット 
0x7bバッテリ充電電流下位5ビット 

バッテリーに充電する電流取得です。取得するのはADCのステップ数なので、ステップ数 × 0.5mAで実際の電流に変換する必要があります。(API上では2で割っています)

GetIdischargeData : バッテリー放電電流取得

0x7cバッテリ放電電流上位8ビット 
0x7dバッテリ放電電流下位4ビット 

バッテリーから放電する電流取得です。取得するのはADCのステップ数なので、ステップ数 × 0.5mAで実際の電流に変換する必要があります。(API上では2で割っています)

GetTempData : 内部温度取得

0x5eAXP192内部温度監視ADCデータ上位8ビット 
0x5fAXP192内部温度監視ADCデータ下位4ビット 

内部の温度を取得します。室温などには使えないので、実際のところあまり利用しないと思いますが、高熱になるとシャットダウンするためについているセンサーです。取得するのはADCのステップ数なので、-144.7度 + ステップ数 × 0.1度で実際の温度に変換する必要があります。

GetPowerbatData : バッテリ瞬時電力取得

0x70バッテリ瞬時電力上位8ビット 
0x71バッテリ瞬時電力中位8ビット 
0x72バッテリ瞬時電力下位8ビット 

バッテリー放電中の電力だと思いますが、データシートにも計算方法が書いてありません。サンプルスケッチ上では「M5.Axp.GetPowerbatData() * 1.1 * 0.5 / 1000」で計算しています。通常は使うことがないデータだと思います。

GetVapsData : APS(内部電源)電圧取得 (0.0.6から?)

0x7EAPS電圧上位8ビット 
0x7FAPS電圧下位4ビット 

マイコンに供給されている電圧だと思います。USB経由の場合には5Vぐらいで、バッテリー駆動の場合には4Vぐらいになります。取得するのはADCのステップ数なので、ステップ数 × 1.4mVで実際の電圧に変換する必要があります。

GitHubだと実装されていましたが、0.0.5だと実装されていません。

SetSleep : スリープ設定 (0.0.6から?)

0x31VOFFシャットダウン電圧設定レジスタ 
0x31VOFFシャットダウン電圧設定レジスタ(1<<3)|buf
0x12DC-DC1/3 & LDO2/3 スイッチ制御レジスタ0x41

スリープ状態に設定します。GitHubだと実装されていましたが、0.0.5だと実装されていません。

GetWarningLeve : 警告レベル取得 (0.0.6から?)

0x47IRQステータスレジスタ4 

設定する関数がなく、初期値の0を所得するだけの関数です。GitHubだと実装されていましたが、0.0.5だと実装されていません。

未実装の機能

VBUS(USB)電圧取得

0x5aVBUS電圧ADCデータ上位8ビット
0x5bVBUS電圧ADCデータ下位4ビット

USBからの供給電圧。取得するのはADCのステップ数なので、ステップ数 × 1.7mVで実際の電圧に変換する必要があります。GetVinData()関数の中身の送信先アドレスを変更することで実装可能です。

VBUS(USB)電流取得

0x5cVBUS電流ADCデータ上位8ビット
0x5dVBUS電流ADCデータ下位4ビット

USBからの供給電流。取得するのはADCのステップ数なので、ステップ数 × 0.375mAで実際の電流に変換する必要があります。GetIinData()関数の中身の送信先アドレスを変更することで実装可能です。 ただし、ステップの幅が0.625mAのGetIinData()とは違うので注意してください。

個人的にはこのVBUSから流れている電流って興味あるんですが、いまのAPIだと無いんですね。

ステップについて

Channel000HSTEPFFFH
Battery Voltage0mV1.1mV4.5045V
Bat discharge current0mA0.5mA4.095A
Bat charge current0mA0.5mA4.095A
ACIN volatge0mV1.7mV6.9615V
ACIN current0mA0.625mA2.5594A
VBUS voltage0mV1.7mV6.9615V
VBUS current0mA0.375mA1.5356A
Internal temperature-144.7℃0.1℃264.8℃
APS voltage0mV1.4mV5.733V
TS pin input0mV0.8mV3.276V
GPIO00/0.7V0.5mV2.0475/2.7475V
GPIO10/0.7V0.5mV2.0475/2.7475V
GPIO20/0.7V0.5mV2.0475/2.7475V
GPIO30/0.7V0.5mV2.0475/2.7475V

ステップについて、APIだと詳細が書かれてなく、サンプルスケッチではマジックナンバーで計算していますが、P24に上記の表があるので、ここを参考に計算をします。

実験で使ったスケッチ

#include <M5StickC.h>

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.Lcd.fillScreen(BLACK);
  
  M5.Axp.EnableCoulombcounter();
}
double vbat = 0.0;
double discharge,charge;
double temp = 0.0;
double bat_p = 0.0;
double bat_p2 = 0.0;

void loop() {
  vbat      = M5.Axp.GetVbatData() * 1.1 / 1000;
  charge    = M5.Axp.GetIchargeData() / 2.0 / 1000;
  discharge = M5.Axp.GetIdischargeData() / 2.0 / 1000;
  temp      =  -144.7 + M5.Axp.GetTempData() * 0.1;
  bat_p     =  M5.Axp.GetPowerbatData() * 1.1 * 0.5 /1000 /1000;
  
  M5.Lcd.setCursor(0, 0, 1);
  M5.Lcd.printf("vbat   :%.2fV\r\n",vbat);
  M5.Lcd.printf("icharge:%.2fA\r\n",charge);
  M5.Lcd.printf("idischg:%.2fA\r\n",discharge);
  M5.Lcd.printf("temp   :%3.1fC\r\n",temp);
  M5.Lcd.printf("pbat   :%.2fW\r\n",bat_p);
  M5.Lcd.printf("CoIn   :%5d\r\n",M5.Axp.GetCoulombchargeData());
  M5.Lcd.printf("CoOut  :%5d\r\n",M5.Axp.GetCoulombdischargeData());
  M5.Lcd.printf("CoD    :%.2f\r\n",M5.Axp.GetCoulombData());
  M5.Lcd.printf("          mAh\r\n");
  M5.Lcd.printf("Vin    :%.2fV\r\n",M5.Axp.GetVinData() * 1.7 /1000);
  M5.Lcd.printf("Iin    :%.2fA\r\n",M5.Axp.GetIinData() * 0.625 /1000);
  M5.Lcd.printf("Vusbin :%.2fV\r\n",GetVusbinData() * 1.7 /1000);
  M5.Lcd.printf("Iusbin :%.2fA\r\n",GetIusbinData() * 0.375 /1000);
  M5.Lcd.printf("VAPS   :%.2fV\r\n", GetVapsData()*1.4/1000);
  M5.Lcd.printf("WL     :%5d\r\n",GetWarningLeve());
  delay(1000);
}

uint16_t GetVusbinData(void){

    uint16_t vin = 0;

    Wire1.beginTransmission(0x34);
    Wire1.write(0x5a);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();

    Wire1.beginTransmission(0x34);
    Wire1.write(0x5b);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf2 = Wire1.read();

    vin = ((buf << 4) + buf2); // V
    return vin;

}

uint16_t GetIusbinData(void){

    uint16_t iin = 0;

    Wire1.beginTransmission(0x34);
    Wire1.write(0x5c);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();

    Wire1.beginTransmission(0x34);
    Wire1.write(0x5d);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf2 = Wire1.read();

    iin = ((buf << 4) + buf2); // V
    return iin;

}

uint16_t GetVapsData(void){

    uint16_t vaps = 0;
    Wire1.beginTransmission(0x34);
    Wire1.write(0x7E);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();

    Wire1.beginTransmission(0x34);
    Wire1.write(0x7F);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf2 = Wire1.read();
    
    vaps = ((uint16_t)(buf << 4) + buf2);
    return vaps;

}

uint8_t GetWarningLeve(void){

    uint16_t vaps = 0;
    Wire1.beginTransmission(0x34);
    Wire1.write(0x47);
    Wire1.endTransmission();
    Wire1.requestFrom(0x34, 1);
    uint8_t buf = Wire1.read();
    return (buf & 0x01);
}

0.0.5で実装されていない関数は、ローカル関数として定義して実験をしました。

まとめ

個人的にはAPIの内部で計算してくれているAPIと、自分で計算しないとだめなAPIが混在しているので、ちょっと使いにくい気がします。

電流とかの精度は未検証ですが、バッテリー充電が6mAとかかなり小さいのが気になりますが、電源つけている状態だとほぼ充電されないので、そんなのものなのかもしれません。

充電するときには左側ボタンを6秒以上おして、電源オフにした状態で充電するのがよさそうでした。

M5StickCが届きました

スイッチサイエンスから6/4の夕方に注文して、6/5に発送、6/6に届きました。

外見

ちゃんと技適の番号入っている新パッケージですね。海外のはまだ古いマークなしだと思いますが、そのうち新パッケージに入れ替わるのかな?

海外から購入したほうが安いですが、技適マーク無いバージョンが届く可能性が高いので、現時点ではスイッチサイエンスさんで購入したほうが無難です。

ちなみに、一度箱から出すと元通りに入れるのかなり大変です。。。

起動

最初に入っているプログラムは液晶輝度マックスなので、かなり明るいです。M5と書かれているホームボタンを押すと明るさが変わって、右側のボタンで赤いLEDがついたり消えたりします。

明るさマックスだとすぐにバッテリーが無くなる感じです、、、

Hello world

ArduinoでESP32の開発環境が整っていると、ボードにすでにM5Stick-Cがいるのですが、ライブラリは別に入れる必要があります!

ライブラリマネージャーでM5StickCを入れましょう。上記は0.0.5ですが、オフィシャルのGitHubだともう少し更新されていました。

動きました!

ただ、斜めから見れば大丈夫ですが、真上からだと上が1ドットぐらい隠れているきがします。

ちなみにUSB Type-Cが搭載されていますが、データリンクのできるマグネットケーブルでも転送できました。

I2Cの温度センサーってどれ使えばいいの?

いろいろありすぎて迷ったので、有名な製品の一覧を作ってみました。

一覧

メーカー型番標準アドレス可変数最低電圧最高電圧推奨電圧最低温度最高温度温度誤差湿度計気圧計ガス計WebDatasheet
Analog DevicesADT74100x4842.75.53-551500.44Web PagePDF
Analog DevicesADT74200x4842.75.53-401500.25Web PagePDF
AosongAM23200x5c固定3.35.53.3-40800.5WebPDF
BoschBME2800x7621.713.61.8-40851Web PagePDF
BoschBME6800x7621.713.61.8-40851Web PagePDF
BoschBMP1800x77固定1.623.62.5-40852Web PagePDF
BoschBMP2800x7621.713.61.8-40851Web PagePDF
Texas InstrumentsHDC10800x40固定2.75.53-20850.4Web PagePDF
TE ConnectivityHTU21D0x40固定1.53.63-401250.5Web PagePDF
Texas InstrumentsLM75A0x4882.75.5-551252Web PagePDF
MicrochipMCP96000x6082.75.53.3-401251.5Web PagePDF
MicrochipMCP98080x1882.75.5-401250.5Web PagePDF
SensirionSHT10複数固定2.45.53.3-40123.81.5Web PagePDF
SensirionSHT11複数固定2.45.53.3-40123.81.5Web PagePDF
SensirionSHT15複数固定2.45.53.3-40123.81Web PagePDF
SensirionSHT20複数固定2.13.63-401250.5Web PagePDF
SensirionSHT21複数固定2.13.63-401250.5Web PagePDF
SensirionSHT25複数固定2.13.63-401250.5Web PagePDF
SensirionSHT300x4422.155.53.3-401250.5Web PagePDF
SensirionSHT310x4422.155.53.3-401250.5Web PagePDF
SensirionSHT350x4422.155.53.3-401250.3Web PagePDF
Silicon LaboratoriesSi70210x40固定1.93.6-101250.4Web PagePDF
TE ConnectivityTSYS010x7622.23.63.3-401250.1Web PagePDF

結構大きなテーブルになりましたが、BME280の場合、デフォルト7ビットI2Cアドレスが0x76で、設定可能なアドレスが2なので、0x77にも設定できます。

1.71Vから3.6Vで動作して、推奨1.8Vで、-40度から85度まで温度が測定できて誤差が+-1度で、湿度計と気圧計もついています。

測定誤差は温度帯によって違うので50度前後の精度を拾っています。電圧によって違うものは推奨電圧から少しだけずれた電圧で、5Vで動かすともっとずれるものがありますので、詳しくはデータシートみてください。

わかりやすい資料

ストロベリー・リナックスさんの通販サイトが一番まとまっています。特にセンサ・セレクションガイドのPDFがどんな製品があるのかがわかりやすいです。

おすすめセンサ

TE Connectivity TSYS01

+-0.1度精度の温度センサーで、普通に購入できる中では一番精度が高いです。反面取り扱っている店があまりないので、入手性が悪いです。国内だとストロベリー・リナックスさんが980円で取り扱っています。

あと湿度が取れないので、湿度が必要だったら他の物がいいです。

Sensirion SHT30 or SHT31 or SHT35

SHT21あたりが定番だと思いますが、I2C互換であって、I2Cそのものじゃない感じなのでSHT3xシリーズをおすすめします。SHT30とSHT31の差は温度がマイナスになったときと65度を超えるときにSHT30の方が精度が低くなります。

氷点下の測定をする場合にはSHT31の方がいいですが、SHT30でも-20度で+-0.75度の誤差まで悪化する程度です。SHT35は90度以下の場合+-0.3度の精度になり、10度から60度は+-0.1度の精度になる場合もあります。

その他

定番としてBosch BME280がありますが、このシリーズは気圧計と湿度計の補正で使うための温度計なので、外部影響を受けやすいのであまり精度が上がらないみたいです。

ヨーグルトメーカー

最近ヨーグルトメーカーを使っていて、おすすめなので紹介します。

アイリスオーヤマ PYG-15-A

使っているのはアイリスオーヤマの型落ちヨーグルトメーカーです。少し前はもう少し安かったのですが、在庫がなくなったのか値段があがっています。

このヨーグルトメーカーの特徴は1.5リットルと150ccの容器がついていることです。しかしながら大きな容器は絶望的に持ちにくいので、一度も使ったことがありません。

使っているのはこちらの容器! もうピッタリとジャストフィットで、かなり使いやすいです。

一般的な縦型の牛乳パックがそのまま入るやつでもいいのですが、柄の長いスプーンとかが必要になるので、ちょっと面倒です。

ヨーグルトの作り方

容器に少しだけ水をいれて、電子レンジで2分加熱して消毒します。その後に牛乳を半分ぐらい入れてから、ドリンクタイプのヨーグルトを3分の1から半分を入れてから、残りの牛乳を入れるだけです。

あとは温度と時間をセットして、完成まで待つだけです。時間は6時間から12時間ぐらいで、6時間だとかなり柔らか目で、今は8時間ぐらいで作っています。

時間によって結構硬さが違うのと、種となるヨーグルトが少ないと固まりにくいので、少し時間を伸ばす必要があります。普通の固形ヨーグルトでもいいですが、スプーンを使うとそれも消毒する必要があるのと、混ぜるのが面倒なので、ドリンクタイプが簡単です。

おすすめのヨーグルト種

LG21ドリンクタイプ 低糖・低カロリー

使うヨーグルトによってかなり味が違うので、いろいろ試してみるといいと思います。メインで使っているのはLG21で、かなりしっかりしたかためのヨーグルトになります。

R-1 ドリンクタイプ 低糖・低カロリー

R1はLG21より、しっとりと柔らかです。その分ホエイが出るのがちょっと難点。水切りヨーグルトにするんだったらLG21よりR1がおすすめです。

カスピ海ヨーグルト

種菌もありますが、市販のヨーグルトを種にしても作ることができます。カスピ海は出来上がったヨーグルトを保存しておいて、次の種にするので牛乳だけで作り続けることが可能です。

反面スプーンや保存容器の消毒などが必要になるので、ちょっと面倒です。LG21を少し長めに作ることで、ねっとりとしますので私はそっちにしています。

食べ方

そのままでもいいですが、ヨーグルトはオリゴ糖と一緒に食べると腸にいいので、おすすめです。

まとめ

市販のヨーグルトは牛乳100%のものは少なく、結構混ぜものが入っています。自分で作るのを食べると、安いのは違和感が出てきます。

また、種にするヨーグルトによってかなり味が違うので、いろいろ試すのも楽しいです。ただし、ヨーグルトには3種類以上の乳酸菌が入っているので、R1を使って育てても、R1と同じ乳酸菌の割合には育たないと思ったほうがいいです。

WeMosはどこいった?

ESP32で有名だったWeMosは最近あまり見かけません。どこにいったのでしょうか?

WeMosはLOLINに

どうやら偽物のWeMosが多すぎて、ブランド名をLOLINに変更したようです。

オフィシャルサイト

取扱商品

LOLIN D1 mini

小型のボードにESP8266を搭載しています。しかしながら技適を取得していないので、日本では利用することができません。

LOLIN D32

ESP-WROOM-32を搭載したボードです。バッテリー端子がついているのが特徴で、ピン配置も他のボードと比べると結構違います。

LOLIN D32 Pro

ESP-WROVERを搭載したボードです。真ん中にTFT用のポートと、左にI2C、バッテリ0用の端子、右下にMicroSDカードのスロットがあります。

まとめ

日本からだとWeMosあらため、LOLINのボードはほぼ手に入りません。そして中国から購入しても送料が結構高いので、わざわざ使う必要はないと思います。

おまけ

TTGO

最近元気がいいのがTTGOです。TTGOはLilyGOという会社のブランドで、もともと偽WeMosの最大手でした!

たぶんWeMosに怒られて、WeMosじゃなくてTTGOというブランド名で展開しています。TTGOの特徴として、ディスプレイを搭載しているボードが多いです。

ESP32、ESP8266の選び方

マイコンの種類

ESP8266系(Wi-fiのみ)

Wi-fiのみ利用できるマイコンです。海外ではESP32に比べて安いのでよく使われていますが、国内ではあまり値段差が無いのでESP32でいい気がします。

ESP-WROOM-02206-000519ESP8266の技適取得済みパッケージ
ESP-WROOM-02D201-171000ESP-WROOM-02の無線部分改良版
ESP-WROOM-02U211-171104ESP-WROOM-02Dの外部アンテナ版
技適と同じアンテナを使わないと電波法違反になります

無印とDはどっちを使ってもほとんど変わりませんが、どうせならESP-WROOM-02Dを利用したほうがいい気がしますが、あまり入手性がよくありません。Uは技適で使われているアンテナを準備するのが難しいと思うので、普通は使いません。

ESP32系(Wi-fi+Bluetooth)

ESP-WROOM-32211-161007ESP32の技適取得済みパッケージ
ESP-WROOM-32D211-171102上記とほぼ変わりませんが内部のチップが違います
ESP32-WROOM-32U211-171103外部アンテナバージョン
技適と同じアンテナを使わないと電波法違反になります
ESP32-SOLO-1211-180105シングルコアバージョン
省電力向け以外では利用しない
ESP32-WROVER211-180613PSRAM8M搭載のESP32(初期型)
ESP32-WROVER-I211-180613上記の外部アンテナバージョン
技適と同じアンテナを使わないと電波法違反になります
ESP32-WROVER-B211-180419ESP32-WROVERのチップ変更版
ESP32-WROVER-IB211-180419上記の外部アンテナバージョン
技適と同じアンテナを使わないと電波法違反になります
ESP32-PICO-D4技適無し小型のESP32向けチップ
パッケージとしての技適はありません

通常用途はESP-WROOM-32D、省電力用途でESP32-SOLO-1、PSRAMが欲しかったらESP32-WROVER-Bを選びましょう。

PICOは今後増えてくると思いますが、パッケージでの技適が無いのでボートになった商品単位で技適を取得する必要があるので、技適取得済みかを確認してから利用する必要があります。

ボードの種類

ESP8266系

実際のところ、ESP8266で技適取得済みボードはほとんどありません。積極的に使う必要はないと思います。

ESP-WROOM-32系

ESP32-DevKitC型(38pin) 25.4mm

ESPシリーズの開発元であるEspressifが作ったリファレンスボード互換のタイプです。純正品はAmazonだと売っていませんが、秋月電子では取り扱っています。見分け方は左上のピンが3.3Vでその下がENのピンになっています。

横幅が大きいので、普通のブレッドボードにさすと、片側のピンに空きがなくなってアクセスできません。

この先、ほとんど同じボードが何個も登場するのは、ピンレイアウトとサイズが違うからです。その結果ESP32はシールドがほとんど発売されていません。Groveシールドを一番右側に追加してありますが、このシールドはサイズ別に3種類作られています!

ESP32-DevKitC型(38pin) 22.86mm

ESP32-DevKitCより横幅が狭いボードです。見分け方はESP32のチップの左右に隙間があるかないかの差になります。横幅が1ピン分減っているので、ブレッドボードにさして両側のピンにアクセスが可能です。

この形が日本だと一番流通しているかもしれません。Windowsだとリセットがうまくかからないことが多く、ENピンとGNDの間にコンデンサを追加する必要があります。

DOIT Esp32 DevKit型(36pin)

オリジナルはESP32-DevKitCから、通常利用しないピンを減らした36ピンですが、あまり商品を見ません。国内だとほぼ取り扱いがないはずです。

DOIT Esp32 DevKitショート型(30pin)

海外製の安い開発ボードはこのタイプになります。DOITを元にして、さらに通常利用しないピンを減らしています。見分け方は左上のピンがENになっています。このボードはWindowsだとリセットがうまくかからないことが多く、ENピンとGNDの間にコンデンサを追加する必要があります。

最近はDevKitC型の値段が下がってきているので、DOIT型を選ぶ利点は少ないかもしれません。

Arduino UNO型(32pin)

Arduino UNOと同じシールドを使える利点がありますが、あまりメジャーではないと思います。

ESP32-WROVER型

PSRAMを使うことがないのであれば普通のESP32ボードを使ったほうがいいと思います。PSRAM以外でもSDカードや、外部接続のメモリなどありますので、普通のボードで困ってから手を出したほうがいいと思います。

カメラ付きのボードは便利そうですが、外部へのピンが少ないので用途が限定されているので注意してください。

M5stack型

ESP32に液晶画面とボタンをつけたボードで、積み重ねることで機能追加することができるボードです。バッテリーなどもあるので、割高に思えますが、ちょっとしたことを開発するのにはオールインワンで最終的に安くなる場合もあります。

M5stackはESP-WROOM-32などのパッケージを利用するのではなく、M5Stack-COREとして技適を取得しています。

ESP32-PICO-D4

ESP32-PICO-D4はアンテナを含めたパッケージではなく、小型のチップのみですので商品別に技適を取る必要があります。現在のところESP32-PICO-KITとM5StickCが技適を取得していますが、まだ国内正規流通は無いようです。

(2019/06/04)スイッチサイエンスさんでM5StickCの取扱が始まりました。
https://www.switch-science.com/catalog/5517/

購入場所

スイッチサイエンス

https://www.switch-science.com/

無線系のマイコンを購入する場合には、一番安心できるお店です。技適を取得していない商品は基本的には置いていないか、委託品などの場合警告文章が書かれています。

品揃え的に偏りがあるので、汎用部品は他の店の方が安かったり、取り扱っていないものなどがあります。

秋月電子通商

http://akizukidenshi.com

一番有名な電子部品の通販サイトです。技適取得していない製品なども取り扱っていますので、日本国内で利用できるかは確かめてから購入しましょう。

Amazon

https://www.amazon.co.jp

実際のところ、圧倒的に配送が早いので急いでいるときにはAmazonで購入することが多いです。商品は外国製の安いものも取り扱っているので、上記2つの国内正式流通品より安い場合もあります。

反面日本で使えないものも大量に販売しているので注意してください。またAmazon Prime配送でない商品は中国から郵便で届くことがあり、2週間以上かかるので注意してください。

Aliexpress.com‎

https://ja.aliexpress.com/

中国大手の通販サイトです。あらゆるものを取り扱っていますが、アメリカなどの企業の商品や、大手メーカーの商品は手薄いです。

非常に安く買えますが、届くまでに2週間以上かかるので、すぐに使わないものを頼むことになります。その結果余計なものを大量に買って、忘れたころに届くようになります。。。

技適新着 ESP-EYE

気になった新着製品の紹介です。

ESP-EYE

https://lang-ship.com/giteki/detail.php?number=211-190104

Espressif Systems (Shanghai) Co., Ltd.が申請しているので、新製品ですね。

https://www.espressif.com/en/products/hardware/esp-eye/overview

オフィシャルページは上記です。aliexpressとかだと少し前から販売されていましたが、日本でも技適を取得したみたいです。

チップはESP32-PICO-D4じゃなくて、普通のESP32で、8MのPSRAMと4MのFlashでカメラと音声処理ができるみたいです。ただESP32-PICO-KITも技適マーク付きのがまだ流通していないので、ESP-EYEも技適マーク付きのが流通するのはまだまだ先でしょうか?