CAB 6. Lenguaje Arduino. Variables y Constantes

6.1 Introducción

Una variable es un objeto, o más estrictamente, un espacio reservado de memoria donde guardamos un valor determinado con el que podemos operar durante la ejecución de un programa o sketch mediante un nombre o etiqueta que asignamos a dicho objeto.

Detallando la definición anterior, tenemos que una variable

  • Tiene un espacio de memoria reservado
  • Posee un nombre o etiqueta para operar con ella
  • Almacena un valor que podemos modificar y consultar
  • Además ese valor es modificable durante la ejecución del programa
  • Debe ser de un tipo de datos soportado por el lenguaje Arduino

Respecto al nombre o etiqueta de la variable se deben cumplir unas normas

  • Tiene que empezar por una letra (mayúscula o minúscula) o el carácter «_»
  • El resto del nombre además puede contener caracteres numéricos
  • No debe contener espacios
  • No puede ser el mismo que una palabra reservada del lenguaje
  • Como recomendaciones
    • No debe ser excesivamente largo
    • Debe ser descriptivo de tal forma que mejore la legibilidad del código.

El lenguaje Arduino diferencia entre mayúsculas y minúsculas en el nombre de las variables, por lo tanto no será la misma variable, por ejemplo codigo_pin que Codigo_pin.

6.2 Declaración, Asignación e Inicialización de Variables

La declaración de una variable supone su creación o más poéticamente su nacimiento.

En esta fase se asigna el tipo de la misma. Veremos los tipos posibles en un punto posterior.

Durante la declaración, además es cuando se asigna un espacio de memoria concreto reservado para dicha variable. Este espacio vendrá definido por el tipo de la misma.

La sintaxis de la declaración de una variable es

tipo nombre_de_la_variable;

Algunos ejemplos serían

string nombre_dispositivo;

int led_PIN;

Una vez que tenemos declarada una variable ya podemos operar con ella, o lo que es lo mismo realizar una asignación, cuya sintaxis sería

nombre_de_la_variable = X;

Con esta operación asignaríamos el valor X a la variable nombre_de_la_variable. Ambos valores deben ser del mismo tipo para no generar un error en el programa.

Un ejemplo de declaración y posterior asignación sería

int led_PIN;      // Declaramos la variable led_PIN del tipo int (entero)

led_PIN = 9;      // Asignamos el valor 9 a la variable led_PIN

Cuando asignamos por primera vez un valor a una variable decimos que la hemos inicializado.

Es decir, la operación de inicializar una variable es asignar el primer valor a una variable después de haberla declarado.

En el ejemplo anterior, al asignar el valor 9 a la variable led_PIN declarada justo anteriormente y al ser la primera vez que le asignamos un valor, este sería su valor de inicialización.

Es necesario, para evitar errores de compilación y comportamientos inesperados en la ejecución del sketch, asignar un valor a toda variable declarada. Es decir, es necesario inicializar una variable.

Por agilidad ambas operaciones se pueden realizar conjuntamente en el lenguaje Arduino.

En el ejemplo siguiente haríamos la declaración e inicialización de la variable en la misma línea

int led_PIN = 9;

Por último, durante la ejecución del programa podemos modificar el valor de las variables.

En el ejemplo siguiente declaramos y asignamos la variable a con un valor 1. En el programa modificamos su valor incrementándolo en 1.

int a = 1;     // Declaramos la variable con el tipo int (entero) y la inicializamos con el valor 1

// Programa
a = a +1;        // Incrementamos el valor de a en 1. En este caso, a tendría ahora el valor 2.

6.3 Variables Locales y Globales

Dependiendo del ámbito de actuación de una variable esta puede ser Local o Global.

6.3.1 Variables Locales

Son las definidas dentro de un bloque o función concreta.

En este caso decimos que el alcance o ámbito de actuación de la variable es Local.

Cuando definimos una variable dentro del código de una función podremos utilizarla dentro de esa función, pero no fuera de ella, pues nos daría un error ya que no estaría definida.

Su uso es Local, por eso está restringido solo a la función donde ha sido declarada.

6.3.2 Variables Globales

Son las definidas fuera de cualquier bloque o función. Generalmente, por legibilidad del código, en la parte de la cabecera del sketch.

En este caso el alcance o ámbito de actuación de la variable es Global.

Una variable Global es visible y puede ser utilizada en cualquier lugar del sketch, ya sea dentro o fuera de funciones.

La experiencia y los buenos hábitos de programación nos enseñarán que debemos definir las mínimas variables globales necesarias y cuando sea estrictamente necesario.

Siempre que podamos debemos definir una variable Local si solo vamos a utilizarla en el ámbito de esa función concreta.

Las variables globales que modificamos dentro y fuera de funciones, cuando el sketch crece y se hace extenso son más difíciles de controlar y pueden provocar errores de funcionamiento que no de compilación, que como veremos son los más difíciles de encontrar y resolver.

6.4 Tipos de Variables

El lenguaje Arduino implementa varios tipos de variables y deberemos elegir el que más se adapte al uso y características de los datos que necesitemos representar.

Como ya hemos mencionado, una variable ocupa un espacio reservado de memoria.

Debemos escoger el tipo de una variable atendiendo al criterio de «mínimo gasto de memoria» necesario para el almacenamiento de los posibles valores que pueda tener la misma durante la ejecución de nuestro sketch, eligiendo el tipo más adecuado.

A continuación vamos a ver los principales tipos de variables utilizados en lenguaje Arduino.

6.4.1 Tipo void

Este tipo es un tanto especial pues podemos considerarlo como el tipo nulo y su uso suele estar restringido a la declaración de funciones cuando queremos indicar que dicha función no devolverá ningún valor al finalizar su ejecución.

Obviamente, como no tenemos que almacenar ningún valor, en este caso no se asigna memoria.

// Ejemplo tipo void

void setup () {
}

6.4.2 Tipo byte

Es el tipo que nos permite utilizar el número entero más pequeño en el lenguaje Arduino.

Se puede utilizar un número entero positivo entre 0 y 255.

Utiliza un espacio en memoria de 1 byte, es decir, 8 bits.

// Ejemplo tipo byte

byte a = 112;

6.4.3 Tipo int

Es el tipo entero más utilizado en la programación con Arduino.

Permite representar números en el rango -32.768 a +32.767.

Ocupa en memoria 2 bytes, osea 16 bits.

// Ejemplo tipo int

int a = -1556;

int b = 28000;

int c = 0;

6.4.4 Tipo unsigned int

Es como el tipo int pero positivo.

Permite valores entre 0 a +65.535.

Es similar al tipo int en ocupación de memoria ya que también utiliza 2 bytes.

// Ejemplo tipo unsigned int

unsigned int a = 48.375;

unsigned int b = 0;

6.4.5 Tipo long

Es un tipo que representa enteros más grandes que el tipo int.

Permite valores entre -2.147.483.648 a +2.147.483.647.

Por lo tanto utiliza 4 bytes, es decir, 32 bits de memora RAM.

// Ejemplo tipo long

long a = 345678;

long b = -456876;

6.4.6 Tipo unsigned long

Es similar al tipo long pero solo con valores positivos.

Pueden ser números comprendidos entre 0 hasta 4.294.967.295.

De igual modo que long, utiliza 32 bits de memoria.

// Ejemplo tipo unsigned long

unsigned long a = 3333456;

6.4.7 Tipo float

Permite operar con datos en punto flotante, es decir, nos permite representar valores numéricos decimales con precisión de 6 a 7 decimales.

Podemos utilizar valores entre -3.4028235E+38 hasta 3.4028235E+38.

Emplea 32 bits de RAM.

Es un tipo de variable lenta para operar, por lo tanto deberemos utilizarlo lo mínimo posible y cuando sea estrictamente necesario.

// Ejemplo tipo float

float a = 3.14159;

6.4.8 Tipo boolean

Es el tipo de datos que menor uso de memoria, solo 1 bit.

Permite representar valores buleanos, de VERDADERO y FALSO, aunque su codificación en memoria será 1 para VERDADERO y 0 para FALSO.

Muy utilizado en estructuras condicionales dentro de bucles, como ya veremos en el siguiente capítulo del curso.

// Ejemplo tipo boolean

boolean terminar = false;

6.4.9 Tipo char

Permite representar un carácter alfanumérico, por eso suele ser conocido como tipo carácter.

Internamente se almacena con un valor entre -128 y +127.

Se codifica según la tabla ASCII.

Podemos utilizar el propio carácter alfanumérico entre apóstrofes o mediante su código ASCII, como podemos ver en el ejemplo.

// Ejemplo tipo char

char letra_a = 'A';

char ASCII_letra_a = 65;

6.4.10 Tipo string

Es el tipo denominado cadena de caracteres y permite almacenar un conjunto de caracteres.

Este tipo de datos se puede representar como

  • Tabla de caracteres y se denota por string (todas las letras en minúsculas).
  • Clase String (con mayúsculas la letra S).

Es un tipo especial que nos permite diversas operaciones. Por ello, lo veremos con más profundidad en un capítulo posterior.

// Ejemplo tipo string

string dia_semana = "Lunes";

6.5 Modificadores

Cuando realizamos la declaración de las variables, podemos anteponer ciertos modificadores o cualificadores (qualifier), que son palabras reservadas del lenguaje Arduino, que cualifican o modifican el comportamiento de las mismas.

Estos modificadores son

6.5.1 Modificador static

Cuando anteponemos el modificador static en la declaración de la variable:

  • Indicamos que esta variable es solo visible en la función en la que esta declarada, es decir, tiene ámbito local
  • Que su valor deber perdurar o persistir entre diferentes llamadas a dicha función

Un ejemplo de declaración de una variable con el modificador static sería

static int codigo_color = 255;

En el caso anterior, si se tratara de una variable de una función, la primera vez que llamamos a la función se declara e inicializa la variable codigo_color.

En las siguientes llamadas a dicha función no se inicializará de nuevo.

Además el valor se conservará con el último valor que tenía dicha variable cuando finalizó la función en nuestra anterior llamada a la misma.

6.5.2 Modificador volatile

Este modificador, realmente es una directiva del compilador.

Es propio del lenguaje Arduino.

Con este modificador indicamos a Arduino que el compilador cargue la variable de la memoria RAM en lugar de los registros del microprocesador, que son ubicaciones de memoria temporal en las que se almacenan y manipulan las variables del programa consiguiendo de esta forma más velocidad en la ejecución.

Es decir, realmente le estamos indicando a Arduino que no queremos optimizar el uso de la variable o que en ciertas condiciones específicas el valor de la variable almacenada en los registros puede ser incorrecto. Son situaciones especiales, que veremos con más detalle más adelante.

Un ejemplo de declaración de una variable con el modificador volatile es

volatile int estado = 3;

6.5.3 Modificador const

Al anteponer el modificador const convertimos la variable en una constante y por lo tanto ya no podremos modificar el valor de la misma.

En caso de intentar modificar una variable modificada o cualificada con const recibiremos un error de compilación.

Un ejemplo de una variable con el modificador const sería

const float pi = 3.14;

6.6 Constantes

Las constantes son lo contrario a las variables, en el sentido de que cuando asignamos un valor a una constante ya no puede modificarse durante la ejecución del sketch.

Las constantes se suelen utilizar para fines diversos en la programación de Arduino, pero los dos objetivos principales son:

  • Agilizar la programación
  • Mejorar la legibilidad del código

Ejemplo

Veremos mejor el uso y la utilidad de las constante con un ejemplo.

Si conectamos un led al pin 10 de Arduino, podríamos referirnos a lo largo del sketck siempre con el número 10 para identificar el pin con el que estamos operando con el led.

Sin embargo resulta más legible definir

const int led_pin = 10;

en la cabecera del programa y así podemos referirnos con este nombre a lo largo del código sin tener que recordar cual era el número para operar con el led.

Puedes ver un ejemplo, mas detallado, de su uso y funcionamiento en el Proyecto PB2.

El código de dicho Proyecto lo ponemos a continuación, a modo de ejemplo.

Como puedes observar el uso de las constantes definidas al principio del Sketch clarifica la lectura del código.

// -------------------------------------------------------------
//  Proyecto:   PB2 - Semáforo Arduino con Pulsador
//  Autor:      LabRob (Jose Delgado)
//  Fecha:      Octubre 2019
//  Explicacion:
//              Enceder secuencialmente un led rojo, led
//              amarillo y led verde conforme presionemos
//              un pulsador.              
// -------------------------------------------------------------
 
// ================================================
// Declaraciones, Constantes, Variables ...
// ================================================
const int led_rojo_PIN = 9;       // Asignamos a la constante led_rojo_PIN el valor 9
const int led_amarillo_PIN = 10;  // Asignamos a la constante led_amarillo_PIN el valor 10
const int led_verde_PIN = 11;     // Asignamos a la constante led_verde_PIN el valor 11
 
const int pulsador_PIN = 2;       // Asignamos a la constante pulsador_PIN el valor 4
 
int led_encendido = 0;            // 0 Led Encendido --> Ninguno
                                  // 1 Led Encendido --> Rojo
                                  // 2 Led Encendido --> Amarillo
                                  // 3 Led Encendido --> Verde
 
// ================================================
// Modulo Inicializacion y Configuracion
// ================================================
void setup()
{
  pinMode(led_rojo_PIN , OUTPUT);     // Definimos el PIN del Led Rojo como SALIDA
  pinMode(led_amarillo_PIN , OUTPUT); // Definimos el PIN del Led Amarillo como SALIDA
  pinMode(led_verde_PIN , OUTPUT);    // Definimos el PIN del Led Verde como SALIDA
 
  digitalWrite(led_rojo_PIN, LOW);    // Inicialmente apagamos todos los leds
  digitalWrite(led_amarillo_PIN, LOW);
  digitalWrite(led_verde_PIN, LOW);
   
  pinMode(pulsador_PIN, INPUT);       // Definimos el PIN del Pulsador como ENTRADA
}
 
// ================================================
// Bucle Programa
// ================================================                 
void loop()
{
  while (digitalRead(pulsador_PIN) == LOW);  // No hacemos nada mientras no se presiona el Pulsador
   
  // Hemos llegado aqui porque se ha presionado el Pulsador
  // Asignamos el Led que le toca encenderse de forma secuencial y cíclica
  // Si el Led encendido es el Verde (3) pasamos a encender el Rojo (1)
  if (led_encendido == 3){
    led_encendido = 1;
  }
  else{
    led_encendido = led_encendido + 1;
  }
 
  // Encendemos el Led Rojo y apagamos el Amarillo y el Verde
  if (led_encendido == 1) {
    digitalWrite(led_rojo_PIN, HIGH);  
    digitalWrite(led_amarillo_PIN, LOW);
    digitalWrite(led_verde_PIN, LOW);   
  }
 
  // Encendemos el Led Amarillo y apagamos el Rojo y el Verde
  if (led_encendido == 2) {
    digitalWrite(led_rojo_PIN, LOW);   
    digitalWrite(led_amarillo_PIN, HIGH);
    digitalWrite(led_verde_PIN, LOW);  
  }
 
  // Encendemos el Led Verde y apagamos el Rojo y el Amarillo
  if (led_encendido == 3) {
    digitalWrite(led_rojo_PIN, LOW);   
    digitalWrite(led_amarillo_PIN, LOW);
    digitalWrite(led_verde_PIN, HIGH);  
  }
   
  while (digitalRead(pulsador_PIN) == HIGH);   // Si el Pulsador sigue presionado no continuamos
                                               // Cuando el Pulsador no está presionado seguimos con el Bucle Pincipal
}

Resulta mucho más fácil y el código es más legible al referirnos en el programa con el nombre led_amarillo_PIN que recordar que el PIN de la placa Arduino que hemos asignado al led amarillo es el número 10.

Con la práctica, descubrirás lo útiles que resultan las constantes en la programación.

Cabe destacar, que como hemos visto con anterioridad, una constante podremos definirla tanto con la palabra reservada del lenguaje Arduino #define como con la instrucción const. En general, es más habitual el uso de const para definir las constantes.

6.7 Constantes Especiales

En el lenguaje Arduino podemos encontrar algunas constantes que ya están definidas y que son específicas del lenguaje.

Estas constantes suelen utilizarse para configurar y controlar los pines o conectores de entrada y salida de las tarjetas Arduino.

HIGH , LOW

Se utilizan con los conectores digitales.

Permiten representar los valores que pueden adquirir estos conectores.

Si el conector está en modo lectura

  • HIGH representa un valor de tensión superior a 3v
  • LOW un valor inferior a 1,5v

Si el conector está en modo escritura

  • HIGH significa que el microcontrolador debe proporcionar un valor de 5v
  • LOW que debe asignar 0v

OUTPUT , INPUT

Estas constantes permiten determinar y configurar el modo en el que debe funcionar un conector.

Con OUTPUT le indicamos que funcione en modo lectura.

Mientras que con INPUT el conector estará configurado en modo escritura.

6.8 Operaciones con Variables

A continuación vamos a ver brevemente las principales operaciones que podemos realizar con las variables, agrupadas en tres tipos

  • Operaciones Matemáticas
  • Operaciones Lógicas
  • Operaciones Trigonométricas

6.8.1 Operaciones Matemáticas

Son las más habituales y empleadas en la programación.

  • Suma, se suma el valor de a más el valor de b. Su sintaxis es a + b
  • Resta, se resta el valor de a menos el valor de b. Su sintaxis es a – b
  • División, se divide el valor de a entre el valor de b. Su sintaxis es a / b
  • Multiplicación, se multiplica el valor de a por el valor de b. Su sintaxis es a * b
  • Asignación, se asigna el valor de la variable b a la variable a. Su sintaxis es a = b
  • Valor absoluto, devuelve la parte positiva de un número a. Su sintaxis es int valor_absoluto = abs(a)
  • Módulo, devuelve el resto de una división entera entre a y b. Su sintaxis es int modulo = a % b

6.8.2 Operaciones Lógicas

Son operaciones entre expresiones lógicas, que son la esencia del lenguaje informático.

Una expresión lógica es una expresión que tiene uno de los dos valores posibles: verdadero o falso, es decir, 1 o 0.

Una operación lógica dará como resultado una expresión lógica.

  • Operación Lógica Y, realiza la operación lógica Y entre dos expresiones lógicas A , B. Su sintaxis es A && B
  • Operación Lógica O, realiza la operación lógica O entre dos expresiones lógicas A , B. Su sintaxis es A || B
  • Operación Lógica Comparación, realiza la operación lógica de Comparación o Igualdad entre dos expresiones lógicas A , B. Su sintaxis es A == B

La operación lógica de comparación o igualdad es una de la más utilizada en los programas, sobre todo en las condiciones en las estructuras de control.

No debemos confundir la operación de asignación = y la operación lógica de comparación o igualdad ==

6.8.3 Operaciones Trigonométricas

Estas operaciones permiten realizar cálculos de ángulos y orientación.

Son muy utilizadas en robótica.

  • Coseno. Calcula el coseno de un ángulo en radianes. Su sintaxis es float X = cos (ángulo)
  • Seno. Calcula el seno de un ángulo en radianes. Su sintaxis es float X = sin(ángulo)
  • Tangente. Calcula la tangente de un ángulo en radianes. Su sintaxis es double X = tan(ángulo)

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies