Program Resource

開発者向け各種コード、アルゴリズム、リソース情報ライブラリ もしくはねふぁの覚え書き

前回の記事でI2C通信で4段階のM5Stackのバッテリー表示が出来たが、もう少し細かく電池残量を調べたい。

M5StackのBATTピンからはリポバッテリーの+電圧が出ている。すぐそばにアナログ入力のGPIOピンがある。

と言う事で、GPIO36ピンを使ってリポバッテリーの電圧を測って電池残量を調べてみる。analogReadそのままだとノイズが多い、抵抗で繋ぐので常時バッテリー消耗する(放置しておくと過放電になるかも)と言ったデメリットがあるが一つの方法として紹介。こちらのサイトに測定時のみ通電する方法も紹介されているので、参考に。

リポバッテリーはフルの状態で4.1~4.2V程度の電圧になっているので、GPIOのanalogReadが3.3~3.9Vなのでそのまま接続はできない。抵抗をかまして電圧を落として読み取らせる。

手持ちの抵抗で56Kと180Kがあったので図の様に接続した。ESP32のanalogReadは3.3Vと思っていたので4.2Vが3.3Vになる様にしたのだが、何も設定しない状態だとanalogReadは3.9Vの読み取りの様だ。

リポバッテリーフルを4.1V、空を3.0Vとしてバッテリー残量表示をするサンプルスケッチは以下の通り。中華製抵抗を使ったりして抵抗値のブレが大きくreadvoltageの変換はこちらの環境に合わせてあるので、変換の値は実際の電圧を測って調整する事。

//BATTピン - 56KΩ - GPIO36 - 180KΩ - GND で接続
#include <M5Stack.h>

#define RGB(r,g,b) (int16_t)(b + (g << 5) + (r << 11)) //色0~31 緑0~63

#define BATT_PIN  36
#define BATT_FULL 410 //4.1Vでフル扱い
#define BATT_LOW  300 //3.0Vで空扱い
int lastbattery = -1;
unsigned long lastupdateMillis = 0; //最後にバッテリー確認した時間
unsigned long currentMillis;

void displayBatteryLevel()
{
	if (currentMillis - lastupdateMillis > 1000) {
		int battlevel = 0;
		int battvoltage = 0;
		int readvoltage;

		int val = analogRead(BATT_PIN);
		readvoltage = map(val, 0, 4095, 0, 409); //読み取り電圧
		battvoltage = map(readvoltage, 0, 320, 0, 420); //電池電圧 3.3 -> 4.2V
		battlevel = constrain(map(battvoltage, BATT_LOW, BATT_FULL, 0, 100), 0, 100); //電池%

		if (lastbattery != battlevel) {
			M5.Lcd.fillRect(250, 5, 56, 21, RGB(31, 63, 31));
			M5.Lcd.fillRect(306, 9, 4, 13, RGB(31, 63, 31));
			M5.Lcd.fillRect(252, 7, 52, 17, RGB(0, 0, 0));
			if (battlevel <= 25)
				M5.Lcd.fillRect(253, 8, battlevel / 2, 15, RGB(31, 20, 10));
			else
				M5.Lcd.fillRect(253, 8, battlevel / 2, 15, RGB(20, 40, 31));
			M5.Lcd.setTextColor(WHITE);
			M5.Lcd.setCursor(255, 13);
			M5.Lcd.setTextSize(1);
			M5.Lcd.printf("%.2fV", (float)battvoltage / 100);
			lastbattery = battlevel;
		}
		lastupdateMillis = currentMillis;
	}
}

void setup() {
	M5.begin();
	dacWrite(25, 0); //Speaker OFF(analogreadするとノイズが出るので)
	M5.Lcd.clear();
}

void loop() {
	currentMillis = millis();
	displayBatteryLevel();
}

参考にしたサイト

https://forum.arduino.cc/index.php?topic=595924.0 アナログ入力の安定化についての説明がある。今回はスケッチがごちゃごちゃするので省略。

https://www.youtube.com/watch?v=S34R4zg03uE  電圧測定の基本と抵抗値の計算。

https://kghr.blog.fc2.com/blog-entry-135.html 電圧測定の説明と3.9Vレンジについての情報、測定時のみ通電する方法。

コメントを残す

メールアドレスが公開されることはありません。


*

CAPTCHA