Programación PIC y uso (y no abuso) de delay(milisegundos)

Casi todos, cuando empezamos a programar PIC, tenemos la costumbre de usar la función delay(milisegundos) casi para todo. Hemos de tener en cuenta que esta función detiene la ejecución del programa el tiempo que le digamos.

Tomemos, por ejemplo, un programa que nos muestra la hora, no queremos que en cada iteración del programa nos la muestre, sería terriblemente pesado ver salir muchísimas veces el mismo segundo …. Así que lo que queremos es que nos muestre la hora cada vez que pase un segundo.

Casi todos hemos pensado lo mismo, muestro la hora, espero un segundo y la vuelvo a mostar; y para eso usamos delay():

void loop(){
  Serial.println(dimeFecha());
  delay(1000);
}

Si bien es una solución, no es la mejor. Al llegar a la función delay() el programa se detiene 1 segundo (una eternidad en tiempo de proceso del PIC). Supongamos que tenemos otra parte del programa donde necesitamos la hora para hacer alguna cosa, como el programa se ha detenido 1 segundo nada más poner la hora, el dato de la hora llegará con 1 segundo de retraso a resto del programa. Y eso nos puede dar mucho dolor de cabeza.

Para resolver este problema, voy a proponer dos soluciones: una basada en el uso de la función millis() y otra haciendo uso de la hora devuelta por el propio reloj (que para eso esta ¿no? 😉 ).

Usando millis() tendremos el siguiente código:

long tiempo=0;
void setup(){
}
void loop(){
  if(millis()-tiempo>1000){
    tiempo=millis();
    Serial.println(dimeFecha());
  }
}

¿Qué hace este programa?

  • Establece la variable global tiempo a 0.
  • En el bucle loop() comprueba si los milisegundos transcurridos (millis()) menos el tiempo guardado es mayor a 1000 milisegundos (1 s).
  • En caso que se cumpla la condición, se guarda el valor actual de millis() en la variable tiempo y se muestra la hora.
  • El programa continúa sin detenerse para nada.

Podemos comprobar que es una solución bastante elegante y simple; pero hay algo que debemos tener en cuenta: la función millis() cuenta el tiempo desde que empezó a ejecutarse el programa en ciclos de procesador, es decir, no va sincronizada con el reloj, por lo que al mostrarse la hora llevará un desfase con el tiempo real.

Para solucionar este último inconveniente propongo la solución de usar el propio reloj para mostrar la hora cada segundo, aquí está el código:

int segundos=0;
void setup(){
}
void loop(){
  DateTime ahora;
  ahora=RTC.now();
  if(ahora.second() != segundos){
    segundos=ahora.second();
    Serial.println(dimeFecha());
  }
}

Podemos comprobar que el funcionamiento de este programa es análogo al anterior, pero con la particularidad de que se usa el reloj para controlar cuando se va a imprimir la hora.

Como nota final, comentaros que es muy importante tener en cuenta el uso (o abuso) de la función delay() ya que en la mayoría de los casos un pic nos da la impresión de ir lento y no caemos en la cuenta de que somos nosotros los que estamos haciendo que se pare.

Por otro lado, la función dimeFecha() es esta:

/*
FUNCION PARA OBTENER LA FECHA EN MODO TEXTO
Devuelve: DD-MM-AAAA HH:MM:SS
*/
String dimeFecha(){
  
    char fecha[19];
    DateTime now = RTC.now(); //Obtener fecha y hora actual.

    int dia = now.day();
    int mes = now.month();
    int anio = now.year();
    int hora = now.hour();
    int minuto = now.minute();
    int segundo = now.second();

    sprintf( fecha, "%.2d/%.2d/%.4d %.2d:%.2d:%.2d", dia, mes, anio, hora, minuto, segundo);
    return String( fecha );
}

Hasta el próximo. Espero vuestros comentarios.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: