Autor Tema: Controlar la temperatura de un horno en C para dsPIC  (Leído 3935 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado learntofly

  • PIC10
  • *
  • Mensajes: 4
Controlar la temperatura de un horno en C para dsPIC
« en: 23 de Septiembre de 2008, 14:44:47 »
Hola compis!! Porfin encuentro un foro que quizas pueda ayudarme y resolver unas dudas, puesto que se muy poco de programacion y necesito implementar el control en lazo cerrado de un sistema en lenguaje C sobre dsPIC.

El sistema trata de controlar la temperatura de un horno, calentandolo mediante un resistencia y obteniendo su temperatura mediante una sonda. La resistencia de calentamiento se activa mediante una señal PWM que gobierna un amplificador/generador de corriente, segun la relacion:
 0Amperios=0%duty
20Amperios=100%duty.

La sonda de temperatura se comporta como una resistencia variable en funcion de la temperatura, segun una cierta relacion.
Debido al ruido de este sensor se decide aplicar a la medida de temperatura un filtro digital de media, utilizando los 5valores mas recientes de la señal.

La consigna de temperatura se genera mediante un potenciometro, correspondiendo el minimo del mismo a una consigna de 20ºC y el maximo a una consigna de 120º.
La señal analogica de referencia y la señal analogica del sensor se muestrean con un periodo de 2segundos.


Yo tengo un programa a medias, pero se que tiene fallos porque yo no se programar demasiado bien. En cambio obteniendo un ejemplo con este sistema pordria hacerme una idea de como continuar yo misma con otros ejemplos.

GRacias a quien pueda ayudarme aunq sea un minimo!!!

 :g) :g) :g)

Desconectado learntofly

  • PIC10
  • *
  • Mensajes: 4
Re: Controlar la temperatura de un horno en C para dsPIC
« Respuesta #1 en: 25 de Septiembre de 2008, 04:35:37 »
Esto es lo que he conseguido hasta ahora, alguien q pueda corregirme?? ademas esq no puedo compilarlo porq no tengo el C30 de microchip, gracias!!!!!!

# include <p30f6010.h>

# define T 2  //periodo de muestreo para las señales analogicas//
# define N 5
# define Nsalida 5


float _ref;
float _temp;
int Vcc=10;
int R1=100;

//variables ecuacion en diferencias del regulador//
float ek;
float ek1=0;
float uk;
float uk1=0;
float a[2]={0.51, 0.5};
int b[2]={1,-1};


//variables ecuacion filtro//
float hn[N]={0.2,0.2,0.2,0.2,0.2}
float xk[N];
float ykfir[Nsalida];

//Funciones para implementacion de la ecuacion de diferencias//

void VectorCero(float x[],int n)
{
   int i;
   for(i=0;i<n;i++)
      x=0.0;
}

void VectorDesplaza(float x[],int n)
{
   int i;
   for(i=n-1;i>0;i--)
      x=x[i-1];
}

float VectorMult(float b[],float u[],int n)
{
   int i;
   float yk;
   for(i=0;i<n;i++)
      yk+=b*u;
   return yk;
}

float EcuDif(float a[],float u[],float b[],float y[],int n)
{
   VectorDesplaza(u,n);
   VectorDesplaza(y,n);
   uk[0]=uk;
   yk[0]=VectorMult(a+1,y+1,n-1)+VectorMult(b,u,n);
   return y[0];
}

float Filtro (float xk[], ykfir[], float hn[], float _temp)   //Filtro de media de los ultimos 5 valores
{
   VectorDesplaza (xk);
   VectorDesplaza (ykfir);
   xk[0]=_temp;
   ykfir[0]=VectorMult(xk,hn);
}


float convierteseñal (float x0, float y0, float x1, float y1, float x)   // graficas lineales, uso la expresion de la pendiente
{
   float m;
   m= ( y1 -y0)/(x1-x0);
   return yo+m*(x-x0)
}




void LoadPWMDuty(float ac)
{
   if(ac>1023)
      ac=1023;
   if(ac<0)
      ac=0;
   uk=ac*10/1023-5;
}


void _ISR _T3Interrupt(void)
{
   IFS0bits.T3IF=0;            // limpiar bandera interrupción
   ADCON1bits.ASAM=1;            // iniciar conversión
}

void _ISR _ADCInterrupt()
{
   float RPT100;

   float _ventrada;
   float _temp;

   float adcventrada;
   
   
   adcventrada=ADCBUF1;

   _ventrada=convierte(0, 0, 1023, 5, adcentrada);
   _temp=convierte(0, 20, 1023, 120, adcentrada);
   
   
       
   IFS0bits.ADIF=0;   //limpo bandera
   ADCON1bits.ASAM=0;  //detengo muestreo
   
   

   RPT100=(Vcc*R1/_ventrada)-R1;   //calculo el valor de RPT100
   _temp=(RPT100-R1)/40;      //calculo el valor de la temperatura

   Uk=_ref-_temp;         
   EcuDif(a,ek,b,ek1,uk, uk1);   //ecuacion en diferencias para la salida del dspic

   ykfir[]= Filtro (float xk[], float hn[], float _temp)

   LoadPWMDuty ();

      
}




main()
{
   VectorCero (ykfir, Nsalida);
   VectorCero (yk, Nsalida);
   VectorCero (uk, Nsalida);
   ConfigurarT3(T);      // configurar muestreo AD T=2segundos
   InitAD();         // Inicia conversión AD
   InitPWM();         // Inicia PWM
   ADCON1bits.ADON=1;
   T3CONbits.TON=1;
   while(1){
   
      Idle();
   }
}
« Última modificación: 26 de Septiembre de 2008, 04:31:02 por learntofly »

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: Controlar la temperatura de un horno en C para dsPIC
« Respuesta #2 en: 25 de Septiembre de 2008, 22:52:56 »
El C30 se baja gratis de microchip  :?
Control Automático, DSP & Microcontroladores

Desconectado learntofly

  • PIC10
  • *
  • Mensajes: 4
Re: Controlar la temperatura de un horno en C para dsPIC
« Respuesta #3 en: 26 de Septiembre de 2008, 07:19:17 »
Finalmente este es el programa,.. pero no puedo resolver los errores.

# include <p30f6010.h>

# define T 2  //periodo de muestreo para las señales analogicas//
# define N 5
# define Nsalida 5


float _ref;
float _temp;
int Vcc=10;
int R1=100;

//variables ecuacion en diferencias del regulador//
float ek;
float ek1=0;
float uk;
float uk1=0;
float a[2]={0.51, 0.5};
int signed b[2]={1,-1};
float e[2], u[2];

//variables ecuacion filtro//
float hn[N]={0.2,0.2,0.2,0.2,0.2};
float xkfir[N];
float ykfir[Nsalida];


//Funciones para implementacion de la ecuacion de diferencias//

void VectorCero(float x[],int n)
{
   int i;
   for(i=0;i<n;i++)
      x=0.0;
}

void VectorDesplaza(float x[],int n)
{
   int i;
   for(i=n-1;i>0;i--)
      x=x[i-1];
}

float VectorMult(float b[],float u[],int n)
{
   int i;
   float yk;
   for(i=0;i<n;i++)
      yk+=b*u;
   return yk;
}

float EcuDif(float a[],float x[],float b[],float y[],int n, float xk)
{

   VectorDesplaza(x,N);
   VectorDesplaza(y,Nsalida);
   x[0]=xk;
   y[0]=VectorMult(a+1,y+1,Nsalida-1)+VectorMult(b,x,N);
   return y[0];
}

float Filtro (float xkfir[], float ykfir[], float hn[], float adcventrada, int n)   //Filtro de media de los ultimos 5 valores
{
   VectorDesplaza (xkfir, N);
   VectorDesplaza (ykfir, Nsalida);
   xkfir[0]=adcventrada;
   ykfir[0]=VectorMult(xkfir,hn, Nsalida);
}


float convierte (float x0, float y0, float x1, float y1, float x)   // graficas lineales, uso la expresion de la pendiente
{
   float m;
   m= ( y1 -y0)/(x1-x0);
   return y1=y0+m*(x1-x0);
}


void LoadPWMDuty(float ac)
{
   float u;
   if(ac>1023)
      ac=1023;
   if(ac<0)
      ac=0;
   u=ac*10/1023-5;
}


void _ISR _T3Interrupt(void)
{
   IFS0bits.T3IF=0;            // limpiar bandera interrupción
   ADCON1bits.ASAM=1;            // iniciar conversión
}

void _ISR _ADCInterrupt()
{
   float RPT100;
   float _temp;
   float _ventrada;
   float consigna=ADCBUF0;
   float adcventrada=ADCBUF1;

   int n;

   _temp=convierte(0, 20, 1023, 120, adcventrada);
   _ref=convierte(0,0,5,20,consigna);
   _ventrada= convierte(0,20,5,120,adcventrada );
       
   IFS0bits.ADIF=0;   //limpo bandera
   ADCON1bits.ASAM=0;  //detengo muestreo
   
   

   RPT100=(Vcc*R1/_ventrada)-R1;   //calculo el valor de RPT100
   _temp=(RPT100-R1)/40;      //calculo el valor de la temperatura

   ek=_ref-_temp;
      
   EcuDif(a,e,b,u,Nsalida,uk); //ecuacion diferencias, salida del dspic


   LoadPWMDuty (uk);

      
}




main()
{

   ConfigurarT3(T);      // configurar muestreo AD T=2segundos
   InitAD();         // Inicia conversión AD
   InitPWM();         // Inicia PWM
   ADCON1bits.ADON=1;
   T3CONbits.TON=1;
   while(1){
   
      Idle();
   }
}



Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -D__dsPIC30F6010__ -c -x c "mplabtest.c" -o"mplabtest.o" -g
mplabtest.c:92: warning: No interrupt vector names defined for unspecified dsPIC30F
mplabtest.c: In function '_T3Interrupt':
mplabtest.c:92: warning:  PSV model not specified for '_T3Interrupt';
   assuming 'auto_psv' this may affect latency
mplabtest.c: In function '_ADCInterrupt':
mplabtest.c:121: warning: passing argument 3 of 'EcuDif' from incompatible pointer type
mplabtest.c:98: warning:  PSV model not specified for '_ADCInterrupt';
   assuming 'auto_psv' this may affect latency
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -Wl,"C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.o",--script="C:\Archivos de programa\Microchip\MPLAB C30\support\dsPIC30F\gld\p30f6010.gld",-L"C:\Archivos de programa\Microchip\MPLAB C30\lib",-o"mplabtest.cof"
C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.o(.text+0x2fe): In function `main':
C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.c:135: undefined reference to `ConfigurarT3'
C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.o(.text+0x300):C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.c:136: undefined reference to `InitAD'
C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.o(.text+0x302):C:\Documents and Settings\Admin\Escritorio\Mplabtest\mplabtest.c:137: undefined reference to `InitPWM'
BUILD FAILED: Fri Sep 26 12:19:17 2008




Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: Controlar la temperatura de un horno en C para dsPIC
« Respuesta #4 en: 27 de Septiembre de 2008, 14:10:38 »
No tenes definidas varias funciones ... las de inicializacion del ADC y las del PWM ... Ademas me da la sensación que estas copiando código al asar y compilando sin saber que hace o para que sirve. Sin duda, estas perdiendo tiempo valioso tratando de pegarle a un piñata que esta encima tuyo.

Todo sistema embebido empieza con un diseño de capas, como el tuyo es sencillo, debes definir muy bien primero la capa fisica, es decir todas las funciones que manejarán los perifericos .. en este caso el ADC y el PWM ...  lee el manual de referencia del dsPIC y trata de entender como funciona cada uno (ADC y PWM) luego implementa funciones de inicializacion, toma de dato ADC, actualizacion de salida PWM, cambio de frecuencia del PWM, etc etc .. microchip ya tiene una libreria y ejemplos que hacen eso pero siempre es bueno saber como funcionan, luego, intenta hacer un programita en donde el ADC varie el PWM ..

Luego, si es necesario, tenes que definir las funciones de convesion numérica, por ejemplo, el ADC no te va a dar un número bonito en punto flotante o que realmente represente la unidad de medida de la señal de muestra. Esta seria la capa 2, la cual sirve de comunicacion entre la capa fisica y la capa superior (aplicacion)
 
Despues , define bien tus algoritmos de control (que seria la capa de apliacacion), yo siempre la diseño esta capa en MATLAB y verifico con señales de prueba y gráficos, luego la implemento en C30 y la simulo con el MPLAB SIM.  Luego comparo los resultados con MATLAB.

PD: El programa que presentas tiene muchas cosas sin sentido ...  :( .. entiendo tu intento de hacer algo pero te adelanto que aqui en el foro nadie te va hacer el programa. En lo que si te podemos ayudar es en recomendaciones si presentas algo que se vea que por lo menos funciona ...  lee las reglas del foro ... para que te demos respuestas mas precisas.

Saludos!
« Última modificación: 28 de Septiembre de 2008, 12:25:10 por blackcat »
Control Automático, DSP & Microcontroladores


 

anything