algoritmo del controlador PID para el controlador digital sr90

0

Estoy intentando implementar el algoritmo de control PI en c #. Encontré ayuda en internet y entiendo la fórmula de cómo usarla. He medido el valor (PV) = 20 ° C y el punto de ajuste (SP) = 80 ° C; Me gustaría actualizar cada 2 segundos a tiempo. una vez que el valor medido alcanza el punto de ajuste, el controlador tiene que apagarse así.

Encontré este código enlace al algoritmo pid

pero lo que necesito es cómo calcular los factores de ganancia que ganan Kp y Ki, y qué hay de dt. Estoy descuidando el derivado. Entonces, por favor, ¿puede alguien explicarme cómo calcular esos factores de ganancia? Estoy usando el controlador digital shimaden SR90 (compré esto). Encontré algunos factores en el manual, pero no estoy seguro de poder usar esos factores de ganancia.

  

Editado para dudas.

He intentado su código de esta manera, no estoy seguro de que esta sea la forma correcta o no.

int temperature;
//int setpoint; // i have commented these because we never used.
//int status = 0;
int pulses = 0;
//int integral = 4;
//int derivative = 5;
int upperTemp = 1000; //100.0C
int upperLimit = 100; //pulses per time frame // i can take 100 pulses per sec.


 runtime //make a timer that runs and updates temperature value...lets say every second
{
  read temperature; //every second
  temperature *= 10; //multiply by 10 for decimal place, but still keeping in integer
  pulses = map(temperature, upperTemp, 0, 0, upperLimit);

  //take this value of pulses to update the timer interval
   I didn't understand the above line if i am right then here i need to call the       
   timer like 
   if(pulses> somevalue)
     call timer
   else
     no call
  }

//borrowed from arduino
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Tengo una pregunta aquí 1) ¿Este método parece ser diferente al anterior porque nunca usamos ganancias o errores en este método? 2) Entiendo que "upperTemp" es el valor del punto de ajuste.

Lo he intentado con un ejemplo simple como este

 int temperature = 20;
 int pulses = 0;
 int upperTemp = 800; //80.0C
 int upperLimit = 100; //pulses per time frame // i can take 100 pulses per sec.

 read temperature; //every second which is 20 in this case
 temperature *= 10; //multiply by 10 for decimal place, 20*10 =200;
  pulses = map(temperature, upperTemp, 0, 0, upperLimit);// map(200,800,0,0,100)

 //then map function will return pulses = 75;

//then here i don't understand that much but i am thinking like that

if(pulses> 75)
  switch on;
else 
   switch off; 

No estoy seguro de que estoy haciendo lo correcto! ¿Puedes sugerirme algo más aquí?

    
pregunta reddy

1 respuesta

0

La clave para una buena ingeniería es mantenerlo simple. En su caso, puede usar algo muy simple para activar / desactivar un relé para controlar un calentador. Un código psuedo:

int temperature;
int setpoint;
int status = 0;
int pulses = 0;
int integral = 4;
int derivative = 5;
int upperTemp = 1000; //100.0C
int upperLimit = 100; //pulses per time frame
int counter = 0;

//NO PULSING
runtime //make a timer that runs and updates temperature value
{
  read temperature; 
  temperature *= 10; //still keeping in int for faster processing
  status = ((setpoint - temperature)*integral)/derivative; //EX: (800-400)*4/5 = 320
                                                           //EX: (800-780)*4/5 = 16
  status = abs(status); //get absolute value, this for for within range
                        //(800-850)*4/5 = -40 -> ABS(-40) = 40
  if(status < 16)  //from example, 16 means that value is within 2*C, you can always 
    Relay Off;     //change this value to something else (e.g: (800-795)*4/5 = 4
  else             //4 gives 0.5*C tolerance range...which is a bit tight for temp.
    Relay On;      //anyway, play around with this value;
                   //you can also change integral and derivative if you wish.        
}

//WITH PULSING
runtime //make a timer that runs and updates temperature value...lets say every second
{
  read temperature; //every second
  temperature *= 10; //multiply by 10 for decimal place, but still keeping in integer
  pulses = map(temperature, upperTemp, 0, 0, upperLimit); //when temperature increases, 
                                                          //pulses decreases...vice versa
  //take this value of pulses to update the timer interval
  //timer's interval = pulses per second or minute
}

timer
{
  if(Relay On)
    Relay Off;
  else
    Relay On;   
}

//borrowed from arduino
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

// Método PWM: todavía se necesita el tiempo de ejecución con pulsos desde arriba. Supongamos que recibe 75 pulsos, esto significa que el relé estará activado durante el 75% de la duración de cada impulso y desactivado para el otro 25%. Digamos que desea tener una frecuencia de 1s (1000mS). El relé estará activado durante 750 ms y desactivado durante 250 ms. Si la temperatura está muy alejada del punto de ajuste, incluso podría estar encendida durante el 100% del tiempo.

// elija la duración completa por tick_interval * porcentaje: 100mS * 100 = 10000mS o 10segundos. Volver al ejemplo. Si tiene 75 pulsos, entonces el relé se activará durante 7.5 segundos y se desactivará durante 2.5 segundos.

timer //example 100mS per tick
{
  if(counter > 100) //has reached the end of time period
    counter = 0;
  if(counter > pulses) //pulses from above is now the duty cycle
  {
    if(Relay is On)
      Relay off;
  }
  else
  {
    if(Relay is Off)
      Relay on;
  }
  counter++; //increment by 1
}

// este método es más flexible que usar un número fijo (30 minutos) porque los diferentes controladores del calentador responden de manera diferente

    
respondido por el NothinRandom

Lea otras preguntas en las etiquetas