//outsideEPower.ino // // V1.1: リリース // // V1.0 deepSleepのみ // V1.1 light-sleep + deepSleep(リセットとして利用) // #include #include #include "BME280.h" //#define DEBUG true //基本シリアルメッセージ出力モード #define RESET_SECOND 3600 //hardware reset time #define LOGWT_SECOND (RESET_SECOND/3) //logging interval time(1200s) #define MTCHK_SECOND (RESET_SECOND/12) //check maintenance server mode(300s) //#define MTCHK_SECOND (RESET_SECOND/60) //DEBUG check maintenance server mode(300s) #define DELAY_SECOND (RESET_SECOND/60) //delay time(60s) #define SLEEP_SECOND 45 //deep sleep time(45s) #define FANUP_TEMP 35 //FAN on temperature #define FANDOWN_TEMP 33 //FAN off temperature //WiFi接続 #define HTTP_PORT 80 const char *WIFI_SSID = "xxxxxxxxxxxxxxx"; const char *WIFI_PWD = "xxxxxxxxxxxxxxx"; const char *HOST_NAME = "xxx.inoshita.jp"; const char *HOST_PATH = "/xxx/xxxxxxxxxx"; //ピン定義 #define PINFAN 12 //FAN control digital pin #define PINLED 13 //LED(test) on pin #define PINPWR 14 //5V Power off pin //デバイス定義 #define BME280_ADDRESS 0x76 //HTML #define HTML_HEADER ""\ ""\ ""\ "" #define HTML_FOOTER "" //WEBServerインスタンス ESP8266WebServer server(80); //BME280インスタンス BME280 bme280(BME280_ADDRESS //BME280 I2C ADDRESS , 0b0001 //Temperature oversampling : x1 , 0b0001 //Humidity oversampling : x1 , 0b0001 //Pressure oversampling : x1 , 0b0000 //Mode : Sleep mode(0), Normal mode(3) , 0b0101 //Stand-by time : 1000ms , 0b0000 //filter : 0ff ); static bool serverFlag = false; void deepSleep() { //1: μ秒での復帰までのタイマー時間設定 //2: 復帰するきっかけの設定(モード設定) //第1引数の時間設定はμ秒なので600秒(10分)後に復帰する設定になる //+nは(10分での)補正値 #ifdef DEBUG Serial.print("DEEP SLEEP : "); Serial.print(SLEEP_SECOND); Serial.println(" [s]"); #endif ESP.deepSleep((uint32_t )SLEEP_SECOND * 1000 * 1000 , WAKE_RF_DEFAULT); //deepsleepモード移行までのダミー命令 delay(1000); #ifdef DEBUG //実際には以降の行は実行されない Serial.println("DEEP SLEEPing...."); #endif } String clientRequest(String data) { //Requesting POST data WiFiClient client; if(!client.connect(HOST_NAME, HTTP_PORT)) { #ifdef DEBUG Serial.println("connection failed"); #endif return(String("NG")); } //Send request to the server client.println(String("POST ") + HOST_PATH + " HTTP/1.1"); client.println(String("Host: ") + HOST_NAME); client.println("Content-Type: application/x-www-form-urlencoded"); client.println("Content-Length: " + String(data.length())); client.println(); client.print(data); unsigned long timeout = millis(); while(!client.available()) { if(millis() - timeout > 5000) { #ifdef DEBUG Serial.println("time out failed"); #endif client.stop(); return(String("NG")); } } //HTTPヘッダを含むデータの読み取り(1文字毎) String str = ""; while(client.available()) { str = client.readStringUntil('\n'); } if(client.connected()) client.stop(); return(str); } //バッテリー電圧確認 //ESP8266の読み取り値は10ビットの0から1023の値でTOUT端子が1Vのとき1000となる //MAX16Vで分圧抵抗: 2.145kΩ, 32.76kΩ float getBatteryVolt() { return((float)system_adc_read() * (2.2 + 32.8) / 2.2 / 1023.0); } //ケース温度 //BMP280: 温度,湿度(BMPなので0%),気圧 double getCaseTemp() { double dTemperature, dHumidity, dPressure; bme280.getData(dTemperature, dHumidity, dPressure ); return(dTemperature); } void setup() { //スリープモードの選択 wifi_set_sleep_type(LIGHT_SLEEP_T); #ifdef DEBUG //シリアル通信の開始 Serial.begin(9600); delay(250); while(!Serial); #endif pinMode(PINFAN, OUTPUT); pinMode(PINLED, OUTPUT); pinMode(PINPWR, OUTPUT); //BME280の開始 bme280.begin(); //WiFi接続 #ifdef DEBUG Serial.print("Connecting to "); #endif WiFi.mode(WIFI_STA); //STA(子機)モード WiFi.begin(WIFI_SSID, WIFI_PWD); unsigned long timeout = millis(); while(WiFi.status() != WL_CONNECTED) { if(millis() - timeout > 30000) { #ifdef DEBUG Serial.println(" time out"); #endif deepSleep(); } delay(500); #ifdef DEBUG Serial.print("."); #endif } #ifdef DEBUG Serial.print("WiFi connected.\nIP address: "); Serial.println(WiFi.localIP()); #endif for(int second = 0; second < RESET_SECOND; second += DELAY_SECOND) { float vbat = getBatteryVolt(); double temp = getCaseTemp(); #ifdef DEBUG //センサー読み取りデータのシリアル表示 Serial.println("=============="); Serial.print("- Second : "); Serial.println(second); Serial.print("- temperature : "); Serial.print(temp); Serial.println(" [DegC]"); Serial.print("- Battery : "); Serial.print(vbat); Serial.println(" [V]"); Serial.println("=============="); #endif if(temp > FANUP_TEMP) digitalWrite(PINFAN, HIGH); if(temp < FANDOWN_TEMP) digitalWrite(PINFAN, LOW); String para = ""; if(second % LOGWT_SECOND == 0) { //write logging // WiFi.localIP()はIP class -> String にするならWiFi.localIP().toString() // -> char * にするならWiFi.localIP().toString().c_str() para = "BVOLT=" + String(vbat) + "&UTEMP=" + String(temp) + "&STLOG=1"; } else if(second % MTCHK_SECOND == 0) { //server mode check para = "STLOG=0"; } if(para != "") { #ifdef DEBUG Serial.println(para); Serial.println("=============="); #endif String rstr; if((rstr = clientRequest(para)) == "NG") { #ifdef DEBUG Serial.println("connection failed"); #endif deepSleep(); } #ifdef DEBUG Serial.println(rstr); Serial.println("=============="); #endif if(rstr == "MT") { #ifdef DEBUG Serial.println("server mode"); #endif //メンテナンスモード para = "IPADR=" + WiFi.localIP().toString(); if(clientRequest(para) == "NG") { #ifdef DEBUG Serial.println("connection failed 2"); #endif deepSleep(); } serverMode(); para = "IPADR=255"; if(clientRequest(para) == "NG") { #ifdef DEBUG Serial.println("connection failed 3"); #endif deepSleep(); } #ifdef DEBUG Serial.println("server end"); #endif // WiFi.mode(WIFI_STA); //STA(子機)モード } } #ifdef DEBUG Serial.println("delay"); #endif delay(1000 * DELAY_SECOND); } WiFi.disconnect(); deepSleep(); } void serverMode() { serverFlag = true; //Setup WebServer Handlers //TEST Function server.on("/", [](){ String html = HTML_HEADER "

NodeMCU!

" HTML_FOOTER; server.send(200, "text/html", html); }); server.on("/led/on", [](){ digitalWrite(PINLED, HIGH); String html = HTML_HEADER "

LED ON

" HTML_FOOTER; server.send(200, "text/html", html); }); server.on("/led/off", [](){ digitalWrite(PINLED, LOW); String html = HTML_HEADER "

LED OFF

" HTML_FOOTER; server.send(200, "text/html", html); }); server.on("/fan/on", [](){ digitalWrite(PINFAN, HIGH); String html = HTML_HEADER "

FAN ON

" HTML_FOOTER; server.send(200, "text/html", html); }); server.on("/fan/off", [](){ digitalWrite(PINFAN, LOW); String html = HTML_HEADER "

FAN OFF

" HTML_FOOTER; server.send(200, "text/html", html); }); //Client Function server.on("/power/reset", [](){ //10秒間電源切断して投入 String html = HTML_HEADER "

POWER RESET

" HTML_FOOTER; server.send(200, "text/html", html); digitalWrite(PINPWR, HIGH); delay(10000); digitalWrite(PINPWR, LOW); }); server.on("/server/status", [](){ float vbat = getBatteryVolt(); double temp = getCaseTemp(); String html = String(HTML_HEADER) + String("

") + String(vbat) + String("V, ") + String(temp) + String("℃

") + String(HTML_FOOTER); server.send(200, "text/html", html); }); server.on("/server/end", [](){ String html = HTML_HEADER "

Server End

" HTML_FOOTER; server.send(200, "text/html", html); delay(2000); serverFlag = false; }); server.begin(); while(serverFlag) { server.handleClient(); } server.stop(); server.close(); } void loop() {}