[Aporte] Temporizador regresivo programable hasta 100 horas

D@rkbytes

Moderador general
Hace algún tiempo quise hacer este proyecto para contar el tiempo de encendido de la lampara para revelar las mallas de serigrafía que uso para hacer los circuitos impresos.
Anteriormente lo hacía con el clásico timer 555 pero obviamente no es nada preciso.

Como verán, 100 horas es mucho tiempo, pero aprovechando que se hace uso de un microcontrolador, decidí que contara hasta 100 horas y así poderle dar otros usos al mismo, que dejo a su imaginación.

Características:

Para ingresar el tiempo se hace uso de un teclado matricial 3x4.
El formato del tiempo está basado en horas y mostrado como HH:MM:SS
Así que al contrario de otros temporizadores basados en segundos/minutos, en este se pueden ingresar las horas, los minutos y los segundos, mostrando un conteo descendente.
Se pueden contar hasta un máximo de 100 horas. (99H+59M+59S)
El tiempo requerido se puede guardar en la memoria interna del microcontrolador. (PIC16F88)
Tiene aviso sonoro, salida para un relevador, (adaptable a otro tipo) y pantalla LCD 16x2 estándar.

El programa está escrito en C (PCWHD Compiler v5) y adjunto también el código fuente.

Espero sea de su agrado y utilidad.

Saludos y suerte.

Bugs encontrados:
25/03/2014
El PIC16F88 cuenta con un sistema de detección ante una falla del oscilador primario llamado FCMEN (Fail-Safe Clock Monitor)
El programa está diseñado para trabajar con cristal de cuarzo para mayor precisión, y en caso de fallar se activa el oscilador interno.
Al estar trabajando cristal y oscilador interno a la misma frecuencia, (4MHz) en caso de alguna falla del cristal,
no se pierde sincronía y el cambio de uno a otro no se nota. (Solo en precisión)
Esta función está declarada en el programa, sin embargo no funciona.
Los valores agregados por el compilador al registro OSCCON no son los que se requieren para esta función.

Para solucionar este problema, que aunque no es común que un cristal falle, puede suceder y se debe hacer lo siguiente:
Agregar esto en la cabecera del programa: #byte OSCCON = getenv("SFR:OSCCON")
Y dentro del bloque main configurar el registro OSCCON con este agregado: OSCCON = 0b01100110;

Con eso se soluciona este bug que es uno de tantos que tiene el compilador PCWHD.

Nota: También se debe omitir la librería stdlib.h ya que no se está usando en el programa.

14/10/2014
* Corrección para versiones de PICC Compiler superiores a la v5.020 (Actual: v5.027)
* Se agregó la posibilidad de reingresar el tiempo sin presionar reset y otras mejoras.
 

Adjuntos

  • Timer_Prog_99H_SCH.jpg
    Timer_Prog_99H_SCH.jpg
    126.5 KB · Visitas: 261
  • 16F88 Timer Programable.rar
    89.5 KB · Visitas: 210
  • 16F88 Timer programable v2.rar
    73.4 KB · Visitas: 166
Última edición:
Cuando empieza a contar y presionas una tecla se ven signos raros en el LCD, la única forma de interrumpirlo es con el MCLR?, estaría bien que pusieras una tecla por decir * presionada y se interrumpiera para ingresar los datos de nuevo, y se bloqueen las demás teclas para que no se vean símbolos raros :D!, solo sugerencias u opiniones con buen fin..

saludos!!
 
Cuando empieza a contar y presionas una tecla se ven signos raros en el LCD
Eso únicamente sucede en el simulador, físicamente no ocurre.
¿La única forma de interrumpirlo es con el MCLR?
Estaría bien que pusieras una tecla por decir * presionada y se interrumpiera para ingresar los datos de nuevo, y se bloqueen las demás teclas para que no se vean símbolos raros :D!, solo sugerencias u opiniones con buen fin.

saludos!!
Si, para el propósito para el cual fue diseñado, detener el conteo no es buena idea.
Sin embargo, si lo desean se puede agregar esa función al código fuente del programa.
Ya que monten el circuito físicamente verán que al presionar las teclas no aparecen símbolos raros.

Saludos.
 
Lo monté y funciona bien. ¿No lo tienes para trabajar con displays de 7 segmentos?
Únicamente lo diseñe para usarlo con una pantalla LCD, ya que la programación para displays de 7 segmentos es muy diferente, más complicada y no se pueden mostrar las opciones de configuración tan fácilmente.
Gracias por tus aportes, son muy buenos.

Saludos.
Gracias, suerte.
 
hola que tal a todo estoy tratando de hacer un temporizador programable donde mediante unos pulsadores yo pueda elegir a que minuto se deba energizar un relevador para encender un foco y en que momento se apague, por el momento ya pude realizar el conteo de 0 a 60 min, solo que tengo un pequeño problema, no se porque el cero no lo muestra, en vez de mostrar el cero muestra dos puntos [:] Les adjunto mi programa para que alguien pueda ayudarme con mi problema.

Otra duda que tengo es... no se como hacer para que yo pueda ingresar mediante los pulsadores el tiempo en que se active el relevador, espero que alguien me pueda ayudar con unas ideas porque la verdad no se me viene a la mente como hacerlo.

De antemano muchas gracias por su atención y espero que alguien me pueda ayudar con mi problema..gracias
 

Adjuntos

  • Temporizador.rar
    20 KB · Visitas: 89
Ya logre que contara y que incrementara el tiempo que quiero que temporize ahora el único problema es que no puedo decrementar el tiempo que requiero temporizar, con el boton en Porta0 poniéndolo a 1 indico al microcontrolador que estoy por ingresar el tiempo de temporizacion, con el boton en porta1 incremento el tiempo y con el boton en porta2 decremento el tiempo, cuando pongo a 0 el boton de porta0 empieza a correr el tiempo y se activa un rele y cuando termina vuelve a su estado inicial.

Les agradeceria mucho si alguien me podría ayudar o darme una idea de como drecrementar el valor que estoy ingresando por medio del porta2, porque ya intente de todo y no logro hacerlo.. ;( :cry:
 

Adjuntos

  • temporizador.txt
    13 KB · Visitas: 50
Última edición:
Hola.

Soy nuevo con esto de los microcontroladores y he estudiado algo para poder entender tu código del temporizador programable de 100 horas, lo que deseo es hacer un temporizador programable continuo, me explico poder ingresar el tiempo que dura una bombilla prendida y el tiempo que esta misma dure apagada,pero que esto sea continuo hasta que yo decida oprimir reset, como puedo lograr esto?

Agradecería tu colaboración.
 
Hola.

Soy nuevo con esto de los microcontroladores y he estudiado algo para poder entender tu código del temporizador programable de 100 horas, lo que deseo es hacer un temporizador programable continuo, me explico poder ingresar el tiempo que dura una bombilla prendida y el tiempo que esta misma dure apagada,pero que esto sea continuo hasta que yo decida oprimir reset, como puedo lograr esto?

Agradecería tu colaboración.

Eso sería un contabilizador :unsure:

Cuenta horas
 
pero digo yo que para eso no hace falta un contador, con un simple while y unas condiciones lo tendra hecho.

Ejemplo:

Código:
Void main()             // Empezamos el programa principal
    {
 lcd_init();             // Iniciamos la pantalla lcd
 
 output_high(pin_b3);    // Encendemos el led de B3
 output_low(pin_b4);     // Apagamos el led de B4

  while(true)
     {
    seg++;  
  if(seg>59)
      {
   seg=0;  
   min++;
    }
  
 if(min>59)
    {
   seg=0;
   min=0;
   horas++;
    }    
 
 if(horas==2)
   {
  seg=0;
   min=0;
   horas=0;
 output_toggle(pin_b3);    // Cambiamos salida de B3
 output_toggle(pin_b4);    // Cambiamos salida de B4     
   }
 
 lcd_gotoxy(1,1);        // Iniciamos el lcd en columna 1 fila 1
 printf(lcd_putc,"   Segundos: %02.0d   ",seg);
 lcd_gotoxy(1,2);        // Iniciamos el lcd en columna 2 fila 1
 printf(lcd_putc,"Min: %02.0d  Hor: %02.0d",min,horas);   
   delay_ms(1000);   
      }
    }
 
Última edición:
Comentaste lo más elemental, y no el programa principal.
El uso de output_toggle requiere verificación y el retardo (delay) debería ser por un timer.
Esos corchetes de apertura y cierre de rutinas a la mitad de las instrucciones son muy extraños. (No propios de una buena tabulación)

Y perdón, pero si lo que se requiere es que los tiempos sean programables, (Como se menciona) eso no sirve.
lo que deseo es hacer un temporizador programable continuo.
Ya viendo lo expuesto y tratando de entender lo sugerido. (Que no es muy claro)
Porque un programador ve las cosas con más lógica y le surgen dudas.
Dudas que deben ser aclaradas por quien requiere el programa.

La opción de modificar el código que subí para tal propósito, no sería complicada.
Pero cuando alguien dice.. Traté de entender tu programa para usarlo en algo que requiero, pero no doy con bola.
Simplemente es porque no tiene idea de programación.
Y de ahí a que entienda el programa para modificarlo, a que haga un programa propio, existe mucha distancia.

Quien me conoce ya sabrá que no soy egoísta al compartir y enseñar, pero una de la reglas básicas de este Foro, es ser uno mismo quien aporte los primeros pasos sobre lo que desea hacer.
Si el forero no entiende algo, aquí habemos muchas personas capaces de colaborar con dichas dificultades.
Siempre y cuando sea él quien exponga su código.
Antes yo veía temas de consulta sin código ni esquemas expuestos, sólo pedían.
Yo de manera voluntaria les proporcionaba todo lo requerido y muchas veces ni gracias daban.

Al ser un aporte, el tema no será eliminado, pero nos deja muy en claro que hay personas que no valoran lo que se les proporciona y simplemente toman lo que quieren y se van.

También hay personas que se nota cuando son novatos en programación, y a ellos si les ofrezco una ayuda inicial, si la ayuda requerida pasa a ser un abuso, se va directamente a F29.
 
Última edición:
Comentaste lo más elemental, y no el programa principal.
El uso de output_toggle requiere verificación y el retardo (delay) debería ser por un timer.
Esos corchetes de apertura y cierre de rutinas a la mitad de las instrucciones son muy extraños. (No propios de una buena tabulación)

Hola D@rkbytes, si con ese parrrafo te refieres a mi sobre como he puesto el codigo, solo decirte que lo unico que intentado es darle una idea, ya que lo que, segun me parecio leer, es que quiere que se encienda un tiempo y luego se apague.

Esta claro que no soy ningun lince solo intento dar una idea.

Eso es para un pic 16F877A y esta claro que no he puesto otros datos como por ejemplos, las variables, o los includes o demas.

Esto lo utilizo en un aparcamiento en el cual deve estar encendidas las luces todo el dia, asi consigo, que como son bombillas leds, en teoria, no se estropeen tanto.

Sobre lo de los corchetes no se a que te refieres, yo traslade el codigo y salio asi de separado.

Decirte que el programa que hiziste lo tengo y me a servido en su momento.

Una pregunta, dices que el uso del toggle necesita verificacion, eso no lo entiendo que quieres decir, el toggle no es hacer lo contrario de lo que estaba haciendo dicha instruccion? por que se deve verificar?. Gracias
 
Hola D@rkbytes, si con ese parrrafo te refieres a mi sobre como he puesto el código, solo decirte que lo único que he intentado es darle una idea, ya que lo que, según me pareció leer, es que quiere que se encienda un tiempo y luego se apague.
Sí, mi mensaje aparece después del tuyo, tampoco cité, por lo mismo.
Sobre lo de los corchetes no sé a qué te refieres, yo traslade el código y salió así de separado.
Eso es porque no usas el tabulador al escribir el código.
No es una regla, así como tampoco es obligatorio tabular, pero sirve bastante para definir un bloque de código.
En lenguaje ensamblador también se usa el tabulador, pero la sintaxis de sus instrucciones, pocas veces permiten realizar una tabulación que permita definir bloques.
En el Basic, C y otros lenguajes, tabular es bastante común y eso le da mejor compresión al programa.
Ejemplo de tabulación en código: (Basic)


Tabulación en código.jpg
Una pregunta, ¿dices que el uso del toggle necesita verificación?
No entiendo qué quieres decir. ¿El toggle no es hacer lo contrario de lo que estaba haciendo dicha instrucción?
¿Por qué se debe verificar?
Porque hacer un cambio de estado con toggle puede tener un resultado inverso al esperado si no se sabe el estado en que se encuentra el pin.
El pin debe ser inicializado con un valor, (así como lo hiciste) pero ese estado puede verse afectado por fallas el programa, (bugs) un reset por software, un cuelgue, u otras circunstancias que podrían hacer que los pines no sigan manteniendo el mismo estado.
Por eso es arriesgado hacer un toggle, y es mejor definir plenamente un estado.
Y la verdad es que unas cuantas líneas extra de código para comprobar un estado, bien valen la pena.
 
Última edición:
Ahora entendido nuevos conceptos, tal y como has explicado lo de tabular o lo de toggle y demas no lo habia visto nunca asi, sobre todo lo de toggle, tienes razon, bien valen un par de linias mas de codigo y curarse en salud.

Gracias D@rkbytes, contigo siempre estoy aprendiendo jejejeje.

Permiteme una pregunta si no te importa, en el anterior post dices que el retardo(delay) es mejor con un timer, digo yo, el codigo es muy corto y no afecta a nada mas, solo tiene que encender un tiempo y luego estar apagado otro tiempo, tambien para ese codigo tan pequeño es mejor hacer el retardo con un timer?, en cierto modo implica mas codigo o no?. Gracias de nuevo
 
Última edición:
Permíteme una pregunta si no te importa.
En el anterior post dices que el retardo(delay) es mejor con un timer, digo yo, el código es muy corto y no afecta a nada mas.
Sólo tiene que encender un tiempo y luego estar apagado otro tiempo.
¿También para ese código tan pequeño es mejor hacer el retardo con un timer?
¿En cierto modo implica más código o no?
Obviamente hacer uso de los timers implica más código, pero tienes la ventaja de que se pueden realizar otras tareas mientras el timer hace lo suyo.
En programas pequeños en donde su única función va a ser ejecutar una rutina y luego esperar, el uso de retardos no tiene problemas, pero para hacer retardos largos se necesita un bucle.
Dentro de ese bucle puedes verificar otras cosas para aprovecharlo.
 
Atrás
Arriba