// ==================================================================== // SmartFlow ACS - Lógica Definitiva (Corrección Sonda NTC) // ==================================================================== #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 ORIGINALES --- const int PIN_NTC = D0; const int PIN_BOMBA_IN1 = D1; const int PIN_BOMBA_IN2 = D2; const int PIN_BUTTON = D3; const int PIN_VALVULA_IN1 = D6; const int PIN_VALVULA_IN2 = D7; // --- 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) enum Estados { REPOSO, PANTALLA_TEMPORAL, FUNCIONANDO, FASE_APAGANDO }; Estados estadoActual = REPOSO; unsigned long tiempoInicioEstado = 0; unsigned long tiempoFaseApagando = 0; void setup() { Serial.begin(115200); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); } pinMode(PIN_BOMBA_IN1, OUTPUT); pinMode(PIN_BOMBA_IN2, OUTPUT); pinMode(PIN_VALVULA_IN1, OUTPUT); pinMode(PIN_VALVULA_IN2, OUTPUT); pinMode(PIN_BUTTON, INPUT); // Pantalla de cortesía al arrancar display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(0, 10); display.println(" SISTEMA CONFIGURADO"); display.setCursor(0, 30); display.println(" Listo..."); display.display(); delay(2000); apagarActuadores(); } void loop() { // 1. Leer temperatura real con la ecuación para NTC int analogValue = analogRead(PIN_NTC); // Calcular la resistencia de la NTC basándonos en la lectura del ADC // (Ajustado para el divisor de tensión común: NTC conectada a GND y R_10K a VCC) float resistenciaNTC = RESISTENCIA_SERIE / ((float)ADC_MAX / analogValue - 1.0); // Aplicar ecuación de Steinhart-Hart (Beta) float temp; temp = resistenciaNTC / TERMISTOR_NOMINAL; // (R/Ro) temp = log(temp); // ln(R/Ro) temp /= BETA; // 1/B * ln(R/Ro) temp += 1.0 / (TEMP_NOMINAL + 273.15); // + (1/To) temp = 1.0 / temp; // Invertir para obtener Kelvin temp -= 273.15; // Convertir a Celsius // *Nota de seguridad*: Si notas que sigue invertida, significa que en tu PCB la NTC // está hacia VCC. En ese caso, la línea de 'resistenciaNTC' se cambiaría por: // float resistenciaNTC = RESISTENCIA_SERIE * ((float)ADC_MAX / analogValue - 1.0); // 2. Detectar pulsación real (Flanco de bajada: pasa de HIGH a LOW) bool botonPulsado = false; if (digitalRead(PIN_BUTTON) == LOW) { delay(50); // Pequeño filtro físico para ignorar el chispazo inicial if (digitalRead(PIN_BUTTON) == LOW) { botonPulsado = true; // FRENO DE MANO: Espera aquí bloqueado hasta que SUELTES el botón por completo while(digitalRead(PIN_BUTTON) == LOW) { delay(10); } } } // 3. Máquina de estados switch (estadoActual) { case REPOSO: apagarActuadores(); display.clearDisplay(); display.display(); // Pantalla a negro en ahorro energético if (botonPulsado) { tiempoInicioEstado = millis(); if (temp > 30.0) { estadoActual = PANTALLA_TEMPORAL; } else { estadoActual = FUNCIONANDO; tiempoInicioEstado = millis(); // Guardamos cuándo empezó a funcionar (para los 5 min) } } break; case PANTALLA_TEMPORAL: mostrarOLED("TEMP ALTA", temp, "REPOSO"); // A los 5 segundos se apaga sola if (millis() - tiempoInicioEstado >= 5000) { estadoActual = REPOSO; } break; case FUNCIONANDO: encenderActuadores(); mostrarOLED("RUNNING", temp, "B:ON / V:ON"); // Paramos si: sube de 35°C, pasan 5 min (300.000 ms) o vuelves a pulsar if (temp >= 35.0 || (millis() - tiempoInicioEstado >= 300000) || botonPulsado) { estadoActual = FASE_APAGANDO; tiempoFaseApagando = millis(); } break; case FASE_APAGANDO: unsigned long transcurrido = millis() - tiempoFaseApagando; if (transcurrido < 5000) { // Primeros 5 segundos: Bomba OFF, Válvula sigue ON digitalWrite(PIN_BOMBA_IN1, LOW); digitalWrite(PIN_BOMBA_IN2, LOW); digitalWrite(PIN_VALVULA_IN1, HIGH); digitalWrite(PIN_VALVULA_IN2, LOW); mostrarOLED("OFF BOMBA", temp, "B:OFF / V:ON"); } else if (transcurrido >= 5000 && transcurrido < 10000) { // Del segundo 5 al 10: Todo OFF apagarActuadores(); mostrarOLED("OFF TODO", temp, "B:OFF / V:OFF"); } else { // A los 10 segundos, volvemos a reposo total y pantalla a negro estadoActual = REPOSO; } break; } delay(20); } void encenderActuadores() { digitalWrite(PIN_BOMBA_IN1, HIGH); digitalWrite(PIN_BOMBA_IN2, LOW); digitalWrite(PIN_VALVULA_IN1, HIGH); digitalWrite(PIN_VALVULA_IN2, LOW); } void apagarActuadores() { digitalWrite(PIN_BOMBA_IN1, LOW); digitalWrite(PIN_BOMBA_IN2, LOW); digitalWrite(PIN_VALVULA_IN1, LOW); digitalWrite(PIN_VALVULA_IN2, LOW); } 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(); }