Hola controleros y controleras, en el día de hoy vamos a tomar un horno eléctrico, vamos a sensar su temperatura con una termocupla tipo K y un microcontrolador PIC, haremos una adquisición de datos a través de MATLAB comunicando inhalámbricamente el PIC con el computador por Radiofrecuencia usando los modulos XBEE y por último haremos la identificación del sistema para obtener la función de transferencia del horno eléctrico.
Antes de comenzar con la explicación detallada y antes de mostrarte los códigos Gratuitos, te invito a que veas el 👉 curso de microcontroladores PIC Gratuito del sitio web.
Proceso: Horno Eléctrico
Antes que nada, vamos a entender que el proceso que vamos a tratar aquí, será un horno eléctrico, de esos convencionales que podremos encontrar en casa.
Este POST es la Segunda parte de la entrada pasada, donde EXPLICAMOS el funcionamiento del HORNO, junto con su circuito de POTENCIA y junto con la lectura, comunicación y graficación de la temperatura en el computador.
Por eso, para que puedas ENTENDER este post, será necesário que leas el post anterior, te dejo el link a continuación.
Mira como 👉 Monitorear la temperatura de un Horno usando un PIC.
Esquema del Circuito de Adquisición de Datos
A continuación te muestro el esquema del circuito que vamos a usar para tomar los datos del horno, que es exactamente el mismo circuito de la entrada anterior. NOTA: El circuito es meramente ilustrativo en Proteus, la simulación de este circuito no es funcional en proteus.
Adquisición de Datos
La adquisición de datos del horno se hará a traves de Matlab, tomando los datos de temperatura sensados por el microcontrolador PIC cada 1 segundo.
Los datos obtenidos de este proceso, junto con el código de adquisición de datos estarán disponibles al final de este post.
La respuesta obtenida en lazo abierto, del sistema, despues de hacer un estímulo con un escalón de 110C, fue la siguiente.
Como podemos observar, el sistema presenta un comportamiento parecido a un sistema de primer orden con retardo. Adicionalmente dado que la temperatura dió por encima del escalón podemos intuir que la ganancia estática del sistema es mayor que 1, por lo tanto es un sistema amplificador.
Tratamiento de los datos del Horno
Una vez tenemos la dinámica del horno en datos, procedemos a hacer un recorte de los datos, para tomar únicamente los datos que están dentro del escalón del 110 y adicionalmente haremos una traslación de los datos hacia el origen, para trabajar en algo que se conoce como la variable desvio.
El código para hacer este tratamiento, también está disponible al final de este post.
Identificación el Sistema
Para obtener la función de transferencia del sistema, utilizaremos el toolboz de System Identification del MATLAB
Primero importamos los datos transladados y recortados, que se obtienen despues de ejecutar el código.
Luego procedemos a realizar la estimación del proceso a través de una función de transferencia. Para este caso se optó por obtener una función de transferencia de primer orden con retardo (1 polo y delay). Se dá estimar y se obtienen los parametros mostrados en el paso 4 de la siguiente figura.
Según la estimación del proceso, nuestra función de transferencia para el horno es:
Control del Proceso
En la próxima entrada veremos como realizar un control PI dentro de una estructura de Predictor de Smith para este proceso, sin embargo, si deseas aprender a crear tus propios controladores en la vida real, te invito a realizar mis cursos de control en sistemas embebidos, basta con seleccionar el curso con el dispositivo embebido de tu preferencia (PIC o Arduino):
- Curso de Sistemas de Control en Dispositivos Microcontrolados en UDEMY (PIC y ARDUINO)
- Certificado de Aprobación una vez finalices el Curso
- DESCUENTO si accedes directamente con los siguientes botones de acceso.
- NOTA: Si buscas el curso directamente en UDEMY o si lo adquieres en otra plataforma distintas a las mostradas anteriormente NO OBTENDRÁS NINGUN DESCUENTO sobre el valor final del Curso.
Códigos de Implementación
A continuación te dejo todos los códigos para que puedas reproduzir esta práctica. Sabes que para acceder a ellos, solo basta con compartir la información de este post, para que más personas tengan conocimiento de esta información.
Código del PIC C Compiler
Para descargar la librería del MAX6675 deberás hacerlo desde el post anterior: 👉
#include <18F4550.h> #device ADC=10 #FUSES NOWDT //No Watch Dog Timer #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale #FUSES NOBROWNOUT //No brownout reset #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode) #FUSES HS #use delay(crystal=20000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) #define TC_CLK PIN_B1 #define TC_CS PIN_C0 #define TC_DATA PIN_B0 #include "max6675.c" #include <stdlib.h> #include <string.h> long deg=0; short timeout_error; char car[10]; char timed_getc() { long timeout; timeout_error=FALSE; timeout=0; while(!kbhit()&&(++timeout<50000)) // 1/2 second delay_ms(100); if(kbhit()) return(getc()); else { timeout_error=TRUE; return(0); } } //Define la interrupción por recepción Serial #int_RDA void RDA_isr() { int i=0,ini=0,fin=0; char dat[5]; char degC[5]; long duty; // Almacena 10 datos leidos del serial for(i=0;i<5;i++){ dat[i]=getc(); putc(dat[i]); } //Busco el valor del escalon en los datos recibidos for(i=0;i<5;i++){ if(dat[i]=='S'){ ini=i+1; i=10; } } for(i=ini;i<5;i++){ if(dat[i]==' ){ fin=i-1; i=10; } } if(ini!=0 && fin!=0){ // salvo en degC el caracter con el escalon for(i=ini;i<=fin;i++){ degC[i-ini]=dat[i]; } deg = atol(degC); //Convierte el String en un valor numerico // valida que el escalón esté ente 0 y 300 grados celcius if(deg>600) deg=600; if(deg<0) deg=0; duty=deg*10/6; set_pwm1_duty(duty); // set PWM del PIC } } //! void main() { char msg[32]; delay_ms(50); //allow oscillator to stabilise setup_timer_2(t2_div_by_4,249,1); //Configuracion de Timer 2 para establecer frec. PWM a 1kHz setup_ccp1(ccp_pwm); //Configurar modulo CCP1 en modo PWM set_pwm1_duty(0); //Dejo en cero la salida PWM enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); while(1){ delay_ms(1000); //sprintf(msg,"%3.2f%cC\r\n",do_everything(),0xB0); sprintf(msg,"I%3.2fFI%3.2fFI%3.2fF",do_everything(),do_everything(),do_everything()); printf("%s",msg); } }
Código en MATLAB
Si lo deseas puedes descargar la lista de datos que se obtuvo en ente proceso. CLICK AQUI PARA DESCARGAR
Para poder ver estos datos, debes digitar en MATLAB:
plot(tiempo,escalon,tiempo,salida)
Código del Tratamiento de Datos
%Programa de Identificacion load('Ident1.mat') plot(tiempo,escalon,tiempo,salida); %Renombra variables us=escalon; ys=salida; ts=tiempo; b=110; % Escalon donde se hizo lA IDENTIFICACION %Busca el momento exacto donde se insertó el escalón i=1; while(us(i)<b) i=i+1; end x1=i; while(us(i)==b) i=i+1; end x2=i-1; %Recortar datos hasta el origen ur=us(x1:x2); yr=ys(x1:x2); tr=ts(x1:x2); %transladar los datos ut=ur-us(1); yt=yr-yr(2); tt=tr-tr(1); %Graficar escalon Trasladado figure(2) plot(tt,ut,tt,yt,'linewidth',3),grid title('Datos recortados y transladados') xlabel('Tiempo (s)') ylabel('Temperatura (C)')
Código de la Interfaz Gráfica para Adquisición de Datos
%% Ejemplo Monitoreo de señales en tiempo Real function varargout=monitoreo(varargin) parar=false; fclose('all') global tiempo salida escalon y fig(1)=figure('name','Monitor','menubar','none','position',[200 200 800 700],'color',[0.9 0.6 0.3]) movegui(fig(1),'center'); axe(1)=axes('parent',fig(1),'units','pixels','position',[60 80 600 550],'xlim',[0 40],'ylim',[0 200],'xgrid','on','ygrid','on') set(get(axe(1),'XLabel'),'String','Tiempo (Seg)') set(get(axe(1),'YLabel'),'String','Temperatura (°C)') lin(1)=line('parent',axe(1),'xdata',[],'ydata',[],'Color','r','LineWidth',2.5); lin(2)=line('parent',axe(1),'xdata',[],'ydata',[],'Color','k','LineWidth',2); bot(1)=uicontrol('parent',fig(1),'style','pushbutton','string','Detener','position',[680 50 100 50],'callback',@stop,'fontsize',11) bot(2)=uicontrol('parent',fig(1),'style','pushbutton','string','Enviar','position',[680 200 100 50],'callback',@enviar,'fontsize',11) txbx(1)=uicontrol('parent',fig(1),'style','tex','string','Temp','position',[680 100 100 50],'fontsize',11) txbx(2)=uicontrol('parent',fig(1),'style','edit','string','000','position',[680 250 100 50],'fontsize',11) %% Funcion Pare function varargout=stop(hObject,evendata) parar=true; fclose(SerialP); delete(SerialP); clear SerialP; end %% Funcion enviar function varargout=enviar(hObject,evendata) deg1=get(txbx(2),'string'); deg=["S"+deg1+"$"]; fwrite(SerialP,deg,'uchar'); end %% funcion Graficar % function varargout=grafique(hObject,evendata) tiempo=[0]; salida=[0]; escalon=[0]; deg1="0"; dt=1; limx=[0 40]; limy=[0 200]; set(axe(1),'xlim',limx,'ylim',limy); %% Configura el Puerto Serial SerialP=serial('COM8'); set(SerialP,'Baudrate',9600); % se configura la velocidad a 9600 Baudios set(SerialP,'StopBits',1); % se configura bit de parada a uno set(SerialP,'DataBits',8); % se configura que el dato es de 8 bits, debe estar entre 5 y 8 set(SerialP,'Parity','none'); % se configura sin paridad fopen(SerialP); %% Grafico k=5;nit = 10000; while(~parar) % Lectura del Dato por Puerto Serial variable= (fread(SerialP,20,'uchar')); ini=find(variable==73); %Busca el retorno de carro (Primer dato) ini=ini(1)+1; fin=find(variable==70); %Busca operador grados (ultimo dato) fin= fin(find(fin>ini))-1; fin=fin(1); tempC=char(variable(ini:fin))'; temp=str2num(tempC); set(txbx(1),'string',tempC); %Actualiza las variables del grafico tiempo=[tiempo tiempo(end)+dt]; salida=[salida temp]; escalon=[escalon str2num(deg1)]; set(lin(1),'xdata',tiempo,'ydata',salida); set(lin(2),'xdata',tiempo,'ydata',escalon); pause(dt); %% espera 0.1 seg para cada interación if tiempo(end)>=limx % actualizo grafica cuando llega a su limite en tiempo real limx=[0 limx(2)+40]; set(axe(1),'xlim',limx); end if salida(end)>=limy % actualizo grafica cuando llega a su limite en tiempo real limy=[0 limy(2)+30]; set(axe(1),'ylim',limy); end k=k+1; if(k==nit) parar=true; end end parar=false; end
Perfecto Controleros y Controleras, con esto llegamos al final de nuestra páctica del día de hoy.
Recuerda que si deseas apoyar mi trabajo, puedes invitarme a un café y seguirme ayudando a mantener los servidores de este sitio web, es muy barato el café y contribuyes con el tiempo y esfuerzo invertidos en las clases elaboradas en el canal y pagina web: 👉Invitar a un Café a Sergio ☕️
Espero que esten muy bien y nos vemos en la próxima.
Mi nombre es Sergio Andres Castaño Giraldo, y en este sitio web voy a compartir una de las cosas que mas me gusta en la vida y es sobre la Ingeniería de Control y Automatización. El sitio web estará en constante crecimiento, voy a ir publicando material sobre el asunto desde temas básicos hasta temas un poco más complejos. Suscríbete al sitio web, dale me gusta a la página en Facebook y únete al canal de youtube. Espero de corazón que la información que comparto en este sitio, te pueda ser de utilidad. Y nuevamente te doy las gracias y la bienvenida a control automático educación.