Control PID automático de velocidad de un motor DC

Busca informacion sobre la ecuacion de diferencias de la funcion pid (proporcional integrativo derivativo)
 
Hola de nuevo, aún no abandono el tema es solo que me han tenido muy atareado...

Volviendo al asunto:
Estuve buscando más información acerca de los controladores PID y antes de armar el prototipo, me di cuenta de que no sabía en que consiste la automatización. Sé algunas cosas muy básicas sobre control, como la función de transferencia de lazo abierto y lazo cerrado, que imagino, esta última es el principio de la automatización, ¿no? :confused:

Entonces, me podrían aclarar ¿qué es la automatización?, ¿en que consiste físicamente? o alguna forma en la que pudieran explicarme esto por favor. Creo que así tendría una mejor idea de lo que hago, o de lo que pienso hacer...

Sin mas por el momento, les agradezco su tiempo y sus respuestas... Que tengan un buen día :)
 
amigo adonayo . yo hice un control PID, controlo la temperatura de un horno, el tema de automatización o control indutrial es un tema un poco complicado, yo te puedo ayudar con esto de control automatico soy ingeniero en electricidad y electronica y como te dije hice un control de temperatura de un horno indutrial. agregame al msn para que te informacion y los pasos a seguir por si queres saber mas sobre el tema ok...
Mejor leo las Normas de Participación@forosdeelectronica.com
atte jose tecol
 
Última edición por un moderador:
Muchas gracias por tu interes amigo jose tecol, espero tu guía (y) :)...

Perdon por abandonar por un buen rato este tema... no es que haya perdido el interes, es solo que en la escuela avanzan con otros temas y pues no puedo disponer de todo mi tiempo para algo que se supone que debi de haber hecho hace mucho tiempo :oops: ...

Entonces, volviendo al tema! :LOL:

El controlador PID ya vi como funciona, teoricamente claro... he visto la respuesta de salida de cada bloque (control proporcional, control integrativo y control derivativo) y la salida del conjunto de estas...

El único problema es que no se en donde meter la retroalimentación :confused: o que cosa agragar para hacer de ese control, un control automatico, aún no me queda claro el porque un control pasa a hacer automatico :cabezon:...

Ayudenme por fa... prometo estar mas al pendiente de este post!

Saludos a todos y muchas gracias! :)
 
retroalimentacion y bloque suma.

La retroalimentacion es la señal de salida del sistema que se resta a la entrada. Se simboliza en un diagrama de esta forma.

algeb10.jpg


De manera que en un PID como es tu caso, tienes la señal de las RPM del motor, ya convertidas a un nivel de voltaje. Por ejemplo, 2000RPM = 2V.
Así que si tu referencia o señal de entrada del sistema es de 3000 RPM = 3V, el bloque suma en su salida te devera dar:

3V (de la referencia) - 2V (de tu medidor de RPM) = 1V (es el que entra en cada bloque del P I D).

En el caso de un PID análogo con operacionales pues es muy simple. El bloque suma es equivalente a este simbolo eléctrico.

opamp_block.jpg


Usando esta configuracion eléctrica

Diag5.gif


Y ya, la salida del opamp es la salida de lo que se representa en el bloque de suma.
 
Adonayo, El circuito que pusiste originalmente es un control de velocidad que no es automático; eso está claro, verdad?. ¿Por qué?. Porque si le pones carga al eje del motor, éste va a reducir su velocidad y si quieres compensar esa pérdida de velocidad, debes intervenir moviendo ese potenciómetro. Ahora si tomas la lectura de velocidad del motor y la traduces por ejemplo a voltaje y lo ingresas al control para que éste compense la velocidad (aumente o baje) manteniéndola constante o igual al valor puesto. Esto es lo que se llama un control automático, en éste caso de velocidad. Como ves, hay una realimentación que le indica al control el valor de la variable controlada. Hay que considerar otras variables para proteger al sistema, sea al control o al propio dispositivo controlado como ser límite de corriente.
 
@antiworldx:
Mmmm :unsure: con que eso es la retroalimentación... ¡Gracias amigo, ahora me queda más claro! (y):)

@Alberto91:
Gracias, con tú respuesta y la de antiworldx me ha quedado más claro que es lo que me falta... En este caso es un sensor, ¿no? el cual comprobará que la velocidad del motor no suba o baje mas alla de un cierto límite...
Ahora (por favor corrijanme si me equivoco), el sensor quedara a la salida del circuito, es decir en donde esta la flecha del motor para medir su velocidad, y la salida de este sensor será la retroalimentación que entrara en el primer operacional (entrada inversora) para que mantenga una velociadad constante, ¿cierto?

Solo una pregunta más... ¿qué dispositivo podría usar para sensar la velocidad? Podría hacer la comparación de voltaje de salida en lugar de medir las rpm del motor, ¿cierto?

¡Muchas gracias por su ayuda!:) Espero sus respuestas...

¡Saludos!:cool:
 
Mira, que hay sensores que conectas al eje del motor y te da una salida en voltaje proporcinal a las PRM. No recuerdo su nombre... En el foro en alguna parte ya resolvieron ese detalle, buscale buscale.

O la otra es hacerlo con una rueda dentada, un encoder y un micro, pero es mas complicado...
 
Última edición:
El voltaje de salida para el motor puede estar sin variación en un amplio rango de carga o de velocidad, además que si tomas el voltaje de salida para realimentar, no estarías sensando la variable a controlar. Si no requieres precisión, un buen sensor es el que te detecta las rpm en el eje del motor; éste te dará pulsos, le agrega un pequeño capacitor y obtendrás niveles de dc de acuerdo a la velocidad. El sensor lo puedes hacer óptico o magnético. Podrías aprovechar un mouse viejo (de los de bolita), ahi trae el conjunto emisor , receptor y disco ranurado. Magnético con un sensor de efecto hall digital.

Si lo quieres más preciso, puedes usar el LM2907 que es un convertidor de frecuencia a voltaje, busca en www.alldatasheet.com su hoja de datos donde hay la aplicación de tacómetro que te serviría.
 
Última edición:
Hasta a mi me sirve esa sugerencia alberto, por que yo se hacerlo muy preciso con un microcontrolador, y para aplicaciones de PID digitales es excelente. Pero con los PID análogos ya no es buena idea usar el microcontrolador por que lo vuelve complicado usar el micro y luego un DAC.
 
Pues asi es ya tienes todo solo te falta el valor de retro-alimentacion que lo tienes que tomar de tu motor y se supone que ese valor tratara de llegar a tu voltaje de referencia en mi caso quiero controlar temperatura :D entonces le pondre un lm35 que da voltaje y a ver si funciona primero lo simulare pero si tu lo que quieres son rmp pues tienes que medirlas y trasformarlas a voltaje y ese voltaje te digo tratara de llegar a tu voltaje de referencia .... suerte
 
Buenas, qui os dejo este projecto..:LOL:
Código:
         // Programa: Controlador Fuzzy PI LM35
         

         #include <16F877.H>
         #device adc = 10                                            // Utilizar A/D de 10 bits
         #fuses NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
         #use delay(clock = 4000000)                                 // Define clock de 4MHz
         #priority timer0, ext                                       // Define enterrupcion como priodidad
         #include <LCD.C>        

         #use fast_io(a)
         #use fast_io(b)
         #use fast_io(c)
         #use fast_io(d)
         #use fast_io(e)

         int temp_ref = 26;                                          // Temperatura de referencia
         
      // *** Interrupção que garante um tempo de amostragem de 1 segundo ***
      
         #int_timer0
         void trata_tmr0() 
      {
         static int cont_timer0;                                     // Variável de contagem para o timer 0
         set_timer0(131);                                            // Inicializa o timer no valor 131
         cont_timer0++;                                              // Incrementa a variável de contagem em uma unidade
         
         if (cont_timer0 == 125)                                     // Ocorreram 125 interrupções (1s)?
      {
         float temp;                                                 // Temperatura
         float erro;                                                 // Erro da temperatura
         static float erro_anterior;                                 // Erro anterior da temperatura
         static float out_fuzzy_anterior;                            // Saída anterior do controlador Fuzzy PI
         
         boolean control_on = 1;                                     // Variável que diz o estado do sistema de controle
         cont_timer0 = 0;                                            // Zera a variável de contagem
         
         set_ADC_channel(0);                                         // Seleciona o canal AN0 para conversão
         delay_us(20);                                               // Espera 20 microsegundos
         temp = read_adc();                                          // Lê o valor no conversor A/D
         temp = temp * 5000 / 1023 / 110 - 1;                        // Temperatura do sensor
         
         printf(lcd_putc, "\fTemp. = %2.1f ", temp);                 // Mostra a temperatura no LCD
         lcd_send_byte(1, 0b11011111);                               // Coloca o símbolo de "grau" no LCD
         printf(lcd_putc, "C\n");                                    // Mostra o C no LCD
         
         erro = temp_ref - temp;                                     // Calcula o erro
        
         if (erro >= 0.5)
         {
         control_on = 0;                                             // Desliga o sistema de controle
         set_pwm1_duty(0);                                           // Desliga o cooler
         }
         
         if (control_on) 
      {
         const int Ki = 1;                                           // Ganhos do controlador Fuzzy PI 
         const int K = 10;
         const int Ku = 40;                                          // Ganho de controle incremental
         float out_fuzzy;                                            // Saída do controlador Fuzzy PI
         signed int16 ciclo;                                         // Ciclo de trabalho do PWM1
         float taxa;                                                 // Taxa em que o erro varia
         float abs_taxa;                                             // Módulo da taxa
         float abs_erro_ant;                                         // Módulo do erro anterior
         float out_inc_fuzzy;                                        // Incremento na saída do controlador Fuzzy PI
         
         taxa = erro - erro_anterior;                                // Calcula a derivada do erro
         erro_anterior = erro;
         abs_erro_ant = abs(erro_anterior);                          // Calcula o módulo do erro
         abs_taxa = abs(taxa);                                       // Calcula o módulo da derivada do erro
         
// *** Calcula a saída da base de regras do controlador nebuloso ***
// *** Regiões IC1, IC2, IC5 e IC6 ***
         if ((K * abs_taxa <= Ki * abs_erro_ant) && (Ki * abs_erro_ant <= 1))
         out_inc_fuzzy = (Ki * erro + K * taxa) / (2 * (2 - Ki * abs_erro_ant));
// *** Regiões IC3, IC4, IC7 e IC8 ***
         else if ((Ki * abs_erro_ant <= K * abs_taxa) && (K * abs_taxa <= 1))
         out_inc_fuzzy = (Ki * erro + K * taxa) / (2 * (2 - K * abs_taxa));
// *** Regiões IC9 e IC10 ***
         else if ((Ki * erro > 1) && (K * abs_taxa < 1))
         out_inc_fuzzy = 0.5 * (K * taxa + 1);
// *** Regiões IC11 e IC12 ***
         else if ((K * taxa > 1) && (Ki * abs_erro_ant < 1))
         out_inc_fuzzy = 0.5 * (Ki * erro + 1);
// *** Regiões IC13 e IC14 ***
         else if ((Ki * erro < -1) && (K * abs_taxa < 1))
         out_inc_fuzzy = 0.5 * (K * taxa - 1);
// *** Regiões IC15 e IC16 ***
         else if ((K * taxa < -1) && (Ki * abs_erro_ant < 1))
         out_inc_fuzzy = 0.5 * (Ki * erro - 1);
// *** Região IC17 ***
         else if ((Ki * erro > 1) && (K * taxa > 1))
         out_inc_fuzzy = 1;
// *** Regiões IC19 ***
         else if ((Ki * erro < -1) && (K * taxa < -1))
         out_inc_fuzzy = -1;
// *** Regiões IC18 e IC20 ***
         else out_inc_fuzzy = 0;

// *** Calcula a saída do controlador fuzzy PI ***
         out_fuzzy = out_fuzzy_anterior + Ku * out_inc_fuzzy;
         ciclo = out_fuzzy;                                       // Seta o ciclo de trabalho do cooler
         ciclo = abs(ciclo);                                      // Calcula o módulo do ciclo de trabalho
         if (ciclo > 1020) ciclo = 1020;                          // Saturação no máximo
         if (ciclo < 255) ciclo = 255;                            // Saturação no mínimo
         out_fuzzy = ciclo;
         set_pwm1_duty(ciclo);                                    // Seta o ciclo de trabalho para o PWM1
         out_fuzzy_anterior = -out_fuzzy;
// *** Calcula a porcentagem do ciclo de trabalho ***
         out_fuzzy = out_fuzzy / 1020 * 100;
         out_fuzzy = abs(out_fuzzy);
// *** Mostra o ciclo de trabalho do PWM1 ***
         printf(lcd_putc, "Ciclo = %3.1f ", out_fuzzy);
         lcd_send_byte(1, 0b00100101);                            // Envia o símbolo de porcentagem ao LCD
      }
      }
      }
      

         #int_ext                                                 // Interrupção para o funcionamento do botâo que altera o setpoint 
         void trata_rb() 
      {
         temp_ref++;                                              // Incrementa o setpoint em uma unidade
         if (temp_ref == 31) temp_ref = 26;                       // Volta a 30º o setpoint
         printf(lcd_putc, "\fSetpoint = %u ", temp_ref);          // Mostra o setpoint no LCD
         lcd_send_byte(1, 0b11011111);                            // Coloca o símbolo de "grau" no LCD
         printf(lcd_putc, "C\n");                                 // Coloca a letra C no LCD
         delay_ms(250);                                           // Delay para exibição da mensagem
      }
      
         void main()                                              // Método principal do programa 
      {
         set_tris_a(0b11111111);                                  // Define as direção das portas 
         set_tris_b(0b11111111);
         set_tris_c(0b11111011);
         set_tris_d(0b00001000);
         set_tris_e(0b00000111);
         
         lcd_init();                                              // Inicializa o display

         setup_ADC_ports(AN0);                                    // Configura o conversor A/D, AN0, VRef+ = VDD, VRef- = VSS
         setup_ADC(ADC_CLOCK_DIV_32);                             // Divide o clock interno por 64
         setup_timer_2(T2_DIV_BY_16, 254, 1);                     // Configura as saídas PWM,Frequência de 245Hz
         set_pwm1_duty(0);                                        // Seta ciclo de trabalho em 0 para o PWM1
         setup_ccp1(CCP_PWM);                                     // Configura o CCP1 para modo PWM
         setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);              // Configura o timer0, Clock interno e prescaler de 64
         set_timer0(131);                                         // Inicia o timer 0 em 131

         ext_int_edge(H_TO_L);                                    // Configuração da interrupção no pino Rb.0, do nível alto para o baixo
         clear_interrupt(INT_EXT);                                // Limpa a interrupção externa

         enable_interrupts(INT_TIMER0);                           // Interrupção do timer 0
         enable_interrupts(INT_EXT);                              // Interrupção externa
         enable_interrupts(GLOBAL);                               // Interrupção global

         while (true)                                             // Loop infinito
      {
      }
      }
 

Adjuntos

  • Fuzzy_PI_CCS.rar
    44.2 KB · Visitas: 129
  • Fuzzy_PI_Proteus.rar
    78.6 KB · Visitas: 134
  • Sin título.png
    Sin título.png
    105.7 KB · Visitas: 137
Última edición por un moderador:
Mmm un PID :unsure:

Bueno, primero que nada, te sugerirìa utilizar otra estrategia de control.

Para lo que planteas, un simple controlador tipo P te podrìa servir, màximo un PI, pero un PID? se me hace demasiado y podrìa meter complicaciones a tu planta.

El control proporcional darà a tu motor la ganancia extra que necesita para cuando entre (en tu analogìa) una caja, mientras que la acciòn integral te ayudarà a seguir una referencia (una velocidad por ejemplo) y a rechazar perturbaciones.

Con un Pic? Mmm, serà mi poca experiencia en pics, pero, a mì tampoco me agrada la idea. Màs allà de que, tienes que utilizar un convertidor analògico digital y viceversa, la planta y el controlador, lo tienes que pasar al dominio discreto (transformada Z, no es sòlo poner los valores analògicos, si es que ya los tienes, si vas a intentar a prueba y error, ya cambia la cosa), pero en tal caso, si ya vas a usar un pic y algo de màs circuiterìa, una tarjeta de adquisiciòn de datos sencillita te serìa màs ùtil, pero, ... yo apoyo la idea de puro analògico.
 
bueno quien lo diria casi un año despues desde que comenzo este foro pero bueno quiero indicar esto ACABO DE HEREDAR TU PROYECTO =D me lo han dejado en la universidad y bueno la idea del control pid es basica osea ya lo tengo ahora el problema es tmb lo de la retro alimentacion lo cual tengo ideas la cual es usar un disco en el motor y con un foto sensor o camellito que aca le llamamos contar las rpm en las que gira el motor normalmente ahora las ingresamos a un micro osea programa basico el cual con un contador las contaria y tendriamos en un tiempo cuantas por segundo dan las revoluciones entonces mi problema es usar un variador de frecuencia en voltaje para agregarlo al comienzo del circuito como resultado de la retroalimentacion en el cual veremos que si cuenta un numero distinto podriamos aumentar el voltaje y mantener la velocidad del motor constante.

ahora si alguien sabe como hacer esta retro alimentacion y todo seria muy amable =D o apoyarme en la idea =D
 
Buenas tardes, amigo mira me parece que desde el principio, tienes dudas y las sigues arrastrando hasta ejemplos mas complejos...el titulo dice controlador PID para velocidad de motor DC.

De entrada tienes que tener muy claro los conceptos de control... tal vez el circuito que dió el profesor esta correcto, el detalle es que ese circuito está diseñado para control de posición, cual es la diferencia de eso y lo que tu quieres hacer?
La posición y la velocidad son dos variables mecánicas distintas y por consecuencia se miden de distinta manera.

POSICIÓN( angular ), la estas midiendo en grados, donde cada grado representa una posición del potenciometro(sensor).

VELOCIDAD ANGULAR( integral de la posición angular), esta se mide en radianes por segundos, y no la puedes medir con un potenciometro, que tal de manera analógica con otro motor similar acoplado mecánicamente al otro motor.. o a una parte móvil de la banda...y deberia de generar un voltaje proporcional a la velocidad de giro de este....

si te interesa mi respuesta avísame falta todavía algo mas por explicar....
 
una preguntica adoyano o cualquiera que responda el circuito que mostrastes primero sirve? el que se controla la velocidad del motor con el potenciometro de 100k
 
Busca por un Tacogenerador (otro motor de cd puede puede generar el voltaje pero necesitaras condicionar la señal por ruidos introducidos por las escobillas del motor). Los hay de varios precios y lo que deseas especificar, ademas de las dimensiones mecanicas, son Los Volts x 1000 rpm que entrega.
Una vez teniendo esta relacion es facil acoplar y acondicionar la señal al bucle de retro-alimentacion del control de velocidad.

Ademas en el circuito inicialmente publicado tienes un error en tu sumador. Ya que tienes una referencia de hasta 12 V atenuada a 6V por el divisor de resistencias. Pero solo 5V de feedback tambien atenuada a 2.5V por el mismo divisor. O sea despues de la referencia sea mayor a 5V, no hay forma de controlar la velocidad del motor y esta se va al maximo gracias a la accion integral del PID, (Si utilizas pot lineal para ajustar la referencia, esto es menos del 50% del viaje del pot).

Corrige para que tu divisor de la retro entregue un voltaje un poco mayor o igual a la referencia.

Ademas en la parte Integral .. tienes una super ganancia 100k / 10 ohms = 10K .. o sea solo necesita un error de .001 para saturar el control. y la constante de tiempo es super rapida.
Increnta la constante con un capacitor mas grande ... 10uF es standard con un tiempo de 100 ms
y vaja la ganancia de dc .... Yo agregaria ademas un pot para tener ganancia ajustable a las caracteristicas de tu sistema. Lee un poco sobre Op-amps y los circuitos de ganancia infinita.
 
Última edición:
Control de velocidad de motor y visualizacion de las revoluciones por minuto del mismo en una pantalla lcd de 16x2. El pic es 16f690.

Los datos del motor son :
Hitachi motor dc
type D06D304E
Hasta 38 V
Hasta 1.6 amperios
3700 RPM
encoder 240 P/R pulsos por revolución
El encoder tiene 2 señales:
1ra señal :

8V 106us pulso
12.2V 7400us pulso
16.7V 46us
17V 44us



2da señal:

5.4V 220us Pulso
6.9V 172us Pulso
9.8V 128us Pulso
12.1V 104us Pulso
16.4V 72us pulso


Estado tratando de hacer esto pero se me hace un poco dificil programar en picc espero sus comentarios gracias.

He probado simular con el proteus el motor encoder pero los resultados son totalmente diferentes a la realidad.
 
Atrás
Arriba