1. はじめに:なぜESP-NOWと電池残量チェックなのか
本記事は、前回構築した低消費電力のESP-NOWワイヤレスドアセンサーを、さらに実用的にするための改良版です。最大の改良点は、電池駆動のIoT機器の最大の課題である「突然の電池切れ」を防ぐため、 子機の電池電圧を監視し、残量が低下したら親機に警告を送信する「LOW BATTERY警告機能」 を追加したことです。これにより、信頼性と実用性が大幅に向上します。
2. 改良に必要な追加部品と接続方法
ESP32は電源電圧を直接測定できないため、分圧回路を構成し、その出力を ADC(アナログ-デジタル変換器) で読み取ります。
2-1. 追加部品と概算費用
役割 | 部品名 | 数量 | 規格の目安 | 概算価格 | 役割 |
抵抗 | 分圧抵抗 R1 | 1 | 100kΩ | 数十円 | 電圧を降下させます |
抵抗 | 分圧抵抗 R2 | 1 | 47kΩ | 数十円 | 電圧を降下させます |
コンデンサ | 安定化コンデンサ C3 | 1 | 0.1μF | 数十円 | ADC測定時のノイズを低減します |
親機 | LED(オプション) | 1 | 数十円 | LOW BATTERY警告表示用 |
分圧回路: R1=100kΩ と R2=47kΩ の組み合わせで、最大 4.5V のバッテリー電圧を 1.44V 程度まで下げ、安全にESP32のADC(最大 3.3V)に入力します。
2-2. 子機(センサー側)の接続【電池電圧検知回路】
この回路は、子機の電源入力(電池ボックスの出力)とESP32のADCピンの間に接続します。
接続元 | 接続先 | 備考 |
電池ボックス +極 (VBAT) | 分圧抵抗 R1 (100kΩ) の一方 | バッテリーのプラス側を抵抗に接続します。 |
R1 の反対側 | R2 (47kΩ) の一方 + ESP32のADCピン (例: GPIO 35) | ここが分圧された電圧 Vout の出力点です。 |
R2 の反対側 | GND | R2 をグランドに落とします。 |
Vout 点と GND | 安定化コンデンサ C3 | ADC測定の安定化のために接続します。 |
2-3. 親機(ブザー側)の接続
LOW BATTERY警告用のLEDを親機に追加します。(ブザーは前回と同じ GPIO 25)
接続元 | 接続先 | 備考 |
警告LED(+) | 電流制限抵抗 → GPIO 26 | LOW BATTERY警告表示用 |
警告LED(-) | GND |
3. プログラムコードの変更(電池残量検知)
3-1. 共通:ESP-NOWメッセージ構造体の変更
電池残量情報を伝えるため、メッセージ構造体に lowBattery
フラグを追加します。
C++
typedef struct struct_message {
int id; // センサーID
int sensorValue; // センサー状態 (1: 開, 0: 閉)
bool lowBattery; // 新規: 電池残量低下フラグ (true: 低い)
} struct_message;
struct_message myData;
3-2. 子機(センサー側)のコード
ADCでの電圧測定とLOW BATTERY判定のロジックを setup()
と loop()
に追加し、送信データに含めます。
C++
#include <esp_now.h>
#include <WiFi.h>
// --- 定数設定 ---
// (GPIO27: センサー, GPIO35: ADCピンとして使用を想定)
#define DOOR_SENSOR_PIN 27
#define BATTERY_PIN 35
#define R1 100000
#define R2 47000
#define LOW_BATTERY_THRESHOLD 3.3 // 電圧が3.3Vを下回ったら警告 (調整推奨)
// ... (struct_messageの定義) ...
// 電池電圧を測定する関数
float readBatteryVoltage() {
int adcValue = analogRead(BATTERY_PIN);
// ADC値を電圧に変換(ESP32のADCリファレンスに合わせて係数を調整してください)
float vOut = (float)adcValue * (3.3 / 4095.0);
// 分圧回路の逆算
float vIn = vOut * ((float)R1 + (float)R2) / (float)R2;
return vIn;
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// ... ESP-NOWの初期化とピア登録 ...
pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP);
pinMode(BATTERY_PIN, INPUT);
// 初回起動時に電池電圧をチェックし、myDataに格納
float currentVoltage = readBatteryVoltage();
Serial.printf("Initial Battery Voltage: %.2fV\n", currentVoltage);
if (currentVoltage < LOW_BATTERY_THRESHOLD) {
myData.lowBattery = true;
} else {
myData.lowBattery = false;
}
}
void loop() {
// センサー値の読み取り
myData.sensorValue = digitalRead(DOOR_SENSOR_PIN) == HIGH ? 1 : 0;
// *重要* LOW BATTERY状態を送信前に更新(頻度は環境に応じて調整)
// 通常はディープスリープ起動時にのみチェックすれば十分です。
float currentVoltage = readBatteryVoltage();
if (currentVoltage < LOW_BATTERY_THRESHOLD) {
myData.lowBattery = true;
} else {
myData.lowBattery = false;
}
// ESP-NOW送信
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
// 省電力化のためディープスリープへ (10秒間)
esp_sleep_enable_timer_wakeup(10000000);
esp_deep_sleep_start();
}
3-3. 親機(ブザー側)のコード
受信した lowBattery
フラグに応じて警告LEDを点灯させるロジックを追加します。
C++
#include <esp_now.h>
#include <WiFi.h>
// --- 定数設定 ---
#define BUZZER_PIN 25
#define WARNING_LED_PIN 26 // LOW BATTERY警告用LED
// ... (struct_messageの定義) ...
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
// --- 【LOW BATTERY チェックロジック】 ---
if (myData.lowBattery) {
Serial.println("!!! LOW BATTERY WARNING !!! - 交換が必要です");
// LOW BATTERY警告としてLEDを点灯
digitalWrite(WARNING_LED_PIN, HIGH);
} else {
digitalWrite(WARNING_LED_PIN, LOW);
}
// ----------------------------------------
// 通常のドア開閉ロジック
if (myData.sensorValue == 1) {
Serial.println("DOOR OPEN - WARNING!");
// ブザーを鳴らす
digitalWrite(BUZZER_PIN, HIGH);
delay(500);
digitalWrite(BUZZER_PIN, LOW);
} else {
Serial.println("DOOR CLOSED - Safe.");
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// ピン設定
pinMode(BUZZER_PIN, OUTPUT);
pinMode(WARNING_LED_PIN, OUTPUT);
digitalWrite(WARNING_LED_PIN, LOW);
// ... ESP-NOWの初期化とデータ受信コールバック設定 ...
}
void loop() {
// 親機側は無限ループでデータ受信を待機
delay(100);
}
4. まとめ:信頼性の向上
この改良により、あなたのワイヤレスドアセンサーは単なる開閉検知器ではなく、自己診断能力を持つ実用的なIoTデバイスに進化しました。電池寿命が尽きる前に警告を受け取れるため、セキュリティ機器としての信頼性が格段に向上します。