TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: djblackmagic en 16 de Febrero de 2011, 17:35:23
-
que tal amigos del foro, pido su ayuda para poder arreglar mi programa que realice en C para un control de temperatura, en proteus al hacer la simulacion jala muy bien pero ya armandolo en proto empieza a funcionar mal, espero me puedan ayudar. el control en si tiene dos entradas analogicas una proveniente de un lm35 sensor de temperatura y otra de un potenciometro que va a hacer la temperatura deseada, el problema que al probarlo fisicamente las salidas empiezan a intercambiars eunas con otras , es decir si le pusiera leds , estos empezarian a prender unos y otros sin control, uso el pic16f876a y aqui mi programa:
#include <16f876a.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#define FOCO PIN_B2
#define CALENTARCEL PIN_B1
#define ENFRIARCEL PIN_B0
#define COMPRESOR PIN_B3
float pot,sensor,t1,t2;
void main(void) {
//set_tris_b(0x00);
setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(ALL_ANALOG);//entrada 0 y 1 como analogicas
delay_ms(1);
disable_interrupts(GLOBAL);
while(1){
// Lectura del canal 0 por AN0
set_adc_channel(0);
delay_ms(10);
pot=read_adc();
delay_ms(10); //para que se estabilice
pot=pot*5*10/255;
t1=pot-(pot*20/100);
delay_ms(10);
//lectura del canal 1 por AN1
set_adc_channel(1);
delay_ms(10);
sensor=read_adc();
delay_ms(10);
sensor=sensor*5*10/255;
t2=pot+(pot*20/100);
delay_ms(10);
if(sensor<t1)//prende foco
{
output_high(foco);//se prende foco
output_low(compresor);//esta en apagado compresor
output_low(enfriarcel);//apagada la parte que enfria de la celda
output_low(calentarcel);//apagada la parte que calienta de la celda
}
if (sensor>=t1 & sensor<=t2)
{
output_low(compresor);
output_low(foco);
if(pot>sensor)//calentar
{
output_low(enfriarcel);
output_high(calentarcel);
output_low(foco);
output_low(compresor);
}
if(pot<sensor)//enfriar
{
output_high(enfriarcel);
output_low(calentarcel);
output_low(foco);
output_low(compresor);
}
if(pot==sensor)//no hagas nada
{
output_low(enfriarcel);
output_low(calentarcel);
output_low(foco);
output_low(compresor);
}
}
if(sensor>t2)
{
output_low(foco);
output_high(compresor);
output_low(enfriarcel);
output_low(calentarcel);
}
}
}
espero me puedan ayudar, saludos.....
-
mirandolo por encima el problema lo tendras en los if que se pueden dar varias condiciones a la vez yo emplearia else if
para probar.
-
ok lo voy a checar como dices gracias por responder...saludos
-
ya lo hice agregando unos else, pero como no se mucho de programacion no se si esta bien o no, de todos modos no pude evitar poner los if, hice el programa y lo simule y jalo pero aramdo de nuevo no funciona, estaba leyendo que tal vez por el largo del cable del sensor, cause estas variaciones, acorte el cable y disminuyo un poco el problema, que mas puedo hacer, porque al parecer es problema de conexiones en el circuito...saludos
-
Hola.
Toma varias lecturas del dato analogico y promedialas.
Saludos
-
estaba leyendo que tal vez por el largo del cable del sensor, cause estas variaciones, acorte el cable y disminuyo un poco el problema, que mas puedo hacer, porque al parecer es problema de conexiones en el circuito...saludos
si estas enviando la tension del lm35 directamente por un cable hasta la entrada del pic, es un gran problema por ruidos electronicos temperaturas radiofrecuencias etc... yo hice un proeycto algo parecido, si te fijas en la hoja de datos del LM35 hay un pequeño circuito
(http://img713.imageshack.us/img713/2281/69655699.th.png)
ahi lo que haces es convertir la tension proporcional del LM35 a corriente, y luego en el circuito del pic le agregas una resistencia a masa en la entrada analogica (para convertir la corriente en tension)
(http://img812.imageshack.us/img812/407/lm2.png)
capaz que te sirve de ayuda, yo hice un circuito parecido al tullo, pero en ves de regular la temperatura con un potenciomentro lo hice con pulsadores, pero ahi podes ver mas o menos bien como es el tema del circuito, te digo la verdad yo lo he probado y hasta 80 mts 90 mts aprox. no tuve ningun inconveniente.
http://www.todopic.com.ar/foros/index.php?topic=32726.0
espero que te sea de ayuda.
Saludos
-
Hola.
Toma varias lecturas del dato analogico y promedialas.
Saludos
Hola djblackmagic, lo que te sugiere MLO__ es altamente recomendable. Además, como tienes configuradas todas las entradas análogas, deberías conectar las que no estás usando al negativo para evitar el ingreso de ruido por esos pines. Otra posible causa además de lo anterior (ya me pasó), es que tu fuente no esté debidamente regulada.
Saludos!
-
hola a todos, antes que nada quiero agradecerles por tomarse el tiempo para leer y reponder al tema, quiero decirles que tengo conectado el lm35 a un circuito seguidor con un amplificador tl081 y despues al pic, voy a conectar las demas entradas analogicas a masa y realizare el circuito del datsheet del lm35 y comentare resultados, gracias y saludossss...
-
ya lo probe con el circuito del datasheet y aun asi me sigue presentando el mismo error, no se si la falla este en mi programa puesto que soy nuevo programando y el codigo que muestro lo hice basandome en varios aportes de este foro.
-
nose si estoy en lo correcto, pero no se si hace falta declarar las variables como float, yo en mi ejemplo que te deje en el enlace mio de mi proyecto, la he declarado a las variables de temperatura como signed long, o mejor dicho variables enteras sin usar punto flotante porque no lo vi necesario, podrias adjuntar el esquema en proteus con el archivos cof? si no te es molstia.
Saludos!!
-
aun mas, con variables int16 y un AOP a la entrada del micro, podes llegar hasta usar decimales en las mediciones de temperaturas.
pero bueno, como se dice siempre, opciones son opciones, cada uno toma la que mas le convenga ( o la q mas quiera)
Saludos!!
-
no es molestia al contrario gracias por tu ayuda, no entendi muy bien lo que me pides, te adjunto el archivo .cof de mi codigo en C y no se como pasarte el esquema del circuito en proteus pues en windows no me lo muestra y al abrirlo desde isis proteus me sale con un candado, no se cual sea el problema...al codigo le eh hecho varias modificaciones y aun asi no queda..saludos
-
ok, ahora me lo monto en el proteus, y si me aguantas 15 minutos te comento la experiencia
-
gracias ya pude obtener el archivo .dsn del diagrama, te paso el diagrama en proteus del control para que cheques el funcionamiento
-
duda que tengo, en las operacion que utilizas luego de leer los canales?
porque haces por ejemplo:
pot=pot*50/1023;
t1=pot-(pot*20/100);
a vos realemente te funciona con ese tipo de calculos?
mejor dicho, vos inventaste ese tipo de calculos o lo sacaste de otra parte del foro, dsiculpa mi ignoracion sino.
yo lo hubiese hecho asi
pot=((pot*488)/1000)
488 es la cantidad de milivolts por paso del conversor, pero capaz que me estoy llendo por las ramas.
por otro lado, yo habilitaria solo las entradas analogicas que utilizaria, ah y otro pequeño gran consejo que me ha ocurrido ami, has puesto un capacitor (de unos 10uf capaz) bien cerca de los pines de alimentacion del micro??
yo en el proyecto (del hilo mio jeje) tuve exactamente el mismo problema que me aparecian cualquier variable (en mi caso en un display) y es como que se volvia loco el sistema, pero se soluciono con ese capacitor.
-
ok, mira: el valor de pot=pot*50/1023; lo sque del foro y es para obtener la conversion a grados centigrados y es de la formula: T°=Vref*Escala*read_adc()/(2^n-1)
el otro valor: t1=pot-(pot*20/100); es ´porque t1 es el 20% por debajo de el valor de pot y t2 es el 20% por arriba del valor de pot. esto lo hice porque cuando la temperatura que sense el lm35 este 20% arriba que la del potenciometro active una salida, y cuando este 20% por debajo del valor del potenciometro active otra, ojala y me hayas entendido, y en cuanto al capacitor, la verdad es que no se lo puse, y como va el capacitor, entre vcc y masa , o a que te refieres con cerca de los pines de alimentacion del micro?
-
exactamente entre vcc y masa, pero lo mas cerca del micro posible, no se si tendras osciloscopio, yo tengo uno portatil y bueno me llevaba loco ese problema, hasta que medi los pines de alimentacion y aparecia un ruido generado por el cristal y ahi fue cuando inserte mi capacitor y me soluciono todo.
ahora entiendo bien lo de tus operaciones jajaja. cada dia se aprende algo nuevo en este foro por pequeño que sea.
entonces ahora me tiro mas claramente a que hay un ruido electrico, y que deberias desabilitar las entradas analogicas que no utilices.
y los delay para las lecturas de las entradas analogicas lo dejaria en delay_us(20), porque en milisegundos es muy lento, en microsegundos y 20 es mas que suficiente.
#use standard_io(b)
#use fast_io(a)
y nose me ocurre otra cosa
cualquier cosilla, estamos en contacto...
Saludos!!
-
ok, mira he intentado habilitar nada mas ra0 y ra1 como entradas analogicas, sin embargo a la hora de compilar el programa me marca error, la verdad no se porque, asi que tuve que habilitar todas y asi fue como jalo.
estoy mirando el comportamiento del circuito y veo que el descontrol lo hace cuando las dos señales se aproximan, es decir ahi es cuando empieza a activar una salida y la otra, intercambiandose, como si el pic no supiera para cual lado irse jajaja, checare lo del capacitor y cambiare a 20 us..saludos y gracias
-
Hola djblackmagic, fijate en el archivo .h del PIC. allí te muestra cuales entradas análogas puedes activar a la vez. También lo puedes ver en la hoja de datos del PIC.
Saludos!
-
y djblackmagic como te fue ahora con tu experiencia?
Saludos!
-
que tal, pues de tanto probar y probar logre que mas o menos funcionara, y pues al parecer para las condiciones que necesito anda bien, lo que hice fue solo hacer el retardo mas grande en cada comparacion y al parecer con eso,..... de todos modos sigo abierto a sugerencias para mejorarlo...gracias y saludoss
-
#include <16f876a.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOPUT
#use delay(clock=4000000)
#use fast_io(a)
#use standard_io(b)
#define FOCO PIN_B2
#define CALENTARCEL PIN_B1
#define ENFRIARCEL PIN_B0
#define COMPRESOR PIN_B3
float pot,sensor,t1,t2;
void main(void) {
set_tris_b(0x00);
set_tris_a(0xff);
setup_adc_ports(ALL_ANALOG);//entrada 0 y 1 como analogicas
setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
while(true){
// Lectura del canal 0 por AN0
set_adc_channel(0);
delay_us(20);
pot=read_adc();
delay_us(20); //para que se estabilice
pot=pot*50/1023;
delay_ms(50);
t1=pot-(pot*20/100);
delay_ms(50);
//lectura del canal 1 por AN1
set_adc_channel(1);
delay_ms(20);
sensor=read_adc();
delay_ms(20);
sensor=sensor*50/1023;
delay_ms(50);
t2=pot+(pot*20/100);
delay_ms(50);
if(sensor<t1)//prende foco
{
output_high(foco);//se prende foco
output_low(compresor);//esta en apagado compresor
output_low(enfriarcel);//apagada la parte que enfria de la celda
output_low(calentarcel);//apagada la parte que calienta de la celda
//delay_ms(100);
}
if (sensor>=t1 && sensor<=t2)
{
output_low(compresor);
output_low(foco);
//delay_ms(100);
if(pot>=sensor)//calentar
{
output_low(enfriarcel);
output_high(calentarcel);
output_low(foco);
output_low(compresor);
//delay_ms(100);
}
if(pot<sensor)//enfriar
{
output_high(enfriarcel);
output_low(calentarcel);
output_low(foco);
output_low(compresor);
//delay_ms(100);
}
if(pot==sensor)//no hagas nada
{
output_low(enfriarcel);
output_low(calentarcel);
output_low(foco);
output_low(compresor);
// delay_ms(100);
}
}
if(sensor>=t2)
{
output_low(foco);
output_high(compresor);
output_low(enfriarcel);
output_low(calentarcel);
// delay_ms(100);
}
}
}
yo lo he probado asi con mi pequeño 16f877a, y por lo que interprete del circuito funciona bastante bien, no tuve inconvenientes con mi micro y el ruido...
me surge otra duda ahora..
el circuito donde lo tienes montado??
-
que tal, pues lo he montado en una protoboard, para hacer las pruebas , despues cuando lo arme ya seria en un circuito impreso, que raro que te funciona bien, a mi me da muchos problemas
-
bueno, ahi puede estar el pequeño gran problema, con las protoboard te puedes esperar cualquier cosa, pero cualquiera, yo he comprado hasta la mas cara y me han traido siempre problemas, que por el ruido, que por los contactos, que la corriente y bla bla bla.
asi que ese puede ser otro inconveniente que puedes tener, quisiera que algun administrador venga a revisar y dar su opinion... (pienso en voz alta jeje)...
-
Hola djblackmagic, uno de los problemas que le veo al circuito que subiste en proteus y también a tu código, es que tienes como voltaje de referencia para las entradas análogas a V+ (5V), por lo que en la práctica ves tanta inestabilidad. Te recomendaría un circuito como este (http://www.todopic.com.ar/foros/index.php?topic=13389.0) (Respuesta #3), que usa una referencia de voltaje más baja.
También creo que estaría bien hacer lo que te sugiere korpaztk en usar las variables que toman los valores de ADC (pot y sensor) como variables int16.
Saludos!
-
gracias por sus consejos y pues lo que me resta es probar cada una de sus sugerencias, voy a checarlo con lo del circuito para el voltaje de referencia y lo de las declaracion de las varibles, saludos despues comento reultados, gracias de nuevo