#include "sketch.h"
// SENSORS
#define DHT_PIN 38
DHT22 dht22(DHT_PIN);
#define LDR_PIN 1
#define TRIG_PIN 39
#define ECHO_PIN 2
#define PH_PIN 18
#define SOIL_PIN 8
#define TEMPERATURE_PIN 10
#define ILLUMINATION_PIN 11
#define SOIL_HUMIDITY_PIN 12
#define SOIL_PH_PIN 13
#define LOW_WATER_ALARM_PIN 14
void setup() {
Serial.begin(9600);
pinMode(LDR_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PH_PIN, INPUT);
pinMode(SOIL_PIN, INPUT);
pinMode(TEMPERATURE_PIN, OUTPUT);
pinMode(ILLUMINATION_PIN, OUTPUT);
pinMode(SOIL_HUMIDITY_PIN, OUTPUT);
pinMode(SOIL_PH_PIN, OUTPUT);
pinMode(LOW_WATER_ALARM_PIN, OUTPUT);
printMutex = xSemaphoreCreateMutex();
temperatureMutex = xSemaphoreCreateMutex();
humidityMutex = xSemaphoreCreateMutex();
illuminationMutex = xSemaphoreCreateMutex();
waterMutex = xSemaphoreCreateMutex();
soilPHMutex = xSemaphoreCreateMutex();
soilHumidityMutex = xSemaphoreCreateMutex();
connectWiFi();
MQTTClient.setServer(MQTT_BROKER.c_str(), MQTT_PORT);
MQTTClient.setBufferSize(512);
MQTTClient.setCallback(cmd);
connectMQTT();
// Create tasks
xTaskCreate(connect, "connect", 4096, NULL, 1, NULL);
xTaskCreate(sendData, "sendData", 4096, NULL, 1, NULL);
xTaskCreate(readTemperature, "readTemperature", 2048, NULL, 3, NULL);
xTaskCreate(readHumidity, "readHumidity", 2048, NULL, 3, NULL);
xTaskCreate(readIllumination, "readIllumination", 2048, NULL, 3, NULL);
xTaskCreate(readWater, "readWater", 2048, NULL, 3, NULL);
xTaskCreate(readSoilPH, "readSoilPH", 2048, NULL, 3, NULL);
xTaskCreate(readSoilHumidity, "readSoilHumidity", 2048, NULL, 3, NULL);
xTaskCreate(controlTemperature, "controlTemperature", 2048, NULL, 1, NULL);
xTaskCreate(controlIllumination, "controlIllumination", 2048, NULL, 1, NULL);
xTaskCreate(controlSoilPH, "controlSoilPH", 2048, NULL, 3, NULL);
xTaskCreate(readHumidity, "controlSoilHumidity", 2048, NULL, 3, NULL);
xTaskCreate(readIllumination, "readIllumination", 2048, NULL, 3, NULL);
xTaskCreate(readWater, "controlLowWaterAlarm", 2048, NULL, 3, NULL);
}
void loop() {
MQTTClient.loop();
}
void controlTemperature(void *pvParameters) {
while(true) {
float localTemperature;
if (xSemaphoreTake(temperatureMutex, portMAX_DELAY) == pdTRUE) {
localTemperature = temperature;
xSemaphoreGive(temperatureMutex);
}
unsigned long now = millis();
if ( (now < temperatureActuatorTime && temperatureActuatorAction) || (temperatureActuatorTime < now &&
(localTemperature < temperatureObjective - temperatureRange || localTemperature > temperatureObjective + temperatureRange))) {
digitalWrite(TEMPERATURE_PIN, HIGH);
} else {
digitalWrite(TEMPERATURE_PIN, LOW);
}
vTaskDelay(periodControlTemperature / portTICK_PERIOD_MS);
}
}
void controlIllumination(void *pvParameters) {
while(true) {
float localIllumination;
if (xSemaphoreTake(illuminationMutex, portMAX_DELAY) == pdTRUE) {
localIllumination = illumination;
xSemaphoreGive(illuminationMutex);
}
unsigned long now = millis();
if ((now < illuminationActuatorTime && illuminationActuatorAction) || (illuminationActuatorTime < now &&
(localIllumination < temperatureObjective))) {
digitalWrite(ILLUMINATION_PIN, HIGH);
} else {
digitalWrite(ILLUMINATION_PIN, LOW);
}
vTaskDelay(periodControlIllumination / portTICK_PERIOD_MS);
}
}
void controlSoilPH(void *pvParameters) {
while(true) {
float localSoilPH;
if (xSemaphoreTake(soilPHMutex, portMAX_DELAY) == pdTRUE) {
localSoilPH = soilPH;
xSemaphoreGive(soilPHMutex);
}
unsigned long now = millis();
if ((now < soilPHActuatorTime && soilPHActuatorAction) || (soilPHActuatorTime < now &&
(localSoilPH < soilPHObjective - soilPHRange || localSoilPH > soilPHObjective + soilPHRange))) {
digitalWrite(SOIL_PH_PIN, HIGH);
} else {
digitalWrite(SOIL_PH_PIN, LOW);
}
vTaskDelay(periodControlSoilPH / portTICK_PERIOD_MS);
}
}
void controlSoilHumidity(void *pvParameters) {
while(true) {
float localSoilHumidity;
if (xSemaphoreTake(soilHumidityMutex, portMAX_DELAY) == pdTRUE) {
localSoilHumidity = soilHumidity;
xSemaphoreGive(soilHumidityMutex);
}
unsigned long now = millis();
if ((now < soilHumidityActuatorTime && soilHumidityActuatorAction) || (soilHumidityActuatorTime < now &&
(localSoilHumidity < soilHumidityObjective))) {
digitalWrite(SOIL_HUMIDITY_PIN, HIGH);
} else {
digitalWrite(SOIL_HUMIDITY_PIN, LOW);
}
vTaskDelay(periodControlSoilHumidity / portTICK_PERIOD_MS);
}
}
void controlLowWaterAlarm(void *pvParameters) {
while(true) {
float localWater;
if (xSemaphoreTake(waterMutex, portMAX_DELAY) == pdTRUE) {
localWater = water;
xSemaphoreGive(waterMutex);
}
unsigned long now = millis();
if ((now < waterActuatorTime && waterActuatorAction) || (waterActuatorTime < now &&
(localWater < waterLimit))) {
digitalWrite(LOW_WATER_ALARM_PIN, HIGH);
} else {
digitalWrite(LOW_WATER_ALARM_PIN, LOW);
}
vTaskDelay(periodControlWater / portTICK_PERIOD_MS);
}
}
void cmd(char* topic, byte* payload, unsigned int length) {
String topicString = String(topic);
String message = String(std::string((char * ) payload, length).c_str());
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("[" + topicString + "] " + message);
xSemaphoreGive(printMutex);
}
StaticJsonDocument <200> doc;
DeserializationError error = deserializeJson(doc, message);
if (error) {
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.print("Error al deserializar el JSON: ");
Serial.println(error.c_str());
xSemaphoreGive(printMutex);
}
return;
}
if (topicString == TOPIC_SUB_CONFIG | topicString == TOPIC_SUB_CONFIG_ALL) {
if (doc.containsKey("DEVICE_ID")) {
DEVICE_ID = doc["DEVICE_ID"].as<String>();
Serial.print("Var DEVICE_ID changed to " + DEVICE_ID);
}
if (doc.containsKey("WIFI_SSID")) {
WIFI_SSID = doc["WIFI_SSID"].as<String>();
Serial.print("Var WIFI_SSID changed to " + WIFI_SSID);
}
if (doc.containsKey("WIFI_PASSWORD")) {
WIFI_PASSWORD = doc["WIFI_PASSWORD"].as<String>();
Serial.print("Var WIFI_PASSWORD changed to " + WIFI_PASSWORD);
}
if (doc.containsKey("MQTT_PORT")) {
MQTT_PORT = doc["MQTT_PORT"].as<int>();
Serial.print("Var MQTT_PORT changed to " + MQTT_PORT);
}
if (doc.containsKey("MQTT_BROKER")) {
MQTT_BROKER = doc["MQTT_BROKER"].as<String>();
Serial.print("Var MQTT_BROKER changed to " + MQTT_BROKER);
}
if (doc.containsKey("MQTT_USER")) {
MQTT_USER = doc["MQTT_USER"].as<String>();
Serial.print("Var MQTT_USER changed to " + MQTT_USER);
}
if (doc.containsKey("MQTT_PASSWORD")) {
MQTT_PASSWORD = doc["MQTT_PASSWORD"].as<String>();
Serial.print("Var MQTT_PASSWORD changed to " + MQTT_PASSWORD);
}
if (doc.containsKey("TOPIC_PUB_STATUS")) {
TOPIC_PUB_STATUS = doc["TOPIC_PUB_STATUS"].as<String>();
Serial.print("Var TOPIC_PUB_STATUS changed to " + TOPIC_PUB_STATUS);
}
if (doc.containsKey("TOPIC_PUB_DATA")) {
TOPIC_PUB_DATA = doc["TOPIC_PUB_DATA"].as<String>();
Serial.print("Var TOPIC_PUB_DATA changed to " + TOPIC_PUB_DATA);
}
if (doc.containsKey("TOPIC_SUB_CONFIG")) {
TOPIC_SUB_CONFIG = doc["TOPIC_SUB_CONFIG"].as<String>();
Serial.print("Var TOPIC_SUB_CONFIG changed to " + TOPIC_SUB_CONFIG);
}
if (doc.containsKey("TOPIC_SUB_CONFIG_ALL")) {
TOPIC_SUB_CONFIG_ALL = doc["TOPIC_SUB_CONFIG_ALL"].as<String>();
Serial.print("Var TOPIC_SUB_CONFIG_ALL changed to " + TOPIC_SUB_CONFIG_ALL);
}
if (doc.containsKey("FIRST_MESSAGE")) {
FIRST_MESSAGE = doc["FIRST_MESSAGE"].as<String>();
Serial.print("Var FIRST_MESSAGE changed to " + FIRST_MESSAGE);
}
if (doc.containsKey("LAST_MESSAGE")) {
LAST_MESSAGE = doc["LAST_MESSAGE"].as<String>();
Serial.print("Var LAST_MESSAGE changed to " + LAST_MESSAGE);
}
if (doc.containsKey("periodSendData")) {
periodSendData = doc["periodSendData"].as<int>();
Serial.print("Var periodSendData changed to " + periodSendData);
}
if (doc.containsKey("periodConnect")) {
periodConnect = doc["periodConnect"].as<int>();
Serial.print("Var periodConnect changed to " + periodConnect);
}
if (doc.containsKey("periodReadTemperature")) {
periodReadTemperature = doc["periodReadTemperature"].as<int>();
Serial.print("Var periodReadTemperature changed to " + periodReadTemperature);
}
if (doc.containsKey("periodReadHumidity")) {
periodReadHumidity = doc["periodReadHumidity"].as<int>();
Serial.print("Var periodReadHumidity changed to " + periodReadHumidity);
}
if (doc.containsKey("periodReadIllumination")) {
periodReadIllumination = doc["periodReadIllumination"].as<int>();
Serial.print("Var periodReadIllumination changed to " + periodReadIllumination);
}
if (doc.containsKey("periodReadWater")) {
periodReadWater = doc["periodReadWater"].as<int>();
Serial.print("Var periodReadWater changed to " + periodReadWater);
}
if (doc.containsKey("periodReadSoilPH")) {
periodReadSoilPH = doc["periodReadSoilPH"].as<int>();
Serial.print("Var periodReadSoilPH changed to " + periodReadSoilPH);
}
if (doc.containsKey("periodReadSoilHumidity")) {
periodReadSoilHumidity = doc["periodReadSoilHumidity"].as<int>();
Serial.print("Var periodReadSoilHumidity changed to " + periodReadSoilHumidity);
}
if (doc.containsKey("periodControlTemperature")) {
periodControlTemperature = doc["periodControlTemperature"].as<int>();
Serial.print("Var periodControlTemperature changed to " + periodControlTemperature);
}
if (doc.containsKey("periodControlHumidity")) {
periodControlHumidity = doc["periodControlHumidity"].as<int>();
Serial.print("Var periodControlHumidity changed to " + periodControlHumidity);
}
if (doc.containsKey("periodControlIllumination")) {
periodControlIllumination = doc["periodControlIllumination"].as<int>();
Serial.print("Var periodControlIllumination changed to " + periodControlIllumination);
}
if (doc.containsKey("periodControlWater")) {
periodControlWater = doc["periodControlWater"].as<int>();
Serial.print("Var periodControlWater changed to " + periodControlWater);
}
if (doc.containsKey("periodControlSoilPH")) {
periodControlSoilPH = doc["periodControlSoilPH"].as<int>();
Serial.print("Var periodControlSoilPH changed to " + periodControlSoilPH);
}
if (doc.containsKey("periodControlSoilHumidity")) {
periodControlSoilHumidity = doc["periodControlSoilHumidity"].as<int>();
Serial.print("Var periodControlSoilHumidity changed to " + periodControlSoilHumidity);
}
if (doc.containsKey("temperatureObjective")) {
temperatureObjective = doc["temperatureObjective"].as<float>();
Serial.print("Var temperatureObjective changed to " + String(temperatureObjective));
}
if (doc.containsKey("temperatureRange")) {
temperatureRange = doc["temperatureRange"].as<float>();
Serial.print("Var temperatureRange changed to " + String(temperatureRange));
}
if (doc.containsKey("illuminationObjective")) {
illuminationObjective = doc["illuminationObjective"].as<float>();
Serial.print("Var illuminationObjective changed to " + String(illuminationObjective));
}
if (doc.containsKey("soilPHObjective")) {
soilPHObjective = doc["soilPHObjective"].as<float>();
Serial.print("Var soilPHObjective changed to " + String(soilPHObjective));
}
if (doc.containsKey("soilPHRange")) {
soilPHRange = doc["soilPHRange"].as<float>();
Serial.print("Var soilPHRange changed to " + String(soilPHRange));
}
if (doc.containsKey("soilHumidityObjective")) {
soilHumidityObjective = doc["soilHumidityObjective"].as<float>();
Serial.print("Var soilHumidityObjective changed to " + String(soilHumidityObjective));
}
} else if (topicString == TOPIC_SUB_ACTUATORS | topicString == TOPIC_SUB_ACTUATORS_ALL) {
if (doc.containsKey("temperatureActuator")) {
JsonObject jsonObj = doc["temperatureActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
temperatureActuatorAction = jsonObj["action"].as<bool>();
temperatureActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Temperature actuator set to " + String(temperatureActuatorAction) + " during " + String(temperatureActuatorTime) + "ms");
}
}
if (doc.containsKey("humidityActuator")) {
JsonObject jsonObj = doc["humidityActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
humidityActuatorAction = jsonObj["action"].as<bool>();
humidityActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Temperature actuator set to " + String(humidityActuatorAction) + " during " + String(humidityActuatorTime) + "ms");
}
}
if (doc.containsKey("illuminationActuator")) {
JsonObject jsonObj = doc["illuminationActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
illuminationActuatorAction = jsonObj["action"].as<bool>();
illuminationActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Illumination actuator set to " + String(illuminationActuatorAction) + " during " + String(illuminationActuatorTime) + "ms");
}
}
if (doc.containsKey("waterActuator")) {
JsonObject jsonObj = doc["waterActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
waterActuatorAction = jsonObj["action"].as<bool>();
waterActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Water actuator set to " + String(waterActuatorAction) + " during " + String(waterActuatorTime) + "ms");
}
}
if (doc.containsKey("soilPHActuator")) {
JsonObject jsonObj = doc["soilPHActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
soilPHActuatorAction = jsonObj["action"].as<bool>();
soilPHActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Soil pH actuator set to " + String(soilPHActuatorAction) + " during " + String(soilPHActuatorTime) + "ms");
}
}
if (doc.containsKey("soilHumidityActuator")) {
JsonObject jsonObj = doc["soilHumidityActuator"];
if (jsonObj.containsKey("action") && jsonObj.containsKey("time")) {
soilHumidityActuatorAction = jsonObj["action"].as<bool>();
soilHumidityActuatorTime = millis() + jsonObj["time"].as<unsigned long>();
Serial.print("Soil Humidity actuator set to " + String(soilHumidityActuatorAction) + " during " + String(soilHumidityActuatorTime) + "ms");
}
}
}
}
void connectWiFi() {
if (WiFi.status() != WL_CONNECTED) {
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Connecting to WIFI SSID " + String(WIFI_SSID) + " ");
xSemaphoreGive(printMutex);
}
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Connected to WIFI SSID " + String(WIFI_SSID) + " with IP " + WiFi.localIP().toString());
xSemaphoreGive(printMutex);
}
}
}
void connectMQTT() {
if (!MQTTClient.connected()) {
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Connecting to MQTT broker " + String(MQTT_BROKER));
xSemaphoreGive(printMutex);
}
while(!MQTTClient.connected()) {
if (MQTTClient.connect(DEVICE_ID.c_str(), NULL, NULL, TOPIC_PUB_STATUS.c_str(), 2, true, LAST_MESSAGE.c_str())) {
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Connected to MQTT broker " + String(MQTT_BROKER));
xSemaphoreGive(printMutex);
}
MQTTClient.publish(TOPIC_PUB_STATUS.c_str(), FIRST_MESSAGE.c_str(), true);
MQTTClient.subscribe(TOPIC_SUB_CONFIG.c_str());
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Suscribed to " + TOPIC_SUB_CONFIG);
xSemaphoreGive(printMutex);
}
MQTTClient.subscribe(TOPIC_SUB_CONFIG_ALL.c_str());
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Suscribed to " + TOPIC_SUB_CONFIG_ALL);
xSemaphoreGive(printMutex);
}
MQTTClient.subscribe(TOPIC_SUB_ACTUATORS.c_str());
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Suscribed to " + TOPIC_SUB_ACTUATORS);
xSemaphoreGive(printMutex);
}
MQTTClient.subscribe(TOPIC_SUB_ACTUATORS_ALL.c_str());
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Suscribed to " + TOPIC_SUB_ACTUATORS_ALL);
xSemaphoreGive(printMutex);
}
}
}
}
}
void connect(void *pvParameters) {
while(true){
connectWiFi();
connectMQTT();
vTaskDelay(periodConnect / portTICK_PERIOD_MS);
}
}
void sendData(void *pvParameters) {
float localTemperature;
float localHumidity;
float localIllumination;
float localWater;
float localSoilPH;
float localSoilHumidity;
StaticJsonDocument<200> jsonDocument;
String jsonString;
while(true){
if (xSemaphoreTake(temperatureMutex, portMAX_DELAY) == pdTRUE) {
localTemperature = temperature;
xSemaphoreGive(temperatureMutex);
}
if (xSemaphoreTake(humidityMutex, portMAX_DELAY) == pdTRUE) {
localHumidity = humidity;
xSemaphoreGive(humidityMutex);
}
if (xSemaphoreTake(illuminationMutex, portMAX_DELAY) == pdTRUE) {
localIllumination = illumination;
xSemaphoreGive(illuminationMutex);
}
if (xSemaphoreTake(waterMutex, portMAX_DELAY) == pdTRUE) {
localWater = water;
xSemaphoreGive(waterMutex);
}
if (xSemaphoreTake(soilPHMutex, portMAX_DELAY) == pdTRUE) {
localSoilPH = soilPH;
xSemaphoreGive(soilPHMutex);
}
if (xSemaphoreTake(soilHumidityMutex, portMAX_DELAY) == pdTRUE) {
localSoilHumidity = soilHumidity;
xSemaphoreGive(soilHumidityMutex);
}
jsonDocument["device"] = DEVICE_ID;
jsonDocument["temperature"] = localTemperature;
jsonDocument["humidity"] = localHumidity;
jsonDocument["illumination"] = localIllumination;
jsonDocument["water"] = localWater;
jsonDocument["soilPH"] = localSoilPH;
jsonDocument["soilHumidity"] = localSoilHumidity;
serializeJson(jsonDocument, jsonString);
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Sending JSON data to cloud: " + jsonString);
xSemaphoreGive(printMutex);
}
MQTTClient.publish(TOPIC_PUB_DATA.c_str(), jsonString.c_str(), false);
vTaskDelay(periodSendData / portTICK_PERIOD_MS);
}
}
void readTemperature(void *pvParameters) {
float localTemperature = 0;
while(true) {
localTemperature = dht22.getTemperature();
if (xSemaphoreTake(temperatureMutex, portMAX_DELAY) == pdTRUE) {
temperature = localTemperature;
xSemaphoreGive(temperatureMutex);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Temperature: " + String(localTemperature) + " °C");
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadTemperature / portTICK_PERIOD_MS);
}
}
void readHumidity(void *pvParameters) {
float localHumidity = 0;
while(true) {
localHumidity = dht22.getHumidity();
if (xSemaphoreTake(humidityMutex, portMAX_DELAY) == pdTRUE) {
humidity = localHumidity;
xSemaphoreGive(humidityMutex);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Humidity: " + String(localHumidity) + "%");
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadHumidity / portTICK_PERIOD_MS);
}
}
void readIllumination(void *pvParameters) {
const float GAMMA = 0.7, RL10 = 50;
float localIllumination = 0, voltage, resistance;
int analogValue;
while(true) {
analogValue = analogRead(LDR_PIN);
voltage = analogValue / 1024. * 5;
resistance = 2000 * voltage / (1 - voltage / 5);
localIllumination = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
if (isfinite(localIllumination)) {
if (xSemaphoreTake(illuminationMutex, portMAX_DELAY) == pdTRUE) {
illumination = localIllumination;
xSemaphoreGive(illuminationMutex);
}
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Illumination: " + String(localIllumination) + " lux");
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadIllumination / portTICK_PERIOD_MS);
}
}
void readWater(void *pvParameters) {
float localWater = 0;
while(true) {
taskENTER_CRITICAL(&cs_spinlock);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
taskEXIT_CRITICAL(&cs_spinlock);
localWater = pulseIn(ECHO_PIN, HIGH) / 58;
if (xSemaphoreTake(waterMutex, portMAX_DELAY) == pdTRUE) {
water = localWater;
xSemaphoreGive(waterMutex);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Water level: " + String(localWater) + " cm");
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadWater / portTICK_PERIOD_MS);
}
}
void readSoilPH(void *pvParameters) {
float localSoilPH = 0;
while(true) {
localSoilPH = analogRead(PH_PIN) / 409.6;
if (xSemaphoreTake(soilPHMutex, portMAX_DELAY) == pdTRUE) {
soilPH = localSoilPH;
xSemaphoreGive(soilPHMutex);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Soil pH: " + String(localSoilPH));
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadSoilPH / portTICK_PERIOD_MS);
}
}
void readSoilHumidity(void *pvParameters) {
float localSoilHumidity = 0;
while(true) {
localSoilHumidity = analogRead(SOIL_PIN) / 40.96;
if (xSemaphoreTake(soilHumidityMutex, portMAX_DELAY) == pdTRUE) {
soilHumidity = localSoilHumidity;
xSemaphoreGive(soilHumidityMutex);
}
if (xSemaphoreTake(printMutex, portMAX_DELAY) == pdTRUE) {
Serial.println("Soil Humidity: " + String(localSoilHumidity) + "%");
xSemaphoreGive(printMutex);
}
vTaskDelay(periodReadSoilHumidity / portTICK_PERIOD_MS);
}
}
Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1