Sunteți pe pagina 1din 5

E:\FOCO\receptor de sony sincronizado aprende mas led mas fotores22mar07.

c
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
ESTE PROGRAMA DECODIFICA LAS SEALES DE UN CONTROL REMOTO SONY
//
//
____________________________________________________________________
//
//
//
//
//
//
Sus funciones son:
//
//
//
//
* Apagado y encendido de una lampara
//
//
* Regular gradualmente la intensidad de la lampara.
//
//
//
//
//
//
Se aprende los botones, regula la intensidad en forma automatica, tiene //
//
modo sleep y modo de encendido por dia.
//
//
//
//
La entrada del sensor es el pin A0, el sincronismo es A1 y la lampara //
//
es conectada al pin ccp1(GP2).
//
//
//
//
En pin a3 es para seleccionar entre foco normal o ahorrador, el pin A5 //
//
es conectado un led indicador.
//
//
//
//
El pin a4 es la entrada de la fotoresistencia para controlar automati- //
//
-camente la intensidad.
//
//
//
//
Conectar la fotoresistencia con el divisor de voltaje de tal modo que
//
//
a mas luz menos voltaje.
//
//
//
//
se corrigieron problemas con foco ahorrador
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <12f683.h>
// Declaramos pic (se ocupa este por ser el unico de 8 pin con pwm).
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOCPD, NOMCLR, INTRC_IO, NOIESO, NOFCMEN
#device ADC=10
#use delay(clock=1000000) //frecuencia de trabajo de 1Mhz
#use fast_io (A)
byte

codigo[2]={0,0},code_up[2]={0,0},code_down[2]={0,0},code_onoff[2]={0,0};

////////////////////////////////////////////////////////////////////////////////
///////// variables de codigo leido del control y codigos de funcin /////////
////////////////////////////////////////////////////////////////////////////////

int16 tstart=440,ton=250,adc;
// Tiempo de bit de start 3T=1800 uS y tiempo de bit 1 2T=1200 uS
int cont1=0,cont2=0;
// Contadores de bits leidos
unsigned int disparo=128;
// Angulo de disparo por default esta entre 28 y 129 (rango dependiendo de config timer
short sincro1=0,on_off=0;
// Banderas de ciclo completo, apagar (para antirrebote)
unsigned int aprender=0,ciclos=0,ciclos1=0,hold=0;
// Aprender codigo segun alguna condicion(solo para compatibilidad), ya se han leido los 3 codigos y cargalos a la ram
// Banderas: ciclo completo, ciclos transcurridos(usados para retardos),
// Cuenta cuando se deja presionado la tecla encender apagar,
short
short
int16
short

modo_auto=0,auto_ini=1;
modo_time1=0,modo_time2=0;
base_tiempo=0;
ahorrador=0,edo_ahorrador=0;

//
//
//
//

Bandera para indicar si se activo el modo automatico,bandera que inicializa el modo


Banderas para activar modo sleep o encendido por tiempo
Se usa para llevar la cuenta del tiempo en modo sleep y modo ciclico
Bandera que indica si esta usando foco ahorrador,foco ahorrador prendido o apagado

////////////////////////////////////////////////////////////////////////////////
///////////////////// Rutina de sincronismo con la AC //////////////////////////
////////////////////////////////////////////////////////////////////////////////
void sincroniza(void)
{
if(!input(PIN_A1)) sincro1=1;
if(sincro1 & input(pin_A1))
{
if(!ahorrador)
{
if(disparo!=28)
{
set_timer2(disparo);
setup_ccp1(CCP_PWM);
}
else
setup_ccp1(CCP_OFF);
}
sincro1=0;
ciclos++;
ciclos1++;
}

// Ha pasado ciclo positivo? si = activa bandera


// Es un ciclo completo? y esta como bombilla
// Si no esta como foco ahorrador sincroniza

// Si el angulo no es minimo, <<=== aumentar el valor de angulo minimo cambiado a 28 en


// Actualiza el valor del angulo de disparo
// Ajusta el sincronismo

// Si el angulo de disparo es muy pequeo mejor apaga pwm para que no haya fugas de cor
//
//
//
//

Reiniciar otro ciclo


Cuenta los ciclos que van (para ser usado en retardo o antirrebotes)
como el programa esta atendiendo mas de una variable a la vez no se pueden usar reta
Retardo para la correccion de error en modo automatico y cuenta los ciclos para form

E:\FOCO\receptor de sony sincronizado aprende mas led mas fotores22mar07.c


// Termina la funcin sincroniza

////////////////////////////////////////////////////////////////////////////////
////////////////////////////// escribir eeprom /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void wr_eeprom(byte address,byte data)
{

// los datos a ser leidos o escritos en eeprom son convertidos


// a variables tipo byte para evitar conflictos y como es lento hay que sincroniz

write_eeprom(address,data);
sincroniza();
}

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// leer eeprom ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
byte rd_eeprom(byte address)
{
return(read_eeprom(address));
sincroniza();
}

//-----------------------------------------------------------------void carga_code(void)

// Carga en ram los codigos una vez


// que se tienen listos los 3 codigos

{
code_up[1]=rd_eeprom(0x12); code_up[0]=rd_eeprom (0x11);
code_down[1]=rd_eeprom(0x14); code_down[0]=rd_eeprom (0x13);
code_onoff[1]=rd_eeprom(0x16); code_onoff[0]=rd_eeprom (0x15);
}

//Cierra carga_code

//---------------------------------------------------------------void guarda_code(void)
//guarda en eeprom los 3 codigos de funcion y solo los acepta si son diferentes
{
if(aprender!=0)
//si se activo la bandera aprender guarda los codigos
{
if(aprender==1)
//guarda codigo para aumentar intensidad
{wr_eeprom(0x11,codigo[0]); wr_eeprom(0x12,codigo[1]);}
if(aprender==2)
//guarda codigo para disminuir intensidad y comrara que sea diferente al primero
{
if((codigo[0]!=rd_eeprom (0x11)) | (codigo[1]!=rd_eeprom (0x12)))
{ wr_eeprom(0x13,codigo[0]); wr_eeprom(0x14,codigo[1]); }
else
aprender=1;
}
if(aprender==3)
//guarda codigo para on-off y compara que sea diferente al primero y segundo y si ya se
{
if(((codigo[0]!=rd_eeprom (0x11)) | (codigo[1]!=rd_eeprom (0x12))) & ((codigo[0]!=rd_eeprom (0x13)) | (codigo[1]!=rd_eeprom
{ wr_eeprom(0x15,codigo[0]); wr_eeprom(0x16,codigo[1]); carga_code();}
else
aprender=2;
}
if(aprender>=3)
// si ya se han leido 3 diferentes sale y ya no vuelve a entrar a la subrutina
aprender=0;
else
aprender++;
}
}
// Cierra guarda_code

void readcodigo(void)
{
//----------------------lee codigo------------------------------- <<-- posible version todas marcas
//muestreando a cada cierto tiempo y guarda en un arreglo grande rotando bits
//aplicando reglas generales posibles problemas de memoria
SET_TIMER1(0);//start =3t t=600uS
//inicia a contar timer 1
while(!input(PIN_A0)){sincroniza();} //se espera en lo que dura el bit de start y esta sincronizando
if( GET_TIMER1() < tstart )
//checa si el tiempo corresponde al bit de start y si no se sale
goto salir;
codigo[0]=0; //inicializar codigo proveniente del control
codigo[1]=0;
for(cont1=1;cont1<=12;cont1++) //lee los 12 bit de codigo (norma RECS80 de sony)
{
while(input(PIN_A0)){sincroniza();} //se mide el tiempo de cada transicion y verifica si es 1 o 0 segun su duracion
SET_TIMER1(0);
while(!input(PIN_A0)){sincroniza();}//el tiempo que interesa el el tiempo en bajo (si dura t o 2t)
if(GET_TIMER1()>ton)
shift_left(codigo,2,1);//rota 1 posicion e inserta 1 si bit=1 trabaja con 2 bytes
else
shift_left(codigo,2,0);//rota 1 posicion e inserta 0 si bit=0 trabaja con 2 bytes
}
2

E:\FOCO\receptor de sony sincronizado aprende mas led mas fotores22mar07.c


//-------------------compara codigo--------------------------------//ejecuta la accion segun el codigo recibido

if((code_up[0]==codigo[0]) & (code_up[1]==codigo[1])) {if(disparo<129 & input(PIN_A3)) {ahorrador=0; disparo++;}//aumentar inte


if(auto_ini==0){modo_auto=0; auto_ini=1; modo_time1=1; output_low(pin_a2); delay_ms(500); if(input(PIN_A3))disparo=128; else{ se
}
//ademas si se estaba en modo auto o modo time se sale y toma en cuenta el tipo de foco para encenderlo (inicia cuenta de tiempo

if((code_down[0]==codigo[0]) & (code_down[1]==codigo[1])) {if(disparo>28 & input(PIN_A3)) {disparo--; ahorrador=0;}//disminuir i


if(auto_ini==0){modo_auto=0; auto_ini=1; modo_time2=1; output_low(pin_a2); delay_ms(500); if(input(PIN_A3))disparo=128; else{ se
}
//ademas si se estaba en modo auto se sale y entra a modo sleep y toma en cuenta el tipo de foco para encenderlo (inicia cuenta
if((code_onoff[0]==codigo[0]) & (code_onoff[1]==codigo[1])) {on_off=1; ciclos=0;//apagar-encender
if(auto_ini==0){modo_auto=0; auto_ini=1; } modo_time1=0; modo_time2=0; base_tiempo=0; output_high(PIN_A5); }
//ademas si se estaba en modo auto, sleep o ciclico se sale y apaga led
guarda_code();// si no se han grabado en eeprom los codigos se ejecuta la subrutina
//-------------------------borra codigo----------------------------salir:
set_timer1(0);
codigo[0]=0;
codigo[1]=0;
}//read codigo
//-------------interrupcion para activar el control automatico--------#INT_TIMER0
control_auto(void)
// <<=== aumentar tiempo (no es posible con timer0 ya tiene maximo prescaler)
{
if(on_off) //si se mantiene presionada la tecla on-off cuenta
{
hold++;
if(hold>12) //si se mantuvo presionada la tecla on-off aprox 3 seg o mas se activa el modo automatico
{modo_auto=1; auto_ini=1;}
}
else
{
hold=0; //al soltar la tecla on-off se limpia la variable hold
}
}
//--------------------------------inicio---------------------------------main(void)
{
setup_oscillator( OSC_1MHZ | OSC_INTRC);//se configura oscilador rc interno sin salida de seal al exterior a 1Mhz
set_tris_a(0x1B); //gp4 in gp1 in gp0 in gp3 in
output_low(PIN_A5); //encendemos led de espera de encendido(logica invertida)
output_low(PIN_A2); //primeros segundos foco apagado
delay_ms(800);
output_high(PIN_A5);
//-------------inicializaciones-------------------------------------------setup_adc(ADC_CLOCK_INTERNAL); // usamos adc
setup_adc_ports(sAN3); //a4 al adc para leer la fotoresistencia(pin a4 pero canal analogo 3)
set_adc_channel(3); //a4 seleccionado
setup_timer_0 (RTCC_DIV_256|RTCC_INTERNAL); //timer 0 se desborda aprox cada .2 seg para usarlo en hold (interrupcion)
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1); //timer 1 se incrementa cada 4 uS
set_rtcc(0);
disable_interrupts(INT_EXT);
//
\
disable_interrupts(INT_TIMER1); //
|
disable_interrupts(INT_TIMER2); //
|
disable_interrupts(INT_RA);
//
> no utilizamos estas interrupciones-*-*disable_interrupts(INT_CCP1);
//
|
disable_interrupts(INT_COMP);
//
/
enable_interrupts(INT_TIMER0);// usamos estas interrupciones
enable_interrupts(GLOBAL);// habilitamos en general las interrupciones
setup_comparator(NC_NC_NC_NC); //comparador analogico apagado
setup_timer_2(T2_DIV_BY_16, 130, 1); //timer 2 configurado para pwm a una frecuencia de 120 Hz
//-------------------comprobacion para ver si se queren cambiar los codigos de funcion----------------if(rd_eeprom(0x17)==0x01) //si apago y encendio dos veces el modulo aprende codigos y enciende a media intensidad
{
aprender=1; //activamos bandera de guardar codigos de funcion
if(input(PIN_A3)) //si esta como bombilla
disparo=65; //angulo de disparo por default (variable que se carga a timer 2 al sincronizar y es el
//numero desde que empieza a contar timer2 y de acuerdo a la configuracion de setup_timer2 se
//incrementa cada cierto tiempo y a desbordarse es cuando pwm genera un pulso en alto o sea duty(1) )
else //si esta como foco ahorrador
{
output_high(PIN_A2); //enciende y apaga 2 veces
delay_ms(200);
output_low(PIN_A2);
delay_ms(200);
output_high(PIN_A2);
delay_ms(200);
output_low(PIN_A2);
}
3

E:\FOCO\receptor de sony sincronizado aprende mas led mas fotores22mar07.c


}
else
//si no aprendes codigos entonces prende a maxima intensidad segun tipo de foco
disparo=128;

wr_eeprom(0x17,0x01);//activamos bandera en eeprom de encendido del modulo


delay_ms(1200); //si pasa 1 segundo y no apagamos el modulo quiere decir que no queremos que se aprenda codigos nuevos
wr_eeprom(0x17,0x00);//desactivamos bandera en eeprom de encendido del modulo
set_pwm1_duty(1); //ancho del pulso en alto para disparo, solo un pequeo pulso en alto
if(!input(PIN_A3))
{
setup_ccp1(CCP_OFF);
output_high(PIN_A2);
ahorrador=1;
}
carga_code(); //cargamos codigos de funcion de eeprom
//---------------------------------------------------------------------------------while(TRUE) //ciclo principal
{
sincroniza(); //la mayor parte de tiempo esta sincronizando
if(modo_time1)//si fue activado el modo sleep permanece activado 1 o 5 min y se apaga
if(ciclos>=60)
{

ciclos=0; base_tiempo++; output_toggle(PIN_A5); if(base_tiempo==60){disparo=28; base_tiempo=0; modo_time1=0; if(input(PIN_A


}

//verifica que se ha cumplido la base de tiempo (1 seg) y al cumplirse 60 seg se apaga y ya no entra a la rutina ya sea com

if(modo_time2)//si fue activado el modo de encendido temporal permanece activado 3 hrs y se apaga y al dia sig otras 3 hora
if(ciclos>=120)
{

ciclos=0; base_tiempo++; output_toggle(PIN_A5); if(base_tiempo<5){ if(input(PIN_A3)){disparo=128; ahorrador=0;}else{ahorrad


}
//verifica que se ha cumplido la base de tiempo (2 seg) y al cmplirse 3 hrs se apaga y al cumplirse 24 vuelve a iniciar ya
if(!input(PIN_A0)) readcodigo(); //si hay seal de mando ir, decodificalo

if(on_off) //retardo para evitar rebotes en la funcion on off (la comparacion on_off fue cambiada en esta posicion para ocu
if(ciclos==45)
{
if(input(PIN_A3))
{
ahorrador=0; if(disparo==28) disparo=128; else disparo=28;
}
else
{

ahorrador=1; setup_ccp1(CCP_OFF); if(edo_ahorrador){output_low(PIN_A2); edo_ahorrador=0;} else{output_high(PIN_A2); edo_aho


}
codigo[0]=0; codigo[1]=0; on_off=0; ciclos=0; hold=0;
}
//si bandera on_off fue activada apaga o prende respetando el tipo de foco
//on_off
sincroniza();//se agrega otro sincroniza para aumentar la prioridad de la tarea
if(modo_auto) //si fue activado el modo control automatico de iluminacion-*-*-*-**
{
if(auto_ini)// si es apenas activado el modo automatico-*-*-*-*
{
setup_ccp1(CCP_OFF);//apagamos temporalmente el pwm
output_high(PIN_A2); //enciende y apaga
delay_ms(300);
output_low(PIN_A2);
delay_ms(300);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
delay_ms(300);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
delay_ms(300);
on_off=0;
auto_ini=0;//ya no entres a esta condicion hasta que se vuelva a activar modo auto--*-*-*-*-*
disparo=28;
}
if(input(PIN_A3)) //si esta como foco normal
{
if(ciclos1>10)//esperamos hasta que se cumpla un tiempo

<<=== aumentar tiempo (fue cambiado de 8 a 10)

{
ahorrador=0;
adc=read_adc();//leemos la intensidad luminosa por medio de fotorresistencia
4

E:\FOCO\receptor de sony sincronizado aprende mas led mas fotores22mar07.c


sincroniza();
if(adc<600 & disparo>28) disparo--; //si hay mucha luz disminuyela y espera cierto tiempo <====simplificar (ya se simplifi
if(adc>610 & disparo<128) disparo++; //si hay poca luz aumentala y espera cierto tiempo
(se usa histeresis para evitar in
//en estas dos condiciones anteriores se limita el valor al mismo tiempo y el set point esta en ese rango
ciclos1=0;
}
}
else //si esta como foco ahorrador
{
adc=read_adc();//leemos la intensidad luminosa
sincroniza();
if(read_adc()>980) {setup_ccp1(CCP_OFF); output_high(PIN_A2); ahorrador=1; }
if(read_adc()<200) {setup_ccp1(CCP_OFF); output_low(PIN_A2); ahorrador=1; }
}
}
}
}

//
//
//
//
//

Prende la lampara al 100% cuando obscur


a cierto nivel (on-off con histeresis).
Modo auto.
Cierra while true.
Cierra main.

S-ar putea să vă placă și