Hola a todos, he estado desarrollando un control de temperatura PID de una lampara incandescente con arduino mediante el uso de un TRIAC y un opto-acoplador MOC3041, en el cual inicialmente, la lampara esta a su máxima capacidad para permitir el aumento de temperatura y a medida que dicha temperatura se acerca a un setpoint la luz de la lampara debe tener menos intensidad. Para el sensor de temperatura, estoy usando un LM35.
El inconveniente que se me presenta es que la lampara comienza a parpadear en vez de rebajar la intensidad de luz. Alguien sabe como podría solucionar esto?
El código que estoy utilizando es el siguiente:
const int numReadings = 20;
int readings[numReadings];
int index = 0;
int total = 0;
float Tprom = 0;
float chaloTEM = A7; //Puerto analogico de lectura del sensor lm35
float TempR; // Temperatura actual leída
int setpoint = 30; // Temperatura deseada "set point"
float error_actual = 0; // Variables de ERROR
float error_anterior = 0;
float t_muestreo = 1000; //Tiempo de muestreo [ms]
//=====Constantes del control PID ================
float Kpe = 40; // Constante Proporcional
float Kie = 0.00005; //Constante integral
float Kde = 0.7; //Constante Derivativa del Sistema
float PID = 0; //Señal
//Recordar que las constantes deben ser halladas previamente según el comportamiento del sistema en lazo abierto
//=====Variables de cálculo=====================
float prop = 0;
float inte = 0;
float deri = 0;
float acum = 0;
float area = 0;
float Ts = 0;//Tiempo de Muestreo
void setup()
{
Serial.begin(9600);
pinMode(7, OUTPUT); // salida de la señal PWM
pinMode(8, OUTPUT);
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0; //For para cantidad de datos promedios del smooting
}
void loop()
{
//Operaciòn del smooting
total= total - readings[index];
// lectura del sensor
readings[index] = analogRead(chaloTEM);
// suma la lectura al total:
total= total + readings[index];
// avance a la siguiente posiciòn en el conteo
index = index + 1;
// si estamos al final del conteo...
if (index >= numReadings)
// ...vuelva al principio
index = 0;
Tprom= ( 5.0 * total * 100.0) / (1023.0 * numReadings);//se pasa de voltaje a temperature y se divide en el numero de lecturas que se quiere promediar
if (setpoint <= Tprom) //
{
PID = PID ;
analogWrite(7,PID);
analogWrite(8,PID);
Serial.print(Tprom);
Serial.print(",");
//Serial.print(" PID = ");
Serial.println(PID);
Serial.print(" ERROR (-) = ");
Serial.println(error_actual);
Serial.println(" ");
}
else //
{
//Tiempo de muestreo en segundos:
Ts = t_muestreo/1000;
// Tomo la lectura del sensor
TempR = Tprom; // Consigno el valor leido en esta variable
// Conversión lineal de la señal de entrada a temperatura en grados centígrados :
error_actual = setpoint - Tprom; //cálculo de error
//error -> proporcional
prop = error_actual*Kpe; // Error Proporcional=Kp*errror
//error -> integral
area = error_actual+error_anterior; // error sumatoria
area = area*Ts;
area = area*0.5;
acum = acum+area;
inte = acum*Kie;
inte = constrain(inte, -110, 110); //filtro anti-windup, para evitar saturación del actuador
//error -> derivada
deri = error_actual-error_anterior;
deri = deri*Kde;
//PID-->>
PID = prop + inte + deri;
PID = constrain(PID, 0, 255); //restricción de la acción de control a rangos admisibles de PWM.
//Almacenamiento del error actual
error_anterior = error_actual;
if(error_actual>1)
{
PID = PID;
//condición primaria
}
else
PID=0;
analogWrite(7,PID);
analogWrite(8,PID);
//imprimo los valores deseados
Serial.print(Tprom);
Serial.print(",");
Serial.println(PID);
Serial.print(" ERROR (+) = ");
Serial.println(error_actual);
Serial.println(" ");
}
delay(t_muestreo);
}