//nodeMCU v1.0 (black) with Arduino IDE //stream temperature data DS18B20 with 1wire on ESP8266 ESP12-E (nodeMCU v1.0) //Temperature measurement //Timer switch with 4 timers //switch temperature dependend as well //publish temperature data to thingspeak #include #include #include #include //Time stuff #include #include //file system #include "FS.h" //webserver #include #include #include #include #include #include ESP8266WebServer server(80); MDNSResponder mdns; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 7200, 600000); String webPage, webPage1, webPage2; int count = 0; int WFTMP = 1; int gpio0_pin = 0; int gpio2_pin = 12; //time stuff uint32_t currentMillis = 0; uint32_t previousMillis = 0; //webserver //Def #define myPeriodic 600 // in sec | Thingspeak pub is 10 min #define ONE_WIRE_BUS 2 // DS18B20 on arduino pin2 corresponds to D4 on physical board OneWire oneWire(ONE_WIRE_BUS); DallasTemperature DS18B20(&oneWire); float prevTemp = 0; float SwitchTemp1, SwitchTemp2; const char* IOTserver = "api.thingspeak.com"; String apiKey = "your api"; //String MY_SSID = "your ssid"; //String MY_PWD = "you pwd"; String tempC; String tempV; String tempW, CURR_time, CURR_day, TEMP1_SET, TEMP2_SET, TON_HR_set, TOFF_HR_set, TON_MIN_set, TOFF_MIN_set, T_DAY_set; int sent = 0; char temperatureString[6]; float temp; String tmax_state; String tmin_state; String TON_HR_ARR; String TOFF_HR_ARR; String TON_MIN_ARR; String TOFF_MIN_ARR; String T_DAY_ARR; String TON[4], TOFF[4]; String TDAY[4][7]; //String TIMER_SET; String TIMER_SET = "OFF" ; void setup() { //webserver WiFi.mode(WIFI_STA); // preparing GPIOs and set to low only one is used so far pinMode(gpio0_pin, OUTPUT); pinMode(gpio2_pin, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); webPage1 = ""; webPage1 += "\n"; webPage1 += "\n"; webPage1 += "\n"; webPage1 += " Circulation Pump \n"; webPage1 += " \n"; webPage1 += " \n"; webPage1 += ""; webPage1 += ""; //webPage1 +=""; webPage1 += "

Circulation Pump

"; webPage1 += " "; webPage1 += "

"; webPage2 = ""; //webPage2 +="
"; webPage2 += " "; webPage2 += " Temperature Maximum"; webPage2 += "

"; webPage2 += " "; webPage2 += " "; webPage2 += "

"; webPage2 += " Temperature Minimum"; webPage2 += "

"; webPage2 += " "; webPage2 += " "; webPage2 += "

"; webPage2 += "
"; webPage2 += "
"; webPage2 += "

Pump ON/OFF "; webPage2 += "

"; webPage2 += "
"; webPage2 += "
"; webPage2 += "

RESET WIFI Connection

"; webPage2 += "

Connect to 192.168.4.1 after reset

"; webPage2 += "
"; webPage2 += " \n"; webPage2 += "\n"; webPage2 += "\n"; //SettingsRemove(); bool result = SPIFFS.begin(); Serial.println("SPIFFS opened: " + result); File f2 = SPIFFS.open("/t.txt", "r"); if (!f2) { tmax_state = "36"; tmin_state = "24"; TON_HR_ARR = "12,12,12,12"; TOFF_HR_ARR = "13,13,13,13"; TON_MIN_ARR = "31,32,33,34"; TOFF_MIN_ARR = "41,42,43,44"; T_DAY_ARR = "ON,ON,ON,ON,ON,OFF,OFF,ON,ON,ON,ON,ON,OFF,OFF,OFF,OFF,OFF,OFF,OFF,ON,ON,OFF,OFF,OFF,OFF,OFF,ON,ON"; // MY_SSID = "your ssid"; // MY_PWD = "your pwd"; SettingsWrite(); Serial.println("Test file open failed"); } f2.close(); SettingsRead(); connectWifi(); timeClient.begin(); timeClient.update(); GetSWtime(); GetSWday(); webpagebuild(); } void loop() { gettemperature(); checkOST(); CURR_time = timeClient.getFormattedTime(); CURR_time.remove(CURR_time.length() - 3); CURR_day = timeClient.getDay(); for (int i = 0; i < 4 ; i++) { if (CURR_time == TON[i] && TDAY[i][timeClient.getDay()] == "ON") { Serial.println("switch on the shit" ); TIMER_SET = "ON"; } if (CURR_time == TOFF[i] && TDAY[i][timeClient.getDay()] == "ON") { Serial.println("switch off the shit" ); TIMER_SET = "OFF"; } } // Turn the LED on (Note that LOW is the voltage level if (temp <= SwitchTemp2 && WFTMP == 1 && TIMER_SET == "ON") { WFTMP = 0; digitalWrite(LED_BUILTIN, LOW); digitalWrite(gpio2_pin, HIGH); } // Turn the LED off (Note that HIGH is the voltage level if ((temp >= SwitchTemp1 && WFTMP == 0 && TIMER_SET == "ON") or TIMER_SET == "OFF" ) { WFTMP = 1; digitalWrite(LED_BUILTIN, HIGH); digitalWrite(gpio2_pin, LOW); } server.handleClient(); count++ ; if (count == myPeriodic) { sendTeperatureTS(temp); count = 0; } delay(1000); } void webpagebuild() { tmax_state.trim(); tmin_state.trim(); TON_HR_ARR.trim(); TON_MIN_ARR.trim(); TOFF_HR_ARR.trim(); TOFF_HR_ARR.trim(); TOFF_MIN_ARR.trim(); T_DAY_ARR.trim(); TIMER_SET.trim(); webPage = ""; webPage += webPage1; webPage += "

" + tempC + " °C

"; webPage += ""; webPage += webPage2; } void GetSWtime() { for ( int k = 0; k < 4 ; k++ ) { String st1 = getStringPartByNr(TON_HR_ARR, ',', k); String st2 = getStringPartByNr(TON_MIN_ARR, ',', k); String st3 = getStringPartByNr(TOFF_HR_ARR, ',', k); String st4 = getStringPartByNr(TOFF_MIN_ARR, ',', k); if (st1.length() == 1) { st1 = "0" + st1; } if (st2.length() == 1) { st2 = "0" + st2; } if (st3.length() == 1) { st3 = "0" + st3; } if (st4.length() == 1) { st4 = "0" + st4; } TON[k] = st1 + ":" + st2; TOFF[k] = st3 + ":" + st4; // Serial.println(k); // Serial.println("On time " + st1 + ":" + st2 +" Off time " + st3 + ":" + st4 ); } } void GetSWday() { int n = 0; int j = 0; for ( int k = 0; k < 28 ; k++ ) { String st5 = getStringPartByNr(T_DAY_ARR, ',', k); //the ifs were done to align the input of weekdays in ISO format with the weekday delivered from NTP library which is in US format if (n == 0) { TDAY[j][6] = st5; } if (0 > n < 6) { TDAY[j][n] = st5; } if (n == 6) { TDAY[j][0] = st5; } n++; if (n == 7) { n = 0; j++; } } // } } // in case the settings file has to be renmoved void SettingsRemove() { bool result = SPIFFS.begin(); Serial.println("Delete SPIFFS opened: " + result); SPIFFS.remove("/t.txt"); File f = SPIFFS.open("/t.txt", "w"); if (!f) { Serial.println("Test file open failed"); } } void SettingsWrite() { bool result = SPIFFS.begin(); Serial.println("SPIFFS opened: " + result); File f = SPIFFS.open("/t.txt", "w"); // this opens the file "t.txt" in write-mode if (f) { // Serial.println("File t.txt exist"); TEMP1_SET = String("Temp1 = " + tmax_state); TEMP2_SET = String("Temp2 = " + tmin_state); TON_HR_set = String("TONHR = " + TON_HR_ARR); TOFF_HR_set = String("TOFFHR = " + TOFF_HR_ARR); TON_MIN_set = String("TONMIN = " + TON_MIN_ARR); TOFF_MIN_set = String("TOFFMIN = " + TOFF_MIN_ARR); T_DAY_set = String("TDAY = " + T_DAY_ARR); TON_HR_ARR.trim(); // Serial.println("stringlength "+ TON_HR_ARR); // Serial.println(TON_HR_ARR.length()); f.println (String("SSID = test")); f.println (String("PWD = test1")); f.println(TEMP1_SET); f.println(TEMP2_SET); f.println(TON_HR_set); f.println(TOFF_HR_set); f.println(TON_MIN_set); f.println(TOFF_MIN_set); f.println(T_DAY_set); Serial.println("write to file"); } f.close(); } void SettingsRead() { bool result = SPIFFS.begin(); Serial.println("SPIFFS opened: " + result); File f1 = SPIFFS.open("/t.txt", "r"); // this opens the file "t.txt" in read-mode // we could open the file while (f1.available()) { //Lets read line by line from the file String line = f1.readStringUntil('\n'); // Serial.print("read line = "); // Serial.println(line); // if (line.substring(0, 5) == "Temp1") if (line.indexOf("Temp1") == 0) { // Serial.println(line.substring(0, 5)); line.remove(0, 8); // line.remove(0, (line.length() - 3)); Serial.println("Found Temperature1"); SwitchTemp1 = line.toFloat(); tmax_state = line; continue; } // if (line.substring(0, 7) == "Temp2 =") if (line.indexOf("Temp2") == 0) { // Serial.println(line.substring(0, 5)); line.remove(0, 8); // line.remove(0, (line.length() - 3)); SwitchTemp2 = line.toFloat(); tmin_state = line; // Serial.println("Found Temperature2 "); continue; } if (line.indexOf("TONHR") == 0) { line.remove(0, 8); TON_HR_ARR = line; Serial.println("Found TONHR " + TON_HR_ARR); continue; } if (line.indexOf("TONMIN") == 0) { line.remove(0, 9); TON_MIN_ARR = line; // Serial.println("Found TON_MIN " + TON_MIN_ARR); continue; } if (line.indexOf("TOFFHR") == 0) { line.remove(0, 9); TOFF_HR_ARR = line; // Serial.println("Found TOFFHR " + TOFF_HR_ARR); continue; } if (line.indexOf("TOFFMIN") == 0) { line.remove(0, 10); TOFF_MIN_ARR = line; // Serial.println("Found TOFF_MIN " + TOFF_MIN_ARR); continue; } if (line.indexOf("TDAY") == 0) { line.remove(0, 7); T_DAY_ARR = line; // Serial.println("Found T_DAY " + T_DAY_ARR); continue; } } f1.close(); } void connectWifi() { WiFiManager wifiManager; wifiManager.autoConnect("AutoConnectAP"); // Serial.print("Connecting to " + MY_SSID); // char charBuf[50]; // char charBuf1[50]; // MY_SSID.toCharArray(charBuf, 50) ; // MY_PWD.toCharArray(charBuf1, 50) ; // WiFi.begin(charBuf, charBuf1); // while (WiFi.status() != WL_CONNECTED) { // delay(1000); // Serial.print("."); // } Serial.println(""); Serial.println("Connected"); Serial.println(""); // Print the IP address Serial.println(WiFi.localIP()); //webserver if (mdns.begin("esp8266", WiFi.localIP())) { Serial.println("Server started"); } server.on("/", []() { for ( int p = 0; p < server.args(); p++ ) { if (server.argName(p) == "RESET_WIFI") { WiFiManager wifiManager1; wifiManager1.resetSettings(); ESP.restart(); } if (server.argName(p) == "ONBTN") { digitalWrite(gpio2_pin, HIGH); digitalWrite(LED_BUILTIN, LOW); Serial.println("ON"); TIMER_SET = "ON" ; } if (server.argName(p) == "OFFBTN") { digitalWrite(gpio2_pin, LOW); digitalWrite(LED_BUILTIN, HIGH); Serial.println("OFF"); TIMER_SET = "OFF" ; } if (server.argName(p) == "TempMAX") { tmax_state = server.arg(p); } if (server.argName(p) == "TempMIN") { tmin_state = server.arg(p); } if (server.argName(p) == "TH00") { TON_HR_ARR = server.arg(p); } if (server.argName(p) == "TH10") { TON_HR_ARR = TON_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TH20") { TON_HR_ARR = TON_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TH30") { TON_HR_ARR = TON_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TM00") { TON_MIN_ARR = server.arg(p); } if (server.argName(p) == "TM10") { TON_MIN_ARR = TON_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "TM20") { TON_MIN_ARR = TON_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "TM30") { TON_MIN_ARR = TON_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "TH01") { TOFF_HR_ARR = server.arg(p); } if (server.argName(p) == "TH11") { TOFF_HR_ARR = TOFF_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TH21") { TOFF_HR_ARR = TOFF_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TH31") { TOFF_HR_ARR = TOFF_HR_ARR + "," + server.arg(p); } if (server.argName(p) == "TM01") { TOFF_MIN_ARR = server.arg(p); } if (server.argName(p) == "TM11") { TOFF_MIN_ARR = TOFF_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "TM21") { TOFF_MIN_ARR = TOFF_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "TM31") { TOFF_MIN_ARR = TOFF_MIN_ARR + "," + server.arg(p); } if (server.argName(p) == "cell02" and server.argName(p + 1) == "cell02") { T_DAY_ARR = "ON"; ++p; } if (server.argName(p) == "cell02" and T_DAY_ARR != "ON") { T_DAY_ARR = "OFF"; } if (server.argName(p).substring(0, 4) == "cell" and server.argName(p) != "cell02") { if (server.argName(p) == server.argName(p + 1)) { T_DAY_ARR = T_DAY_ARR + "," + "ON"; ++p; } else { T_DAY_ARR = T_DAY_ARR + "," + "OFF"; } } } SettingsWrite(); SettingsRead(); webpagebuild(); GetSWday(); GetSWtime(); server.send(200, "text/html", webPage); }); server.begin(); Serial.println("HTTP server started"); }//end connect // string conversion String convertTString (float Ftemp) { return String(dtostrf(Ftemp, 2, 2, temperatureString)); } // get temperature from sensor void gettemperature() { DS18B20.requestTemperatures(); temp = DS18B20.getTempCByIndex(0); tempC = convertTString(temp); } // check time void checkOST() { currentMillis = millis();//actual time in ms //time verification logic if (currentMillis - previousMillis > 10000) { previousMillis = currentMillis; // set time to actual // printf("Time Epoch: %d: ", timeClient.getEpochTime()); // Serial.println(timeClient.getFormattedTime()); timeClient.forceUpdate(); } } ////some string stuff from here:https://github.com/BenTommyE/Arduino_getStringPartByNr usage: getStringPartByNr(string, 'delimiter', position) String getStringPartByNr(String data, char separator, int index) { // spliting a string and return the part nr index // split by separator int stringData = 0; //variable to count data part nr String dataPart = ""; //variable to hole the return text for (int i = 0; i < data.length(); i++) { //Walk through the text one letter at a time if (data[i] == separator) { //Count the number of times separator character appears in the text stringData++; } else if (stringData == index) { //get the text when separator is the rignt one dataPart.concat(data[i]); } else if (stringData > index) { //return text and stop if the next separator appears - to save CPU-time return dataPart; break; } } //return text if this is the last part return dataPart; } // send temperature to thingspeak void sendTeperatureTS(float temp) { WiFiClient client; if (client.connect(IOTserver, 80)) { // use ip 184.106.153.149 or api.thingspeak.com Serial.println("WiFi Client connected "); Serial.print("IP address: "); Serial.println(WiFi.localIP()); String postStr = apiKey; postStr += "&field2="; postStr += String(temp); postStr += "\r\n\r\n"; Serial.println(postStr); client.print("GET /update?api_key=" + apiKey + "&field2=" + String(temp) + "\r\n"); client.print("Host: api.thingspeak.com\r\n"); client.print("Connection: close\r\n"); client.print("Accept: */*\r\n"); client.print("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n"); client.print("\r\n"); delay(1000); }//end if sent++; client.stop(); }//end send