この投稿は書きかけです。
スケッチは参考程度に見てください。
動作時の電流を測定したので載せておきます。
待機時約84mA 赤外線受信Wi-Fi送信時ピーク約120mA sleep時約0.62mA
ポイント
赤外リモコン中継送信機の消費電力削減のために、
ESP32のDeep-sleep Modeを組み込みました。
XIAO ESP32C3でフィードバックLED点灯を断念し代用LEDをGPIO2に接続
#define LED_BUILTIN
でピン指定しても点きません。XIAO ESP32S3ではデフォルトのままでチカチカしてました。
タイトルでは"Wi-Fiで"と表現していますが、正しくは"ESP-NOW"です。
だれでもイメージしやすいように"Wi-Fiで"と表現しています。
SONY製レコーダーのリモコンモード変更設定可能台数不足解決、
同室複数SONY製テレビの赤外線リモコン操作での問題解決に役立ちます。
Tip
SONY新型テレビリモコン(一部機種)は、電源ボタンのみ赤外線で、
以外はbluetooth接続との情報です。
テレビ側設定でbluetoothをOFFで赤外線操作になるが
"googleアシスタント"はbluetooth接続要とのこと。
ちなみにbluetooth接続は、キッチンだと電子レンジの影響が出る可能性があります。
XIAO ESP32C3を使用しました。
Wakeupスイッチ・・・D1(GPIO3)とGND間にプッシュスイッチを接続
状態表示LED・・・D2(GPIO4)と3.3V間に抵抗とLEDを直列接続(抵抗は仮に1K点灯がわかれば良い)
IR_RECEIVE_PIN ・・・D8(GPIO8)
FEEDBACK LED代用・・・D0(GPIO2)をdigitalWrite()で(ESP32C3用)
D0(GPIO2)と3.3V間に抵抗とLEDを直列接続(抵抗は仮に1K点灯がわかれば良い)
ざっくり説明
IRremote、ESP32 ESPNow、ESP32 DeepSleep各exampleから
Seeed Studio wiki のXIAO ESP32C3 Getting Started のスケッチから
必要な部分を使用させていただきました。
DeepSleep組込前スケッチはこちらの記事を見てください
赤外線受信していないときsleep用カウンタを加算、
赤外線受信し"protocol == SONY"でカウンタクリア
カウント値が連続100,000,000回(仮)を超えたときに
"esp_deep_sleep_start()"でsleepする。
D1(GPIO3)プッシュスイッチでWeakup
電源表示LED 動作中点滅、sleep中消灯
ESP32C3でのFEEDBACK LED代用として
D0(GPIO2)をdigitalWrite()で点消灯している。
参考スケッチ
(XIAO ESP32S3では手直し必要、間違いや抜けがあるかも)
//オリジナル部分を省略して主に追加した部分を記述
#define IR_RECEIVE_PIN 8
#define ledPin 4 //sleep中 点滅LED
uint32_t sleepTime_RepeatCount = 0;
uint32_t detectionCount = 100000000; //delay(1)へ変更に伴う
//ESP-NOW Masterは赤外線リモコンを受信してESP-NOW Slaveへ送る
typedef struct struct_IRSendData {
char IR_protocol[10];//"SONY"の文字が入れば良い
uint16_t IR_address;
uint16_t IR_command;
uint8_t IR_repeat;
uint8_t IR_bit;
} struct_IRSendData;
struct_IRSendData IRSendData;
uint8_t irSendRepeatCount = 0;
uint32_t LastSendMillis = 0;
bool ledState = LOW; // sleep中 点滅LED
uint32_t blinkPreviousMillis = 0; // sleep中 点滅LED
const uint16_t blinkInterval = 1000; // sleep中 点滅LED
#include <IRremote.hpp>//"<"と">"は半角に直す
//中略
//以降はsetup()の中
//pinMode(LED_BUILTIN, OUTPUT);//XIAO ESP32S3
pinMode(ledPin, OUTPUT);//LED スリープ中消灯 動作中点滅する
pinMode(2, OUTPUT);//GPIO2(D0)//ESP32C3でFEEDBACK LED代用
digitalWrite(2, HIGH);//ESP32C3でFEEDBACK LED代用起動時点灯するので消しておくため
//LED 3.3V to ANODE ,GPIO2 to CATHODE
/*参考 esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask,
esp_deepsleep_gpio_wake_up_mode_t mode)*/
//wakeup設定部
esp_deep_sleep_enable_gpio_wakeup(BIT(D1), ESP_GPIO_WAKEUP_GPIO_LOW);
//mode -- Select logic function used to determine wakeup condition:
//ESP_GPIO_WAKEUP_GPIO_LOW: wake up when the gpio turn to low.
//ESP_GPIO_WAKEUP_GPIO_HIGH: wake up when the gpio turn to high.
/*ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORSはデフォルト有効
プルアップ、ダウン抵抗指定不要 外部で行う時は
ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS オプションを無効にとあったが
設定方法は見つからんかった*/
//中略
IrReceiver.begin(IR_RECEIVE_PIN)//XIAO ESP32C3の時
//IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);//XIAO ESP32S3
//setup()部分はここまで
loop(){
digitalWrite(2, HIGH);//XIAO ESP32C3でFEEDBACK LEDの代用
if (IrReceiver.decode()) { //赤外線
if (IrReceiver.decodedIRData.protocol == SONY) {
sleepTime_RepeatCount = 0;
Serial.println("sleepTime_RepeatCount clear");
//
strcpy(IRSendData.IR_protocol, "SONY");
IRSendData.IR_address = IrReceiver.decodedIRData.address;
IRSendData.IR_command = IrReceiver.decodedIRData.command;
IRSendData.IR_repeat = 2;//2で固定
IRSendData.IR_bit = IrReceiver.decodedIRData.numberOfBits;
//さっき送ったのと今送った時間差300mS以上のときにカウントをリセットする
uint32_t SendMillis = millis();
if (SendMillis - LastSendMillis >= 300) { //
irSendRepeatCount = 0;
}
/*Serial.print("irSendRepeatCount = "); Serial.println(irSendRepeatCount);*/
LastSendMillis = SendMillis;
//リモコンボタン押し時間が長め(**mS超え)の時 1発目送って少し待って(**mS)2発目送る
//以降は少ない待ち時間で繰り返し
if (irSendRepeatCount == 0 || irSendRepeatCount >= 10) {
sendData();//ESP-NOW
}
irSendRepeatCount++;//
} else if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
}
IrReceiver.resume();
//
digitalWrite(2, LOW);//ESP32C3でFEEDBACK LED代用
} else {
//
sleepTime_RepeatCount++;
//Serial.print("sleepTime_RepeatCount = "); Serial.println(sleepTime_RepeatCount);
delay(1); //修正して様子みる
if (sleepTime_RepeatCount >= detectionCount) { //uint32_t detectionCount no-operation-detection count
//Go to sleep now
Serial.println("Going to sleep now");
esp_deep_sleep_start();
} //if (sleepTime_RepeatCount・・・
} // } else {
//スリープ中以外にLEDを点滅する
uint32_t blinkCurrentMillis = millis();
if (blinkCurrentMillis - blinkPreviousMillis >= blinkInterval) {
blinkPreviousMillis = blinkCurrentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}//loop()
改善点が見つかればつづく