17.CoreInkの電池電圧表示


17.CoreInkの電池電圧表示

電源管理にIP5306を使用していないので、M5Stack Basicのような関数は利用できません。

ブロック図

https://docs.m5stack.com/en/core/coreink?id=schematic
のブロック図より、
・ESP32-PICO-D4: マイコン
・BM8563: I2C用と時計IC
・SY8089: 降圧IC 2.7-5.5V→(1.8V)2A
・SY7088: 昇圧IC 2.3-5V→2.5-5.5V(1.6A)
・CP2104: USB-TO-UARTブリッジ
・TP4057: 充電IC 4.3-6V→4.2V0.5A
は出ていますが、電源制御ICはありません。

スケッチ例

Arduino IDE > ファイル > スケッチ例 > M5-CoreInk > Factory Test.inoに
・getBatVoltage()
 G35の電圧(mV)を読み、x25.1/5.1/1000(V)しています。
 電池電圧を内部で約1/5に分圧して測定していると思われます。
・checkBatteryVoltage(bool powerDownFlag)
 3.2V以下でローバッテリーとし、パワーダウンして、3.2Vより高くなるまで待ちます。
があり、この2つの関数を利用します。

アッテネータ

https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/adc.html#_CPPv425adc1_config_channel_atten14adc1_channel_t11adc_atten_t
によると、
Atten電圧の倍率有効測定範囲
0dB1.000.10–0.95V
2.5dB1.330.10–1.25V
6dB2.000.15–1.75V
11dB3.550.15–2.45V

ADC特性の構造体

構造体 esp_adc_cal_characteristics_t ADCの特性を格納する構造。esp_adc_cal_characterize()を呼び出して、構造を初期化します。

パブリックメンバー
・adc_unit_tadc_num: ADC番号
・adc_atten_tatten: ADCの減衰
・adc_bits_width_tbit_width: ADCビット幅
・uint32_t coeff_a: ADCの勾配-電圧曲線
・uint32_t coeff_b: ADCのオフセット-電圧曲線
・uint32_t vref: ルックアップテーブルで使用されるVref
・const uint32_t *low_curve: ルックアップテーブルの低Vref曲線へのポインタ(未使用の場合はNULL)
・const uint32_t *high_curve: ルックアップテーブルの高Vref曲線へのポインタ(未使用の場合はNULL)

ADC設定

esp_adc_cal_value_t esp_adc_cal_characterize(adc_num, atten, bit_width, default_vref, *chars)
特定の減衰でADCを特性評価します。特定の減衰でADCを特徴付け、[y = coeff_a * x + coeff_b]の形式でADC-電圧曲線を生成します。特性評価は、2点値、eFuse Vref、またはデフォルトVrefに基づくことができ、キャリブレーション値はこの順序で優先されます。ESP32の場合、menuconfigを使用して、2点値とeFuseVrefキャリブレーションを有効/無効にできます。ESP32s2の場合、2点値のキャリブレーションとADC_WIDTH_BIT_13のみがサポートされます。パラメータdefault_vrefは使用されていません。

戻り値
・ESP_ADC_CAL_VAL_EFUSE_VREF:特性評価に使用されるeFuse Vref
・ESP_ADC_CAL_VAL_EFUSE_TP:特性評価に使用される2点値(線形モードのみ)
・ESP_ADC_CAL_VAL_DEFAULT_VREF:特性評価に使用されるデフォルトのVref

パラメーター
・[in] adc_num: 特性化するADC(ADC_UNIT_1 or ADC_UNIT_2)
・[in] atten: 特徴づける減衰
・[in] bit_width: ADCのビット幅
・[in] uint32_t default_vref: デフォルトのADC基準電圧(mV, ESP32のみ、eFuse値が利用できない場合に使用)
・[out] esp_adc_cal_characteristics_t *chars: ADC特性を格納するために使用される空の構造体へのポインタ

ADCの読取値を電圧に変換

uint32_t esp_adc_cal_raw_to_voltage(adc_reading, *chars)
ADC特性に基づいてADCの読取値をmV単位の電圧に変換します。呼び出す前に、特性構造を初期化する必要があります。esp_adc_cal_characterize()を呼び出します。

戻り値:mV単位の電圧

パラメーター
[in] uint32_t adc_reading:ADC読取り
[in] constesp_adc_cal_characteristics_t *chars:ADC特性を含む初期化された構造体へのポインタ

スケッチ


// CoreInkの電池電圧表示
#include <M5CoreInk.h>    // CoreInk使用
#include <esp_adc_cal.h>  // ADC使用
static esp_adc_cal_characteristics_t adc_chars;  // 定義

float getBatVoltage() {  // 電池電圧測定関数
  analogSetPinAttenuation(35, ADC_11db);  // G35(ADC1)のADC減衰器を設定
  esp_adc_cal_characteristics_t *adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
  esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 3600, adc_chars);
  // ADCの設定(ADC No., 減衰量, ビット幅, Vref(mV), 格納するために使用される空の構造体へのポインタ)
  uint16_t ADCValue = analogRead(35);                  // G35からアナログ電圧を読む
  uint32_t BatVolmV = esp_adc_cal_raw_to_voltage(ADCValue, adc_chars); // 読取値をmV単位に変換
  float BatVol = float(BatVolmV) * 25.1 / 5.1 / 1000;  // 分圧を考えて計算
  return BatVol;                                       // 電池電圧を返す
}

void checkBatteryVoltage(bool powerDownFlag) { // 低電圧時充電する関数
  float batVol = getBatVoltage();              // 電池電圧測定関数へ
  Serial.printf("Batt %.2fV\n", batVol);       // シリアルモニタに表示
  if (batVol > 3.2) {           // 3.2Vより高ければ
    return;                     // 正常で戻る
  }
  Serial.println("LOW Batt");   // シリアルモニタに表示
  if (powerDownFlag == true) {  // フラグをtrueに設定していれば
    M5.shutdown();              // 旧PowerDown 電源断(PWRボタンで起動)
  }                             // M5-CoreInk by HadesをVer0.0.2にしておく。
  while (1) {                   // ずっと充電する
    batVol = getBatVoltage();   // 電池電圧測定関数へ
    if (batVol > 3.2) {         // 3.2Vより高ければ
      return;                   // 正常で戻る
    }
  }
}

void setup() {
  M5.begin();        // E-Ink,RTC,I2C,スピーカーを初期化
  M5.M5Ink.clear();  // 画像領域をクリア
  checkBatteryVoltage(false); // 低電圧ならshutdownせず充電 関数へ
}
void loop() {
  checkBatteryVoltage(false); // 低電圧ならshutdownせず充電 関数へ
  delay(1000);                // 1秒待つ
}