mcataldo
Joined: 04 Jul 2010 Posts: 11 Location: Santiago, Chile
|
LM35 simulation problem |
Posted: Wed Jul 07, 2010 1:05 am |
|
|
Hi everybody, i'm having right now a problem with my project (simulating on Proteus). My project is a water temperature control systems through heater power control and valves opening.
Problem is when I run Proteus simulation, temperatures are shown (Tcal and Tmin-1) are 0 even though are 13ºc and 16ºc.
Thank you very much.
Code: |
#include <16F877A.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT
#use delay(clock=4000000)
#include <LCD.c>
#priority rb,timer2
// Declaración de variables
int8 temp_sp;
int temp_sp_ee;
int16 temp_analogo_c;
int16 temp_analogo_f;
int temp_f;
int temp_f1;
int temp_f2;
int temp_f3;
int temp_f4;
int temp_c;
int temp_c1;
int temp_c2;
int temp_c3;
int temp_c4;
int temp_min;
int temp_max;
short temp_read = 0;
// Variables relacionadas a los Servos
signed int d_temp;
signed int d_temp_c;
signed int d_temp_f;
int r_temp;
int contador_c;
int contador_f;
int contador_p;
int N;
int counter = 0;
//short t_default = 1;
// Variables relacionadas a los pulsadores
short msg_max = 0;
short msg_min = 0;
short sp=0;
//short rebote = 0;
// Interrupción para señal PWM de Servomotores
#INT_TIMER2
void servos()
{
N++;
// El timer 2 está contando permanentemente, cuando llega al overflow se detiene
// el main y entra a la rutina de interrupción. Ejecuta los pasos que vienen a
// continuación y regresa a la línea de comandos del main.
switch (N)
{
case 1:output_low(PIN_C2);
set_timer2(contador_f);
break;
case 2:output_low(PIN_C1);
set_timer2(contador_p);
break;
case 7:output_high(PIN_C1);
output_high(PIN_C2);
set_timer2(contador_c);
N = 0;
break;
default:output_low(PIN_C1);
output_low(PIN_C2);
set_timer2(0);
break;
}
}
// Interrupción de cambio de temperatura de Setpoint por pulsadores
#INT_RB
void pulsadores()
{
disable_interrupts(INT_RB);
disable_interrupts(INT_TIMER2);
if(!input(PIN_B4))
{
if(temp_sp < temp_max)
{
temp_sp = temp_sp+1;
sp = 1;
}
else
msg_max = 1;
}
if(!input(PIN_B5))
{
if(temp_sp > temp_min)
{
temp_sp = temp_sp-1;
sp = 1;
}
else
msg_min = 1;
}
enable_interrupts(INT_RB);
enable_interrupts(INT_TIMER2);
}
void main()
{
set_tris_a(0xFF); //interesa que los puertos A0 y A1 sean entradas (1)
set_tris_b(0xFF); // Señal Pulsadores
// se escribe 0xXX cuando se desea en hexadecimal
set_tris_c(0x00); // Señal PWM para los servos
set_tris_d(0x00); // Puertos que van al LED
setup_adc(ADC_CLOCK_DIV_32);
setup_adc_ports(ALL_ANALOG);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_comparator(NC_NC_NC_NC);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1); //el postscale es para determinar cuantos
//overflows para gatillar una interrupción
// se acostumbra a poner aca el enable interrupts ...
lcd_init();
// Mensaje de Bienvenida
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Ducha Electrica");
lcd_gotoxy(1,2);
printf(lcd_putc,"Automatizada V.6");
delay_ms(500);
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc," G.14 : Cataldo");
lcd_gotoxy(1,2);
printf(lcd_putc," Cortes");
delay_ms(500);
// Agua fría
set_adc_channel(0);
temp_analogo_f=read_adc(); //10 bits
temp_f1=(int)500*temp_analogo_f/1023; //conversion a °C (LM335) se mejora con Vref A/D
// Agua Caliente
set_adc_channel(1);
temp_analogo_c=read_adc(); //10 bits
temp_c1=(int)500*temp_analogo_c/1023; //conversion a °C (LM335) se mejora con Vref A/D
temp_min = temp_f+1;
temp_max = temp_f+4;
// Temperatura de Setpoint
temp_sp_ee = read_eeprom(0);
if(temp_sp_ee != 255)
{
temp_sp = temp_sp_ee;
}
else
{
temp_sp = 15;
}
//***** Setup del número al que debe contar timer 2 por defecto
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RB);
//se debe crear el primer pulso que posiciona las válvulas en reposo
output_high(PIN_C1);
output_high(PIN_C2);
contador_c = 94;
contador_f = 0;
contador_p = 156;
set_timer2(162);
N = 0;
while(TRUE)
{
// enable_interrupts(INT_RB);
// LECTURA DE TEMPERATURA ANÁLOGA
// Definición de los anchos de pulso para las señales PWM
// Los casos son los siguientes:
// Primero, para elevar la temperatura, no necesito hacer nada con las válvulas.
// Segundo, si la T° del agua caliente está por sobre la T° de setpoint, debo
// abrir la válvula de agua fría
// Agua fría
switch (counter)
{
case 0:set_adc_channel(0);
temp_analogo_f=read_adc(); //10 bits
temp_f1=(int)500*temp_analogo_f/1023; //conversion a °C (LM335) se mejora con Vref A/D
set_adc_channel(1);
temp_analogo_c=read_adc(); //10 bits
temp_c1=(int)500*temp_analogo_c/1023; //conversion a °C (LM335) se mejora con Vref A/D
counter = 1;
break;
case 1:set_adc_channel(0);
temp_analogo_f=read_adc(); //10 bits
temp_f2=(int)500*temp_analogo_f/1023; //conversion a °C (LM335) se mejora con Vref A/D
set_adc_channel(1);
temp_analogo_c=read_adc(); //10 bits
temp_c2=(int)500*temp_analogo_c/1023; //conversion a °C (LM335) se mejora con Vref A/D
counter = 2;
break;
case 2:set_adc_channel(0);
temp_analogo_f=read_adc(); //10 bits
temp_f3=(int)500*temp_analogo_f/1023; //conversion a °C (LM335) se mejora con Vref A/D
set_adc_channel(1);
temp_analogo_c=read_adc(); //10 bits
temp_c3=(int)500*temp_analogo_c/1023; //conversion a °C (LM335) se mejora con Vref A/D
counter = 3;
break;
default:set_adc_channel(0);
temp_analogo_f=read_adc(); //10 bits
temp_f4=(int)500*temp_analogo_f/1023; //conversion a °C (LM335) se mejora con Vref A/D
set_adc_channel(1);
temp_analogo_c=read_adc(); //10 bits
temp_c4=(int)500*temp_analogo_c/1023; //conversion a °C (LM335) se mejora con Vref A/D
temp_f=(temp_f1+temp_f2+temp_f3+temp_f4)/4;
temp_c=(temp_c1+temp_c2+temp_c3+temp_c4)/4;
temp_read = 1;
counter = 0;
break;
}
if (temp_read == 1)
{
temp_read = 0;
temp_min = temp_f+1;
temp_max = temp_f+4;
d_temp_c = (int)temp_c - temp_sp;
d_temp_f = temp_sp - (int)temp_f;
d_temp = (int)temp_c - (int)temp_f;
r_temp = 300*d_temp_f/d_temp;
if (d_temp_c >= 0 && d_temp > 0)
{
// Al contar hasta 31 se tienen 0,5 ms o -90°
// Al contar hasta 94 se tienen 1,5 ms o 0°
// Al contar hasta 156 se tienen 2,5 ms o +90°
// Al igualar el resultado a una variable del tipo int, ésta tomará el valor
// entero y para que quede redondeada se usa el truco de sumar 0.5
switch (r_temp)
{
case 75:contador_c = 210; // 256-46
contador_f = 162; // 256-(140-46)
contador_p = 116; // 256-140
break;
case 100:contador_c = 204; // 256-52
contador_f = 173; // 256-(135-52)
contador_p = 121; // 256-135
break;
case 150:contador_c = 194; // 256-62
contador_f = 193; // 256-(125-62)
contador_p = 131; // 256-125
break;
case 200:contador_c = 183; // 256-73
contador_f = 215; // 256-(114-73)
contador_p = 142; // 256-114
break;
case 225:contador_c = 177; // 256-79
contador_f = 225; // 256-(110-79)
contador_p = 146; // 256-110
break;
default:contador_c = 162; // 256-94
contador_f = 255;
contador_p = 162; // 256-94
break;
}
}
else
{
contador_c = 162;
contador_f = 255;
contador_p = 162;
}
set_timer2(contador_c);
//en caso de que se alcance la temperatura, entonces:
// Mostrar la temperatura leida en el Display
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Tref:%2u\n",temp_sp);
lcd_gotoxy(9,1);
printf(lcd_putc,"Tcal:%2u\n",temp_c);
lcd_putc(223);
lcd_gotoxy(1,2);
printf(lcd_putc,"Tmin:%2u\n",temp_min);
lcd_gotoxy(9,2);
printf(lcd_putc,"Tmax:%2u\n",temp_max);
lcd_putc(223);
delay_ms(800);
// Guardar temperatura de setpoint
if(sp == 1)
{
sp = 0;
write_eeprom(0,temp_sp);
}
// Mostrar mensaje que se ha alcanzado temperatura máxima o mínima
if(msg_max == 1)
{
msg_max = 0;
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Ha alcanzado la");
lcd_gotoxy(1,2);
printf(lcd_putc," temp. maxima ");
delay_ms(500);
}
if(msg_min == 1)
{
msg_min = 0;
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Ha alcanzado la");
lcd_gotoxy(1,2);
printf(lcd_putc," temp. minima ");
delay_ms(500);
}
// if(rebote == 1);
// {
// rebote = 0;
// delay_ms(20);
// }
delay_ms(1000);
}
}
}
|
|
|