This shows you the differences between two versions of the page.
|
iothings:proiecte:2022sric:soilmoisturemonitoring [2023/06/01 15:38] andreea.paiu created |
iothings:proiecte:2022sric:soilmoisturemonitoring [2023/06/01 16:08] (current) andreea.paiu |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ceva | + | ===== Soil Moisture Monitoring ===== |
| + | Author: Andreea Paiu | ||
| + | |||
| + | === Introduction === | ||
| + | |||
| + | The purpose of this project is to monitor a plant's soil moisture and notice us when the moisture exceeds the set limits. | ||
| + | |||
| + | === Hardware Description === | ||
| + | |||
| + | The components used for the project were the following: | ||
| + | |||
| + | * ESP32 Dev Board | ||
| + | * Hygrometre sensor Module - soil humidity | ||
| + | * Wires | ||
| + | |||
| + | |||
| + | The electronic schema: | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_154707055.png?400|}} | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_154800737.png?400|}} | ||
| + | |||
| + | |||
| + | === Software Description === | ||
| + | Used Libraries: | ||
| + | |||
| + | <code> | ||
| + | #include <WiFi.h> | ||
| + | #include <AsyncTCP.h> | ||
| + | #include <ESPAsyncWebServer.h> | ||
| + | #include <Firebase_ESP_Client.h> | ||
| + | #include "addons/TokenHelper.h" | ||
| + | #include "addons/RTDBHelper.h" | ||
| + | #include <InfluxDbClient.h> | ||
| + | #include <InfluxDbCloud.h> | ||
| + | </code> | ||
| + | |||
| + | Set-ups: | ||
| + | * Firebase | ||
| + | <code> | ||
| + | void setup_firebase() { | ||
| + | config.api_key = API_KEY; | ||
| + | |||
| + | config.database_url = DATABASE_URL; | ||
| + | |||
| + | if (Firebase.signUp(&config, &auth, "", "")){ | ||
| + | Serial.println("ok"); | ||
| + | signupOK = true; | ||
| + | } | ||
| + | else{ | ||
| + | Serial.printf("%s\n", config.signer.signupError.message.c_str()); | ||
| + | } | ||
| + | |||
| + | config.token_status_callback = tokenStatusCallback; | ||
| + | |||
| + | Firebase.begin(&config, &auth); | ||
| + | Firebase.reconnectWiFi(true); | ||
| + | } | ||
| + | |||
| + | </code> | ||
| + | * Routing | ||
| + | <code> | ||
| + | void setup_routing() { | ||
| + | server.on("/", HTTP_GET, MainPage); | ||
| + | server.on("/read_moisture", HTTP_GET, SoilMoisture); | ||
| + | server.on("/update_low_limit_slide", HTTP_GET, UpdateLowLimitSlide); | ||
| + | server.on("/update_high_limit_slide", HTTP_GET, UpdateHighLimitSlide); | ||
| + | server.on("/read_low_limit", HTTP_GET, ReadLowLimit); | ||
| + | server.on("/read_high_limit", HTTP_GET, ReadHighLimit); | ||
| + | server.onNotFound(notFound); | ||
| + | server.begin(); | ||
| + | } | ||
| + | </code> | ||
| + | * Wifi | ||
| + | <code> | ||
| + | WiFi.mode(WIFI_STA); | ||
| + | WiFi.begin(ssid, password); | ||
| + | while(WiFi.waitForConnectResult() != WL_CONNECTED){ | ||
| + | Serial.print("."); | ||
| + | delay(100); | ||
| + | } | ||
| + | </code> | ||
| + | * Tasks | ||
| + | <code> | ||
| + | xTaskCreatePinnedToCore( | ||
| + | Task1code, /* Task function. */ | ||
| + | "Task1", /* name of task. */ | ||
| + | 10000, /* Stack size of task */ | ||
| + | NULL, /* parameter of the task */ | ||
| + | 1, /* priority of the task */ | ||
| + | &Task1, /* Task handle to keep track of created task */ | ||
| + | 0); /* pin task to core 0 */ | ||
| + | xTaskCreatePinnedToCore( | ||
| + | Task2code, /* Task function. */ | ||
| + | "Task2", /* name of task. */ | ||
| + | 10000, /* Stack size of task */ | ||
| + | NULL, /* parameter of the task */ | ||
| + | 1, /* priority of the task */ | ||
| + | &Task2, /* Task handle to keep track of created task */ | ||
| + | 1); /* pin task to core 1 */ | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | We use both cores: | ||
| + | First core get data and sent them in InfluxDB | ||
| + | <code> | ||
| + | void Task1code( void * pvParameters ){ | ||
| + | Serial.println(xPortGetCoreID()); | ||
| + | for(;;){ | ||
| + | sensor.clearFields(); | ||
| + | sensor_analog = analogRead(sensor_pin); | ||
| + | _moisture = ( 100 - ( (sensor_analog/4095.00) * 100 ) ); | ||
| + | sensor.addField("value", _moisture); | ||
| + | Serial.print("Writing: "); | ||
| + | Serial.println(client.pointToLineProtocol(sensor)); | ||
| + | |||
| + | if (!client.writePoint(sensor)) { | ||
| + | Serial.print("InfluxDB write failed: "); | ||
| + | Serial.println(client.getLastErrorMessage()); | ||
| + | } | ||
| + | |||
| + | Serial.print("Moisture = "); | ||
| + | Serial.print(_moisture); | ||
| + | Serial.println("%"); | ||
| + | delay(1000); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </code> | ||
| + | |||
| + | Second core add limit value in Firebase and check values | ||
| + | <code> | ||
| + | void Task2code( void * pvParameters ){ | ||
| + | String low_val = String(0); | ||
| + | String high_val = String(100); | ||
| + | for(;;){ | ||
| + | Serial.print("Task2 running on core "); | ||
| + | Serial.println(xPortGetCoreID()); | ||
| + | String low_val = String(0); | ||
| + | |||
| + | if (Firebase.RTDB.getInt(&fbdo, "/limit/low")) { | ||
| + | if (fbdo.dataType() == "int") { | ||
| + | low_val = fbdo.intData(); | ||
| + | Serial.println(low_val); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | if (Firebase.RTDB.getInt(&fbdo, "/limit/high")) { | ||
| + | if (fbdo.dataType() == "int") { | ||
| + | high_val = fbdo.intData(); | ||
| + | Serial.println(high_val); | ||
| + | } | ||
| + | } | ||
| + | Serial.println(_moisture); | ||
| + | Serial.println("comparatie"); | ||
| + | digitalWrite(led2, LOW); | ||
| + | if(_moisture > high_val.toInt() || _moisture < low_val.toInt()) | ||
| + | digitalWrite(led2, HIGH); | ||
| + | delay(1500); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | === Demo === | ||
| + | [[https://drive.google.com/file/d/1VUl034nP9WEL0LMjl8Zj2UlxCzE9lBbi/view?usp=sharing]] | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_160036058.png?400|}} | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_160115076.png?400|}} | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_160212880.png?400|}} | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_160323681.png?600|}} | ||
| + | |||
| + | {{:iothings:proiecte:2022sric:image_2023-06-01_160352879.png?400|}} | ||
| + | |||
| + | === References === | ||
| + | |||
| + | [[http://www.esp32learning.com/code/esp32-and-soil-moisture-sensor-example.php]] | ||
| + | |||
| + | [[http://www.esp32learning.com/code/esp32-and-soil-moisture-sensor-example.php]] | ||
| + | |||
| + | [[https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/]] | ||
| + | |||
| + | [[https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/]] | ||
| + | |||
| + | [[https://randomnerdtutorials.com/esp32-firebase-realtime-database]] | ||
| + | |||