#include <dht.h>
#define DHT22_PIN 5
#define POT_PIN A0
#define OUTPUT_PIN 9
dht DHT;
// PID
double setpoint; // Temperatura deseada
double input; // Temperatura medida
double output; // Salida PWM
double kP = 2.0; // Ajustar según tu sistema
double kI = 0.1;
double kD = 0.05;
double previousError = 0;
double integral = 0;
// Variables para suavizado
const int N_TEMP = 5; // Número de lecturas para promedio
double tempBuffer[N_TEMP] = {0};
int tempIndex = 0;
const int N_POT = 5; // Número de lecturas para suavizar potenciómetro
double potBuffer[N_POT] = {0};
int potIndex = 0;
// Función para mapear flotantes
double mapFloat(double x, double in_min, double in_max, double out_min, double out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Función para calcular promedio de un buffer
double promedio(double *buffer, int N) {
double suma = 0;
for (int i = 0; i < N; i++) suma += buffer[i];
return suma / N;
}
void setup() {
Serial.begin(9600);
pinMode(OUTPUT_PIN, OUTPUT);
Serial.println("=== PID optimizado con suavizado ===");
}
void loop() {
// --- Lectura de temperatura ---
int chk = DHT.read22(DHT22_PIN);
if (chk == DHTLIB_OK) {
tempBuffer[tempIndex] = DHT.temperature;
tempIndex = (tempIndex + 1) % N_TEMP;
input = promedio(tempBuffer, N_TEMP); // Promedio para suavizado
} else {
Serial.println("Error al leer DHT22");
}
// --- Lectura del potenciómetro ---
potBuffer[potIndex] = analogRead(POT_PIN);
potIndex = (potIndex + 1) % N_POT;
double potProm = promedio(potBuffer, N_POT);
setpoint = mapFloat(potProm, 0, 1023, -40.0, 80.0);
// --- Cálculo PID ---
double error = setpoint - input;
integral += error;
integral = constrain(integral, -100, 100); // Anti-windup
double derivative = error - previousError;
output = kP*error + kI*integral + kD*derivative;
output = constrain(output, 0, 255);
// --- Aplicar salida PWM ---
analogWrite(OUTPUT_PIN, output);
previousError = error;
// --- Información serial ---
Serial.print("Temp: "); Serial.print(input);
Serial.print(" °C | Setpoint: "); Serial.print(setpoint);
Serial.print(" °C | PWM: "); Serial.println(output);
delay(500); // Actualiza cada 500 ms
}