07.Wio Terminalのバッテリー残量表示


07.Wio Terminalのバッテリー残量表示

Wio Terminal Chassis Battery(650mAh)を接続した時のそのバッテリーの残量を表示します。
新バッテリーのWio Terminal Chassis Battery(650mAh)は、旧Wio Terminal Battery Chassisに、Texas Instruments製のバッテリ残量IC BQ27441-G1A
https://www.ti.com/product/ja-jp/BQ27441-G1
が追加されました。これは、LiPo(リチウムポリマ)バッテリーの電圧電流を測定しI2C通信で残容量、充電率、経年変化の推定等を取得できます。

BQ27441-G1Aライブラリをインストール

https://github.com/sparkfun/SparkFun_BQ27441_Arduino_Library
にて、
Code > Download ZIP > "SparkFun_BQ27441_Arduino_Library-master.ZIP"をディスクトップに置く。
Arduino-IDE > スケッチ > ライブラリをインクルード > .ZIP形式のライブラリをインストール... > 先のzipファイルを選択 > 開く

スケッチは
Seeed Wiki > Platform > Wio Terminal > Wio Terminal Chassis Battery(650mAh) の
https://wiki.seeedstudio.com/Wio-Terminal-Chassis-Battery(650mAh)/
に出ているサンプルコードを少し変更して日本語表示しました。
主な変更点
・充電率を電池マーク表示
 電池マーク内に充電率を表示
 25%以下で黄色文字
 10%以下で赤色文字
・バッテリー温度追加
・日本語表示

測定項目

lipo.soc()

符号無し整数
充電率を取得 (%)
残容量/全容量x100 で、満充電時100%、完全放電時0%です。

lipo.voltage()

符号無し整数
バッテリー電圧を取得 (mV)
* スケッチでは(V)に変換しました。

lipo.current(AVG)

符号付き整数
平均電流を取得 (mA)
+は充電,-は放電

lipo.capacity(FULL)

符号無し整数
全容量を取得 (mAh)

lipo.capacity(REMAIN)

符号無し整数
残容量を取得 (mAh)

lipo.power()

符号付き整数
平均消費電力を取得 (mW)
+は充電,-は放電

lipo.soh()

符号無し整数
満充電時の容量維持率を取得(%)
主に充放電による化学物質の劣化により満充電容量は減ってくるので
現在の満充電容量/設計容量x100

lipo.temperature(BATTERY)

符号無し整数
バッテリー温度を取得 (0.1K)
今回のスケッチでは
ケルビン273.15K = 摂氏0℃
より、temperature/10-273.2(℃)と算出
* ヘッターファイルとICのデータシートより追加

バッテリーケースのLED

・上側の充電LED
  緑点灯は充電中
  緑点滅:?
  消灯は充電完
・下側の供給LED
  橙は本体に電圧供給中
  消灯はバッテリーoff

書込み後に充電時の注意

1.USBケーブルを本体側USBに接続し、スケッチを書込みます。(バッテリー側に挿すとCOMが見つからないと言われます。)
2.バッテリーケースのSW操作で充電LEDが緑点灯で充電(電流値はブラス)、充電LEDが消灯で放電(電流値はマイナス)となります。供給LEDはどちらも橙です。
3.スケッチ書込終了後、SWを押し充電LEDを消灯します。
4.本体側USB接続を抜きバッテリー側USBに接続します。(充電LEDが緑点灯時に差替えると、供給LEDが消灯し電源がoffします。)
5.充電LED(緑)が点灯し、充電を開始します。供給LEDは橙点灯のままです。
6.しかし、バッテリーからUSBを外すと必ずリセットします。

スケッチ

充電容量維持率の表示はSeeedの動画でも0%です。?

// バッテリー情報とバッテリーマークの表示 batt.ino
#include <SparkFunBQ27441.h>  // バッテリー残量IC BQ27441を使用
#define LGFX_AUTODETECT       // LovyanGFX対応機種を自動認識
#include <LovyanGFX.hpp>      // LovyanGFXを使用
static LGFX lcd;              // LGFXのインスタンスを作成
const unsigned int BATTERY_CAPACITY = 650; // バッテリー設計容量650mAh

void setGamen() {                    // 画面初期設定関数
  lcd.init();                        // LCD初期化
  lcd.setBrightness(64);             // バックライト輝度(暗0-255明)
  lcd.setRotation(1);                // LCD表示向き
  lcd.setFont(&lgfxJapanGothic_20);  // ゴシック固定長 縦ドット(16,20,24,28,32)
  //lcd.setTextScroll(true);         // 画面下端に到達後スクロール
  //lcd.setScrollRect(0, 0, lcd.width(), lcd.height());//スクロール範囲(X,Y,W,H)
  lcd.setTextSize(1.0);                   // 文字サイズ(幅倍数)
  lcd.setTextColor(TFT_GREEN, TFT_BLACK); // (文字色,背景色)
  //lcd.setCursor(0, 0);                  // 画面左上から開始
}

void setBQ27441() {               // バッテリー残量IC(BQ27441-G1A)初期設定
  if (!lipo.begin()) {            // I2Cを初期化、通信確認出来ない時
    lcd.setTextColor(TFT_RED);    // 赤文字
    lcd.setCursor(100, 120); lcd.println("バッテリー残量ICと通信できません"); // 表示
    lcd.setCursor(100, 160); lcd.println("バッテリーを接続してください");     // 表示
    while (1);                    // 永久ループ
  }                               // 通信出来たら
  lcd.setCursor(20, 100); lcd.println("バッテリー残量ICに接続"); // 表示
  lipo.setCapacity(BATTERY_CAPACITY);                  // バッテリー設計容量650mAhに設定
}

void printBTStats() {                              // バッテリー状態を読取り&表示関数
  unsigned int soc = lipo.soc();                   // 充電率を取得(%) 満充電100% 完全放電0%
  float volts = lipo.voltage() / 1000.0;           // バッテリー電圧取得(V)
  int current = lipo.current(AVG);                 // 平均電流取得(mA) +充電,-放電
  unsigned int fullCapacity = lipo.capacity(FULL); // 全容量を取得(mAh)
  unsigned int capacity = lipo.capacity(REMAIN);   // 残容量を取得(mAh)
  int power = lipo.power();                        // 平均消費電力を取得(mW) +充電,-放電
  int health = lipo.soh();                         // 健康状態を取得(%) 現在の満充電容量/設計容量
  float BTtemp = lipo.temperature(BATTERY) / 10 - 273.2; // バッテリー温度を取得 0.1K→℃

  lcd.drawRoundRect(10, 20, 300, 210, 10, TFT_BLUE); // 青枠(x0,y0,W,H,角r,色)
  lcd.setTextColor(TFT_MAGENTA, TFT_BLACK);          // 黒地に赤紫文字
  lcd.setCursor(50, 30); lcd.print("    充電率:");  // 表示
  lcd.setCursor(50, 55); lcd.print("バッテリー電圧:");  // 表示
  lcd.setCursor(50, 80); lcd.print(" 電流(+充,-放):");  // 表示
  lcd.setCursor(50, 105); lcd.print("    残容量:"); // 表示
  lcd.setCursor(50, 130); lcd.print("  満充電容量:"); // 表示
  lcd.setCursor(50, 155); lcd.print(" 電力(+充,-放):"); // 表示
  lcd.setCursor(50, 180); lcd.print("充電容量維持率:"); // 表示
  lcd.setCursor(50, 205); lcd.print("バッテリー温度:"); // 表示
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);            // 黒地に白文字
  lcd.setCursor(200, 30); lcd.printf("%4d%", soc);  // 充電率
  lcd.setCursor(200, 55); lcd.printf("%5.3fV", volts);         // バッテリー電圧
  lcd.setCursor(200, 80); lcd.printf("%4dmA", current);        // 平均電流
  lcd.setCursor(200, 105); lcd.printf("%3dmAh", capacity);     // 残容量
  lcd.setCursor(200, 130); lcd.printf("%3dmAh", fullCapacity); // 満充電容量
  lcd.setCursor(200, 155); lcd.printf("%4dmW", power);         // 平均消費電力
  lcd.setCursor(200, 180); lcd.printf("%4d%", health);        // 満充電劣化率
  lcd.setCursor(200, 205); lcd.printf("%4.0f℃", BTtemp);      // バッテリー温度

  int x0 = 290, y0 = 0, W0 = 20, H0 = 14, W1 = 3;  // 電池マーク大きさ 0:本体,1:+極
  lcd.fillRect(x0, y0, W0, H0, TFT_WHITE);  // 電池本体 四角形(x0,y0,W,H[,塗りつぶし色])
  lcd.fillRect(x0 + W0, y0 + 2, W1, H0 - 4, TFT_WHITE); // 電池プラス極
  if (soc <= 10) {                           // 0-10%の時
    lcd.setTextColor(TFT_RED, TFT_BLACK);    // 黒地に赤文字
  } else if (soc <= 25) {                    // 11-25%の時
    lcd.setTextColor(TFT_YELLOW, TFT_BLACK); // 黒地に黄色文字
  } else {                                   // 26-100%の時
    lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // 黒地に白文字
  }
  lcd.setTextSize(0.6);                                  // 文字サイズ
  lcd.setCursor(x0 + 1, y0 + 1); lcd.printf("%3d", soc); // 充電率
  lcd.setTextSize(1.0);                                  // 文字サイズ戻す
}

void setup() {
  setGamen();                             // 表示画面の初期設定関数へ
  setBQ27441();                           // バッテリー残量ICからデータ取得&表示関数へ
  lcd.setTextColor(TFT_GREEN, TFT_BLACK); // 黒地に緑文字
  lcd.setCursor(20, 130); lcd.print("バッテリーが初期化されました"); // 表示
  delay(1000);                            // 1秒待つ
  lcd.fillScreen(TFT_BLACK);              // 黒で画面クリア
}
void loop() {
  printBTStats();  // 残量等表示関数へ
  delay(1000);     // 1秒待つ 表示間隔
}
* フラッシュメモリの53%を使用。