Newer
Older
M5StickCPlus_FactoryTest2022 / Battery.h
@Motoki Miura Motoki Miura on 10 Apr 2022 5 KB lower boundary
/**
 * 電池残量表示
 * 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);
}