#if defined(ESP8266) #include #include #include #elif defined(ESP32) #include #include #include #include #else #error "This sketch supports ESP8266 and ESP32 boards only." #endif const int PIN_COMMON_ELECTRODE = 13; // GPIO13 / D7 const int PIN_LEVEL1 = 5; // GPIO5 / D1 - najnizsia hladina const int PIN_LEVEL2 = 4; // GPIO4 / D2 const int PIN_LEVEL3 = 14; // GPIO14 / D5 const int PIN_LEVEL4 = 12; // GPIO12 / D6 - najvyssia hladina const int DEBUG = 0; const char WIFI_SSID[] = "TP-Link_DD1E"; const char WIFI_PASS[] = "33784120"; const unsigned long SLEEP_TIME_SEC = 1800; const char URL_LOG[] = "https://vihorlat.tpsoft.org/hladinac/server/log.php"; const unsigned long WIFI_TIMEOUT_MS = 15000; const unsigned long MEASUREMENT_STABILIZE_MS = 50; struct WaterLevels { int level1; int level2; int level3; int level4; }; void initPins(); WaterLevels readLevels(); void printLevels(const WaterLevels &levels); String buildPostBody(const WaterLevels &levels); bool connectWifi(); bool sendLevelsToServer(const WaterLevels &levels); void enterDeepSleep(); void setupLevelPin(int pin); void setCommonElectrodeOn(); void setCommonElectrodeOff(); int readLevelPin(int pin); void setup() { Serial.begin(115200); delay(200); Serial.println("Hladinac v0.3 started."); initPins(); if (DEBUG == 0) { WaterLevels levels = readLevels(); printLevels(levels); if (connectWifi()) { sendLevelsToServer(levels); WiFi.disconnect(true); WiFi.mode(WIFI_OFF); } else { Serial.println("WiFi connection failed, skipping upload."); } enterDeepSleep(); } else if (DEBUG == 2) { connectWifi(); } } void loop() { if (DEBUG == 1) { WaterLevels levels = readLevels(); printLevels(levels); delay(1000); } else if (DEBUG == 2) { WaterLevels levels = readLevels(); printLevels(levels); if (WiFi.status() != WL_CONNECTED) { connectWifi(); } sendLevelsToServer(levels); delay(5000); } } void initPins() { pinMode(PIN_COMMON_ELECTRODE, OUTPUT); setCommonElectrodeOff(); setupLevelPin(PIN_LEVEL1); setupLevelPin(PIN_LEVEL2); setupLevelPin(PIN_LEVEL3); setupLevelPin(PIN_LEVEL4); } void setupLevelPin(int pin) { #if defined(ESP32) pinMode(pin, INPUT_PULLDOWN); #else // ESP8266 pouziva externe pull-down rezistory na GND. pinMode(pin, INPUT); #endif } void setCommonElectrodeOn() { #if defined(ESP8266) digitalWrite(PIN_COMMON_ELECTRODE, HIGH); #else digitalWrite(PIN_COMMON_ELECTRODE, HIGH); #endif } void setCommonElectrodeOff() { #if defined(ESP8266) digitalWrite(PIN_COMMON_ELECTRODE, LOW); #else digitalWrite(PIN_COMMON_ELECTRODE, LOW); #endif } int readLevelPin(int pin) { #if defined(ESP8266) return digitalRead(pin) == HIGH ? 1 : 0; #else return digitalRead(pin) == HIGH ? 1 : 0; #endif } WaterLevels readLevels() { WaterLevels levels; // Spolocna elektroda je zapnuta iba pocas merania, aby sa znizila korozia. setCommonElectrodeOn(); delay(MEASUREMENT_STABILIZE_MS); levels.level1 = readLevelPin(PIN_LEVEL1); levels.level2 = readLevelPin(PIN_LEVEL2); levels.level3 = readLevelPin(PIN_LEVEL3); levels.level4 = readLevelPin(PIN_LEVEL4); setCommonElectrodeOff(); return levels; } void printLevels(const WaterLevels &levels) { Serial.print("level1="); Serial.print(levels.level1); Serial.print(" level2="); Serial.print(levels.level2); Serial.print(" level3="); Serial.print(levels.level3); Serial.print(" level4="); Serial.println(levels.level4); } String buildPostBody(const WaterLevels &levels) { String body = "level1=" + String(levels.level1); body += "&level2=" + String(levels.level2); body += "&level3=" + String(levels.level3); body += "&level4=" + String(levels.level4); return body; } bool connectWifi() { if (WiFi.status() == WL_CONNECTED) { return true; } Serial.print("Connecting to WiFi"); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); unsigned long startedAt = millis(); while (WiFi.status() != WL_CONNECTED && millis() - startedAt < WIFI_TIMEOUT_MS) { delay(500); Serial.print("."); } if (WiFi.status() == WL_CONNECTED) { Serial.println(); Serial.print("WiFi connected, IP="); Serial.println(WiFi.localIP()); return true; } Serial.println(); Serial.println("WiFi connection timeout."); return false; } bool sendLevelsToServer(const WaterLevels &levels) { if (WiFi.status() != WL_CONNECTED) { Serial.println("Cannot send data, WiFi is not connected."); return false; } #if defined(ESP8266) BearSSL::WiFiClientSecure client; #else WiFiClientSecure client; #endif client.setInsecure(); HTTPClient http; if (!http.begin(client, URL_LOG)) { Serial.println("HTTP begin failed."); return false; } String body = buildPostBody(levels); http.addHeader("Content-Type", "application/x-www-form-urlencoded"); int httpCode = http.POST(body); if (httpCode > 0) { Serial.print("POST sent, HTTP code="); Serial.println(httpCode); } else { Serial.print("POST failed: "); Serial.println(http.errorToString(httpCode)); } http.end(); return httpCode > 0 && httpCode < 400; } void enterDeepSleep() { Serial.print("Entering deep sleep for "); Serial.print(SLEEP_TIME_SEC); Serial.println(" seconds."); Serial.flush(); #if defined(ESP8266) ESP.deepSleep((uint64_t)SLEEP_TIME_SEC * 1000000ULL); #else esp_sleep_enable_timer_wakeup((uint64_t)SLEEP_TIME_SEC * 1000000ULL); esp_deep_sleep_start(); #endif }