#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ThingSpeak.h>
#include <DHT.h> // Biblioteca para el sensor DHT22
int sensorPin = 14;
// Configuración de las válvulas (Relés) para entrada recirculación
#define V4 16 // Relé 1 - Válvula de entrada de agua de red
#define V5 17 // Relé 2 - Válvula de entrada de agua recuperada
#define V6 5 // Relé 3 - Válvula de solución Bebrosheen entrada
#define V7 4 // Relé 4 - Válvula de recirculación interna
#define V8 15 // Relé 5 - Bomba de impulsión hacia llenadora
#define V9 25 // Relé 6 - Válvula de retorno
#define LED_BOMBA 15 // LED para simular la bomba (conectado a V8)
#define LED2_BOMBA 25 // LED para simular retorno bomba (conectado a V9)
#define LEDRGB_INTERCAMBIADOR // Led para simular la temp alcanzada de Recirculación
int rojo=22;
int verde=21;
int azul=19;
bool state = false; // Declaración e inicialización de la variable global
// Configuración de las válvulas (Relés) para retorno recirculación
#define V1 33 // Relé 7 - Válvula de ingreso de agua de red al circuito CIP
#define V2 32 // Relé 8 - Válvula de retorno agua recuperada
#define V3 26 // Relé 9 - Válvula de solución Bebrosheen retorno
#define V10 18 // Relé 10 - Válvula de descarga bebrosheen
// Configuración del sensor de temperatura (DS18B20)
#define ONE_WIRE_BUS 14 // Pin donde está conectado el sensor DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Configuración del sensor DHT22 (para medir concentración)
#define DHT_PIN 12 // Pin donde está conectado el sensor DHT22
DHT dht(DHT_PIN, DHT22); // Creación de objeto DHT22
// Configuración del sensor de flujo (Potenciómetro)
#define FLOW_SENSOR_PIN 35 // Pin analógico para leer el potenciometro de flujo
int flow_value = 0; // variable para almacenar el valor del potenciómetro
// Configuración de Wi-Fi
const char* ssid = "Wokwi-GUEST"; // Usuario Wi-Fi
const char* password = ""; // Contraseña Wi-Fi
WiFiClient client;
// ThingSpeak
unsigned long myChannelNumber = 2767550; // Reemplazar con tu Channel ID
const char* myWriteAPIKey = "NU1MBU26RR0LWT7R"; // Reemplazar con tu API Key
// Conexión a Wi-Fi
void connectWifi() {
Serial.print("Conectando a Wi-Fi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Conectado al Wi-Fi");
ThingSpeak.begin(client);
}
// Función para encender o apagar válvulas
void controlValve(int valvePin, bool state) {
digitalWrite(valvePin, state ? HIGH : LOW);
}
// Función para simular la bomba de la valvula V8 con el LED
void simulatePump(bool state) {
digitalWrite(LED_BOMBA, state ? HIGH : LOW);
}
// Función para simular la bomba de la valvula V9 con el LED2
void simulatePump2(bool state) {
digitalWrite(LED2_BOMBA, state ? HIGH : LOW);
}
// Función para simular intercambiador con el LEDRGB
void simulatePump3(bool state) {
digitalWrite(rojo, state? HIGH : LOW); // señal del rojo
}
void simulatePump4(bool state) {
digitalWrite(verde, state ? HIGH : LOW); // señal del verde
}
void simulatePump5(bool state) {
digitalWrite(azul, state ? HIGH : LOW); // señal del azul
}
// Función para leer la temperatura en °C desde DS18B20
float readTemperatureDS18B20() {
sensors.requestTemperatures(); // Solicitar lectura de temperatura
float tempC = sensors.getTempCByIndex(0); // Leer la temperatura del primer sensor
return tempC;
}
// Función para leer la concentración (%) desde DHT22
float readConcentrationDHT22() {
float c = dht.readHumidity(); // Leer la humedad como valor de concentración
return c; // Devuelve la humedad como un valor de concentración
}
// Función para leer el flujo en L/min desde el potenciómetro
float readFlow() {
flow_value = analogRead(FLOW_SENSOR_PIN);
// Mapeo de 0-4095 a 0-50 L/min
return (flow_value * 50.0) / 4095.0;
}
// Función para enviar datos a ThingSpeak
void sendDataToThingSpeak(float temperature, float flowRate, float concentration) {
ThingSpeak.setField(1, temperature); // Campo 1: Temperatura (°C)
ThingSpeak.setField(2, flowRate); // Campo 2: Flujo (L/min)
ThingSpeak.setField(3, concentration); // Campo 3: Concentración (%)
ThingSpeak.writeFields( 2767550, "NU1MBU26RR0LWT7R");
// Desde aqui el control remoto del intercambiador de calor
int estado = ThingSpeak.readIntField(2767550,4);
Serial.println(estado);
digitalWrite(verde,estado);
}
// Variables para manejar el tiempo
unsigned long recirculationStartTime = 0; // Tiempo de inicio de la recirculación
bool recirculationActive = false; // Estado de la recirculación
// Configuración de pines
void setup() {
Serial.begin(115200);
// Configuración de pines de las válvulas
pinMode(V1, OUTPUT);
pinMode(V2, OUTPUT);
pinMode(V3, OUTPUT);
pinMode(V4, OUTPUT);
pinMode(V5, OUTPUT);
pinMode(V6, OUTPUT);
pinMode(V7, OUTPUT);
pinMode(V8, OUTPUT);
pinMode(V9, OUTPUT);
pinMode(V10, OUTPUT);
pinMode(LED_BOMBA, OUTPUT); // LED simula la bomba para impulsar el flujo
pinMode(LED2_BOMBA, OUTPUT); // LED simula la bomba para retorno el flujo
// Codigo de configuración Led RGB
pinMode(rojo, OUTPUT); // rojo salida
pinMode(verde, OUTPUT); // verde salida
pinMode(azul, OUTPUT); // azul salida
{
// Configuraciones iniciales
state = true; // Cambiar el valor si es necesario
state = false;
}
// Conexión a Wi-Fi
connectWifi();
// Inicializar el sensor de temperatura DS18B20
sensors.begin();
// Inicializar el sensor DHT22
dht.begin();
}
void loop() {
// Leer datos de sensores
float temperature = readTemperatureDS18B20();
float flowRate = readFlow();
float concentration = readConcentrationDHT22();
// Función para simular intercambiador con el LEDRGB
digitalWrite(rojo, LOW); // señal del rojo
digitalWrite(verde, LOW); // señal del verde
digitalWrite(azul, LOW); // señal del azul
// Enviar datos a ThingSpeak
sendDataToThingSpeak(temperature, flowRate, concentration);
// Mostrar valores en el monitor serial
Serial.print("Temperatura: ");
Serial.print(temperature);
Serial.print(" °C Flujo: ");
Serial.print(flowRate);
Serial.print(" L/min Concentración:""%");
Serial.println(concentration);
//Declaro variable de temperatura
temperature = readTemperatureDS18B20();
// Fase 1: Enjuague Inicial (Temperatura aproximadamente 20°C)
if (temperature <= 22) {
Serial.println("Fase 1: Enjuague Inicial");
controlValve(V1, HIGH); // Abre V1 - Abre el ingreso principal de agua de red
delay(5000); // Espera 5 segundos
controlValve(V1, LOW); // permanece cerrada V1 - cierra agua de red.
delay(5000); // Espera 5 segundos
Serial.println("Fase 1: Se enciende el Intercambiador de Color verde");
controlValve(V4, HIGH); // Abre V4 - Salida de agua
controlValve(V9, HIGH); // Abre V9 - Dirección de flujo hacia agua recuperada
simulatePump2(true); // Enciende el LED de la bomba
delay(1500);
controlValve(V8, HIGH); // Activa V8 - impulsar flujo con la Bomba
simulatePump(true); // Enciende el LED de la bomba
delay(1000);
controlValve(V2, HIGH); // Abre V2 - Retorno al tanque de agua recuperada
controlValve(V5, LOW); // permanece cerrada V5 - Retorno al tanque de agua recuperada
delay(10000); // Espera 10 segundos
}
// Fase 2: Limpieza Química (Temperatura entre 60°C y 77°C)
if (temperature > 60 && temperature <= 72) {
Serial.println("Fase 2: Limpieza Química");
controlValve(V4, LOW); // Cierra V4 - Entrada de agua de red
controlValve(V2, LOW); // Cierra V2 - Retorno al tanque de agua recuperada
controlValve(V6, HIGH); // Abre V6 - Solución Bebrosheen
simulatePump5(true); // Enciende el intercambiador
delay(1500);
controlValve(V8, HIGH); // Mantiene V8 - Bomba activa implusa flujo
simulatePump(true); // Enciende el LED de la bomba
delay(1000);
controlValve(V5, LOW); // Cambia dirección cierre de flujo hacia Bebrosheen
controlValve(V9, LOW); // Abre retorno dirección de flujo Bebrosheen
simulatePump2(true); // Enciende el LED de la bomba
delay(1500);
controlValve(V3, HIGH); // Abre V3 retorno de flujo tanque bebrosheen
delay(10000); // Espera 10 segundos
}
if (temperature < 72) {
controlValve(V7, LOW); // permanece cerrada V7 - Recirculación interna
}
// Fase 3: Recirculación del Bebrosheen (Temperatura > 77°C)
if (temperature > 73 && temperature <= 77) {
Serial.println("Fase 3: Recirculación del Bebrosheen");
controlValve(V6, HIGH); // Permanece abierta V6 - Solución Bebrosheen
controlValve(V7, HIGH); // Abre V7 - Recirculación interna
controlValve(V8, HIGH); // Mantiene V8 - Bomba activa
simulatePump(true); // Enciende el LED de la bomba
controlValve(V9, LOW); // Retorno cerrado para recircular Bebrosheen
simulatePump3(true); // Enciende el intercambiador
delay(10000);
simulatePump2(false); // Apaga el LED de la bomba
controlValve(V3, HIGH); // Permanece abierta V3 retorno de flujo tanque bebrosheen
delay(15000); // Espera 15 segundos
// Si la recirculación está activa
if (millis() - recirculationStartTime >= 15000) {
Serial.println("Recirculación finalizada, ajustando válvulas y bombas...");
// Desde aqui el control remoto de la valvula V10 descarga Bebrosheen
int estado = ThingSpeak.readIntField(2767550,5);
Serial.println(estado);
digitalWrite(V10,estado);
controlValve(V6, LOW); // Cerrar V6 - Solución Bebrosheen
controlValve(V7, LOW); // Cerrar V7 - Recirculación interna
controlValve(V8, LOW); // V8 - Bomba apagar
simulatePump(false); // Apagar el LED de la bomba
controlValve(V9, LOW); // Apagar Retorno para recircular Bebrosheen
simulatePump2(false); // Apaga el LED de la bomba
controlValve(V3, LOW); // Cerrrar V3 retorno de flujo tanque bebrosheen
simulatePump3(false); // Apaga el intercambiador
delay(10000);
}
}
// Fase 4: Enjuague Final (Temperatura < 29°C)
if (temperature >= 26 && temperature <= 29) {
Serial.println("Fase 4: Enjuague Final");
controlValve(V4, HIGH); // Abre V4 - Entrada de agua
controlValve(V9, HIGH); // Dirección de flujo hacia agua recuperada
simulatePump2(true); // Apaga el LED de la bomba
controlValve(V8, HIGH); // Mantiene V8 - Bomba activa
simulatePump(true); // Enciende el LED de la bomba
controlValve(V2, HIGH); // Abre V2 - Retorno al tanque de agua recuperada
delay(12000); // Espera 10 segundos
Serial.println( "Final CIP");
controlValve(V4, LOW); // Cambia dirección cierre de flujo hacia Bebrosheen
controlValve(V9, LOW); // Cierra retorno dirección de flujo Bebrosheen
simulatePump2(false); // Apaga el LED de la bomba
controlValve(V8, LOW); // V8 - Bomba se apaga
simulatePump(false); // Apaga el LED de la bomba
controlValve(V2, LOW); // Cierra V2 - Retorno al tanque de agua recuperada
delay(5000); // Espera 5 segundos
simulatePump3(true); // se apaga el CIP
simulatePump4(true);
simulatePump5(true);
delay(1000);
// Desde aqui el controlo apagar/encender bomba de la V9
int estado = ThingSpeak.readIntField(2767550,6);
Serial.println(estado);
digitalWrite(LED2_BOMBA,estado);
}
// Espera antes de repetir el ciclo
delay(15000);
}