TODOPIC
Microcontroladores PIC => - Niple - => Mensaje iniciado por: Coldplay en 30 de Junio de 2008, 22:03:40
-
Señores tengo una duda que me carcome el cerebro, necesito hacer un programita que sense el tiempo entre señales y luego envíe la señal atrasada, por ejemplo:
* Si el tiempo es menor a 1 segundo que envíe la señal 2 segundos después de la señal recibida.
* Si el tiempo es mayor a 1 segundo que envíe la señal 4 segundos después de recibida.
Ahora el tema, cómo hago para medir el tiempo mientras el PIC está haciendo otro proceso? Porque capaz que mientras está en el retardo para mandar la señal atrasada y aparece otra que tiene que ir contandola. En caso de necesitar un interrupción, tema que me cuesta y mucho, algún ejemplo práctico con diagramita como para focalizar mejor la idea?
Desde ya gracias gente!
-
Si las interrupciones te cuestan trabajo, la forma mas obvia es hacer tu propia rutina de tiempo.
Para ello tenemos que decir como funcionan las rutinas que Niple llama: Temporizadores, tiempos por ciclos.
Las rutina de espera por ciclos, funcionan haciendo Nop para consumir tiempo del microprocesador, y calculando de esta forma, cuanto tiempo ha pasado, esto se saca a partir de una formula matemática, donde tiene que ver la velocidad del Cristal de Reloj que estas usando.
Ahora imagina que en lugar de Nop, tienes un pequeño código para ver si la señal ha cambiado o no. De esta forma podrías esperar hasta que la señal cambie y calcular el tiempo esperado al mismo tiempo. Para esto tienes que usar un poco de matemáticas, pero es muy factible hacerlo.
Por otro lado, los tiempos por interrupciones por Timers son más fáciles de hacer. La interrupción se ejecuta cada vez que pasa X cantidad de tiempo, desafortunadamente no se puede poner un segundo de tiempo en un Timer (por lo menos no en la serie 16F8XX), así que lo que tendremos que hacer es contar cuantas veces se ejecuta la interrupción hasta que lleguemos a un segundo.
Para calcular el tiempo, puedes usar una herramienta que viene con Niple que se llama Calculo del tiempo por TMR0. Esta herramienta la encuentras en el menú Herramientas. Ahi pones 1 Segundos y veras que arroja el siguiente dato (Para cristal de 4Mhz), Preescalado 64, Incremento de TMR0 125, Bucle1 de 125.
Ahora para codificar esto, serán los siguientes pasos:
1.- Selecciona Temporizadores, TMR's Internos y luego TMR0, Config. TMR0
En el cuadro de configuración pondremos, Predivisor 64, Origen de la señal de Reloj: Señal de Reloj Interna
2.- Luego usamos Interrupciones, Activar/Desactivar y en el cuadro de opciones escojemos:
Habilitador general d Interrupciones: Activado
Interrupción por temporizador TMR0: Activado
3.- Luego usamos: Interrupciones, Insertar Interrupción, por TMR0
4.- Ahora cambiemos a Modo experto, como la herramienta nos dijo que era 125 y la interrupción se activa cuando llega a 255, lo que haremos sera a 255 restarle 125 y esto nos da 130, así que asigneremos el valor 130 a la variable TMR0 dentro de nuestra interrupcion.
5.- Cambiemos a Modo normal, e Incrementos una variable (por ejemplo ciclo1) + 1
6.- Si esta variable llego a 125 entonces que active un Bit, o otra variable (por ejemplo el bit PasoSegundo) y termine la interrupción, si la respuesta es NO, que también termine.
7.- En nuestro programa principal, para activar el conteo de nuestra Interrupcion pondremos los siguientes valores: ciclo1=0, PasoSegundo=0 y usando el modo experto, TMR0 = 130
8.- Cuando queramos saber si ya paso un segundo, preguntamos PasoSegundo vale 1 ? entonces si es verdadero, habra pasado un segundo.
Como Nota, en esta explicación existe un pequeño error, por que cuando se entra a la interrupción se paran las interrupciones, entonces el tiempo en que haces el calculo del paso de segundo, tiene que ser descontado a la formula original, pero es tan pequeño que es prácticamente despreciable. Si necesitas mucha precisión en la cuenta del segundo, debes calcular el tiempo del código dentro del TMR0 para des contarlo de la espera.
Intentalo es fácil y si te atora pregunta de nuevo.
Espero haberte ayudado. Saludos!
-
Mike79
-
Ahora para codificar esto, serán los siguientes pasos:
1.- Selecciona Temporizadores, TMR's Internos y luego TMR0, Config. TMR0
En el cuadro de configuración pondremos, Predivisor 64, Origen de la señal de Reloj: Señal de Reloj Interna
2.- Luego usamos Interrupciones, Activar/Desactivar y en el cuadro de opciones escojemos:
Habilitador general d Interrupciones: Activado
Interrupción por temporizador TMR0: Activado
3.- Luego usamos: Interrupciones, Insertar Interrupción, por TMR0
4.- Ahora cambiemos a Modo experto, y asignemos el valor 125 a la variable TMR0 dentro de nuestra interrupcion. Esto lo hago asignandole una valor desde la EEPROM? Cambio el valor del TMR0 por un decimal = 125?
5.- Cambiemos a Modo normal, e Incrementos una variable (por ejemplo ciclo1) + 1
6.- Si esta variable llego a 125 entonces que active un Bit, o otra variable (por ejemplo el bit PasoSegundo) y termine la interrupción, si la respuesta es NO, que también termine. Entonces cuando Ciclo1 llegue a 125 pasó un segundo no?
7.- En nuestro programa principal, para activar el conteo de nuestra Interrupcion pondremos los siguientes valores: ciclo1=0, PasoSegundo=0 y usando el modo experto, TMR0 = 125 También modificando la EEPROM? Aunque me trabé aquí y no comprendo la idea de este paso.
8.- Cuando queramos saber si ya paso un segundo, preguntamos PasoSegundo vale 1 ? entonces si es verdadero, habra pasado un segundo. Si es verdadero puedo poner a 0 Paso Segundo para que empiece a contar de nuevo no?
Como Nota, en esta explicación existe un pequeño error, por que cuando se entra a la interrupción se paran las interrupciones, entonces el tiempo en que haces el calculo del paso de segundo, tiene que ser descontado a la formula original, pero es tan pequeño que es prácticamente despreciable. Si necesitas mucha precisión en la cuenta del segundo, debes calcular el tiempo del código dentro del TMR0 para des contarlo de la espera.
Intentalo es fácil y si te atora pregunta de nuevo.
Espero haberte ayudado. Saludos!
-
Mike79
De esta manera que me explicás podría ir contando a pesar de estar realizando otra acción no? Porque si la realizaría con un bucle cerrado con un retardo, si justo la señal llega durante el retardo me la pierdo. En cambio con la interrupción por tiempo no.
Muy muy muy buena tu explicación, muy detallada, gracias y disculpá las molestias.
-
Ahorita que lo volvi a leer, me di cuenta que el paso 4 esta mal, es 130 (ya modifique el post original y explica el por que).
Si en el paso 6 ya paso un segundo, pero marcamos un Bit para saberlo, si AGREGAS mucho código en la interrupción el error del segundo Se ira incrementando. Ya que cuando entras en la interrupción, el Timer esta parado, tienes que salir lo más rápido posible para que siga contando.
El paso 7 es para inicializar el contador, Cada vez que desees que cuente un segundo, debes hacer estos pasos para que el contador empiece a contar.
En el punto 8 haces otra pregunta, La respuesta es NO, tienes que poner PAsoSegundo = 0, TMR0 = 130 (125 estaba mal), ciclo1=0. De lo contrario no volvera a contar un segundo.
Agrego Ejemplo en Niple v5. Como veras agregue un par de cosas. Hice que cuando pasa un segundo prendiera A0, y al siguiente segundo la apagara y así sucesivamente, de esta forma veras que A0 se activa y desactiva constantemente.
Use Proteus para correr el HEX de este ejemplo, y tomarle el tiempo, descubri que el Segundo se activa cada 1.010 Segundos, es decir, que existen 10 Milisegundos por el código agregado en la interrupción (multiplicado por 125 veces que se ejecuta este código para dar un segundo). Si necesitas que sea más preciso, tienes que descontar este tiempo.
Saludos!
-
Mike79
-
Ahora me queda todo claro, gracias!!!
El ejemplo no lo pude ver porque tengo el 2.2 Versión Educativa.
Te hago otra consulta así voy definiendo los últimos pasos del programa:
Resulta que como comenté al principio, según el tiempo que yo cuente voy a iniciar una retardo, en todal van a ser 60 retardos. Mi idea en un principio era comparar el valor y realizar el retardo correspondiente, pero luego se me ocurrío usar alguna tabla. Podría cargar los 60 valores en tabla? Al momento de realizar la consulta, cómo se hace? Y cómo hago para trasformar ese valor de tabla en un retardo o bien en un bucle de tiempo?
Desde ya gracias y disculpá tantas molestias, sabés que me solucionaste un tema de hace 2 años, que era las temporizaciones e interupciones? Gracias MIL!!!
-
Con niple es muy facil.
Solo creas una tabla, le pones de Nombre por ejemplo: Retardo. En esta tabla le pones todos los valores que desees.
Posteriormente, cargas el valor que deseas consultar de la tabla en una variable, por ejemplo: Posicion = 3, para consultar la posición 3 d tu tabla.
Luego llamas a: Consultar Tabla, aquí te pediría que selecciones la tabla guardada anteriormente. Te pedira el valor del indice, en este caso seria la variable Posicion, y te pedira donde guarda el resultado, en este caso escoges otra variable.
Por ultimo, llamas un temporizador por ciclos, de Tiempo variable, y utilizas la variable donde guardaste el resultado de la tabla.
Haciéndolo de esta forma, todos los retardos deben estar en la misma unidad de tiempo, es decir, deben ser o bien Microsegundos, Milisegundos o Segundos. No podras mezclarlos ya que no habría forma de cambiar la unidad de tiempo.
Sin embargo con ingenio si podrias hacerlo, Para esto tendrias que usar dos tablas, una para los retardos, y otra para el tipo de Unidad, Consultas ambas tablas usando el mismo indice y guardando el resultado en dos variables diferentes, supongamos Retardo y Unidad.
Entonces después haces una comparación Lógica, y si Unidad vale 1 usas un ratardo de Tipo variable en milisegundos y si vale 2, un retardo variable en segundos.
Saludos!
-
Mike79
-
Permitime sacarme el sombrero, excelente respuesta, estuve toda la noche pensando cómo podría ser y se me ocurrío los mismo, pero que un maestro como vos me lo certifique es otra cosa!!! Gracias!!!
Me parece que tengo un fin de semana a puro Nipple, comentaré los resultados!!!
Gracias nuevamente!
-
Coldplay, el Sr. Mike con el niple es un toro! :lol:
Saludos, nos leemos! :mrgreen:
-
Con todo respecto Firepic, es NOTORIO que solo posteas por postear.
Ojala lo hicieras más discretamente.
Coldplay, gracias por el comentario, no soy experto, solo uso Niple desde hace ya tiempo y pues ya tengo un poco de experiencia usandolo :P
-
Siento gran admiración por las personas expertas del foro y me gusta hacerlo saber.
Leí el hilo y me llamó la atención la forma tan rápida como resolviste el problema, quería expresártelo.
Si ves mis últimos mensajes verás que otros sí son más significativos, trato de hacerme solidario con otros como lo han sido conmigo.
Pero entiendo tu punto de vista y me disculpo, no volvere a halagarte.
Claro que en cosas de niple te las dejo a vos porque yo no he trabajado con él. Pero trato de colaborar en Basic y C siempre que puedo.
Nuevamente disculpas.
Saludos cordiales.