You are on page 1of 9

2017

Proyecto de diseño de
sistemas digitales:
Core de un bloque PID

ANALISIS Y SIMULACION DE CORE DE UN BLOQUE PID


MIGUEL SANDOYA MAN GING

ESPOL
Objetivo
Analizar y simular el Core de un bloque PID, identificar las variables que actúan en el
proceso, así como el código en VHDL.

Controlador PID
Un controlador PID es un mecanismo de control por realimentación ampliamente usado
en sistemas de control industrial.

Características:

• Utiliza la realimentación para rechazar las perturbaciones.


• Elimina el error estacionario con la acción integral.
• Con la acción derivativa puede anticipar el futuro El control PID combina tres
acciones: Proporcional, Integral y Derivativa.

Parámetros de control Ganancia proporcional: Constante de proporcionalidad en la


acción de control proporcional.
Constante de tiempo integral: El tiempo requerido para que la acción integral
contribuya a la salida del controlador en una cantidad igual a la acción proporcional.

Constante de tiempo derivativa: El tiempo requerido para que la acción proporcional


contribuya a la salida del controlador en una cantidad igual a la acción derivativa.

Otras formas de control:


Control P: Produce una señal de control proporcional a la señal de error.
Características: o Simple o Fácil de sintonizar o Puede reducir, pero no eliminar, el error
de estado estacionario.
Control PI: Proporciona una corrección para compensar las perturbaciones y mantener
la variable controlada en el punto de consigna. Características: o Elimina errores
estacionarios o Más del 90% de los lazos de control utilizan PI o Puede desestabilizar al
sistema si la constante de tiempo integral disminuye mucho.
Control PD: Anticipa el efecto de la acción proporcional para estabilizar más
rápidamente la variable controlada después de la perturbación. Características: o
Responde a la velocidad del cambio del error o Produce una corrección significativa
antes de que la magnitud del error se vuelva demasiado grande.
Código en VHDL: pid_controller.VHD
library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pid_controller is

generic

-- size of input and output data --

iDataWidith : integer range 8 to 32 := 8;

-- proportionally gain --

iKP : integer range 0 to 7 := 3; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256

-- integral gain --

iKI : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256

-- differential gain --

iKD : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256

-- master gain --

iKM : integer range 0 to 7 := 1; -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128

-- delay between samples of error --

iDelayD : integer range 1 to 16 := 10;

-- 0 - controller use derivative of PATERN_I and PATERN_ESTIMATION_I, 1 - controller use error to


work --

iWork : integer range 0 to 1 := 1

);

port

CLK_I : in std_logic;

RESET_I : in std_logic;

-- error --

ERROR_I : in std_logic_vector(iDataWidith - 1 downto 0);


-- threshold --

PATERN_I : in std_logic_vector(iDataWidith - 1 downto 0);

-- current sample --

PATERN_ESTIMATION_I : in std_logic_vector(iDataWidith - 1 downto 0);

-- correction --

CORRECT_O : out std_logic_vector(iDataWidith - 1 downto 0)

);

end entity pid_controller;

architecture rtl of pid_controller is

-------------------------------------------------------------------------------

-- functions --

-------------------------------------------------------------------------------

-- purpose: make a std_logic_vector of size c_size and build from c_value --

function f_something ( constant c_size : integer; signal c_value : std_logic) return std_logic_vector is

variable var_temp : std_logic_vector(c_size - 1 downto 0);

begin -- function f_something --

var_temp := (others => c_value);

return var_temp;

end function f_something;

-- examples:

-- f_something(c_size => 3 , c_value => 'Z') == "ZZZ"

-- f_something(c_size => 3 , c_value => '1') == "111"

-- ...

-------------------------------------------------------------------------------

-- types --

-------------------------------------------------------------------------------
-- delay register --

type type_sr is array (0 to iDelayD - 1) of std_logic_vector(iDataWidith - 1 downto 0);

-------------------------------------------------------------------------------

-- signals --

-------------------------------------------------------------------------------

signal v_error : std_logic_vector(iDataWidith - 1 downto 0);

signal v_error_KM : std_logic_vector(iDataWidith - 1 downto 0);

signal v_error_KP : std_logic_vector(iDataWidith - 1 downto 0);

signal v_error_KD : std_logic_vector(iDataWidith - 1 downto 0);

signal v_error_KI : std_logic_vector(iDataWidith - 1 downto 0);

signal t_div_late : type_sr;

signal v_div : std_logic_vector(iDataWidith - 1 downto 0);

signal v_acu_earl : std_logic_vector(iDataWidith - 1 downto 0);

signal v_acu : std_logic_vector(iDataWidith - 1 downto 0);

signal v_sum : std_logic_vector(iDataWidith - 1 downto 0);

begin -- architecture rtl --

-- choice source of input data --

v_error <= ERROR_I when iWork = 1 else

conv_std_logic_vector(signed(PATERN_I) - signed(PATERN_ESTIMATION_I) , iDataWidith) when


iWork = 0 else

(others => '0');

-- master gain execute by shift of iKM bits to the right --

v_error_KM <= v_error when iKM = 0 else

f_something(c_size => iKM , c_value => v_error(iDataWidith - 1)) & v_error(iDataWidith - 1


downto iKM) when iKM > 0 else

(others => '0');

-- proportionally gain execute by shift of (iKP - 1) bits to the right --

v_error_KP <= f_something(c_size => iKP + 1 , c_value => v_error_KM(iDataWidith - 1)) &
v_error_KM(iDataWidith - 1 downto iKP + 1);
-- derivative gain execute by shift of (iKD - 1) bits to the right --

v_error_KD <= f_something(c_size => iKD + 1 , c_value => v_error_KM(iDataWidith - 1)) &
v_error_KM(iDataWidith - 1 downto iKD + 1);

-- integral gain execute by shift of (iKI + 1) bits to the right --

v_error_KI <= f_something(c_size => iKI + 1 , c_value => v_error_KM(iDataWidith - 1)) &
v_error_KM(iDataWidith - 1 downto iKI + 1);

DI00: process (CLK_I) is

begin -- process DI00

if rising_edge(CLK_I) then

-- synchronous reset --

if RESET_I = '1' then

t_div_late <= (others => (others => '0'));

v_div <= (others => '0');

v_acu <= (others => '0');

v_acu_earl <= (others => '0');

else

-- delay register --

t_div_late <= v_error_KD & t_div_late(0 to iDelayD - 2);

-- difference between samples --

v_div <= conv_std_logic_vector(signed(v_error_KD) - signed(t_div_late(iDelayD - 1)) , iDataWidith);

-- integration of error --

v_acu <= conv_std_logic_vector(signed(v_error_KI) + signed(v_acu_earl) , iDataWidith);

-- sum of N - 1 samples of error --

v_acu_earl <= v_acu;


end if;

end if;

end process DI00;

-- first stage of adder --

v_sum <= conv_std_logic_vector(signed(v_acu) + signed(v_div) , iDataWidith);

-- correction and second stage of adder --

CORRECT_O <= conv_std_logic_vector(signed(v_error_KP) + signed(v_sum) , iDataWidith) when


RESET_I = '0' else

(others => '0');

end architecture rtl;

Análisis de código
Lo primero que se hizo fue declarar unas variables genéricas, las cuales cambian su valor
de acuerdo con el comportamiento del sistema, estas variables son:
El ancho de datos de entrada = iDataWidith
La ganancia proporcional = iKP
La ganancia integral = iKI
La ganancia derivativa = iKD
La ganancia principal = iKM
Un retardo para tomar muestras de tiempo= iDelayD
Luego declaramos las variables que simularemos, que serán la señal de reloj, de reset,
el error, la señal de retro alimentación, el factor de corrección y estimación.
Luego en la arquitectura lo que hace el programa es leer las variables de retro
alimentación y la estimación que es el valor que se pone inicialmente para que este se
mantenga, y guarda la resta de ambos en la variable error y de acuerdo a cuan grande
sea se sumara un valor a las ganancias del pid para así poder conservar el valor inicial.
Simulación

Se puede observar como la señal de retro alimentación aumenta su valor para llegar a
los 1791 que es valor al cual se quiere llegar, además se observa la señal del error y el
factor de corrección.
Conclusión

• Se pudo analizar y simular el core pid, mediante esto se observo como es su


comportamiento, el cual trata de llegar al valor seteado aumentando las
ganancias del sistema de acuerdo a la señal de error.
• Se identifico las variables principales del sistema que son las que al modificarlas
producen un cambio, estas son las ganancias proporcional, integral, derivativa,
el error y la retro alimentación.

You might also like