/** * 電池残量表示 * https://rikoubou.hatenablog.com/entry/2021/04/02/174338 * を一部改変 */ #include <M5StickCPlus.h> /** * Batteryクラス * * 電池残量を表示する。 */ class Battery { public: Battery(); void setPosAndSize(int posX, int posY, int showSizeNum); void setDeleteBgColor(uint16_t color); void setTextColor(uint16_t color); void batteryUpdate(); void setSprite(TFT_eSprite *sprite); void setCheckRate(uint16_t rate); private: const float MAX_BATTERY_VOLTAGE = 4.0f; const float MIN_BATTERY_VOLTAGE = 3.2f; const int8_t BITS_PER_PIXEL = 1; const int TRANS_PARENTS = 0; const int MAX_SHOW_SIZE = 7; const int MIN_SHOW_SIZE = 1; TFT_eSprite *_sprite; // = TFT_eSprite(&M5.Lcd); bool _showFlg; int _x; int _y; int _showSize; int _width; int _height; int _top_width; uint16_t _bg_color; uint16_t _line_color; uint16_t _text_color; uint16_t ratecount = 100; uint16_t rateskip = 100; int i_percent = -1; uint16_t statusColor = 0; void drawBatteryLines(); int calcBatteryPercent(); uint16_t getBatteryColor(); void showBatteryPercent(); bool isLowBattery(); bool isUsingBattery(); }; /** * コンストラクタ */ Battery::Battery() { // 初期化 _showFlg = true; _x = 0; _y = 0; _showSize = 1; _width = 28 * _showSize; _height = 10 * _showSize; _top_width = 2 * _showSize; _bg_color = TFT_BLACK; _line_color = TFT_WHITE; _text_color = TFT_WHITE; } void Battery::setSprite(TFT_eSprite *sprite) { _sprite = sprite; } /** * 表示位置(x, y)と表示サイズを設定する関数 */ void Battery::setPosAndSize(int posX, int posY, int showSizeNum) { _x = posX; _y = posY; if (MAX_SHOW_SIZE < showSizeNum) { _showSize = MAX_SHOW_SIZE; } else if (showSizeNum < MIN_SHOW_SIZE) { _showSize = MIN_SHOW_SIZE; } else { _showSize = showSizeNum; } _width = 28 * _showSize; _height = 10 * _showSize; _top_width = 2 * _showSize; } void Battery::setCheckRate(uint16_t _checkrate) { ratecount = _checkrate; } /** * 削除時の背景色を設定する関数 */ void Battery::setDeleteBgColor(uint16_t color) { _bg_color = color; } /** * 電池図形と文字の色を設定する関数 */ void Battery::setTextColor(uint16_t color) { _line_color = color; _text_color = color; } /** * バッテリー残量の表示を更新する関数(ここを定期的に呼び出す) */ void Battery::batteryUpdate() { if (rateskip % 5 == 0 || statusColor == 0) { statusColor = getBatteryColor(); } if (rateskip == 1 || i_percent == -1) { i_percent = calcBatteryPercent(); rateskip = ratecount; } // 電池図形内部背景塗りつぶし _sprite->fillRect(_x, _y, _width - 1, _height - 1, TFT_BLACK); // 電池の外形 drawBatteryLines(); // バッテリー残量の割合を計算して背景色塗りつぶし int b_width = int((_width - 2) * (i_percent / 100.0f)); _sprite->fillRect(_x + 2, _y + 2, b_width, _height - 3, statusColor); showBatteryPercent(); // バッテリー数値を表示 // Serial.printf("batt %d", i_percent); // _sprite->pushSprite(_x + 1, _y + 1); // ディスプレイに表示 rateskip--; } /** * 電池の図形を作成する関数 */ void Battery::drawBatteryLines() { // 電池図形を作成 _sprite->fillRect(_x, _y, _width + 1, _height + 1, _line_color); _sprite->fillRect(_x + 1, _y + 1, _width - 1, _height - 1, TRANS_PARENTS); _sprite->fillRect(_x + _width + 1, _y + _top_width, _top_width, _height - (_top_width * 2) + 1, _line_color); // _sprite->setBitmapColor(_line_color, TRANS_PARENTS); // 色を設定 // _sprite->pushSprite(_x, _y, TRANS_PARENTS); // 表示 // _sprite->deleteSprite(); // メモリ開放 } /** * バッテリー残量を表示する関数 */ void Battery::showBatteryPercent() { // バッテリー数値を表示 _sprite->setCursor(_x + _width + 7, _y + _showSize + 1); _sprite->setTextFont(1); _sprite->setTextColor(_text_color); _sprite->setTextSize(_showSize); _sprite->print(i_percent); _sprite->print("%"); } /** * バッテリーの状態に応じて色を取得する関数 */ uint16_t Battery::getBatteryColor() { // バッテリー稼働中は緑、電圧が低い時は赤色、充電中は青色 uint16_t color = TFT_BLUE; if (isLowBattery()) { color = TFT_RED; } else if (!isUsingBattery()) { color = TFT_GREEN; } return color; } /** * 低電圧状態かを判定する関数 */ bool Battery::isLowBattery() { // 低電圧状態(3.4V以下)だと1それ以外は0 uint8_t _low_bat = M5.Axp.GetWarningLeve(); if (_low_bat == 0) { return false; } else { return true; } } /** * バッテリー稼働か充電中かを判定する関数 */ bool Battery::isUsingBattery() { // プラスが充電、マイナスがバッテリー稼働 float _ibat = M5.Axp.GetBatCurrent(); if (_ibat < 0.0f) { return true; } else { return false; } } /** * バッテリー残量%を計算する関数(戻り値は0~100) */ int Battery::calcBatteryPercent() { float _vbat = M5.Axp.GetBatVoltage(); float percent = (_vbat - MIN_BATTERY_VOLTAGE) / (MAX_BATTERY_VOLTAGE - MIN_BATTERY_VOLTAGE); if (percent > 1.0f) percent = 1.0f; if (percent < 0.0f) percent = 0.0f; return roundf(percent * 100.0f); }