※現時点の情報ですので、最新情報はM5StickC非公式日本語リファレンスを確認してください。
ちょっとAXP192のライブラリの動きが不明だったので、データシートをみて調べてみました。
- データシート
- I2C通信レジスター P29
- APIでの呼び出し確認
- bigin : 利用開始
- ScreenBreath : 画面の明るさ設定
- EnableCoulombcounter : バッテリ残量ゲージ有効
- DisableCoulombcounter : バッテリ残量ゲージ無効
- StopCoulombcounter : バッテリ残量ゲージ停止
- ClearCoulombcounter : バッテリ残量ゲージクリア
- GetCoulombchargeData : バッテリ充電状態取得
- GetCoulombdischargeData : バッテリ放電状態取得
- GetCoulombData : バッテリ状態取得
- GetVinData : ACIN(外部電源)電圧取得
- GetIinData : ACIN(外部電源)電流取得
- GetIchargeData : バッテリー充電電流取得
- GetIdischargeData : バッテリー放電電流取得
- GetTempData : 内部温度取得
- GetPowerbatData : バッテリ瞬時電力取得
- GetVapsData : APS(内部電源)電圧取得 (0.0.6から?)
- SetSleep : スリープ設定 (0.0.6から?)
- GetWarningLeve : 警告レベル取得 (0.0.6から?)
- 未実装の機能
- ステップについて
- 実験で使ったスケッチ
- まとめ
データシート
英語のデータシートがなんとありません。。。
製造元サイトのは概要のみなので、GitHubにある中国語のデータシートをがんばって解読することが必要です。
I2C通信レジスター P29
グループ | アドレス | 説明 | R/W | デフォルト値 |
電力制御 | 00 | 電源ステータスレジスタ | R | |
電力制御 | 01 | 電力モード/充電ステータスレジスタ | R | |
電力制御 | 04 | OTG VBUSステータスレジスタ | R | |
電力制御 | 06-0B | データキャッシュレジスタ 0-5 | R/W | F0/0F/00/FF/00/00 |
電力制御 | 10 | EXTEN & DC-DC2 スイッチ制御レジスタ | R/W | X5H |
電力制御 | 12 | DC-DC1/3 & LDO2/3 スイッチ制御レジスタ | R/W | XFH |
電力制御 | 23 | DC-DC2 電圧設定レジスタ | R/W | 16H |
電力制御 | 25 | DC-DC2 電圧勾配パラメータ設定レジスタ | R/W | 00H |
電力制御 | 26 | DC-DC1 電圧設定レジスタ | R/W | 68H |
電力制御 | 27 | DC-DC3 電圧設定レジスタ | R/W | 48H |
電力制御 | 28 | LDO2/3 電圧設定レジスタ | R/W | CFH |
電力制御 | 30 | VBUS-IPSOUT パス設定レジスタ | R/W | 60H |
電力制御 | 31 | VOFFシャットダウン電圧設定レジスタ | R/W | X3H |
電力制御 | 32 | シャットダウン、電池検知、CHGLED制御レジスタ | R/W | 46H |
電力制御 | 33 | 充電制御レジスタ 1 | R/W | C8H |
電力制御 | 34 | 充電制御レジスタ 2 | R/W | 41H |
電力制御 | 35 | バックアップ電池充電制御レジスタ | R/W | 22H |
電力制御 | 36 | PEKパラメータ設定レジスタ | R/W | 5DH |
電力制御 | 37 | DCDCコンバータ動作周波数設定レジスタ | R/W | 08H |
電力制御 | 38 | バッテリ充電低温警報設定レジスタ | R/W | A5H |
電力制御 | 39 | バッテリ充電高温警報設定レジスタ | R/W | 1FH |
電力制御 | 3A | APS低電力レベル1設定レジスタ | R/W | 68H |
電力制御 | 3B | APS低電力レベル2設定レジスタ | R/W | 5FH |
電力制御 | 3C | バッテリ放電低温警報設定レジスタ | R/W | FCH |
電力制御 | 3D | バッテリ放電高温警報設定レジスタ | R/W | 16H |
電力制御 | 80 | DCDC動作モード設定レジスタ | R/W | E0H |
電力制御 | 82 | ADCイネーブル設定レジスタ1 | R/W | 83H |
電力制御 | 83 | ADCイネーブル設定レジスタ2 | R/W | 80H |
電力制御 | 84 | ADCサンプルレート設定、TS端子制御レジスタ | R/W | 32H |
電力制御 | 85 | GPIO [3:0]入力範囲設定レジスタ | R/W | X0H |
電力制御 | 86 | GPIO1 ADC IRQ立ち上がりエッジしきい値設定 | R/W | FFH |
電力制御 | 87 | GPIO1 ADC IRQ立ち下がりエッジしきい値設定 | R/W | 00H |
電力制御 | 8A | タイマ制御レジスタ | R/W | 00H |
電力制御 | 8B | VBUS監視設定レジスタ | R/W | 00H |
電力制御 | 8F | 過熱シャットダウン制御レジスタ | R/W | 01H |
GPIO制御 | 90 | GPIO0制御レジスタ | R/W | 07H |
GPIO制御 | 91 | GPIO0 LDOモード出力電圧設定レジスタ | R/W | A0H |
GPIO制御 | 92 | GPIO1制御レジスタ | R/W | 07H |
GPIO制御 | 93 | GPIO2制御レジスタ | R/W | 07H |
GPIO制御 | 94 | GPIO [2:0]信号ステータスレジスタ | R/W | 00H |
GPIO制御 | 95 | GPIO [4:3]機能制御レジスタ | R/W | 00H |
GPIO制御 | 96 | GPIO [4:3]信号ステータスレジスタ | R/W | 00H |
GPIO制御 | 97 | GPIO [2:0]プルダウン制御レジスタ | R/W | 00H |
GPIO制御 | 98 | PWM1周波数設定レジスタ | R/W | 00H |
GPIO制御 | 99 | PWM1デューティサイクル設定レジスタ1 | R/W | 16H |
GPIO制御 | 9A | PWM1デューティサイクル設定レジスタ2 | R/W | 0BH |
GPIO制御 | 9B | PWM2周波数設定レジスタ | R/W | 00H |
GPIO制御 | 9C | PWM2デューティサイクル設定レジスタ1 | R/W | 16H |
GPIO制御 | 9D | PWM2デューティサイクル設定レジスタ2 | R/W | 0BH |
GPIO制御 | 9E | N_RSTO (GPIO5) 制御レジスタ | R/W | 20H |
割込制御 | 40 | IRQイネーブル制御レジスタ1 | R/W | D8H |
割込制御 | 41 | IRQイネーブル制御レジスタ2 | R/W | FFH |
割込制御 | 42 | IRQイネーブル制御レジスタ3 | R/W | 3BH |
割込制御 | 43 | IRQイネーブル制御レジスタ4 | R/W | C1H |
割込制御 | 4A | IRQイネーブル制御レジスタ5 | R/W | 00H |
割込制御 | 44 | IRQステータスレジスタ1 | R/W | 00H |
割込制御 | 45 | IRQステータスレジスタ2 | R/W | 00H |
割込制御 | 46 | IRQステータスレジスタ3 | R/W | 00H |
割込制御 | 47 | IRQステータスレジスタ4 | R/W | 00H |
割込制御 | 4D | IRQステータスレジスタ5 | R/W | 00H |
ADCデータ | 56 | ACIN電圧ADCデータ上位8ビット | R | |
ADCデータ | 57 | ACIN電圧ADCデータ下位4ビット | R | |
ADCデータ | 58 | ACIN電流ADCデータ上位8ビット | R | |
ADCデータ | 59 | ACIN電流ADCデータ下位4ビット | R | |
ADCデータ | 5A | VBUS電圧ADCデータ上位8ビット | R | |
ADCデータ | 5B | VBUS電圧ADCデータ下位4ビット | R | |
ADCデータ | 5C | VBUS電流ADCデータ上位8ビット | R | |
ADCデータ | 5D | VBUS電流ADCデータ下位4ビット | R | |
ADCデータ | 5E | AXP192内部温度監視ADCデータ上位8ビット | R | |
ADCデータ | 5F | AXP192内部温度監視ADCデータ下位4ビット | R | |
ADCデータ | 62 | TS入力ADCデータ上位8ビット、デフォルトのバッテリ温度監視 | R | |
ADCデータ | 63 | TS入力ADCデータは4ビット下位、デフォルトモニタバッテリ温度 | R | |
ADCデータ | 64 | GPIO0電圧ADCデータ上位8ビット | R | |
ADCデータ | 65 | GPIO0電圧ADCデータ下位4ビット | R | |
ADCデータ | 66 | GPIO1電圧ADCデータ上位8ビット | R | |
ADCデータ | 67 | GPIO1電圧ADCデータ下位4ビット | R | |
ADCデータ | 68 | GPIO2電圧ADCデータ上位8ビット | R | |
ADCデータ | 69 | GPIO2電圧ADCデータ下位4ビット | R | |
ADCデータ | 6A | GPIO3電圧ADCデータ上位8ビット | R | |
ADCデータ | 6B | GPIO3電圧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データ | 7E | APS電圧上位8ビット | R | |
ADCデータ | 7F | APS電圧下位4ビット | R | |
バッテリ | B0 | バッテリ充電クーロンカウントデータレジスタ[31:24] | R/W | 00H |
バッテリ | B1 | バッテリ充電クーロンカウントデータレジスタ[23:16] | R/W | 00H |
バッテリ | B2 | バッテリ充電クーロンカウントデータレジスタ[15:8] | R/W | 00H |
バッテリ | B3 | バッテリ充電クーロンカウントデータレジスタ[7:0] | R/W | 00H |
バッテリ | B4 | バッテリ放電クーロンカウントデータレジスタ[31:24] | R/W | 00H |
バッテリ | B5 | バッテリ放電クーロンカウントデータレジスタ[23:16] | R/W | 00H |
バッテリ | B6 | バッテリ放電クーロンカウントデータレジスタ[15:8] | R/W | 00H |
バッテリ | B7 | バッテリ放電クーロンカウントデータレジスタ[7:0] | R/W | 00H |
バッテリ | B8 | クーロンカウンタ制御レジスタ | R/W | 00H |
ここは肝になりますが、基本的にAPI経由だと知らなくてもなんとかなります。
APIでの呼び出し確認
bigin : 利用開始
アドレス | アドレス説明 | 値 |
0x10 | EXTEN & DC-DC2 スイッチ制御レジスタ | 0xff |
0x28 | LDO2/3 電圧設定レジスタ | 0xff |
0x82 | ADCイネーブル設定レジスタ1 | 0xff |
0x33 | 充電制御レジスタ 1 | 0xC0 |
0xB8 | クーロンカウンタ制御レジスタ | 0x80 |
0x12 | DC-DC1/3 & LDO2/3 スイッチ制御レジスタ | 0x4d |
0x36 | PEKパラメータ設定レジスタ | 0x5c |
0x90 | GPIO0制御レジスタ | 0x02 |
0x31 | VOFFシャットダウン電圧設定レジスタ | 0x04 |
初期設定をしています。バッテリーは4.2Vまで100mAで充電して、3.0V以下になったらシャットダウンします。
ScreenBreath : 画面の明るさ設定
0x28 | LDO2/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(外部電源)電圧取得
0x56 | ACIN電圧ADCデータ上位8ビット | |
0x57 | ACIN電圧ADCデータ下位4ビット |
お尻の端子からの5V外部電源の電圧取得です。取得するのはADCのステップ数なので、ステップ数 × 1.7mVで実際の電圧に変換する必要があります。
GetIinData : ACIN(外部電源)電流取得
0x58 | ACIN電流ADCデータ上位8ビット | |
0x59 | ACIN電流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 : 内部温度取得
0x5e | AXP192内部温度監視ADCデータ上位8ビット | |
0x5f | AXP192内部温度監視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から?)
0x7E | APS電圧上位8ビット | |
0x7F | APS電圧下位4ビット |
マイコンに供給されている電圧だと思います。USB経由の場合には5Vぐらいで、バッテリー駆動の場合には4Vぐらいになります。取得するのはADCのステップ数なので、ステップ数 × 1.4mVで実際の電圧に変換する必要があります。
GitHubだと実装されていましたが、0.0.5だと実装されていません。
SetSleep : スリープ設定 (0.0.6から?)
0x31 | VOFFシャットダウン電圧設定レジスタ | |
0x31 | VOFFシャットダウン電圧設定レジスタ | (1<<3)|buf |
0x12 | DC-DC1/3 & LDO2/3 スイッチ制御レジスタ | 0x41 |
スリープ状態に設定します。GitHubだと実装されていましたが、0.0.5だと実装されていません。
GetWarningLeve : 警告レベル取得 (0.0.6から?)
0x47 | IRQステータスレジスタ4 |
設定する関数がなく、初期値の0を所得するだけの関数です。GitHubだと実装されていましたが、0.0.5だと実装されていません。
未実装の機能
VBUS(USB)電圧取得
0x5a | VBUS電圧ADCデータ上位8ビット | |
0x5b | VBUS電圧ADCデータ下位4ビット |
USBからの供給電圧。取得するのはADCのステップ数なので、ステップ数 × 1.7mVで実際の電圧に変換する必要があります。GetVinData()関数の中身の送信先アドレスを変更することで実装可能です。
VBUS(USB)電流取得
0x5c | VBUS電流ADCデータ上位8ビット | |
0x5d | VBUS電流ADCデータ下位4ビット |
USBからの供給電流。取得するのはADCのステップ数なので、ステップ数 × 0.375mAで実際の電流に変換する必要があります。GetIinData()関数の中身の送信先アドレスを変更することで実装可能です。 ただし、ステップの幅が0.625mAのGetIinData()とは違うので注意してください。
個人的にはこのVBUSから流れている電流って興味あるんですが、いまのAPIだと無いんですね。
ステップについて
Channel | 000H | STEP | FFFH |
Battery Voltage | 0mV | 1.1mV | 4.5045V |
Bat discharge current | 0mA | 0.5mA | 4.095A |
Bat charge current | 0mA | 0.5mA | 4.095A |
ACIN volatge | 0mV | 1.7mV | 6.9615V |
ACIN current | 0mA | 0.625mA | 2.5594A |
VBUS voltage | 0mV | 1.7mV | 6.9615V |
VBUS current | 0mA | 0.375mA | 1.5356A |
Internal temperature | -144.7℃ | 0.1℃ | 264.8℃ |
APS voltage | 0mV | 1.4mV | 5.733V |
TS pin input | 0mV | 0.8mV | 3.276V |
GPIO0 | 0/0.7V | 0.5mV | 2.0475/2.7475V |
GPIO1 | 0/0.7V | 0.5mV | 2.0475/2.7475V |
GPIO2 | 0/0.7V | 0.5mV | 2.0475/2.7475V |
GPIO3 | 0/0.7V | 0.5mV | 2.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秒以上おして、電源オフにした状態で充電するのがよさそうでした。
コメント