2.5 Ámbito de las variables

2.5.1 Variables locales y globales

En todos los lenguajes estructurados como el del Arduino las variables tienen una propiedad llamada “ámbito” (“scope” en inglés). Esta propiedad se refiere al hecho de que el valor de la variable puede ser accedido o no en unas partes del sketch  según cómo y dónde esta variable haya sido definida.

Aquellas variables que hayan sido definidas fuera de las funciones setup y loop (veremos que representan estas funciones más tarde cuando hablemos de las funciones y las estructuras) se denominan variables globales y su valor puede ser accedido desde cualquier punto del programa o sketch.

Por el contrario, aquellas variables definidas dentro de una función se llaman variables locales y tienen un ámbito (scope) local: sus valores son accesibles solamente desde dentro de la función en la que han sido declaradas.

El siguiente sketch muestra el uso de variables globales y locales:

int pinNoLedGlobal = 12;     (pinNoLedGlobal definida como variable global)
void Setup       {
       pinMode(pinNoLedGlobal, OUTPUT);
}
void loop         {
       int pinNoLedLocal =13;   //pinNoLedLocal definida como variable local dentro de loop        pinMode(pinNoLedLocal, OUTPUT);
       digitalWrite(pinNoLedGlobal, HIGH);
       digitalWrite(pinNoLedLocal, LOW);
}

A medida que tus programas (sketches) crecen en tamaño y complejidad, el uso de variables locales es aconsejado porque evita confusiones entre variables con el mismo nombre.

En este punto podéis preguntaros que sucede con el ámbito de las variables en el caso de variables declaradas dentro de funciones anidadas (una función llamada desde otra función, que a su vez ha sido llamada desde otra función). Lógicamente, él ámbito de aquellas variables definidas en las funciones exteriores se extiende a las funciones interiores, pero no viceversa.

La siguiente figura ilustra este concepto:

disponibilidad de una variable

El valor de la variable “varA” puede ser accedido desde las funciones “funciónA”, “funciónB” y “funciónC” es decir, es una variable global. En cambio las variables “varB” y “varC” son variables locales. El valor de la variable “varB” sólo puede ser accedido desde las funciones   “funciónB” y “funciónC”, mientras que la variable local “varC” sólo puede ser leída desde la función “funciónC”.

 

2.5.2 Variables estáticas

La palabra reservada (keyword) “static” se usa para crear variables que son visibles únicamente para una function. La diferencia con las variables locales es que éstas son creadas y destruidas cada vez que se llama a una función. Las variables definidas como “static” persisten cuando la function ha terminado y conservan los datos almacenados en ellas disponibles para la próxima vez que se llame a esa función. Estas variables se crean e inicializan solamente la primera vez que la función que las crea es llamada.

Ejemplo:

/* RandomWalk
* Paul Badger 2007
* RandomWalk wanders up and down randomly between two
* endpoints. The maximum move in one loop is governed by
* the parameter "stepsize".
* A static variable is moved up and down a random amount.
* This technique is also known as "pink noise" and "drunken walk".
*/
#define randomWalkLowRange -20
#define randomWalkHighRange 20
int stepsize;

int thisTime;
int total;

void setup()
{  Serial.begin(9600);
}

void loop()
{        //  tetst randomWalk function
     stepsize = 5; 
     thisTime = randomWalk(stepsize);
     Serial.println(thisTime);
     delay(10);
}

int randomWalk(int moveSize){
  static int  place;     // variable to store value in random walk - declared static so that it stores
                         // values in between function calls, but no other functions can change its value
  place = place + (random(-moveSize, moveSize + 1));
  if (place < randomWalkLowRange)
   {  // check lower and upper limits
      place = place + (randomWalkLowRange - place); // reflect number back in positive direction
   }
  else if(place > randomWalkHighRange){
        place = place - (place - randomWalkHighRange);     // reflect number back in negative direction
  }
return place;
}

2.5.3 Variables volátiles

Cuando declaramos una variable como “volatile” lo que estamos haciendo es instruyendo al compilador a cargar siempre la variable desde la memoria RAM y no desde uno de los registros internos del procesador.

La razón por la que hacemos esto es que, bajo ciertas condiciones, el valor de una variable almacenada en los registros internos puede sufrir alteraciones. En Arduino el único sitio en el que esto puede suceder es en las las partes de código asociado con interrupciones (interrup service routines).

Ejemplo

// conmuta un LED cuando el pin de interrupción cambia de estado
int pin = 13;
volatile int state = LOW;
void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{  state = !state;
}