Hola Muchachos :
Estoy haciendo un medidor de termocuplas con termoculas K como saben exiten tablas o ecuaciones que lineatilan aproximadamente los valores en las curvas de las termpciplas .
Estas ecuaciones para que no hayan tantas e innecesarias multiplicaciones se las coloca de otra forma ahí entonces ocupan menos memoria , algunos te sugieren que uses hasta el exponencial 4 pero no mide con precision asi que hay que poner la ecuación completa y realmente mide con bastante precision .
Yo lo verifique con una termocupla tipo j y anduvo de 10, ………peeeeeero cuando me pase a la termocupla tipo K la ecuación es demasiado comleja y la empece a partir para que no me diera expresión too complex (dado que la necesito entera), en ese momento me salio out of room. Estoy usando un 16f876 que tiene bastante memoria.
RESUMIENDO
¿ Como podria hacer para que entren esas expresiones en la capacidad de memoria que posee el pic?
CODIGO
#include <16f876.h> //pic a utilizar
#device *=16
#device adc=10
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT,NOCPD, NOWRT,NODEBUG //No Debug mode for ICD
#use delay (clock=4000000) //Fosc=4Mhz
#define SAA1064_DINAMICO //trabajar en modo dinamico el saa1064
#define SAA1064_SCL PIN_C3 //definicion de pines...
#define SAA1064_SDA PIN_C4 //...de manejo del saa1064
#define use_portb_lcd TRUE
#include <vs_saa1064M.c>
#include <lcd.c> //libreria para lcd
#include<stdlib.h>
#include<math.h>
void nro_a_BCD();
void imprime_BCD();
void lineal();
void muestra_en_display();
int16 decimal, unidad, decena, centena,t1=0;//,t1entc,t1entd,t1entu,t1entdec;
float lm35,temperatura=0,linealizacion,V,T,v1,Vcompensado,exponente;//t1c,t1d,t1u,t1dec,
int32 temp;//esta variable se usa para la conversion y en main x10
//range: 0.000, 1372.000, The coefficients
//* are in units of °C and mV and are listed in the order of constant
//* term up to the highest order
//formula tipo: E = sum(i=0 to n) c_i t^i + a0 exp(a1 (t - a2)^2).
/*
//0ºa a 500 ºc - 0.000 to 20.644mv
//500ºc a 1372 ºc 20.644 to 54.886
//formula tipo: t_90 = d_0 + d_1*E + d_2*E^2 + ...+ d_n*E^n,
*/
///PROGRAMA
void main(void)
{
float p1,p2,p3,p4,p5,p6,p7,p8,p9;
float c1=-0.176004136860E-01,c2= 0.389212049750E-01,c3=0.185587700320E-04,c4=-0.994575928740E-07,c5= 0.318409457190E-09,c6= -0.560728448890E-12,c7= 0.560750590590E-15,c8=-0.320207200030E-18,c9=0.971511471520E-22,c10=-0.121047212750E-25;
float ex0 =0.118597600000, ex1 =-0.118343200000E-03, ex2=0.126968600000E+03;
lcd_init( ); //inicializamos lcd
lcd_putc(" Medidor de \n temperatura");
delay_ms(1000);
lcd_putc("\f");
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
while (true)
{
///////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// Bits de control: X C6 C5 C4 C3 C2 C1 C0 ///
/// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ///
/// C0=0 modo estatico->digitos 1 y 2 ///
/// C0=1 modo dinamico->digitos 1&3 y 2&4 alternativamente ///
/// C1=0/1 digitos 1&3 no parpadep/parpadeo ///
/// C2=0/1 digitos 2&4 no parpadep/parpadeo ///
/// C3=1 test segmentos ///
/// C4=1 +3mA de salida ///
/// C5=1 +6mA de salida ///
/// C6=1 +12mA de salida ///
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////
/// ///
/// LM35 TEMPERATURA DE REFERENCIA///
/// ///
///////////////////////////////////////
saa1064_init(0x76); //inicializo saa1064 conectado a Vcc D1
saa1064_conf(0b01000111); //12mA & parpadeo & Dinamico
saa1064_putc(0X77,0X79,0X71,0x63);//(R,E,F,CENTIGRADO); //T1 titilando
delay_ms(100);
saa1064_stop();
set_adc_channel(4);//seteo y lectura de lm35
delay_ms(50);
t1=read_adc();
temperatura=(float)t1*0.0048828125*100*0.3333333333333333333333333333;//t1 valor digital de la tension
T=temperatura;
temp=T*10;//multiplico el valor de temperatura pra que aparezca como entero
exponente=ex0*exp(ex1*((T-ex2)*(T-ex2)));
T =(float) Vcompensado * (a1+ Vcompensado* (a2 +Vcompensado*(a3+Vcompensado*(a4+Vcompensado*(a5+Vcompensado*(a6+Vcompensado*(a7+Vcompensado*((a8+Vcompensado*(a9))))))))));
V1=(float)(c1*T+exponente)+(c2*T*exp(2)+exponente);//+(c4*p3+exponente)+(c5*p4+exponente)+(c6* p5+exponente)+(c7*p6+exponente)+(c8*p7+exponente)+(c9*p8+exponente);
V1=(float)v1+(c3* T*exp(3) +exponente)+(c4*T*exp(4)+exponente);//+(c7*p6+exponente)+(c8*p7+exponente)+(c9*p8+exponente);
v1=(float)v1+(c5*T*exp(5)+exponente)+(c6*T*exp(6)+exponente);
v1=(float)v1+(c7*T*exp(7)+exponente)+(c8*T*exp(
+exponente);
v1=(float)v1+(c9*T*exp(9)+exponente);
printf(lcd_putc,"V1 %9f",V1);
nro_a_BCD();
imprime_BCD();
/***********FIN LM35 TEMPERATURA DE REFERENCIA*************************/
///////////////////////////////////////
/// ///
/// 1era termocupla ///
/// ///
///////////////////////////////////////
saa1064_init(0x76); //inicializo saa1064 conectado a Vcc D1
saa1064_conf(0b01000111); //12mA & parpadeo & Dinamico
saa1064_putc(0x78,0x06,0x00,0x00); //T1 titilando
delay_ms(500);
saa1064_stop();
set_adc_channel(0);//seteo y lectura de termocupla1
delay_ms(70);
t1=read_adc();
//V=(float)t1*0.0048828125*10;//es x 10 para simular 50 mv como 50 Voltios
V=(float)t1*0.0048828125*10;
Vcompensado=(float)V+V1;
lineal();
muestra_en_display();
nro_a_BCD();
imprime_BCD();
/***********FIN 1era termocupla*************************/
}
}
/*************************************************************/
///////////////////////////////////////
/// ///
/// FIN MAIN ///
/// ///
///////////////////////////////////////
///////////////////////////////////////////////////
/// ////
///FUNCION DESGLOSA EL VALOR Y CONVIERTE A BCD ///
/// ////
/////////////////////////////////////////////////
/*
/**************************************/
void nro_a_BCD()
{
char tab7segCONPUNTO[10]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7};//7seg hex 0-9
char tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex 0-9 con punto
int tempBCD[5];
itoa(temp,10, tempBCD);
// tempBCD[0]=decimal T
// tempBCD[1]=unidad T
// tempBCD[2]=decena T
// tempBCD[3]=centena T
if (temp<1000)//entra aca si el valor e menor a 100ºc
{
if (temp<100)//entra aca si el valor e menor a 10ºc
{
decimal=tab7seg[tempBCD[1]-48];//Aqui se resta 48 porque me imprime el valoer en ascii del caracter
unidad=tab7segCONPUNTO[tempBCD[0]-48];//por ej 0 es =48 1=49 y asi.....
decena=0x00;//mando la centena al saa1064
centena=0x00;//mando la centena al saa1064
}
else
{
decimal=tab7seg[tempBCD[2]-48];
unidad=tab7segCONPUNTO[tempBCD[1]-48];
decena=tab7seg[tempBCD[0]-48];//mando la centena al saa1064
centena=0x00;//mando la centena al saa1064
}
}
else//entra aca si el valor e ssuperior a 100ºc
{
decimal=tab7seg[tempBCD[3]-48];
unidad=tab7segCONPUNTO[tempBCD[2]-48];
decena=tab7seg[tempBCD[1]-48];//mando la centena al saa1064
centena=tab7seg[tempBCD[0]-48];//mando la centena al saa1064
}
}
///////////////////////////////////////////////////
/// ////
///FUNCION ENVIA EL NRO AL BCD ///
/// ////
/////////////////////////////////////////////////
void imprime_BCD()
{
saa1064_init(0x76); //inicializo saa1064 conectado a Vcc D1
saa1064_conf(0b01000001); //12mA & NO parpadeo & Dinamico
saa1064_putc(centena,decena,unidad,decimal); //HOLA
delay_ms(4000);
saa1064_stop();
}
/***********FIN FUNCION ENVIA EL NRO AL BCD*********************************************/
///////////////////////////////////////////////////
/// ////
///FUNCION LINEALIZA EL VALOR DE TEMP Y VOLTAJE ///
/// ////
/////////////////////////////////////////////////
void lineal()
{
float a1=2.508355E+01 ,a2=7.860106E-02 ,a3=-2.503131E-01 ,a4=8.315270E-02 ,a5=-1.228034E-02 ,a6=9.804036E-04 ,a7=-4.413030E-05 ,a8=1.057734E-06 ,a9=-1.052755E-08 ;
//0ºa a 500 ºc - 0.000 to 20.644mv
float a11=-1.318058E+02 ,a12=4.830222E+01 ,a13=-1.646031E+00 ,a14=5.464731E-02 ,a15=-9.650715E-04 ,a16=8.802193E-06 ,a17=-3.110810E-08 ;
//500ºc a 1372 ºc 20.644 to 54.886
//formula tipo: t_90 = d_0 + d_1*E + d_2*E^2 + ...+ d_n*E^n,
if(Vcompensado<20.6)
{
T =(float) Vcompensado * (a1+ Vcompensado* (a2 +Vcompensado*(a3+Vcompensado*(a4+Vcompensado*(a5+Vcompensado*(a6+Vcompensado*(a7+Vcompensado*((a8+Vcompensado*(a9))))))))));
}
else
{
T =(float) Vcompensado * (a11+ Vcompensado* (a12 +Vcompensado*(a13+Vcompensado*(a14+Vcompensado*(a15+Vcompensado*(a16+Vcompensado*(a17)))))));
}
temp=T*10;//multiplico el valor de temperatura pra que aparezca como entero
}
///////////////////////////////////////////////////
/// ////
///FUNCION muestra_en_display IMPRIME EN LCD ///
/// ////
/////////////////////////////////////////////////
void muestra_en_display()
{
lcd_gotoxy(1,1);
printf(lcd_putc,"V %f",T);
lcd_gotoxy(1,2);
printf(lcd_putc,"mV %f",Vcompensado);
}