Go Down

Topic: cronometro con millis y botones de paro y iniciar/pausa (Read 186 times) previous topic - next topic

lacurvamva

buenas noches compañeros estoy haciendo un marcador de futbol el cual lleba el cronometro pero me e topado con el dilema de poner los botones de iniciar pausa y reinicio o paro el reinicio si lo puedo hacer ya que hago la resta del tiempo pasado menos el tiempo actual (estoy utilizando millis) y lo estoy integrando con nodemcu y la app de blink  sin mas compañeros quisiera si me pudieran dar alguna idea de como lograrlo no pido la solución pero me gustaría una ideas de como lograrlo.

gracias por su tiempo..

surbyte

No vemos código de modo que es dificil ayudarte en el "aire".

Aporta tu código usando etiquetas (lee las normas) y luego te guiaremos.

Hay ejemplos de contadores en Documentación.

Lucario448

Para realizar un cronómetro con millis pero con las funciones de iniciar, parar y reiniciar; se necesita de tener almacenada la siguiente información:
  • Momento en que inició la cuenta.
  • Momento en que se detuvo.
  • A menos que deliberadamente se detenga el contador de millis (es posible hacerlo), también un acumulador de tiempo detenido; el cuál se utiliza para no tomar en cuenta el lapso de paro después de reanudar.
  • Un dato lógico o "booleano" que se use como "bandera" para indicar si el cronómetro debería estar corriendo o no.


Cuando se inicia la cuenta, se guarda ese momento y se establece la bandera.
Cuando se detiene, se guarda ese momento y se reinicia la bandera.
Cuando se reinicia, se restablecen los valores a los que tenía por defecto.

Una forma de distinguir entre un inicio desde cero de una reanudación, es preguntando si el momento en que inició la cuenta es cero; si lo es, entonces no es necesario calcular el tiempo detenido para sumarlo al acumulador (pero hay que guardar el momento ya que en este caso es un inicio desde cero); caso contrario, antes de establecer la bandera,  habría que sumar el resultado de la siguiente fórmula para calcular el tiempo detenido:

Code: [Select]
tDetenido += millis() - tParada;


Para obtener el tiempo transcurrido, se obtiene la diferencia entre el tiempo actual y el de inicio más el acumulado de tiempo detenido. Cómo fórmula se vería así:

Code: [Select]
millis() - (tInicio + tDetenido);


¿Mejor ahora?

IgnoranteAbsoluto

Creo que hay una forma de resolverlo más sencilla que la que propone Lucario448. Este sería un boceto de la posible implementación:
Code: [Select]
unsigned long tiempoContabilizado = 0;  // Variable que nos guardará en milisegundos el tiempo que ha contabilizdo el cronómetro
unsigned long instanteAnterior = 0;     // Variable auxiliar que nos ayudará a calcular el tiempo trancurrido entre cada iteración de loop()
unsigned long instanteActual = 0;       // Variable auxiliar que nos ayudará a calcular el tiempo trancurrido entre cada iteración de loop()
boolean cronometroActivo = false;       // Variable que controla si el cronómetro tiene que contabilizar el tiempo o está parado
...

void loop() {
    instanteAnterior = instanteActual;  // Lo que antes era el instante actual, ahora es el anterior
    instanteActual = millis();          // Averiguamos cual es el instante actual
    if (cronometroActivo) {
        tiempoContabilizado += instanteActual - instanteAnterior;   // Sumamos el tiempo transcurrido desde la vez anterior, para contabilizar el tiempo
        ...     // Aquí haremos las cosas que se tengan que hacer sólo cuando el cronómetre esté contando.
                // Entre otras cosas, poner cronometroActivo a false cuando se deba detener el cronómetro.
    }
    else {
        ...     // Aquí haremos las cosas que se tengan que hacer sólo cuando el cronómetro esté parado.
                // Entre otras cosas, poner cronometroActivo a true cuando se deba reaundar el cronómetro.
    }
    ...     // Aquí haremos lo que se tenga que hacer independientemente de si el cronómetro está contando o no.
}

Los puntos suspensivos es para indicar que ahí va el resto de todo lo que le falta al programa. Esto sólo es el boceto de la idea.

La idea consiste en calcular cuanto tiempo transcurre entre cada ejecución del loop() y sumarlo al "cronómetro" (tiempoContabilizado) cuando esté "en marcha" (cronometroActivo) y descartando ese tiempo cuando esté "parado". Hay que tener en cuenta que el tiempo se mide en milisegundos, con lo que habría que convertirlos en segundos, minutos u horas según sea necesario.

Cuando se desee poner a cero el cronómetro, habría que poner a cero la variable tiempoContabilizado. Para activar o desactivar el cronómetro, habría que poner a true o false la variable cronometroActivo.

Todo esto es suponiendo que lo que quieres es que el cronómetro empiece desde cero y se incremente mientras esté activo. Si lo que quieres es una "cuenta atrás", se puede aplicar la idea base de contabilizar el tiempo transcurrido desde la última iteración del loop() e ir restándolo. Pero no siempre, porque has de restar siempre que tengas tiempo. Hay que tener cuidado, ya que las variables que controlan el tiempo son sin signo (unsigned long) y si ha transcurrido más tiempo del que quedaba, y lo restas, no te va a dar negativo (sino todo lo contrario, un numero muy grande). Debes antes comprobar que el tiempo restante es mayor que el transcurrido y en tal caso restarlo. Si el tiempo restante no es mayor que el transcurrido, es que ya se acabó el tiempo, con lo que el tiempo restante ha de ser cero. Pues has de hacer eso, ponerlo a cero, sin restar nada en ese caso porque entonces puedes "tener problemas". Pero este galimatías (que no lo es tanto) es sólo en el caso de la "cuenta atrás". Si fuera este el caso, lo dices y te pongo el boceto para ello.

lacurvamva

#4
Aug 10, 2017, 06:51 am Last Edit: Aug 10, 2017, 09:53 am by lacurvamva
Buenas noches compañeros primero que nada muchas gracias por comentar ayer no les pude poner el codigo ps no tenia mi pc ala mano se los pongo quiero aclara que esta aplicaion es integrada con nodemcu y la app de blink aqui el codigo con su sugerencia:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include "LedControl.h"
LedControl lc=LedControl(D8,D7,D6,1);  // data in,clk,load,numero de max7219
char auth[] = "2e58c760ec7c4bf292b4bfa6da699f31";
char ssid[] = "iphone6s";
char pass[] = "12345678";



                 //  CRONOMETRO
                 
unsigned long tiempoContabilizado = 0;  // Variable que nos guardará en milisegundos el tiempo que ha contabilizdo el cronómetro
unsigned long instanteAnterior = 0;     // Variable auxiliar que nos ayudará a calcular el tiempo trancurrido entre cada iteración de loop()
unsigned long instanteActual = 0;       // Variable auxiliar que nos ayudará a calcular el tiempo trancurrido entre cada iteración de loop()
boolean cronometroActivo = false;       // Variable que controla si el cronómetro tiene que contabilizar el tiempo o está parado
int m, mu=0,md=0;                           
int s, su=0,sd=0;
int l, lu=0,ld=0,lc1=0;
unsigned long previousMillis = 0;     /// ALARMA
const long interval = 1000;
int ledState = LOW;
int eter=0;

#define LED_BUILTIN 16          // salida alarma

 
  // VARIABLES BLINK
int AD=0;
int AS=0;
int mint=0;



BLYNK_WRITE(V3)  //  CRONOMETRO  RESET
{  AS = param.asInt();
}
BLYNK_WRITE(V4)  //  CRONOMETRO
{
 AD=param.asInt();
}

 BLYNK_WRITE(V5)  //  CRONOMETRO minutos
 {
  mint=param.asInt();
      }

void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  lc.shutdown(0,false);   // Enable display
  lc.setIntensity(0,15);  // Set brightness level (0 is min, 15 is max)
  lc.clearDisplay(0);     // Clear display register
 
}

void loop()
{
  Blynk.run();

   instanteAnterior = instanteActual;  // Lo que antes era el instante actual, ahora es el anterior
    instanteActual = millis();          // Averiguamos cual es el instante actual
    if (AD==1) {
        tiempoContabilizado += instanteActual - instanteAnterior;   // Sumamos el tiempo transcurrido desde la vez anterior, para contabilizar el tiempo
   }
   
   if (AS==1) 
   {
    tiempoContabilizado=0;     /// Poner el cronometro en cero reset
   }

   
       m=(tiempoContabilizado/1000)/60;                 //Calculamos los minutos
      mu=m%10;                            //Descomponemos los minutos y sacamos el valor de las unidades
      md=(m-mu)/10;                       //Descomponemos los minutos y sacamos el valor de las decenas
       
      s=(tiempoContabilizado/1000)%60;                 //Calculamos los segundos
      su=s%10;                            //Descomponemos los segundos y sacamos el valor de las unidades
      sd=(s-su)/10;                       //Descomponemos los segundos y sacamos el valor de las decenas
       
      l=(tiempoContabilizado%1000);                    //Calculamos las milesimas de segundo
      lu=l%10;                            //Descomponemos las milesimas y sacamos el valor de las unidades
      ld=((l-lu)/10)%10;                  //Descomponemos las milesimas y sacamos el valor de las decenas
      lc1=(l-(ld*10)-lu)/100;              //Descomponemos las milesimas y sacamos el valor de las centenas
     
     lc.setDigit(0,5,md,false); //UNIDADES
    lc.setDigit(0,4,mu,ledState); //DECENAS
    lc.setDigit(0,3,sd,false); //UNIDADES
    lc.setDigit(0,2,su,false); //DECENAS


if ( instanteActual - previousMillis >= interval) {
         previousMillis =  instanteActual;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
 }
 if (m==mint)
 {tiempoContabilizado=0;}
       
       

    Serial.println(tiempoContabilizado);
}
 y si me a funcionado solo voy a poner la alarma de fin de tiempo y los marcadores de gol y falta muchas gracias lucari 448 y ignoranteAbsuluto por darme ese empujón y ver que cada cabeza piensa diferente me cerre pero hay va saliendo terminando les enseño el codigo completo para ver que errores tengo o que se puedo simplificar

surbyte

Aporta tu código usando etiquetas (lee las normas) y luego te guiaremos.
Creo haberte pedido que leyeras las normas y usaras etiquetas.
Ahora edita tu post anterior por favor!!!

Go Up