// ==================================================================== // SmartFlow ACS - Lógica de Producción con Relés (NTC Definitiva) // v3.2 - Actualización de temperatura cada 1 segundo // ==================================================================== #include #include #include #include // Necesaria para el cálculo del logaritmo (NTC) #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // --- MAPEO DE PINES DEFINITIVO CON RELÉS --- const int PIN_NTC = D0; // Entrada analógica del termistor const int PIN_BUTTON = D3; // Botón físico en D3 const int PIN_RELE_BOMBA = D8; // Salida para relé de la Bomba const int PIN_RELE_VALVULA = D9; // Salida para relé de la Válvula // --- PARÁMETROS CONFIGURACIÓN NTC --- const float RESISTENCIA_SERIE = 10000.0; // Resistencia de 10K fija const float TERMISTOR_NOMINAL = 10000.0; // Resistencia de la NTC a 25°C (10K) const float TEMP_NOMINAL = 25.0; // Temperatura de referencia const float BETA = 3950.0; // Coeficiente Beta típico de las NTC comerciales const int ADC_MAX = 1023; // Resolución del ADC (10 bits) // --- CONFIGURACIÓN DE LÓGICA DIRECTA --- const int RELE_ON = HIGH; // HIGH activa el relé externo const int RELE_OFF = LOW; // LOW lo desactiva enum Estados { REPOSO, PANTALLA_TEMPORAL, FUNCIONANDO, FASE_APAGANDO }; Estados estadoActual = REPOSO; unsigned long tiempoInicioEstado = 0; unsigned long tiempoFaseApagando = 0; // --- VARIABLES PARA ESTABILIZAR TEMPERATURA --- unsigned long ultimoMuestreoTemp = 0; // Guarda cuándo se midió por última vez float tempEstable = 20.0; // Almacena el último valor calculado para usarlo en el bucle void setup() { Serial.begin(115200); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); } // Configuración de los pines de los relés como salidas pinMode(PIN_RELE_BOMBA, OUTPUT); pinMode(PIN_RELE_VALVULA, OUTPUT); pinMode(PIN_BUTTON, INPUT); // Por seguridad, aseguramos que arranquen apagados apagarActuadores(); // Pantalla de cortesía al arrancar display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(0, 10); display.println(" SMARTFLOW ACS v3.2"); display.setCursor(0, 30); display.println(" Temp. Estabilizada"); display.display(); delay(2000); // Hacemos una primera lectura inicial para que no empiece en 20.0ºC por defecto leerTemperatura(); } void loop() { // 1. Muestrear temperatura solo cada 1000 milisegundos (1 segundo) if (millis() - ultimoMuestreoTemp >= 1000) { leerTemperatura(); ultimoMuestreoTemp = millis(); // Reiniciar el temporizador de la muestra } // 2. Detectar pulsación real con control de flanco (espera a soltar) bool botonPulsado = false; if (digitalRead(PIN_BUTTON) == LOW) { delay(50); // Filtro físico anti-chispazo if (digitalRead(PIN_BUTTON) == LOW) { botonPulsado = true; while(digitalRead(PIN_BUTTON) == LOW) { delay(10); // Bloqueo hasta que se suelta el botón } } } // 3. Máquina de estados utilizando la temperatura estable switch (estadoActual) { case REPOSO: apagarActuadores(); display.clearDisplay(); display.display(); // Pantalla a negro (Ahorro energético) if (botonPulsado) { tiempoInicioEstado = millis(); if (tempEstable > 30.0) { estadoActual = PANTALLA_TEMPORAL; } else { estadoActual = FUNCIONANDO; tiempoInicioEstado = millis(); // Guardamos cuándo empezó a funcionar } } break; case PANTALLA_TEMPORAL: mostrarOLED("TEMP ALTA", tempEstable, "REPOSO"); if (millis() - tiempoInicioEstado >= 5000) { estadoActual = REPOSO; } break; case FUNCIONANDO: encenderActuadores(); mostrarOLED("RUNNING", tempEstable, "B:ON / V:ON"); // Condiciones de parada utilizando la temperatura estable if (tempEstable >= 35.0 || (millis() - tiempoInicioEstado >= 300000) || botonPulsado) { estadoActual = FASE_APAGANDO; tiempoFaseApagando = millis(); } break; case FASE_APAGANDO: unsigned long transcurrido = millis() - tiempoFaseApagando; if (transcurrido < 5000) { digitalWrite(PIN_RELE_BOMBA, RELE_OFF); digitalWrite(PIN_RELE_VALVULA, RELE_ON); mostrarOLED("OFF BOMBA", tempEstable, "B:OFF / V:ON"); } else if (transcurrido >= 5000 && transcurrido < 10000) { digitalWrite(PIN_RELE_BOMBA, RELE_OFF); digitalWrite(PIN_RELE_VALVULA, RELE_OFF); mostrarOLED("OFF TODO", tempEstable, "B:OFF / V:OFF"); } else { estadoActual = REPOSO; } break; } delay(20); } // --- FUNCIÓN SEPARADA PARA LEER LA NTC --- void leerTemperatura() { int analogValue = analogRead(PIN_NTC); float resistenciaNTC = RESISTENCIA_SERIE / ((float)ADC_MAX / analogValue - 1.0); float temp; temp = resistenciaNTC / TERMISTOR_NOMINAL; temp = log(temp); temp /= BETA; temp += 1.0 / (TEMP_NOMINAL + 273.15); temp = 1.0 / temp; temp -= 273.15; tempEstable = temp; // Actualizamos la variable global que lee el resto del programa } // --- FUNCIONES DE CONTROL DE ACTUADORES --- void encenderActuadores() { digitalWrite(PIN_RELE_BOMBA, RELE_ON); digitalWrite(PIN_RELE_VALVULA, RELE_ON); } void apagarActuadores() { digitalWrite(PIN_RELE_BOMBA, RELE_OFF); digitalWrite(PIN_RELE_VALVULA, RELE_OFF); } void mostrarOLED(String estado, float temperatura, String actuadores) { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(0, 0); display.print("SMARTFLOW ACS"); display.setCursor(0, 12); display.print("EST: "); display.print(estado); display.setTextSize(2); display.setCursor(0, 26); display.print(temperatura, 1); display.write(247); display.print("C"); display.setTextSize(1); display.setCursor(0, 52); display.print("OUT: "); display.print(actuadores); display.display(); }