#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// UBIDOTS MQTT
#define TOKEN "BBUS-jCWN0C30cKsmnH26Ftf5Fk0Fd1V39S"
#define DEVICE_LABEL "sistema-de-riego"
#define MQTT_CLIENT_NAME "esp32"
char broker[] = "industrial.api.ubidots.com";
char topic[] = "/v1.6/devices/sistema-de-riego";
// WIFI (WOKWI)
const char* ssid = "Wokwi-GUEST";
const char* password = "";
WiFiClient wifiClient;
PubSubClient client(wifiClient);
// DHT22
#define DHTPIN 21
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// SENSORES
#define HUMEDAD1 34
#define HUMEDAD2 35
#define FLUJO 32 // potenciómetro (ADC)
#define NIVEL_BAJO 16
#define NIVEL_MEDIO 2
#define NIVEL_ALTO 4
// RELÉS
#define RELE1 26
#define RELE2 33
#define RELE3 14
#define RELE4 13
void conectarWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void reconnect() {
while (!client.connected()) {
if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
Serial.println("Conectado a Ubidots");
} else {
delay(2000);
}
}
}
void setup() {
Serial.begin(115200);
dht.begin();
conectarWiFi();
client.setServer(broker, 1883);
pinMode(HUMEDAD1, INPUT);
pinMode(HUMEDAD2, INPUT);
pinMode(FLUJO, INPUT); // ahora analógico
pinMode(NIVEL_BAJO, INPUT_PULLUP);
pinMode(NIVEL_MEDIO, INPUT_PULLUP);
pinMode(NIVEL_ALTO, INPUT_PULLUP);
pinMode(RELE1, OUTPUT);
pinMode(RELE2, OUTPUT);
pinMode(RELE3, OUTPUT);
pinMode(RELE4, OUTPUT);
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
//LECTURAS
float humSuelo1 = map(analogRead(HUMEDAD1), 0, 4095, 100, 0);
float humSuelo2 = map(analogRead(HUMEDAD2), 0, 4095, 100, 0);
float temp = dht.readTemperature();
float humAire = dht.readHumidity();
bool bajo = !digitalRead(NIVEL_BAJO);
bool medio = !digitalRead(NIVEL_MEDIO);
bool alto = !digitalRead(NIVEL_ALTO);
// NUEVO FLUJO CON POTENCIÓMETRO
int valFlujo = analogRead(FLUJO);
float flujo = map(valFlujo, 0, 4095, 0, 30); // 0–30 L/min
int nivel = alto ? 3 : (medio ? 2 : (bajo ? 1 : 0));
// AUTOMATIZACIÓN
if (flujo < 20 && (humSuelo1 < 40 || humSuelo2 < 40)) {
digitalWrite(RELE1, HIGH);
digitalWrite(RELE2, LOW);
digitalWrite(RELE3, LOW);
digitalWrite(RELE4, LOW);
Serial.println(" MODO PROTECCIÓN ACTIVADO");
enviarUbidots(temp, humAire, humSuelo1, humSuelo2, flujo, nivel);
delay(2000);
return;
}
// TANQUE
if (bajo) digitalWrite(RELE1, HIGH);
if (alto) digitalWrite(RELE1, LOW);
bool llenandoTanque = digitalRead(RELE1);
if (llenandoTanque) {
digitalWrite(RELE2, LOW);
digitalWrite(RELE3, LOW);
digitalWrite(RELE4, LOW);
Serial.println(" Llenando tanque");
enviarUbidots(temp, humAire, humSuelo1, humSuelo2, flujo, nivel);
delay(2000);
return;
}
// MOTOR
if (temp > 40 || humAire > 50 || humSuelo1 < 40) {
digitalWrite(RELE2, HIGH);
} else {
digitalWrite(RELE2, LOW);
}
// RIEGO
digitalWrite(RELE3, humSuelo1 < 40 ? HIGH : LOW);
digitalWrite(RELE4, humSuelo2 < 40 ? HIGH : LOW);
// 📡 ENVÍO A UBIDOTS
enviarUbidots(temp, humAire, humSuelo1, humSuelo2, flujo, nivel);
// DEBUG
Serial.print("Humedad suelo 1: ");
Serial.print(humSuelo1);
Serial.println("%");
Serial.print("Humedad suelo 2: ");
Serial.print(humSuelo2);
Serial.println("%");
Serial.print("Temp: ");
Serial.print(temp);
Serial.println("°C");
Serial.print("Humedad aire: ");
Serial.print(humAire);
Serial.println("%");
Serial.print("Flujo: ");
Serial.print(flujo);
Serial.println("L/min");
Serial.print("Nivel: ");
if (alto) Serial.println("ALTO");
else if (medio) Serial.println("MEDIO");
else if (bajo) Serial.println("BAJO");
delay(3000);
}
// FUNCIÓN UBIDOTS
void enviarUbidots(float temp, float humAire, float h1, float h2, float flujo, int nivel) {
char payload[300];
sprintf(payload,
"{\"temperatura\":%.2f,"
"\"humedad_aire\":%.2f,"
"\"hum_suelo1\":%.2f,"
"\"hum_suelo2\":%.2f,"
"\"flujo\":%.2f,"
"\"nivel\":%d}",
temp, humAire, h1, h2, flujo, nivel
);
client.publish(topic, payload);
Serial.println(" Datos enviados:");
Serial.println(payload);
}