Lección 2: Segundero

Requerimientos: Haber leído Lección 1.

En esta lección se implementará un “segundero”, es decir un sketch que mostrará inicialmente el número cero, y se irá incrementando a cada segundo. 

Cuando programamos, es muy frecuente tener que almacenar datos en memoria para poder manipularlos y después mostrarlos.

La forma de almacenar un valor, es a través de “variables”. Dichas variables almacenan un valor, que puede ser de distintos tipos, por ejemplo: números, valores booleanos (verdadero o falso), caracteres, cadenas de caracteres, etc.

Para implementar el segundero, tendremos que tener una variable que almacene un número entero, la cual iremos incrementaremos luego de transcurrido cada segundo.

La declaración de dicha variable es la siguiente:

  int segundos;

Utilizamos el tipo int, que representa un valor entero.

Dicha variable debe ser accesible desde las funciones setup() y loop(), por lo debemos declararla de manera global, fuera de ambas funciones.

Su valor inicial debe establecerse una sola vez, por lo que dicha inicialización la haremos en la función setup():

void setup() {

  segundos = 0;
 
}
 

Para mostrar dicho valor inicial en pantalla, usaremos la función print() que ya aprendimos en la lección anterior, pero pasándole la variable segundos como parámetro:

#include <Geobuino.h>
Geobuino geo;
 
int segundos;
 
void setup() {
  segundos = 0;
  geo.begin();
  geo.setCursor(60,30);
  geo.print(segundos);
  geo.updateDisplay();
 
}

void loop() {
 
}
 

Como vemos en el código, antes de imprimir, invocamos a la función setCursor(), para indicar el lugar de la pantalla donde se imprimirá. El primer parámetro de setCursor() corresponde a la posición en el eje x y el segundo al eje y. La esquina superior izquierda de la pantalla corresponde a la posición (0,0). La pantalla de Geobuino es de 128×64 píxeles.

 


Si ejecutamos el código previo en la consola, veremos los siguiente en pantalla:

El paso siguiente es ir incrementando la variable «segundos», y mostrar dicha modificación.

Para ello, escribiremos el siguiente código dentro del método loop(), que como mencionamos en la lección anterior, se ejecuta repetidamente:

void loop() {
  geo.clearDisplay();
  segundos = segundos + 1;
  geo.setCursor(60, 30);
  geo.print(segundos);
  geo.updateDisplay();
 
}
 

Como se aprecia, el código en loop() es muy similar al de setup(), con la diferencia que previamente borramos la pantalla con geo.clearDisplay(), e incrementamos la variable «segundos», antes de imprimir en pantalla.

Si ejecutamos este código, veremos que el incremento del segundero se produce a una velocidad extremadamente alta. Esto sucede porque el microcontrolador de Geobuino se ejecuta las instrucciones a alta velocidad.

Es por eso que debemos limitar la velocidad de ejecución de la función loop(). Esto lo haremos invocando geo.waitFrame().

La función waitFrame() frena la ejecución el tiempo necesario para el loop() se ejecute a una velocidad de 60 veces por segundo (frame rate por defecto de la consola Geobuino).

void loop() {
  geo.waitFrame();
  geo.clearDisplay();
  segundos = segundos + 1;
  geo.setCursor(60, 30);
  geo.print(segundos);
} 

Como se ve, ya no es necesario incovar a updateDisplay(), ya que es invocada dentro de la función waitFrame().

Al ejecutar el sketch vemos que la velocidad del segundero disminuye. Sin embargo se sigue incrementando el valor del segundero a una velocidad mayor que la de un segundo (60 veces por segundo).

La funcíón waitFrame() también se encarga de contabilizar los cuadros(frames) que se van ejecutando. Es por eso que podemos usar una segunda función, llamada framesElapsed() para averiguar en qué momento transcurrieron cierta cantidad de cuadros.

Si invocamos geo.framesElapsed(60), nos va a devolver true (verdadero) cada vez que transcurrieron 60 cuadros. Es bajo esa condición que deberíamos realizar el incremento del segundero e imprimir en pantalla el nuevo valor de la variable “segundos”.

Dicha condición se expresa en C++ y en la mayoría de los lenguajes con la sentencia if

El formato de la sentencia if es la siguiente:

if (una condición es verdadera) {

    //hacer algo

}

Entonces nuestro condición quedaría:

if(geo.framesElapsed(60)){
  geo.clearDisplay();
  segundos = segundos + 1;
  geo.setCursor(60, 30);
  geo.print(segundos);
}
 

El sketch final quedaría asi:

#include <Geobuino.h>
Geobuino geo;
 
int segundos;
 
void setup() {
 segundos = 0;
 geo.begin();
 geo.setCursor( 60,30);
 geo.print(segundos);
 geo.updateDisplay();
 
}
 
void loop() {
  geo.waitFrame();
  if(geo.framesElapsed(60)){
    geo.clearDisplay();
    segundos = segundos + 1;
    geo.setCursor(60, 30);
    geo.print(segundos);
   }
}
 

Si enviamos este sketch a la consola, veremos el segundero actualizándose cada 1 segundo: