スケッチ改変ポイントなどを説明してみようかと思いました。
間違い、文字化け、抜けがあるかもしれません。
素晴らしいライブラリ、サンプルスケッチを公開してくださっている方々に感謝します。
赤外線送信したいコントロール内容を、簡単テキストファイルでSDに保存しておきます。
"コントロール実行(赤外線送信)せよ"と命令来たら、読み込んで赤外線リモコン信号送信します。#include "FS.h"
#include "SD.h"
#include "SPI.h"
中略
uint16_t IRco[20][5];
uint8_t NOIRCO = 0;//Number of IR control operations
中略
if (!SD.begin(44)) { //XIAO ESP32S3 GPIO44/D7
Serial.println("Card Mount Failed");
return;
}
void readFile(fs::FS &fs, const char * path) {
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println("Failed to open file for reading");
return;
}//2次元配列の型とサイズ uint16_t IRco[20][5];//[行][列] 横書きフォーマット
Serial.print("Read from file: ");
while (file.available()) {
//Serial.write(file.read());
String line = file.readStringUntil('\n');//終端文字'\n'が検出されるまで読んで文字列全体をlineへ入れる
line = line.substring(0, line.indexOf('#'));//インデックス0(行頭)から(#までのインデックス数)の文字列取得
//uint8_t NOIRCO = 0;//設定ファイルでは省略してNCOとしました。コントロールの数 Number of IR control operations
if (line.substring(0, 3) == "NCO") { //開始位置(0)は含むが終了位置(3)は含まれない
String NCO = line.substring(4, 6);//String変数名も設定ファイルと同じNCOとしました。
NCO.trim();//スペース等を除去
NOIRCO = NCO.toInt();
Serial.println("NOIRCO = ");
Serial.println(NOIRCO);
} else if (line.substring(0, 3) == "C00") { //開始位置(0)は含むが終了位置(3)は含まれない
String command0_0 = line.substring(4, 8); //address
command0_0.trim();//スペース等を除去
IRco[0][0] = strtol(command0_0.c_str(), NULL, 16);//address uint16_t
String command0_1 = line.substring(9, 11);//command uint8_t
IRco[0][1] = strtol(command0_1.c_str(), NULL, 16);//.toInt();
//repeatは2固定のようなので省略しようと思う
String command0_2 = line.substring(12, 14);//Bit
IRco[0][2] = command0_2.toInt();
String command0_3 = line.substring(15, 20);//interval
command0_3.trim();//スペース等を除去
IRco[0][3] = command0_3.toInt();
} else if (line.substring(0, 3) == "C01") {
中略
} else if (line.substring(0, 3) == "C09") {
String command9_0 = line.substring(4, 8); //address
command9_0.trim();//スペース等を除去
IRco[9][0] = strtol(command9_0.c_str(), NULL, 16);//address uint16_t
String command9_1 = line.substring(9, 11);//command uint8_t
IRco[9][1] = strtol(command9_1.c_str(), NULL, 16);//.toInt();
String command9_2 = line.substring(12, 14);//Bit
IRco[9][2] = command9_2.toInt();
String command9_3 = line.substring(15, 20);//interval
command9_3.trim();//スペース等を除去
IRco[9][3] = command9_3.toInt();
}
}
file.close();
中略
void loop() {
中略
//"SimpleWiFiServer"スケッチへの改変部分です
//クライアントのリクエストが "GET /H "か "GET /L "かをチェックする:Check to see if the client request was "GET /H" or "GET /L":
if (currentLine.endsWith("GET /H")) {
//digitalWrite(5, HIGH); // GET /H turns the LED off
/*ユーザー様の環境に合わせてカスタマイズできるように、
SDメモリに赤外線コード、インターバル時間、送信順序を記述したファイルで設定する*/
//sendSony()関数へ与える引数の型は次の通りです。
//sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
// uint8_t numberOfBits)
/*備忘記 2次元配列 IRco[0][0] //uint8_t NOIRCO = ;*/
CheckTVpower();//GPIO13がLOWの時TVがONしていると検出し"TV_Pon"を"1"にする
//TV電源ONから開始するときはi=0、すでにONしている時はi=1とすれば良いのでは
//TV電源ONのときTV_Ponは"1"
for (uint8_t i = TV_Pon; i < NOIRCO; i++) { //Number of IR control operations
//for (uint8_t i = 0; i < NOIRCO; i++) { //Number of IR control operations
IrSender.sendSony(IRco[i][0], (uint8_t)IRco[i][1] , 2, IRco[i][2]); //POWER ON-OFF
//POWER ONから次の操作を受け付けるまでの待ち時間
delay(IRco[i][3]);
}
関数 bool CheckTvpower()//Check the TV power 電源がONしている時はONのコントロールを省略する7
bool CheckTVpower() {
TV_Pon = !(digitalRead(TV_PowDet_PIN));//TVonのときLOW("0")なので反転して使う
//uint8_t TV_Pon = 0;//"1"でTV電源がONしている
//Serial.print("Check TV power = ");
if (TV_Pon) {
//Serial.println("ON");
return 1;
} else {
//Serial.println("OFF");
return 0;
}
}
素人の書いたコードですが、少しでも参考になればと思います。
終わりかな
スケッチ改変ポイントなどを説明してみようかと思いました。
間違い、文字化けがあるかもしれません。
素晴らしいライブラリ、サンプルスケッチを公開してくださっている方々に感謝します。
Wi-Fi接続と固定IPアドレス設定のために"WiFiManager"ライブラリの
"Advanced"サンプルスケッチで設定したIPAddress、Gateway、Subnetを
(Gatewey、Subnetは不要かもしれない)EEPROMへ保存している。
SSIDとPASSWORDは初回設定後引数指定せずにWiFi.begin();
としてESP32内部に保存された前回WiFi認証情報を使って接続する。#define INI_SETUP_PIN 15 //ESP32 DEV Module INPUT_PULLUP
中略
EEPROMへのデータ保存準備//>>> EEPROM put アドレスを指定する
//なぜかEEPROM_SSID_ADDRESS 0のデータだけ電源OFF-ONで化けるので使っていない
#define EEPROM_SSID_ADDRESS 0 //使っていないが削除して不具合が出ないか心配で残してある
#define EEPROM_PASS_ADDRESS 32 //使っていないが削除して不具合が出ないか心配で残してある
#define EEPROM_IP_ADDRESS 64
#define EEPROM_GATEWAY 96
#define EEPROM_SUBNET 128 // 1アドレスに1byte
String savedSSID;//それぞれの情報が入る変数
String savedPassword;
IPAddress savedIP; //IPAddress型
IPAddress savedGateway;
IPAddress savedSubnet;
//<<< EEPROM PUT //>>>> EEPROM setup
Serial.println("\nTesting EEPROM Library\n");
if (!EEPROM.begin(512)) { //512byte
Serial.println("Failed to initialise EEPROM");//"EEPROMの初期化に失敗しました"
Serial.println("Restarting...");//再起動せずにLEDを高速点滅して停止
delay(1000);
Serial.println("stop...");
while (1) {
// LEDを高速点滅する
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
//ESP.restart();//これで再起動もできますが、再起動で解決できないことが多いかも
} else {
Serial.println("EEPROM Library Test OK ");
} //<<<< EEPROM setup
GPIO15がHIGHの時 EEPROMに保存したWiFi認証&IP情報で接続する。
GPIO15がLOWの時 強制的にconfigPortalを起動して設定&接続する。if (digitalRead(INI_SETUP_PIN) == HIGH) { //GPIO15(INPUT_PULLUP)HIGHの時はEEPROMからGETした情報でWiFi接続する
//LOWのときはconfigPortalを起動してWiFi認証、接続情報設定する
Serial.println("Previous WiFi authentication and connection with IP address in EEPROM");
//"以前のWiFi認証とEEPROM内のIPアドレスによる接続"
eepromGetData(); // EEPROMから保存済のIPアドレスを各変数へ読み込む(WiFi認証情報は未使用)
IPAddress dns1 = savedGateway;//dns1はGateweyと同じなので代入
WiFi.config(savedIP, savedGateway, savedSubnet, dns1);//ESP 引数順序厳守 NTPサーバ名アクセス時dns1要
WiFi.begin();// ESP32内部に保存された前回WiFi認証情報(SSID、PASSWORD)を使って接続する
//>>> 2024.01.29
Serial.print("Connecting to WiFi");
uint8_t i = 0;
while (WiFi.status() != WL_CONNECTED && i++
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
digitalWrite(LED_BUILTIN, LOW);
delay(250);
//delay(500);
Serial.print(i); //Serial.print(".");
}/* while(WiFi.status() != WL_CONNECTED &&...*/
//Serial.println(i);
if (i >= 20) { //iが20以上の時はWiFi認証情報に問題があると思われるのでconfigPortalを起動して設定し直す
Serial.println("Connection Failed!");
//wm.resetSettings();// wipe settings
//ESP.restart(); //ESP32を再起動
//<<
startConfigPortal();//configPortal起動 関数にしてみました
} /*if (i >= 20)*/
} else { //if (INI_SETUP_PIN == HIGH)//GPIO15がHIGHじゃない時
//>>>> WiFiManagerのconfigPortalで接続設定 //関数化する
startConfigPortal();//configPortal起動 関数にしてみました
}
それぞれの関数は適切な位置へ挿入してください。
関数startConfigPortal()
configPortalの一部分を関数化したものです。
"WiFiManager"ライブラリの
"Advanced"サンプルスケッチの改変部分だけ記載しています。void startConfigPortal() {
中略
//set static ip固定IPアドレスをセットする ここに書いたアドレスがデフォルト設定として表示されます。
wm.setSTAStaticIPConfig(IPAddress(192, 168, 2, 100), IPAddress(192, 168, 2, 1), IPAddress(255, 255, 255, 0)); // set static ip,gw,sn
中略
//bool res;
// res = wm.autoConnect(); //chipidからAP名を自動生成 auto generated AP name from chipid
// res = wm.autoConnect("AutoConnectAP"); //匿名AP anonymous ap
//res = wm.autoConnect("AutoConnectAP","password"); //パスワードで保護されたAP password protected ap
/*if(!res) { //戻り値が"false"接続失敗 (res = wm.autoConnect()使用時)
Serial.println("Failed to connect or hit timeout");
//ESP.restart();
} else {
//ここまで来れば、WiFiに接続したことになる。 if you get here you have connected to the WiFi
Serial.println("connected...yeey :)??");
}*/
/*暫定的に無効化するため関数にして移動した*/
// start portal w delay
Serial.println("Starting config portal");
wm.setConfigPortalTimeout(120);
if (!wm.startConfigPortal("OnDemandAP", "password")) {
Serial.println("failed to connect or hit timeout");
delay(3000);
// ESP.restart();
} else {
//if you get here you have connected to the WiFi
Serial.println("now connected...yeey :)");
eepromPutData();
//WiFi認証情報と静的IP設定を保存 関数名変更SaveConfigCallbackをeepromPutDataへ
}
eepromGetData(); // EEPROMから(保存済の?)WiFi認証とIPアドレスをそれぞれの変数へ読み込む
} //<<<
関数eepromGetData()//EEPROMからWiFi認証(保存NGだった)とIPアドレスをそれぞれの変数へ読み込む
void eepromGetData() {
//EEPROM.get(EEPROM_SSID_ADDRESS, savedSSID);//SSIDが電源ON-OFFで化けるため使用中止した
//EEPROM.get(EEPROM_PASS_ADDRESS, savedPassword);//SSID、PASSWORDは設定すると記憶される基本的な機能を活用
EEPROM.get(EEPROM_IP_ADDRESS, savedIP);
EEPROM.get(EEPROM_GATEWAY, savedGateway);
EEPROM.get(EEPROM_SUBNET, savedSubnet);
}
関数eepromPutData () は設定が終わったIPアドレスをESP32のEEPROMへ保存します。
WiFi認証情報の保存、読み出しはうまく行かなかった。 void eepromPutData () {
//関数名変更SaveConfigCallbackをeepromPutDataへ
Serial.println("Save button pressed, saving WiFi credentials and static IP configuration...");
//"保存ボタンが押され、WiFi認証情報と静的IP設定が保存されました..."
EEPROM.put(EEPROM_SSID_ADDRESS, WiFi.SSID());//SSIDはEEPROM保存しているが使っていない
EEPROM.put(EEPROM_PASS_ADDRESS, WiFi.psk());//PASSWORD(psk)はEEPROM保存しているが使っていない
EEPROM.put(EEPROM_IP_ADDRESS, WiFi.localIP());
EEPROM.put(EEPROM_GATEWAY, WiFi.gatewayIP());
EEPROM.put(EEPROM_SUBNET, WiFi.subnetMask());
EEPROM.commit();
}
だんだんわからんなってきた
つづく
"SimpleWiFiServer"
"IRremote"ライブラリの"SendRawDemo"
受信したデータを赤外線リモコン信号にしてテレビへ送信する