祖父の家のエアコンを自動化した話
経緯
祖父が隣で一人暮らしをしていた
歳をとると温度の認知機能も狂ってくるようで明らかに寒すぎたり暑すぎたりすることが増えた
そこで既存のエアコンの設定温度を自動的に調整したいとなった。 方針
時刻情報も加味して朝夕のOnOffも切り替える
準備
実装
材料
開発ボードを使うと良い
温度センサ
湿度とかも取りたいなら
赤外線LED
抵抗
LED用に
プルアップとか必要なら
2SC1815
高輝度なLED使いたいなら
完成
ボード取り付け時
https://gyazo.com/ca6986c24f4caa02dfe6e80a00cb6b4d
ボード取り外し時
https://gyazo.com/e62de77d8812368d7f0cc418a0389901
コード例
code:auto.ino
extern "C" {
}
int ir_out_pin = 13;
int Year;
int Month;
int Day;
int Hour;
bool isOn;
bool isBoost;
unsigned int w21228 = {348, 175, 43, 130, 41, 127, 42, 41, 44, 43, 44, 42, 42, 125, 44, 43, 41, 42, 44, 128, 43, 125, 44, 43, 43, 125, 46, 42, 44, 40, 44, 126, 43, 127, 46, 42, 43, 127, 43, 127, 43, 42, 44, 42, 43, 127, 44, 40, 43, 42, 45, 127, 43, 41, 43, 44, 42, 40, 45, 41, 46, 39, 44, 41, 44, 41, 45, 40, 45, 41, 43, 39, 46, 40, 46, 40, 45, 39, 46, 40, 44, 41, 43, 41, 44, 41, 44, 125, 46, 39, 45, 40, 45, 125, 45, 38, 46, 40, 44, 126, 44, 39, 45, 40, 45, 38, 46, 40, 44, 38, 45, 41, 44, 40, 43, 40, 44, 127, 43, 40, 44, 125, 46, 40, 44, 40, 44, 41, 44, 40, 44, 41, 44, 40, 43, 40, 44, 40, 43, 41, 44, 40, 43, 42, 44, 40, 43, 42, 42, 42, 43, 41, 43, 40, 44, 42, 43, 41, 43, 42, 43, 40, 44, 43, 42, 41, 43, 42, 43, 41, 43, 41, 43, 42, 42, 42, 43, 41, 42, 41, 44, 42, 43, 42, 43, 40, 43, 43, 42, 42, 42, 43, 42, 40, 43, 42, 43, 41, 43, 43, 42, 41, 43, 44, 41, 42, 41, 42, 42, 42, 42, 43, 42, 42, 42, 127, 43, 43, 42, 40, 44, 43, 42, 128, 42, 41, 42}; unsigned int w24228 = {348, 172, 46, 129, 43, 124, 44, 40, 44, 42, 44, 42, 44, 126, 44, 42, 42, 41, 44, 128, 43, 129, 43, 40, 43, 127, 45, 42, 43, 40, 43, 127, 43, 127, 45, 43, 43, 128, 42, 128, 42, 41, 44, 41, 44, 128, 42, 42, 45, 39, 44, 128, 43, 40, 44, 43, 42, 42, 45, 42, 43, 40, 44, 42, 43, 41, 44, 41, 44, 41, 44, 41, 44, 41, 46, 39, 43, 42, 43, 41, 42, 43, 41, 42, 42, 43, 42, 126, 44, 41, 43, 43, 42, 127, 43, 42, 42, 43, 42, 126, 44, 41, 45, 42, 42, 42, 40, 43, 44, 40, 43, 43, 40, 43, 41, 128, 42, 128, 42, 128, 42, 42, 41, 42, 41, 43, 43, 41, 43, 41, 43, 40, 45, 41, 43, 39, 44, 42, 44, 40, 43, 41, 44, 42, 43, 40, 44, 40, 44, 36, 48, 41, 42, 41, 44, 41, 44, 42, 42, 41, 43, 41, 43, 41, 41, 44, 42, 42, 41, 42, 41, 43, 41, 44, 41, 42, 41, 44, 42, 42, 41, 44, 42, 41, 42, 42, 42, 43, 42, 44, 40, 42, 42, 44, 41, 42, 42, 43, 42, 43, 42, 43, 42, 43, 41, 42, 42, 41, 43, 44, 42, 128, 42, 41, 43, 43, 42, 41, 42, 42, 42, 40, 44, 127, 42, 42, 42}; unsigned int c27228 = {348, 171, 47, 127, 43, 127, 43, 40, 44, 40, 46, 40, 45, 125, 47, 39, 45, 39, 47, 126, 44, 125, 45, 41, 44, 125, 47, 39, 45, 39, 45, 125, 46, 125, 46, 40, 45, 124, 46, 126, 44, 40, 46, 41, 44, 123, 47, 39, 45, 40, 48, 123, 47, 38, 45, 40, 46, 39, 46, 39, 47, 40, 43, 41, 45, 40, 46, 39, 46, 39, 46, 38, 46, 40, 48, 39, 44, 40, 45, 39, 44, 41, 46, 38, 44, 41, 44, 125, 45, 40, 44, 40, 45, 123, 47, 38, 46, 39, 46, 122, 47, 125, 44, 40, 44, 40, 46, 40, 43, 38, 47, 40, 43, 40, 45, 40, 44, 40, 46, 125, 44, 40, 44, 39, 46, 40, 43, 40, 45, 40, 43, 41, 46, 39, 43, 40, 45, 41, 42, 41, 44, 40, 44, 41, 44, 41, 43, 41, 45, 38, 45, 41, 45, 39, 44, 41, 45, 41, 43, 40, 46, 40, 43, 41, 44, 41, 43, 41, 43, 41, 43, 41, 44, 42, 42, 41, 45, 41, 43, 42, 43, 41, 42, 43, 43, 40, 42, 41, 45, 41, 42, 42, 43, 42, 42, 42, 42, 41, 42, 41, 44, 42, 41, 42, 43, 43, 40, 43, 42, 41, 41, 43, 43, 41, 41, 43, 42, 42, 42, 43, 42, 43, 40, 129, 42, 42, 43}; unsigned int c25228 = {346, 174, 46, 128, 40, 127, 44, 41, 42, 45, 43, 41, 43, 129, 41, 43, 41, 43, 42, 130, 42, 128, 41, 44, 41, 130, 43, 44, 42, 39, 44, 127, 43, 126, 45, 44, 42, 127, 44, 126, 44, 41, 45, 42, 42, 129, 42, 44, 42, 41, 44, 128, 42, 41, 44, 42, 42, 40, 46, 43, 42, 41, 43, 43, 42, 41, 46, 40, 44, 41, 44, 41, 42, 42, 43, 43, 42, 43, 41, 43, 42, 42, 44, 40, 43, 42, 43, 127, 45, 39, 43, 42, 42, 128, 42, 40, 43, 43, 43, 128, 41, 125, 46, 41, 44, 40, 43, 42, 43, 40, 44, 40, 45, 41, 44, 39, 45, 125, 45, 125, 45, 41, 44, 40, 45, 39, 43, 42, 45, 39, 44, 39, 45, 39, 45, 41, 44, 41, 44, 40, 44, 41, 41, 42, 44, 40, 42, 43, 44, 41, 41, 43, 43, 41, 42, 41, 43, 41, 41, 42, 42, 42, 43, 41, 43, 42, 42, 40, 44, 42, 42, 41, 44, 42, 41, 42, 44, 40, 44, 41, 43, 41, 43, 42, 42, 42, 42, 42, 42, 42, 42, 41, 43, 42, 42, 43, 42, 43, 41, 42, 42, 41, 43, 42, 42, 41, 42, 41, 44, 42, 42, 42, 42, 127, 43, 41, 43, 43, 42, 42, 41, 42, 43, 127, 42, 43, 41}; unsigned int off228 = {346, 176, 43, 128, 43, 128, 42, 43, 41, 44, 42, 42, 42, 129, 42, 42, 43, 43, 43, 129, 41, 129, 41, 41, 43, 128, 43, 44, 42, 42, 42, 127, 44, 126, 44, 43, 43, 127, 43, 127, 45, 40, 45, 42, 43, 128, 42, 44, 40, 42, 43, 129, 43, 42, 43, 41, 41, 42, 43, 44, 42, 41, 42, 43, 42, 41, 46, 41, 42, 42, 40, 45, 41, 43, 43, 44, 42, 44, 40, 42, 43, 43, 40, 43, 44, 41, 41, 42, 43, 42, 43, 42, 43, 127, 43, 42, 42, 41, 44, 128, 42, 43, 41, 41, 42, 44, 41, 41, 44, 42, 42, 42, 43, 42, 41, 44, 42, 128, 44, 42, 42, 129, 41, 42, 43, 43, 42, 42, 42, 44, 41, 42, 42, 42, 43, 42, 42, 42, 42, 42, 43, 42, 41, 42, 43, 42, 42, 42, 42, 44, 39, 44, 44, 43, 40, 41, 45, 42, 41, 42, 43, 44, 41, 43, 43, 43, 41, 41, 44, 42, 41, 42, 44, 42, 41, 42, 44, 41, 42, 40, 45, 43, 41, 42, 43, 42, 41, 42, 42, 43, 42, 43, 43, 42, 41, 42, 43, 41, 42, 42, 43, 41, 42, 43, 43, 43, 40, 43, 43, 42, 41, 42, 44, 43, 41, 42, 44, 42, 45, 50, 50, 50, 50, 91, 43, 42, 43}; void setup() {
Serial.begin(115200);
Serial.println();
pinMode(ir_out_pin, OUTPUT);
isOn = false;
isBoost = false;
// 自分のネットワークに合わせてください
WiFi.begin("XXXXXXXXXXXXX", "xxxxxxxxxxxxx");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// 初期化
// 2390 はローカルのUDPポート。空いている番号なら何番でもいいです。
ntp_begin(2390);
// NTPサーバを変更 (デフォルト: ntp.nict.jp)
setTimeServer("s2csntp.miz.nao.ac.jp");
// NTP同期間隔を変更 (デフォルト: 300秒)
setSyncInterval(10);
}
void getTime() {
time_t n = now();
time_t t;
const char* format = "%04d-%02d-%02d %02d:%02d:%02d";
// JST
t = localtime(n, 9);
sprintf(s, format, year(t), month(t), day(t), hour(t), minute(t), second(t));
Serial.print("JST : ");
Serial.println(s);
Year = year(t);
Month = month(t);
Day = day(t);
Hour = hour(t);
}
float getTemp() {
float val = system_adc_read();
float temp = val * 100 / 1024;
return temp;
}
void sendSignal(unsigned int data[]) {
for (int cnt = 0; cnt < 512; cnt++) {
unsigned long len = datacnt * 10; // dataは10us単位でON/OFF時間を記録している if (len == 0) break; // 0なら終端。
unsigned long us = micros();
do {
digitalWrite(ir_out_pin, 1 - (cnt & 1)); // iが偶数なら赤外線ON、奇数なら0のOFFのまま
delayMicroseconds(8); // キャリア周波数38kHzでON/OFFするよう時間調整
digitalWrite(ir_out_pin, 0);
delayMicroseconds(7);
} while (long(us + len - micros()) > 0); // 送信時間に達するまでループ
}
Serial.print("OK\n");
}
void loop() {
getTime();
if (!isOn) {
if (getTemp() <= 19 && !isBoost) {
if (Hour >= 6 && Hour < 8) {
sendSignal(w24);
isBoost = true;
isOn = false;
} else if (Hour >= 21 && Hour < 23) {
sendSignal(w24);
isBoost = true;
isOn = false;
}
} else if (getTemp() <= 23 && !isBoost) {
if (Hour >= 6 && Hour < 8) {
sendSignal(w21);
isOn = true;
} else if (Hour >= 21 && Hour < 23) {
sendSignal(w21);
isOn = true;
}
} else if (getTemp() > 23 && getTemp() < 26 && isBoost) {
sendSignal(w21);
isBoost = false;
isOn = true;
} else if (getTemp() < 31 && getTemp() > 28 && isBoost) {
sendSignal(c27);
isBoost = false;
isOn = true;
} else if (getTemp() >= 31 && !isBoost) {
if (Hour >= 6 && Hour < 8) {
sendSignal(c27);
isOn = true;
} else if (Hour >= 21 && Hour < 23) {
sendSignal(c27);
isOn = true;
}
} else if (getTemp() >= 34 && !isBoost) {
if (Hour >= 6 && Hour < 8) {
sendSignal(c25);
isBoost = true;
isOn = false;
} else if (Hour >= 21 && Hour < 23) {
sendSignal(c25);
isBoost = true;
isOn = false;
}
}
} else {
if (getTemp() > 26 && getTemp() < 28) {
sendSignal(off);
isOn = false;
} else if (Hour >= 23) {
sendSignal(off);
isOn = false;
} else if (Hour == 8) {
sendSignal(off);
isOn = false;
}
}
Serial.println(getTemp());
Serial.println(isOn);
Serial.println(isBoost);
delay(5000);
}
注意点
ESP8266でアナログ入力を見るにはTOUTピンを見るしかない
このTOUTピンは0V~1Vを1024段階で読み取れる
system_adc_read()で読める
時間について
ESPは簡単にhttpを投げられるのでNTPを毎回叩くことにしています。