TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: alexlarrain en 21 de Mayo de 2007, 17:17:10
-
El programa es para controlar la temperatura que viene dada por una ampolleta ... el termistor toma el valor de temperatura ...lo traduce en voltaje que es adquirido por el pic 16f628 lo compara y manda la señal para que apague la luz a través de un relé
cualquier ayuda consulta y sugerencia es bienvenida
#include <16F628A.h>
#FUSES XT,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR,NOLVP,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8)
#byte VRCON = 0x19
int puerto;
void main()
{
VRCON=4;
setup_comparator(A0_A3_A1_A2);
setup_vref(VREF_LOW|9); // At VDD=5, the voltage is 2.19V
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
port_b_pullups(true);
//set_tris_B(0b11111011);//
set_tris_a(0b00000111); /*a0,a1,a2 entradas, las demas salidas*/
output_b(puerto); /*limpiamos todo puerto B y lo ponemos de salida*/
while(true)
{
Delay_ms(1000);
puerto=0;
output_b(puerto);
while (1){
if (!input(PIN_A0)){
output_high(PIN_B0);}
}
}
}
-
Eso no creo que te ande, probeblemente la sentencia !input(PIN_A0) sea siempre true, ya que el mas minimo ruido en el pin A0 te va a ser diferente de 0 la entrada, por lo que esta sentencia será verdadera.
Deberias ponerle una luz, o rango, o histeresis para tu lamparita.
Solo a modo de ejemplo:
if(Input(Pin_A0)<=100) output_high(PIN_B0);
else output_low(PIN_B0);
Saludos
-
ya lo voi a ver bien ...
ahora q tengo un grabador mejor
muchas gracias
-
el programa funciona ... al llegar al valor de voltaje que esta de referencia en el pic activa el rele...lo que todavia no logro es encender la lamparita..pero en eso estoy trabajando ..
-
hola si tienes problema con la lampara te aconsejaria en vez de un rel un cto implementado con un moc y un triac, eso si la lampara es de ac, si es de dc estaria bien un simple cto con un transistor Tip35 o cualquier npn tipo tip
aqui te adjunto un programa sencillo que se encarga de establecer un pwm y tomar un dato necesitaria unas simples modificaciones para que te sea util, este es la base de un programa que utilize para hacer un control de luminosidad, mucha suerte
este es el .c
#include <LCD.C>
#include <STDLIB.H>
#define ADC=8
#define pulsador1 input(pin_e2)
#define pulsador2 input(pin_e1)
int dato_recibido=50;
unsigned int contador=0,a=5;
#int_RDA
RDA_isr()
{
dato_recibido=getc();
}
#int_TIMER2
TIMER2_isr()
{
/*PWM con timer 2
este PWM es utilizado para para dar un rango de luminosidad al bombillo de 0 a 100
y funciona perfectamene lo unico que tienes que actualizar es la variable "a"
que es la que da el valor del duty.
la entrada del adc es por el canal 5
solo tendria que ver que operacion hacer con valor(vble que toma el dato del adc), para luego elegir el valor de a
*/
contador++;
if(contador==100)
{
contador=0;
}
if(contador<=a)
{
output_high(pin_a2);
}
else if(contador>a)
{
output_low(pin_a2);
}
}
void main()
{
unsigned int valor;
int error;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(5);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_4,200,1);
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
lcd_init();
output_low(pin_d3);
for(;;)
{
read_adc(ADC_START_ONLY);
delay_us(500);
valor=read_adc(ADC_READ_ONLY);
}
}
este es el .h
#include <16F877.h>
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT, BROWNOUT, LVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
-
el programa solo me enciende la luz ...pero no la paga...todavia no se cual es el problema .... no se como hacer para que al voltaje indicado apague la luz a través del rele..
cualquier ayuda es bienvenida
gracias
-
hola estos meses he seguido tratando de encender y apagar la lamparita cuando llegue a cierta temperatura , hace pocos dias me encontre con Tema: Refrigeración Acuario tropial. Ctrol temperatura ... el cual es muy parecido a lo q yo quiero hacer .. bueno el programa lo adapte para lo que quiero pero no me funciona .si alguien puede hecharle un vistazo y me de un consejo ...se lo agradeceria
toma el valor de temp con un lm35 y al llegar al valor determinado apaga o prende una luz a travez de un rele
#include "16F877a.h"
#device adc=10 //ADC DE 10 BITS
#use delay (clock=4000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C4,rcv=PIN_C5)//,ERRORS,stream = PORT1)
#include<stdio.h>
#include<STDLIB.h>
#include <math.h>
#zero_ram
#fuses NOLVP,XT,WDT,NOPROTECT,PUT,BROWNOUT
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
int contador=0,canal=0,cont_ch=0,flag_ch=0,flag_filtro=0; //variables globales
float LnRes,LnRes3,r_term,adc_var,temp=0;
int16 cont_filtro=0;
//Función que captura el valor del ADC y lo almacena en temperatura
void captura(void)
{
double lectura_adc;
if(canal==0){
set_adc_channel(0); //seleccionamos canal AN0
delay_ms(5);
adc_var = read_adc(); //leemos el canal correspondiente
temp=adc_var*50.0/1023.0;
}
}
//Subrutina de control de temperatura
void control_temp(void)
{
if(temp<=35){
output_bit(PIN_B2,1);//si superamos 35º activamos el rele
} //Activa en alta. Rele NA.
if(temp>=36){
output_bit(PIN_B2,0);//si bajamos de 36º desactivamos el rele
} //Activa en alta. Rele NA.
}
//Subrutina de muestreo cada 5 segundos
void muestreo5seg(void)
{//************poner cada 5 segundos o cada 30 segundos
captura(); //capturamos adc
if(canal==0){control_temp();}//vemos como esta la temperatura
contador=0;
}
//Subrutina de interrución del TMR1
#INT_TIMER1
control_timer1()
{
output_bit(pin_b1,!input(pin_b1)); //Parpadeo de Led Status
contador++;
if((cont_filtro==10) && (flag_filtro==1))
{
output_bit(pin_b3,0);
flag_filtro=0;
}
else
{
cont_filtro++;
}
if((cont_ch==10) && (flag_ch==1))
{
canal=0;//ponemso el canal0
flag_ch=0;
}
else
{
cont_ch++;
}
}
void main(void)
{
setup_adc_ports (0x84); //RA3,RA1,RA0 Analog
setup_adc(ADC_CLOCK_INTERNAL);
disable_interrupts(GLOBAL);
set_tris_a(0xFF); // RA0,RA1 y RA3 como entradas analogicas
// RA0--> TEMPERATURA
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0xF1); // RB7:4, RB0 ENTRADAS, RB3:1 SALIDAS
// RB7--> SELECCIONAR Tª
// RB6--> PARA FILTRO DURANTE 5 MINUTOS
// Activo en alta y NC
// RB5-->
// RB2--> SALIDAS RELES
// RB1--> STATUS
//set_tris_c(0x00); // Puerto C entero como salida para display
// RC0:3--> A0:A3 salida BCD para displays
// RC4--> Control display Unidades
// RC5--> Control display Decenas
setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
//enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
contador=0;
output_bit(PIN_B2,0);//luz apagada
}
-
En tu código veo funciones utilizadas que no son llamadas desde ninguna parte.
Por ejemplo tienes activada la interrupcion #int_timer1 y dentro de la interrupcion no llamas a otra función.
En el main no existe ningún bucle de control, es decir que que lo único que se ejecuta indefinidamente es la interrupciòn por desbordamiento del timer1.
Las funciones CAPTURA,CONTROL_TEMP y MUESTREO5SEG no son llamadas,no tomas valor del ADC del pic,ya que el valor del ADC lo recibes a través de la función CAPTURA.
Ese código has de repasarlo bastante mejor
Saludos y suerte
-
gracias lo voi a revisar y probar ...
-
quite algunas funciones y coloque el main para llamar las funciones
si alguien tiene alguna sugerencia , al compilar el programa no hay problema
pero no esta cumpliendo la funcion de encender y apagar la ampolleta a cierta temperatura
#include "16F877a.h"
#device adc=10 //ADC DE 10 BITS
#use delay (clock=4000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C4,rcv=PIN_C5)//,ERRORS,stream = PORT1)
#include<stdio.h>
#include<STDLIB.h>
#include <math.h>
#zero_ram
#fuses NOLVP,XT,WDT,NOPROTECT,PUT,BROWNOUT
#use fast_io(A)
#use fast_io(B)
#byte port_a = 0x05
#byte port_b = 0x06
int contador=0,canal=0,cont_ch=0,flag_ch=0,flag_filtro=0; //variables globales
float LnRes,LnRes3,r_term,adc_var,temp=0;
//Función que captura el valor del ADC y lo almacena en temperatura
void captura(void)
{
double lectura_adc;
if(canal==0){
set_adc_channel(0); //seleccionamos canal AN0
delay_ms(5);
adc_var = read_adc(); //leemos el canal correspondiente
}
}
// Calculo de Temperatura
void calcule_temp(long int adc_var)
{
r_term = ((10.0*adc_var)/(1024-adc_var));
LnRes = log(r_term);
LnRes3 = LnRes*LnRes*LnRes;
temp = (1/(0.00269794+0.00028033*LnRes+0.00000086*LnRes3))-273.15;
delay_ms(1000);
}
//Subrutina de control de temperatura
void control_temp(void)
{
if(temp<=35){
output_bit(PIN_B2,1);//si superamos 35º activamos el rele
}
if(temp>=36){
output_bit(PIN_B2,0);//si bajamos de 36º desactivamos el rele
}
}
//Subrutina de muestreo cada 5 segundos
void muestreo5seg(void)
{//poner cada 5 segundos o cada 30 segundos
captura(); //capturamos adc
if(canal==0){control_temp();}//vemos como esta la temperatura
contador=0;
}
void main(void)
{
setup_adc_ports (0x84); //RA3,RA1,RA0 Analog
setup_adc(ADC_CLOCK_INTERNAL);
disable_interrupts(GLOBAL);
set_tris_a(0xFF); // RA0,RA1 y RA3 como entradas analogicas
// RA0--> TEMPERATURA
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0xF1); // RB7:4, RB0 ENTRADAS, RB3:1 SALIDAS
// RB7--> SELECCIONAR Tª
// RB6--> PARA FILTRO DURANTE 5 MINUTOS
// Activo en alta y NC
// RB5-->
// RB2--> SALIDAS RELES
// RB1--> STATUS
setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
output_bit(PIN_B2,0);
while( 1 )
{
adc_var = READ_ADC();
delay_us(10);
calcule_temp(adc_var);
captura( );
control_temp( );
muestreo5seg( );
}
}
-
Activale el puerto de comunicaciones y utilizalo para hacer debug, a traves del programa para el puerto serie...
Utilizalo para enviar los valores leidos del ADC, el valor calculado y el estado del rele (al menos el que deberia tener).
Creo que tu programa posiblemente este leyendo algun valor que no coincide con los valores de comprobacion... :mrgreen:
-
MGLSOFT gracias por tus consejos..pero realmente no se como hacer eso ...con alguna interrupcion??? o con otra cosa...
si me pudieras guiar te lo agradeceria..
-
Ya tienes declarados tus pines de comunicacion en la linea:
#use rs232(baud=19200,parity=N,xmit=PIN_C4,rcv=PIN_C5)//,ERRORS,stream = PORT1)
Asi que con usar Printf() ya deberias estar comunicandote, si no tienes un Max232 en el circuito, puedes usar la opcion Invert de la sentencia Printf().
Para saber como usarla en la ayuda del compilador esta y hay ejemplos que te daran una idea de como hacerlo...
-
inclui el invert y tambien utilice el Printf()..pero todavia no acciona el led...si tienen alguna sugerencia ...les agradeceria
#include "16F877a.h"
#device adc=10 //ADC DE 10 BITS
#use delay (clock=4000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C4,rcv=PIN_C5,invert)
#include<stdio.h>
#include<STDLIB.h>
#include <math.h>
#zero_ram
#fuses NOLVP,XT,WDT,NOPROTECT,PUT,BROWNOUT
#use fast_io(A)
#use fast_io(B)
#byte port_a = 0x05
#byte port_b = 0x06
int contador=0,canal=0,cont_ch=0,flag_ch=0,flag_filtro=0; //variables globales
float LnRes,LnRes3,r_term,adc_var,temp=0;
//Función que captura el valor del ADC y lo almacena en temperatura
void captura(void)
{
double lectura_adc;
if(canal==0){
set_adc_channel(0); //seleccionamos canal AN0
delay_ms(5);
adc_var = read_adc(); //leemos el canal correspondiente
}
}
// Calculo de Temperatura
void calcule_temp(long int adc_var)
{
r_term = ((10.0*adc_var)/(1024-adc_var));
LnRes = log(r_term);
LnRes3 = LnRes*LnRes*LnRes;
temp = (1/(0.00269794+0.00028033*LnRes+0.00000086*LnRes3))-273.15;
delay_ms(1000);
}
//Subrutina de control de temperatura
void control_temp(void)
{
if(temp<=35){
output_bit(PIN_B2,1);//si es bajo de 35º activamos el rele
}
if(temp>=36){
output_bit(PIN_B2,0);//si se supera de 36º desactivamos el rele
}
}
//Subrutina de muestreo cada 5 segundos
void muestreo5seg(void)
{//poner cada 5 segundos o cada 30 segundos
captura(); //capturamos adc
if(canal==0){control_temp();}//vemos como esta la temperatura
contador=0;
}
void main(void)
{
setup_adc_ports (0x84); //RA3,RA1,RA0 Analog
setup_adc(ADC_CLOCK_INTERNAL);
disable_interrupts(GLOBAL);
set_tris_a(0xFF); // RA0,RA1 y RA3 como entradas analogicas
// RA0--> TEMPERATURA
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0xF1); // RB7:4, RB0 ENTRADAS, RB3:1 SALIDAS
// RB7--> SELECCIONAR Tª
// Activo en alta y NC
// RB5-->
// RB2--> SALIDAS RELES
// RB1--> STATUS
setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
output_bit(PIN_B2,0);
while( 1 )
{
adc_var = READ_ADC();
delay_us(10);
calcule_temp(adc_var);
captura( );
control_temp( );
muestreo5seg( );
printf("D",temp);
}
}
-
el programa hace la funcion de que el rele haga el contacto y encienda la lampara ..pero no apaga a la temperatura deseada...
estara bien hecho la parte para la conversion ..para la temperatura deseada???
si alguien puede tener alguna sugerencia ...
se lo agradeceria ...