TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: retovil en 05 de Octubre de 2016, 01:12:04

Título: Apagar un led despuès de varias horas
Publicado por: retovil en 05 de Octubre de 2016, 01:12:04
 :) prendiendo y apagando un led con un sw me propuse que el led se apague despuès de unas horas ,pero es realmente dificil .No tengo mucha preparaciòn para tal tarea asi que pido que me asistan . Estoy trabajando con un 16F628A ,pic c compiler y icprog . este es el programa. #include<16f628A.h>
//#fuses intrc_io,nomclr,nowdt,noput
#fuses xt,nowdt
#use delay(clock= 4000000)
#use standard_io(b)

//#byte port_b = 0x06
//#byte trisb =0x86
//#byte port_a = 0x05
//#byte trisa =0x85
#define SW1  PIN_A2     //PORTA RA2
#define LED1 PIN_B4     //PORTB RB4

void main(){
set_tris_A(0b11111100); // entrada
set_tris_B(0b00000000);//salida
output_b(0b00000000);

while(1){
    if(input(SW1)==0){
  delay_ms(40);
    if(input(SW1)==1){
     output_toggle(LED1);
     delay_ms(13000);// poner un timer de 6 horas ??
     
     output_low(LED1);
    output_b(0b01000000); delay_ms(1940);
    output_b(0b00000000); delay_ms(240);
     output_b(0b01000000);  delay_ms(240);
    output_b(0b00000000);  delay_ms(240);
     output_b(0b00010000);delay_ms(240);
      output_b(0b01000000);delay_ms(240);
     output_b(0b00010000);delay_ms(240);
      output_b(0b01000000); delay_ms(240);
    output_b(0b00010000);delay_ms(240);
      output_b(0b01000000);delay_ms(240);
     output_b(0b00010000);delay_ms(240);
      output_b(0b01000000); delay_ms(240); 
     output_b(0b00000000);
     
    }
    }
    }
    }
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 05 de Octubre de 2016, 08:27:22
De hacerlo se puede , con un for y repetir muchas veces el delay. Pero eso trae un problema.

Que tu micro va a dejar de responder por esas 4 horas!!!. Es decir no vas a poder sacarlo de su curso normal.

Al Ser un tema de HORAS, te quedan 2 formas, usar un timer que interrumpa cada 0.5s o 1s si es posible y contar la cantidad de segundos que pasaron. Como ves los valores son pequeños, 1s y 0.5s (este mas seguro ). Si quisieramos mas grande, la otra opcion es la de usar un cristal de 32768 Hz sobre el Timer 1, este te va a permitir crear una interrupcion de hasta 16 segundos ( o mejor lo ajustas a 10 segundos).
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 05 de Octubre de 2016, 12:01:30
 :)Gracias KillerJC ,por tu asistencia ,soy novato y estoy apenas entrando en este mundo enorme .El tema de manejar el timer0 en c para mi es un tema .
Me podrìas mencionar alguna pagina que me enseñe a introducirme en el manejo de los timers .Tengo el manual Compilador c ccs y simulador proteus para microcontroladores pic.
pero es muy tecnico y no me permite comprender.  :-)
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 05 de Octubre de 2016, 15:12:25
La verdad que en eso ya no te puedo ayudar, No uso CCS.
Respecto a lo leido siempre me base desde el datasheet del micro que esta en ingles. Deberias buscar aca en el foro o por internet si es que encontras un articulo explicando como funciona el Timer y como hacerlo en CCS, por mas que no encuentres todo junto es una buena lectura y te va a llevar a comprender como funciona y eso a pasa a saber luego como hacerlo al entenderle correctamente.

La explicacion vaga es...

El timer es un contador, y cuenta pulsos de reloj, externos (como el cristal de 32768Hz) o internos (Oscilador interno o XT,HS). Algunos tienen un contador de 8 bits como el Timer0 y otros de 16 bits como el Timer1. Estos cuando pasan del maximo valor a 0, 0xFF a 0x00 - o de 0xFFFF a 0x0000, es decir se pasan de cuenta, activan el flag del timer, si tenes activadas las interrupciones va a entrar a la interrupcion. El truco esta en:

- Cargar un valor de preescaler , que es simplemente un divisor de frecuencia, suponete que tenes un cristal de 4Mhz y usas este, a la entrada del Timer tendrias 1Mhz (se dividide por 4 dentro del PIC en caso de ser el oscilador principal) o que es lo mismo que cada ves que cuenta 1 tarda 1us ( 1 / 1MHz ), si usas un preescaler de 1:4 , quiere decir que la frecuencia se divide en 4, es decir a la entrada del timer tendrias 250Khz y por lo tanto contaria 1 cada 4us.

- Cargar el valor del Timer, cargando lo que le falta para llegar a 0x00, ya que el contador es ascendente.

Hagamos un ejemplo.
Usas el Timer1 con un oscilador externo de 32768 Hz, lo haces pasar por un preescaler de 1:8, por lo cual entra una frecuencia de 4096Hz o que es igual a 244.14us cada cuenta.
El timer1 es de 16bits, por lo tanto lo maximo que puede contar es de 65536, esas 65 mil cuentas de 244.14us equivale a 16segundos.
Si quisiera 10 segundos (por que es mas facil de contar asi para llegar al minuto) deberia hacer: 10s / 244.14us = 40960
Tiene que contar 40960 pero es ascendente, por lo cual deberia cargar el timer con 65536 - 40960 = 24576

Es decir, usando un oscilador externo de 32768Hz en el Timer1, configurandolo para que use el mismo, configurarlo con preescaler 1:8, y cargando el numero 24576 cada ves que se rebalse ( que pase a 0 ) estarias contando de 10s en 10s cuando se active el flag del timer o entre a la interrupcion.
Título: Re:Apagar un led despuès de varias horas
Publicado por: marvicdigital en 05 de Octubre de 2016, 17:32:55
Buenas, buscando por san google encontré varios resultados entre ellos un video en youtube:

Es para 18F pero te puede servir como guía.

Buena suerte.

Saludos
Título: Re:Apagar un led despuès de varias horas
Publicado por: PalitroqueZ en 05 de Octubre de 2016, 19:01:28
aqui en el foro hay temas por cantidades industriales sobre como usar retardos mediante el modulo Timer.

Título: Re:Apagar un led despuès de varias horas
Publicado por: marvicdigital en 06 de Octubre de 2016, 09:48:04
aqui en el foro hay temas por cantidades industriales sobre como usar retardos mediante el modulo Timer.

Es verdad amigo, no hay que ir tan lejos  :mrgreen:

http://www.todopic.com.ar/foros/index.php?topic=43197.msg357684#msg357684 (http://www.todopic.com.ar/foros/index.php?topic=43197.msg357684#msg357684)

http://www.todopic.com.ar/foros/index.php?topic=33244.msg333988#msg333988 (http://www.todopic.com.ar/foros/index.php?topic=33244.msg333988#msg333988)

Saludos amigos 8)
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 17 de Octubre de 2016, 18:38:21
De hacerlo se puede , con un for y repetir muchas veces el delay. Pero eso trae un problema.

Que tu micro va a dejar de responder por esas 4 horas!!!. Es decir no vas a poder sacarlo de su curso normal.

Al Ser un tema de HORAS, te quedan 2 formas, usar un timer que interrumpa cada 0.5s o 1s si es posible y contar la cantidad de segundos que pasaron. Como ves los valores son pequeños, 1s y 0.5s (este mas seguro ). Si quisieramos mas grande, la otra opcion es la de usar un cristal de 32768 Hz sobre el Timer 1, este te va a permitir crear una interrupcion de hasta 16 segundos ( o mejor lo ajustas a 10 segundos).
:( No ,no hay cristales tan pequeños o de tan baja capacidad
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 17 de Octubre de 2016, 18:50:46
:( No ,no hay cristales tan pequeños o de tan baja capacidad

De esos.. Son re comunes. Seguro que los viste por muchos lados.
http://tepuyelectronics.com/485-large_default/cristal-32768khz-oscilador-.jpg

Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 06 de Noviembre de 2016, 22:36:42
Si tenes razòn , yo lei mal . en realidad es de 32,768megas . perdon .
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 06 de Noviembre de 2016, 22:40:30
Buenas, buscando por san google encontré varios resultados entre ellos un video en youtube:

Es para 18F pero te puede servir como guía.

Buena suerte.

Saludos
Ahora si entendi , pero hay algo que no me sale ,es hacer que el led empiece prendido ,siempre empieza apagado . con las preconfiguraciones de puertos no doy pie con bola.
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 06 de Noviembre de 2016, 23:03:10
Hola retovil, te trabaste en lo mas facil. Hay varias formas de hacer que el led empiece encendido. La mas directa es setear el pin donde se encuentre el led como salida y en estado logico 1. Tambien podrias utilizar una variable intermedia e igualmente asignarle el valor 1 o true y el tipo short.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 07 de Noviembre de 2016, 21:15:58
AcoranTf ,no es tan asì me parece no he podido preconfigurar los puertos de ninguna manera . Por lo menos las que consco no te olvides que hay un timer1 donde configuras el
puerto ?  :? este es el codigo :

#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
#use delay(clock=4000000)
#use standard_io(b)

#define TRUE 1
int16 contador=0;
#BIT RB0 = 0x06.1
#int_timer1
void timer0(){
RB0 = 1;
contador++;
if(contador==2000){
output_bit(PIN_B0,1);
  output_b(0b0000011);
 contador=0;
 }
set_timer1(192);
}


void main() {
setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
set_timer1(192);
 enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

while(1){

}
}
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 07 de Noviembre de 2016, 22:15:02
Prueba este codigo y comentas que tal te va.

Código: [Seleccionar]
#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
#use delay(clock=4000000)
#use fast_io(b)

//#define TRUE 1
int16 contador=0;
//#BIT RB0 = 0x06.1
#int_timer1

void TIMER1_isr(void)
{
contador++;

if(contador==2000)
{
output_bit(PIN_B0,0); //Apaga el led
contador=0;
}

//set_timer1(192);

}


void main()
{
set_tris_b (0); //Puerto B como salidas
output_bit(PIN_B0,1); //Inicia con el led encendido
setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
set_timer1(192);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

while(1)
{

/*
Con estos datos el led estara tanto tiempo encendido, como despues apagado
deberas decidir el tiempo que deseas que este apagado y obrar en consecuencia
reprogramando el TIMER1 para ello y una vez encendido de nuevo, volver a los
parametros iniciales para la nueva temporizacion de encendido.
O detener la interrupcion del TIMER1 y programar otro TIMER para el tiempo de apagado.
Deje comentadas las lineas que considero no necesarias.
Lo hice con prisa, espero no haber metido la pata en nada.
*/

}
}

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 07 de Noviembre de 2016, 23:23:13
Gracias ArcanTf , dio resultado, muy bueno no entiendo eso de tener que hacer otro timer para que se apague 
 
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 08 de Noviembre de 2016, 00:07:40
No entendiste bien, no es para que se apague. Se va a apagar tal como esta, pero ya no volvera a encender hasta que reinicies el programa, que se repetira el mismo ciclo. Si eso es lo que quieres no tienes que hacer nada. Pero si no es asi debes hacerte otro temporizador solo para el tiempo que debe permanecer apagado desactivando la interrupcion del TIMER1, o reprogramar el TIMER1 y utilizar una bandera para saber si esta en el tiempo de encendido o apagado.
Al final del tiempo de apagado deberas o bien reactivar la interrupcion del TIMER1 o cambiar la bandera, segun la opcion que hayas elegido. Y si solo deseas un ciclo, o sea que al conectar el PIC encienda el led y pasado el tiempo estipulado se apague y no haga mas nada, no tendrias que hacer nada, tal como esta deberia hacer eso justamente.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: vdiazg en 08 de Noviembre de 2016, 14:52:13
Gracias ArcanTf , dio resultado, muy bueno no entiendo eso de tener que hacer otro timer para que se apague

Estimado, que es lo que realmente deseas hacer, quizas pueda darte una manito
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 09 de Noviembre de 2016, 22:48:56
Gracias ArcanTf , dio resultado, muy bueno no entiendo eso de tener que hacer otro timer para que se apague

Estimado, que es lo que realmente deseas hacer, quizas pueda darte una manito
Lo que busco es que el timer corte a las 3horas y despuès incie de vuelta su ciclo .
al principio querìa que un swich o button prendiera el timer con el cual al tiempo se apagara
pero me resulto dificilisimo .Entiendace que hace poco me puse a programar y todavìa no entiendo bien la configuracion de los puertos para que inicie encendido el led bueno desde ya muchas gracias vdiazg.
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 09 de Noviembre de 2016, 23:38:34
Lo que busco es que el timer corte a las 3horas y despuès incie de vuelta su ciclo .
al principio querìa que un swich o button prendiera el timer con el cual al tiempo se apagara
pero me resulto dificilisimo .Entiendace que hace poco me puse a programar y todavìa no entiendo bien la configuracion de los puertos para que inicie encendido el led bueno desde ya muchas gracias vdiazg.

Hola de nuevo retovil, lo que dices que quieres es muy facil con el pulsador. Defines una bandera para arrancar el temporizador, defines la interrupcion del RB0 y en ella pones que cada vez que se pulse el pulsador situado en RB0, cambie el valor de la variable <start>, deberas seleccionar la deteccion de la pulsacion por flanco ascendente y agregar unos mS de retardo, para evitar rebotes. Te he implementado los cambios necesarios en el codigo adjunto, pero no he declarado la interrupcion del RB0, lo he dejado para que la hagas tu. Estudia un poco y hazlo. Si tienes dudas preguntas.
¡¡ NOTA IMPORTANTE !! He cambiado el led al pin RB7, para aprovechar la interrupcion de RB0 para el pulsador, que estara conectado en el RB0, o sea donde hasta ahora tenias el led. Al pin RB0 debes ponerle una resistencia de pull-up de 4K7.
Si quieres perfeccionarlo mas aun, coloca en la funcion main un if de forma que cuando start sea = 0 deshabilite la interrupcion del TIMER1, ojo solo la del TIMER1, si desabilitas las generales o la del RB0, anularas el pulsador. Y ya para rizar el rizo, en ese mismo if pones que apague el led y que ponga a 0 la variable contador. De ese modo en cualquier momento que pulses el pulsador, el led cambiara de estado y si esta encendido ademas estara corriendo el tiempo del temporizador. Pero si decides detenerlo antes de que acabe, bastara que pulses de nuevo el pulsador y se detendra el temporizador, se apagara el led y se borrara la variable <contador>. Ahora te propongo otro reto, agregale tu otro pulsador en RB1 y haces que provoque solo una pausa en el temporizador y cuando lo pulses de nuevo continue el temporizador por donde iba. El primer pulsador podria llamarse START/STOP y el segundo PAUSA.

Código: [Seleccionar]
#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
#use delay(clock=4000000)
#use fast_io(b)

int16 contador=0;
#int_timer1
int1 start=0; //Bandera de arranque del temporizador

//Coloca aqui la rutina de interrupcion del RB0

void TIMER1_isr(void)
{

if(start) //Si activado temporizador

output_bit(PIN_B7,1); //Inicia con el led encendido

{

contador++;

if(contador==2000) //Si llega al final del tiempo
{
output_bit(PIN_B7,0); //Apaga el led
contador=0;
start=0; //Desactiva el temporizador
}
}

}


void main()
{
set_tris_b (0b00000001); //Puerto B como salidas bits de 1 a 7, el 0 es entrada
setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
set_timer1(192);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

while(1)
{

}
}

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 11 de Noviembre de 2016, 16:17:02
Bueno gracias AcoranTF ,por tu paciencia .

int1 start=0;                  //Bandera de arranque del temporizador

aca la unica rutina de interrupcion para el swich es con la sentencia if y me da error es la que mas conosco, por decirte la unica . :mrgreen:

//Coloca aqui la rutina de interrupcion del RB0

void TIMER1_isr(void)

Esta muy interesante la propuesta con el otro swich.
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 11 de Noviembre de 2016, 21:08:29
Bueno gracias AcoranTF ,por tu paciencia .

int1 start=0;                  //Bandera de arranque del temporizador

aca la unica rutina de interrupcion para el swich es con la sentencia if y me da error es la que mas conosco, por decirte la unica . :mrgreen:

//Coloca aqui la rutina de interrupcion del RB0

void TIMER1_isr(void)

Esta muy interesante la propuesta con el otro swich.

int1 start=0;                  //Bandera de arranque del temporizador  Esto no es una interrupcion, es la declaracion de la variable <start>, con el tipo "boolean, binario o bit". El int1 significa eso que la variable es de un solo bit con las unicas opciones de ser 1 o 0. Tambien se llama short este tipo de variable.

//Coloca aqui la rutina de interrupcion del RB0 deberas declarar una rutina de interrupcion para el RB0, hacer la rutina y colocarla aqui.

Esta muy interesante la propuesta con el otro swich. Me gustaria que lo intentes, de ese modo se aprende bastante. Tambien se podria hacer todo con un solo pulsador, pero es algo mas complicado. Si lo consigues con dos pulsadores, despues te ayudo a hacerlo con uno solo. De ese modo aprenderas a utilizar distintas banderas que te ayuden a cambiar la funcion del pulsador segun convenga.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: soymoe en 12 de Noviembre de 2016, 09:55:33
yo lo hago simple, con el timer cuento medio segundo y lo repito hasta la cantidad que necesito pero no uso for, anda muy bien ya he vendido muchos de esos
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 14 de Noviembre de 2016, 00:01:36
AconranTF ,puede ser que este programa produzca error,sin la rutina de interrupcion, en el Isis proteus .porque se tilda al correrlo .
#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
#use delay(clock=4000000)
#use fast_io(b)

int16 contador=0;
#int_timer1
int1 start=0;                                 //Bandera de arranque del temporizador

//Coloca aqui la rutina de interrupcion del RB0

void TIMER1_isr(void)
   {

      if(start)                              //Si activado temporizador

         output_bit(PIN_B7,1);                  //Inicia con el led encendido
         
         {

            contador++;

            if(contador==2000)                  //Si llega al final del tiempo
               {
                  output_bit(PIN_B7,0);         //Apaga el led
                  contador=0;
                  start=0;                  //Desactiva el temporizador
               }
         }

   }


void main()
   {
      set_tris_b (0b00000001);                  //Puerto B como salidas bits de 1 a 7, el 0 es entrada
      setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
      set_timer1(192);
      enable_interrupts(INT_TIMER1);
      enable_interrupts(GLOBAL);

      while(1)
         {

         }
   }
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 14 de Noviembre de 2016, 05:15:42
Claro retovil, es logico que no funcione sin la rutina que falta de la interrupcion del RB0, ya que nunca va a activarse el temporizador.
Estudia las diferencias entre este programa y el anterior que te puse, de ese modo entenderas porque no puede funcionar este.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 14 de Noviembre de 2016, 12:05:51
yo lo hago simple, con el timer cuento medio segundo y lo repito hasta la cantidad que necesito pero no uso for, anda muy bien ya he vendido muchos de esos
Si Claro moe yo tambien realice ese programa el tema esta en ponerle botones de arranque y parada ,me entendes? :o
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 16 de Noviembre de 2016, 17:23:45
hola,AconranTF  ,encontre esta rutina
 #include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,MCLR
#use delay(clock=4000000)

#use fast_io(b)
#BYTE PORTB = 0X86
#BIT RB0 = 0x06.0
#BIT RB7 = 0x06.7
int16 contador=0;

#int_timer1
int1 start=0;               //Bandera de arranque del temporizador
           
//Coloca aqui la rutina de interrupcion del RB0
#int_EXT
void EXT_isr(void){
If (start){
  RB7=1;
  }
}


 void TIMER1_isr(void)
   {

      if(start)            //Si activado temporizador

         output_bit(PIN_B7,1);      //Inicia con el led encendido
         
         {

            contador++;

            if(contador==2000)      //Si llega al final del tiempo
               {
                  output_bit(PIN_B7,0);         //Apaga el led
                  contador=0;
                  start=0;         //Desactiva el temporizador
               }
         }

   }


void main()
   {
      set_tris_b (0b00000001);         //Puerto B como salidas bits de 1 a 7, el 0 es entrada
          ext_int_edge(L_TO_H);     // activacion flanco de subida ,aunque por default es por flanco de subida .
               setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
      set_timer1(192);
      enable_interrupts(INT_TIMER1);
      enable_interrupts(GLOBAL);

      while(1)
         {

         }
   }

                                       
parece funcionar todavia no lo probe con el circuito por lo meno no produce desbordamiento por pila en el proteus .
De todas maneras me gustarìa ver estudiar el tema pero no hay bibliografia donde estudiar
este caso en particular . donde? se conseguiria estas paginas para estudiar ,consegui hacer una alarma por sencilla con la entrada RB0/INT pero no puede en el caso de la alarma enlazar el timer1
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 16 de Noviembre de 2016, 20:35:22
Con esto:

Código: [Seleccionar]
//Coloca aqui la rutina de interrupcion del RB0
#int_EXT
void EXT_isr(void)
    {
        If (start)
            {
                  RB7=1;
            }
    }

No haces nada. Lo que necesitas es sustituir el if por lo necesario para hacer lo siguiente en este orden: desabilitar la interrupcion exterior, asignar el valor 1 a la variable <start>, retardo de 5 mS para evitar rebotes, rehabilitar la interrupcion exterior. Para hacer mas seguro el antirrebotes tambien es bueno que pongas esta linea en el main: <int_ext_edge(L to H)>, ademas de una resistencia de 10 K entre RB0 y Vcc y el pulsador entre RB0 y GND. De ese modo hasta que no sueltes el pulsador, no lo tendra en cuenta.
Una sugerencia: para hacer mas legible el codigo, es conveniente tabular o sangrar las distintas lineas de forma que con un simple vistazo veas lo que corresponde a cada parte. Tambien es conveniente que al ponerlo aqui en el foro lo hagas como codigo y no como texto. Eso se consigue pinchando en el simbolo # que hay justo encima del ultimo emoticono, ( ((:-))) y pegando a continuacion tu codigo entre las etiquetas [ c o d e ] y [ / c o d e ], los espacios es para que no interprete eso como codigo aqui.
Hay un libro interesante y que te puede ser muy util, se llama <Compilador C CCS y Simulador Proteus para Microcontroladores PIC> de la editorial Marcombo.
Espero ver tus avances pronto.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 24 de Noviembre de 2016, 18:54:47
¿Como andas con el tema?.
¿Te diste por vencido, andas investigando, estas trabado?.

Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 26 de Noviembre de 2016, 00:54:10
Estoy investigando y trabajando ,no me doy por vencido .
He notado varios errores en el codigo que has escrito .Uno es en la configuracion del timer1 . El otro es en la declaracion dela interrupcion ext RB0 dentro del #int_timer1 .
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 26 de Noviembre de 2016, 17:44:26
Estoy investigando y trabajando ,no me doy por vencido .
He notado varios errores en el codigo que has escrito .Uno es en la configuracion del timer1 . El otro es en la declaracion dela interrupcion ext RB0 dentro del #int_timer1 .

Ok, ya nos diras algo.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 01 de Diciembre de 2016, 12:09:11
Hola ,disculpas me retrase por trabajo pero estoy retornando de a poco .
Tengo una pregunta AconranTF, es posible poner el int_ext dentro del int_timer osea :
//...//
#int_timer1
   int1 start=0; 
#int_EXT         //Coloca aqui la rutina de interrupcion del RB0
  void Int_RB0(){
 
}
//----------------------------------------------------------------------------------//
o seria como lo he visto en algunos codigos que primero va la int_ext y despuès va el int_tiemer1???????
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 18 de Diciembre de 2016, 09:55:46
No es buena practica anidar interrupciones, entre otras cosas porque podrias entrar en un bucle sin fin, bloqueando la ejecucion del programa. Aparte si desacivas las interrupciones al entrar en su rutina y dentro pretendes leer otra interrupcion, no sera posible, ya que estarian desactivadas todas las interrupciones.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 18 de Diciembre de 2016, 17:07:06
Bueno entre tantas pruebas parece que uno copia y amontona codigo .
Pero entre las pocas cosas que pude aprender se me ocurren cosas que solo saco de la galera .
haber este codigo que no puedo desifrar no es copiado .
Código: [Seleccionar]
#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,MCLR
#use delay(clock=4000000)
#use fast_io(b)
int1 start=0;
int1 starta=0;
int16 contador=0;

#int_ext
void ext_isr()
 {
   starta=true; // bandera para el TIMI_isr,pruebo haber si selecciona
     start=false; //bandera para el TIMER1_isr  ,pruebo haber si no selecciona
       delay_ms(5);
       
       
 
   }


#int_timer1
void TIMER1_isr(void)
   {
      if(start)//Si activado temporizador

      output_bit(PIN_B7,1);//Inicia con el led encendido
   
   {
      contador++;
      if(contador==100)
         {
               output_toggle(PIN_B7);
               output_bit(PIN_B5,1);
            contador=0;
          }
   }
   }
   
   void TIM1_isr(void)
   {
      if(starta)//Si activado temporizador

      output_bit(PIN_B7,0);//Inicia con el led apagado
   {
      contador++;
      if(contador==300) //tiempo mayor
         {
               output_toggle(PIN_B7);
               output_bit(PIN_B5,0);// se apaga al finalizar el conteo 
            contador=0;
          }
   }
   }
   
 
 
void main()   {
    set_tris_b (0b00000001);
      set_tris_a (0b00000001);//Puerto a como ent
        ext_int_edge(0,L_TO_H);//output_low(int_timer1);//Inicia con el led encendido
       setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
        set_timer1(192);
         enable_interrupts(INT_EXT);
           enable_interrupts(INT_TIMER1);
            enable_interrupts(GLOBAL);
           
     
 while(1);
     
     
         
       
       }

Bueno hasta aqui ,es como volver a empezar de nuevo .
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 18 de Diciembre de 2016, 21:07:33
Bueno entre tantas pruebas parece que uno copia y amontona codigo .
Pero entre las pocas cosas que pude aprender se me ocurren cosas que solo saco de la galera .
haber este codigo que no puedo desifrar no es copiado .
Código: [Seleccionar]
#include<16f628A.h>
#Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,MCLR
#use delay(clock=4000000)
#use fast_io(b)
int1 start=0;
int1 starta=0;
int16 contador=0;

#int_ext
void ext_isr()
 {
   starta=true; // bandera para el TIMI_isr,pruebo haber si selecciona
     start=false; //bandera para el TIMER1_isr  ,pruebo haber si no selecciona
       delay_ms(5);
       
       
 
   }


#int_timer1
void TIMER1_isr(void)
   {
      if(start)//Si activado temporizador

      output_bit(PIN_B7,1);//Inicia con el led encendido
   
   {
      contador++;
      if(contador==100)
         {
               output_toggle(PIN_B7);
               output_bit(PIN_B5,1);
            contador=0;
          }
   }
   }
   
   void TIM1_isr(void)
   {
      if(starta)//Si activado temporizador

      output_bit(PIN_B7,0);//Inicia con el led apagado
   {
      contador++;
      if(contador==300) //tiempo mayor
         {
               output_toggle(PIN_B7);
               output_bit(PIN_B5,0);// se apaga al finalizar el conteo 
            contador=0;
          }
   }
   }
   
 
 
void main()   {
    set_tris_b (0b00000001);
      set_tris_a (0b00000001);//Puerto a como ent
        ext_int_edge(0,L_TO_H);//output_low(int_timer1);//Inicia con el led encendido
       setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
        set_timer1(192);
         enable_interrupts(INT_EXT);
           enable_interrupts(INT_TIMER1);
            enable_interrupts(GLOBAL);
           
     
 while(1);
     
     
         
       
       }

Bueno hasta aqui ,es como volver a empezar de nuevo .

No entiendo que quieres decir con que no puedes descifrarlo. Segun veo ese codigo esta compuesto de fragmentos del que yo te envie y otros que desconozco, supongo que los habras agregado tu. Creo deducir del codigo que mire por encima que pretendes realizar alguna prueba. Si me explicas mejor lo que quieres hacer y lo que no entiendes lo vemos e intentamos arreglarlo.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 19 de Diciembre de 2016, 12:42:26
Si claro esta que la base es la que vos me propusiste y le tenìa que agregar la interrupciòn .
Te aclaro que siempre la idea es cambiar el tiempo por medio de swich.
En la INT_EXT puse dos banderas ,lo cual desde mi ignorancia ,pretendo que el programa por medio de alguna sentencia vinculada al sw,tome el tiempo correpondiente a la bandera  seleccionada  y bueno de esta forma que probe manualmente se puede ver en la interrupcion externa que estan las banderas start y starta no funciona manualmente.
Código: [Seleccionar]
#int_ext
     void ext_isr() {
          starta=true;
           start=false;
 
 
Siempre se activa la primer bandera osea start .y va al void TIMER1_isr(void)que esta vinculado a dicha bandera .
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 20 de Diciembre de 2016, 18:40:23
Retovil en cuanto pueda lo miro a fondo y te digo algo.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 03 de Enero de 2017, 11:21:59
Hola AconranTF, bueno sigo esperando ,espero que el codigo que puse no sea demasiado descabellado o irrealizable .Feliz año ,que esta pequeña relaciòn de alumno maestro,con todo el respeto, dure por muchos años màs .  :)
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 03 de Enero de 2017, 15:16:22
Perdon pero creo que no queda claro lo que tiene que hacer el PIC, ya que fue mutando y agregandose muchas cosas al mismo tiempo. Segun lo que entendi es:

- Una entrada para seleccionar la velocidad con que enciende y apaga.
- Una entrada de ¿start/parada o reiniciar? el estado del temporizador de la luz
- Una salida que deberia apagarse en 3hs y comienza encendida


Las dudas que tengo son:

- Las entradas, ¿ son botones o llaves ?
- La entrada que maneja el temporizado, es de arranque/parada o simplemente resetea el temporizador a 0 para que comienze todo el ciclo de nuevo ?
- Luego de apagarse la salida, ¿que ocurre? Se espera que se presione el boton que resetea el temporizador, mientras se queda apagada la salida, o solo esta 3hs mas y lo enciende de nuevo?.
- ¿Que cantidad de velocidades se desean seleccionar?, si es una sola llave serian 2 velocidades, si son 2 serian 4 velocidades, si es un boton podrian ser mas, pero esto implica tener una salida mas como indicador para saber que velocidad se selecciono. La velocidad seleccionada se debe guardar o debe setearse cada ves que se alimenta el PIC?, si se hace por boton se debe usar la EEPROM, si se hace por llaves no hace falta.
- ¿Se necesita de una gran velocidad de respuesta a las entradas? es decir que si es obligatorio para el PIC que al detectar la entrada lo procese en microsegundos o se puede tardar 100ms sin problemas?- Las entradas, ¿las manejaria una persona? ( con esta ultima se deduce lo de la velocidad )
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 03 de Enero de 2017, 18:36:47
Hola AconranTF, bueno sigo esperando ,espero que el codigo que puse no sea demasiado descabellado o irrealizable .Feliz año ,que esta pequeña relaciòn de alumno maestro,con todo el respeto, dure por muchos años màs .  :)

Feliz año tambien para ti. Siento el retraso pero entre las fiestas y el trabajo no he tenido tiempo de ver el programa a fondo. Voy a intentar dejar un rato y verlo mañana.
De todas formas responde a KillerJc y asi tambien me sirve a mi tu respuesta y el seguro te da tambien alguna idea.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 04 de Enero de 2017, 20:47:13
Bien gracias KillerJC, voy a tratar de contestar tus dudas que son muy profecionales para mi posiciòn .
 Las entradas, ¿ son botones o llaves ? : son pulsadores o botones.
 La entrada que maneja el temporizado, es de arranque/parada o simplemente resetea el temporizador a 0 para que comienze todo el ciclo de nuevo ?: ahi te lo dejo a tu criterio no se que serìa lo mejor .
 Luego de apagarse la salida, ¿que ocurre? :Se espera que se presione el boton que resetea el temporizador, mientras se queda apagada la salida.
 ¿Que cantidad de velocidades se desean seleccionar?:No son velosidades, son tiempos .El programa que realizaste esta muy bien .Lo que quiero ahora es utilizar un  vector,para hacer lo mismo ,con el sentido de aprendizaje.
 Las entradas, ¿las manejaria una persona? ( con esta ultima se deduce lo de la velocidad ): Si ,digo si porque es el usuario quien determina el timpo de calentamiento del agua ,(tener en cuenta que es un calefon electrico).

 :)
 Dejo el circuito que hice en proteus aunque no se porque no me funciona el relay

Por otro lado a mi se me ocurrio poner en la interrupcion externa dos banderas diferentes para llamar a diferentes tiempos del timer1 ,no me dio resultado . A lo mejor con otros codigos se puede realizar lo mismo ,pero me gustarìa que lo analises y me comentes ,esta màs atras .
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 04 de Enero de 2017, 21:57:16
Hola retovil, la razon por la que no te funciona el rele es sencillamente porque esta mal conectado. El emisor del transistor debe ir a GND, un extremo del rele al colector del transistor y el otro extremo del rele a positivo, la R4 sobra debes eliminarla y debes poner un diodo 1N4148 en paralelo con la bobina del rele, el catodo hacia el positivo y el anodo hacia el colector del transistor. Tambien entre la base del transistor y el PIN RB7 debes poner una resistendia de 220 Ohm.
Por otro lado no es aconsejable referenciar la tension de AC a GND, seria mejor dejarla flotante y por tanto aislada del resto del circuito.
Hoy tampoco tuve tiempo de ver el programa.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 04 de Enero de 2017, 22:58:13
No se si funcionara, deberias probarlo.

Código: C
  1. #include <16f628A.h>
  2. #Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
  3. #use delay(clock=4000000)
  4. #use fast_io(b)
  5.  
  6. volatile int1    activo;
  7. volatile int16   contador=0;
  8. int8    indice;
  9. int16   tiempo[4] = {1000,2000,3000,4000};
  10. volatile int16   limite;
  11.  
  12. #int_timer1
  13. void TIMER1_isr(void)
  14. {
  15.     set_timer1(192);
  16.     if(activo)
  17.     {
  18.         contador++;
  19.     }
  20.  
  21.     if(contador>=limite)
  22.     {
  23.         output_bit(PIN_B7,0);                   // Apago Rele
  24.         contador=0;
  25.         activo= false;
  26.     }
  27. }
  28.  
  29.  
  30. void main()
  31. {
  32.    
  33.     int8 i;
  34.    
  35.     // Inicializacion de variables
  36.     indice = 0;
  37.     limite = tiempo[0];
  38.     activo = true;
  39.    
  40.     // Configuracion de los modulos
  41.    
  42.     set_tris_b(0x0F);                               // RB0 a RB3 entradas, RB4 a RB7 salidas
  43.     output_bit(PIN_B7,1);                           //Inicia con el rele encendido
  44.     setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
  45.     set_timer1(192);
  46.     enable_interrupts(INT_TIMER1);
  47.     enable_interrupts(GLOBAL);
  48.  
  49.     while(1)
  50.     {
  51.         /*
  52.          * Boton de reset
  53.          */
  54.         if(input(PIN_B0))                       // Boton de reset
  55.         {
  56.             contador = 0;                           // Reinicio el tiempo
  57.             output_bit(PIN_B7,1);                   // Activo rele
  58.             activo = true;
  59.         }
  60.        
  61.         /*
  62.          * Boton de tiempo
  63.          */
  64.        
  65.         if(input(PIN_B1))                       // Boton seleccion de tiempo
  66.         {
  67.             while(input(PIN_B1));
  68.             indice++;
  69.             limite = tiempo[indice];
  70.             if(indice>=sizeof(tiempo))
  71.             {
  72.                 indice = 0;
  73.             }
  74.             for(i=0;i<=indice;i++)
  75.             {
  76.                 output_bit(PIN_B6,0);
  77.                 delay_ms(200);
  78.                 output_bit(PIN_B6,1);
  79.                 delay_ms(200);
  80.             }
  81.         }
  82.        
  83.         /*
  84.          * Led indicador
  85.          */
  86.         output_bit(PIN_B6,activo);
  87.     }
  88. }

Y para que te des una idea de lo que dice AcoranTF :

(http://www.inventable.eu/media/EduPaginas/Rele-transistor/rele_npn_circuito_sin_diodo_Log5V.png)
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 05 de Enero de 2017, 01:31:17
No AconranTF,ni con la configuracion emisor comun funciona. vos sabes que le conecto directo una fuente de 12 y no acciona .en el simulador proteus sera el proteus ?
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 05 de Enero de 2017, 16:28:48
No AconranTF,ni con la configuracion emisor comun funciona. vos sabes que le conecto directo una fuente de 12 y no acciona .en el simulador proteus sera el proteus ?

Si el rele que has elegido es del voltaje correcto y ademas es simulable y aun asi no funciona, seguro es el Proteus, pero para asegurarte antes de eso, coloca un led en serie con una resistencia de 220 Ohm y el conjunto en paralelo con el rele, ojo el led debe quedar al contrario que el 1N4148. Si enciende el led en el momento que deberia activarse el rele, pero el rele no se activa, el problema es el rele, casi seguro que no es similable. En cambio si no enciende el led ni se activa el rele, podria ser el Proteus. Pero aun puedes hacer otra prueba para asegurarte, desconecta la resistencia de base del lado que va al PIC y conectala directamente a Vcc, con eso en el momento que simules tu circuito deberan encender el led y activarse el rele, si ocurre asi, definitivamente es el Proteus, en caso contrario es otro el problema.
Todo lo anterior vale para el circuito que te recomende antes, el que tu aportas mas arriba no es correcto.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 06 de Enero de 2017, 18:31:19
inclusive los transistores funcionan mal funcionan  como si estuvieran en corto o con fugas
Título: Re:Apagar un led despuès de varias horas
Publicado por: AcoranTf en 06 de Enero de 2017, 23:11:07
inclusive los transistores funcionan mal funcionan  como si estuvieran en corto o con fugas

Retovil lo que comentas no tiene mucho sentido. Es cierto que el Proteus tiene algunos "bugs", pero no hasta el punto de no funcionar correctamente varios componentes tan comunes como reles y transistores de uso generico.
Podria ser un problema de la instalacion de Proteus en tu caso particular.
Hay una forma facil de salir de dudas, adjunta el proyecto de Proteus que te da los problemas y tratare de hacer un hueco y probarlo en el mio. No olvides el programa del PIC, para poder simular.

Saludos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 08 de Enero de 2017, 18:59:23
La verdad es que tenes razon , me puse a mirar con mas detalle y hay elementos de dibujo y otros de simulacion . probe con otro rele y funciona bien asi mismo probe parte de la electronica digital y funciona .
Lo que no puedo hacer funcionar es que dos transistores bc548 funcionen como oscilador.
en configuracion emisior comun .Pero la verdad es que no se como ahora funcionan antes daban un corto .En el caso de que quiero conectar en el pin MCLR de 16f628a un transistor
para resetear no me lo permite . A lo mejor si me explicas porque no puedo meter un reseteador simplemente para probar ,no lo permite queda todo trabado .
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 11 de Enero de 2017, 00:59:56
No se si funcionara, deberias probarlo.

Código: C
  1. #include <16f628A.h>
  2. #Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
  3. #use delay(clock=4000000)
  4. #use fast_io(b)
  5.  
  6. volatile int1    activo;
  7. volatile int16   contador=0;
  8. int8    indice;
  9. int16   tiempo[4] = {1000,2000,3000,4000};
  10. volatile int16   limite;
  11.  
  12. #int_timer1
  13. void TIMER1_isr(void)
  14. {
  15.     set_timer1(192);
  16.     if(activo)
  17.     {
  18.         contador++;
  19.     }
  20.  
  21.     if(contador>=limite)
  22.     {
  23.         output_bit(PIN_B7,0);                   // Apago Rele
  24.         contador=0;
  25.         activo= false;
  26.     }
  27. }
  28.  
  29.  
  30. void main()
  31. {
  32.    
  33.     int8 i;
  34.    
  35.     // Inicializacion de variables
  36.     indice = 0;
  37.     limite = tiempo[0];
  38.     activo = true;
  39.    
  40.     // Configuracion de los modulos
  41.    
  42.     set_tris_b(0x0F);                               // RB0 a RB3 entradas, RB4 a RB7 salidas
  43.     output_bit(PIN_B7,1);                           //Inicia con el rele encendido
  44.     setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
  45.     set_timer1(192);
  46.     enable_interrupts(INT_TIMER1);
  47.     enable_interrupts(GLOBAL);
  48.  
  49.     while(1)
  50.     {
  51.         /*
  52.          * Boton de reset
  53.          */
  54.         if(input(PIN_B0))                       // Boton de reset
  55.         {
  56.             contador = 0;                           // Reinicio el tiempo
  57.             output_bit(PIN_B7,1);                   // Activo rele
  58.             activo = true;
  59.         }
  60.        
  61.         /*
  62.          * Boton de tiempo
  63.          */
  64.        
  65.         if(input(PIN_B1))                       // Boton seleccion de tiempo
  66.         {
  67.             while(input(PIN_B1));
  68.             indice++;
  69.             limite = tiempo[indice];
  70.             if(indice>=sizeof(tiempo))
  71.             {
  72.                 indice = 0;
  73.             }
  74.             for(i=0;i<=indice;i++)
  75.             {
  76.                 output_bit(PIN_B6,0);
  77.                 delay_ms(200);
  78.                 output_bit(PIN_B6,1);
  79.                 delay_ms(200);
  80.             }
  81.         }
  82.        
  83.         /*
  84.          * Led indicador
  85.          */
  86.         output_bit(PIN_B6,activo);
  87.     }
  88. }
Funciona muy bien !  :)
Cuando tengas tiempo me lo podes explicar


Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 11 de Enero de 2017, 02:57:51
Simple, divido el problema en 2 partes.

- Lo que necesito que sea rapido/constante en el tiempo y que no sea bloqueado por nada lo hago en la interrupcion.
- Lo que no necesita velocidad lo hago en el while.

¿Que necesito que se haga de forma constante?

Solamente necesito el timer y contar la cantidad de veces que requiere entrar, nada mas. Por eso esta el codigo del if(contador>= limite), limite en este caso es el punto donde se va a apagar por lo cual necesito cambiar ese valor para cambiar los tiempos ( cantidad de veces que entra a la interrupcion ).
Necesito ademas que cuando llegue al punto que corte deje de contar, por lo tanto uso esa variable de 1 solo bit (activo), para decir que deje de contar o no. Si observas cuando apago la salida tambien deshabilito este bit, de esa forma deja de contar.. Me aseguro de esa forma.
Esto en la interrupcion se va a ejecutar si o si por mas que ponga cualquier cosa en el while

Ahora vamos al while... Es decir las entradas manejadas por la persona o leds, donde no requiero requerimientos de velocidad o responder de manera instantanea.
En el while tenemos 3 secciones definidas con comentarios cada una independiente de la otra.

El primero es el boton de reset, Este boton lo que hace es poner el tiempo transcurrido ( contador ) a 0, activar el rele (por si ya habia terminado el tiempo), y permitir que en la interrupcion se siga aumentando contador (al poner activo a 1). Es decir que el TIEMPO CORRA!, se puede observar que mientras este presionado este boton se va a seguir reseteando a 0 a contador, ya que simplemente no me molesta si tarda 1s mas la persona presionando, si quisiera evitar esto simplemente le pongo un while.

Otra seccion del while es el boton de seleccion de tiempo, Tiene 2 partes, la seleccion de tiempo y la muestra en el led de la velocidad seleccionada.

- La primera parte:
Como pediste tenemos varios tiempos, como con este boton lo que hago es incrementar un numero ( indice ) yo no quiero que incremente varias veces por eso mismo esta el while luego del if, lo cual bloquea el programa hasta que la persona suelte y asi cuenta 1 solo. ¿Pero bloquea algo importante? Me bloquea unicamente la funcion del reset, pero resulta dificil que la persona tenga presionado el boton de velocidad y luego presione el de reset, si lo hace simplemente no logra nada.
En fin la "tecnica" aca es que con cada presion del boton aumente indice, indice me va a decir que valor del array uso, el if(indice>=sizeof(tiempo)) es una proteccion para que si indice es 3 que apunta al ultimo valor y se presiona de nuevo, pase a 0 y no 5 que seria un valor que no existe.

- La segunda
Finalmente para no usar otro led, uso el mismo led que indica que esta corriendo, y le hago hacer pulsos segun la velocidad elegida.

Al final de todo del while llegamos a una ultima instruccion, si recordas usabamos el led que indica que la salida esta activa para indicar la velocidad, que pasaria si presionamos el boton y mantenemos, corta la salida, soltamos, cambia de velocidad y muestra en el led, la ultima instruccion es poner el led a 1. Pero ya esta cortado, no puedo dejarlo encendido al led, por eso actualizo contantemente el led segun si esta la salida activa o no.

------------------------------------------

Estoy mas que seguro que posiblemente la parte de mostrar la velocidad con el led este mal, ya que mi idea era contar los pulsos en que esta encendido y no los que esta apagado.

Y tambien otro "error" que podria llegar a aparecer es que mientras se mantenga presionado un boton y se termine el tiempo, el led no pase a apagado hasta que no se suelte el boton.
Esto se podria solucionar, no creo que sea tan problematico.

Otra cosa mas, debido a que son de 16 bits las variables existe una minuscula posibilidad de que ocurra un error si es que la interrupcion del timer ocurre cuando se presiona el boton de tiempo, se puede salvar simplemente deshabilitando la interrupcion ANTES de asignar el valor a limite y luego habilitarla. O directamente eliminar la variable limite y usar indice solo, teniendo en cuenta que primero se debera calcular sobre otra variable temporal antes de asignarsela a indice. y en la interrupcion usar tiempo[indice], ya que esto es una variable de 8 bits, no necesita actualizar 2 registros sino uno solo, pero hay que posee precauciones de cuando se suma y quede en 4 que es un indice que no posee el array.

------------------------------------------

O por ahi resumentes de que son cada variables:

activo - es un bit o flag que me indica si debo o no seguir contando las entradas a la interrupcion.
contador - es la variable donde voy contando cuantes veces entro a la interrupcion.
indice - como su nombre lo dice me sirve para apuntar a cada elemento del array de tiempos es decir tiempo[2] seria 3000.
tiempo - es un array con todas los tiempos, o mejor dicho con la cantidad de entradas a la interrupcion, si quisiera agregar alguno simplemente pongo una coma mas y el numero.
limite - El tiempo seleccionado lo guardo aca, y lo comparo con la cantidad de veces que entro a la interrupcion.

----------------------------------------

¿Se puede complicar aun mas?

Si, se podria complicar en el punto de que no asigne el tiempo hasta no pasado cierta cantidad de segundos... Esto es por si por ejemplo tenes el corte de 10min, 20min, 30min , tenias seleccionado 20min, iban 15min y querias pasar a 30min, y de golpe porque ocurrio presionaste 2 veces y lo pasaste a 10min, esto automaticamente cortaria y la unica forma que te queda es activarla de nuevo por otros 10min.
Con esta complicacion en el programa podrias tener unos 30 segundos supongamos para seguir presionando y volver a seleccionar los 30min sin que se corte. No es simple de aplicar pero es posible.

Tampoco definimos una parada de emergencia. Que ocurriria si quisieramos pararlo ?, podriamos usar el boton de reset, el cual si esta presionado 5 segundos o mas proceda a detener todo. Y si es menos apagar, o viceversa en caso de se que quiera tener proteccion al activarlo de nuevo.
Tambien podrias hacer que si esta marchando, corte, y si esta parado resetee el tiempo sin esperar segundos.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 16 de Enero de 2017, 11:18:43
Exelente , debo decir que el parpadeo del led por RB6 ,funciona perfectamene ,un relojito .
Pero trato de saber como funciona este codigo que hace parpadear varias veces depende de
la seleccion de tiempo y no puedo .
Quise poner un display de 7 segmentos ,con un arreglo y acoplarlo de alguna forma para que esos parpadeos se conviertan en un 1 ,2 ,3 o 4 . Cosa que quede   mas vistoso y manejable .No pude hacerlo pues salia cualquier cosa menos un numero .
Como funciona este codigo? como hace parpadear al led uno ,dos o tres veces ? :)
Código: [Seleccionar]
if(input(PIN_B1))                       // Boton seleccion de tiempo
        {
            while(input(PIN_B1));
            indice++;
            limite = tiempo[indice];
            if(indice>=sizeof(tiempo))
            {
                indice = 0;
            }
            for(i=0;i<=indice;i++)
            {
                output_bit(PIN_B6,0);
                delay_ms(200);
                output_bit(PIN_B6,1);
                delay_ms(200);
            }
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 16 de Enero de 2017, 14:53:50
Bien, el codigo que pase tiene algunos errores importantes luego te lo doy corregido, pero miremos este codigo que me preguntas
.. separemos el codigo..

Código: C
  1. if(input(PIN_B1))                       // Boton seleccion de tiempo
  2.         {
  3.             while(input(PIN_B1));

Eso simplemente es lo del boton, nada mas, pide que este presionado y luego que se suelte para poder continuar. Esta parte no tienen nada que ver con el parpadeo

Código: C
  1. indice++;
  2.             limite = tiempo[indice];

Esta parte del codigo es donde procedo a cambiar la velocidad, aumento indice, y con el nuevo indice encuentro el tiempo que me dice el array, el indice simplemente es un numero que me dice que posicion del array tomar, 0,1,2,3, etc. Esto no tiene nada que ver con el parpadeo.

Código: C
  1. if(indice>=sizeof(tiempo))
  2.             {
  3.                 indice = 0;
  4.             }

A pesar que este es un error donde esta ubicado pero funciona correctamente, porque deberia ir entre medio de las 2 instrucciones anteriores, en si este codigo te dice que si por algun motivo al incrementar indice pasamos la cantidad de datos que tiene el array tiempo[] paso a 0, es decir los valores en el ejemplo son de 0 a 3 ( 4 elementos ) al llegar indice a 4, deberia pasarse a 0. Con el mayor o igual directamente me aseguro que sea cualquier valor incorrecto ( 100, 124, etc ) pase a 0. Y no me quedo con simplemente == 4. Esto no tiene nada que ver con el parpadeo.

Por ultimo la parte del parpadeo.

Código: C
  1. for(i=0;i<=indice;i++)
  2.             {
  3.                 output_bit(PIN_B6,0);
  4.                 delay_ms(200);
  5.                 output_bit(PIN_B6,1);
  6.                 delay_ms(200);
  7.             }

Un simple for... desde i = 0, hasta que la condicion i <= indice sea falsa. Por que menor o igual y no directamente menor solo ? Porque sino al ser indice = i = 0, no ejecutaria el ciclo for 1 vez. Tambien podria haber realizado una condicion como esta i < (indice +1), cuestion de gustos.

Entonces supongamos que indice era 2. (recorda que el primer elemento es indice 0, por lo tanto seria el 3er elemento)
Comienza el for con i = 0, la condicion es true entonces realiza el codigo
Termina la vuelta e i pasa a valer 1, sigue siendo true y realiza el codigo
Otra vuelta i = 2, sigue siendo true y realiza el codigo, aca ya fueron 3 veces que parpadeo el led, ( los del 0, 1 y 2 )
proxima vuelta i = 3, por lo que ya la condicion pasa a ser false y sale del for.

En todo esto el for se repetio (indice + 1) veces o mejor dicho el numero del elemento elegido si es que empezamos a contar desde 1 y no 0.

-------------------------------

Codigo con unas cuantas cosas corregidas.

Código: C
  1. #include <16f628A.h>
  2. #Fuses xt,nowdt,NOPROTECT, PUT, NOLVP,NOMCLR
  3. #use delay(clock=4000000)
  4. #use fast_io(b)
  5.  
  6. volatile int1    activo;
  7. volatile int16   contador=0;
  8. volatile int8    indice;
  9. int16   tiempo[4] = {1000,2000,3000,4000};
  10. int8   temp;
  11.  
  12. #int_timer1
  13. void TIMER1_isr(void)
  14. {
  15.     set_timer1(192);
  16.     if(activo)
  17.     {
  18.         contador++;
  19.     }
  20.  
  21.     if(contador>=tiempo[indice])
  22.     {
  23.         output_bit(PIN_B7,0);                   // Apago Rele
  24.         contador=0;
  25.         activo= false;
  26.     }
  27. }
  28.  
  29.  
  30. void main(void)
  31. {
  32.    
  33.     int8 i;
  34.    
  35.     // Inicializacion de variables
  36.     indice = 0;
  37.     activo = true;
  38.    
  39.     // Configuracion de los modulos
  40.    
  41.     set_tris_b(0x0F);                               // RB0 a RB3 entradas, RB4 a RB7 salidas
  42.     output_bit(PIN_B7,1);                           //Inicia con el rele encendido
  43.     setup_timer_1(RTCC_INTERNAL| RTCC_DIV_4);
  44.     set_timer1(192);
  45.     enable_interrupts(INT_TIMER1);
  46.     enable_interrupts(GLOBAL);
  47.  
  48.     while(1)
  49.     {
  50.         /*
  51.          * Boton de reset
  52.          */
  53.         if(input(PIN_B0))                       // Boton de reset
  54.         {
  55.             contador = 0;                           // Reinicio el tiempo
  56.             output_bit(PIN_B7,1);                   // Activo rele
  57.             activo = true;
  58.         }
  59.        
  60.         /*
  61.          * Boton de tiempo
  62.          */
  63.        
  64.         if(input(PIN_B1))                       // Boton seleccion de tiempo
  65.         {
  66.             while(input(PIN_B1))
  67.             {
  68.                 output_bit(PIN_B6,activo);
  69.             }
  70.  
  71.             temp = indice + 1;
  72.             if(temp>=sizeof(tiempo))
  73.             {
  74.                 indice = 0;
  75.             }
  76.             else
  77.             {
  78.                 indice++;
  79.             }
  80.  
  81.             for(i=0;i<=indice;i++)
  82.             {
  83.                 output_bit(PIN_B6,0);
  84.                 delay_ms(200);
  85.                 output_bit(PIN_B6,1);
  86.                 delay_ms(200);
  87.             }
  88.         }
  89.  
  90.     /*
  91.      * Led indicador
  92.      */
  93.     output_bit(PIN_B6,activo);        
  94.     }
  95. }

En este codigo soluciono los anteriores errores.

- No asigno "limite" en el while, solo indice que es de 8 bits, Tambien debo usar una variable temporal para un calculo, para saber si se va a exceder o no del valor correcto, de esa forma nunca indice tendria un valor fuera de rango.

- Como recordas mientras se mantenga presionado el boton es posible que no se actualize el led, si es que termina, entonces para eso la solucion mas simple fue ponerlo dentro del while del boton, podria haberlo puesto en el timer tambien, ya que este ultimo siempre se esta ejecutando, pero este interferiria en el for de muestra de velocidad. Por eso no lo hice alli.
Título: Re:Apagar un led despuès de varias horas
Publicado por: retovil en 28 de Febrero de 2017, 01:42:21
hola KillerJC ,me aucente un poco . Debo agradecerte por la explicaciòn circuito parpadeo y de todo el programa ,debo decirte que el reset no funciono pero si lo hiciste aproposito ya lo solucione .
Para que se le pone a las variables la expresion volatile
?
Título: Re:Apagar un led despuès de varias horas
Publicado por: KILLERJC en 28 de Febrero de 2017, 08:28:51
hola KillerJC ,me aucente un poco . Debo agradecerte por la explicaciòn circuito parpadeo y de todo el programa ,debo decirte que el reset no funciono pero si lo hiciste aproposito ya lo solucione .
Para que se le pone a las variables la expresion volatile
?

No fue mi intencion que no funcionara, asi que fue un error.

El volatile usalo cuando tengas una variable que se acceda en la interrupcion y en tu programa principal. Esto hace que el compilador omita la optimizacion de esa variable. Ya que de no ser asi es posible que  el compilador al detectar que nada lo cambia a la variable (tomando la interrupcion y el programa como 2 funciones distintas que nunca se llaman) la elimine y comienzen los problemas. Para eso te aseguras y le pones volatile, pidiendole que lea si o si el registro que contiene la variable.

Si no usa optimizaciones, el volatile no hace nada es lo mismo que no estuviera, pero con optimizaciones es necesario.