TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: nestoriano en 05 de Agosto de 2011, 23:08:51
-
Hola este es mi primer proyecto con pic. Hace 2 semanas empece a programar PICs y en C. Un amigo me pidio que le arme un cooler para que no se queme el amplificador de audio que se esta por armar. Con lo que aprendí leyendo y ensayando en ISIS, pude armar lo que me pidió.
Su funcionamiento es simple,
-Si la temperatura sube a mas de 55 grados enciende cooler hasta bajar la temperatura a 45 grados. El cooler luego de enfriar se apaga.
-Si sube a mas de 70 grados (cosa que no creo) el cooler sigue encendido pero con un led que parpadea que advierte al usuario.
-Y si sigue calentando a mas de 75 grados el led parpadea mas rapido.
-Y si la temperatura pasa los 80 grados, corta un relay que apaga el amplificador. El cooler y el led siguen activos y a los 70 grados vuelve a pegar el relay encendiendo el equipo.
Los componentes principales son el LM35 (sensor de temperatura) y un PIC 12f683 con ADC. Este es mi primer proyecto usando pic y estuve ensayando en el ISIS hasta hacerlo funcionar en la simulacion. Hoy arme el circuito y no me funciona como deberia...
Caliento el LM35 y a los 55 grados enciende el led 1 vez o se queda parpadeando y enciende el cooler, dejo que enfrie y cerca de los 40 grados apaga y prende el cooler un par de veces, cosa que no deberia hacer. El cooler no deberia encender a menos de 55 grados. Y si lo sigo calentando el led empieza a parpadear mucho antes, como a los 55 grados cuando deberia hacerlo a los 70. Y si lo sigo calentando, el relay de corte despega, pega, un par de veces.
Dejo el programa hecho en CCS y el circuito a ver si me pueden indicar porque no me funciona como en la simulacion.
---------------------------------------------------
#include <12F683.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin enabled
#FUSES NOPUT //No Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#use delay(int=4000000)
#define sensor PIN_A0 ////////pata del lm35
#define salida PIN_A1 //////// pata que enciende el cooler
#define corte PIN_A2 //////// relay que enciende y apaga el amplificador
#define danger PIN_A4 //////// led de advertencia cuando la temperatura se pone peligrosa
---------------------------------------------------------------------------------------------------------------------------------------------
#include <pr7.h>
#byte portg=5
int temp =120;
void adv1(void);
void adv2(void);
float medicion;
void main()
{
setup_adc_ports(sAN0|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC);
setup_oscillator(OSC_4MHZ);
portg=0;
set_tris_a(0b00000001); ///// todo salida menos la pata que viene del lm35
//TODO: User Code
output_high(corte); //// pegar relay que enciende el aparato.
do{
set_adc_channel (0);
delay_us (20);
medicion=read_adc ();
temp=medicion/2.046; ///// calculo, se supone que el resultado de la lectura / 2.046, seria la temperatura.
if(temp>75)
adv2();
if(temp>70)
adv1();
if(temp>55)
output_high(salida); /////salida=cooler, danger=led advertencia, corte= relay.
output_low (danger);
output_high(corte);
if(temp<45)
output_low(salida);
output_low (danger);
output_high(corte);
}while(true);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void adv1(void) ///////titila led hasta que la temperatura baje a 65 grados.
{ /////// si se calienta mas pasa a adv2.
do{
output_high(corte);
output_high(salida);
output_high(danger);
delay_ms(500);
output_low(danger);
delay_ms(500);
set_adc_channel (0);
delay_us (20);
medicion=read_adc ();
temp=medicion/2.046;
if(temp>75)
adv2();
}while(temp>65);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void adv2(void) /////// titila led mas rapido. si la temperatura disminuye
{ /////// pasa a adv1, si sigue subiendo a mas de 80 grados corta el relay
/////// y apaga todo.
do{
output_high(salida);
output_high(danger);
delay_ms(200);
output_low(danger);
delay_ms(200);
set_adc_channel (0);
delay_us (20);
medicion=read_adc ();
temp=medicion/2.046;
if(temp>80)
output_low(corte);
}while(temp>71);
}
------------------------------------------------------------------------
En la simulacion funciona de 10. Aver si pueden iluminar mi camino... Gracias.
-
Hola, el problema que me parece esta teniendo es con las condiciones de los if, ya que si la temperatura es de 85ªC el programa hace lo que corresponde a la rutina para 55ªC y 70ªC. Yo lo que haria es crear bannderas, una para cuando la temperatura es de mas de 55, otra para cuando pasa los 70 y otra para cuando es menos de 45.
el seudocodigo seria:
SI BANDERA 45C ES VERDAD
ENTONCES APAGAR COOLER
SI BANDERA 55C ES VERDAD
ENTONCES ENCENDER VENTILADOR
SI BANDERA 55C Y BANDERA 70C ES VERDAD
ENTONCES PARTADEA LED
Otra cosa es que verifique el dato que te tira el read_adc que creo que no es el valor de la temperatura en decimal, sino en binario.