Inicio / Arduino

Estructura de un programa para Arduino

Los programas de Arduino se escriben en lenguaje C++ adaptado, y todos comparten el mismo esqueleto: dos funciones obligatorias, setup() y loop(). Entender qué hace cada una es lo primero, porque todo lo demás se construye encima.

El esqueleto mínimo

Este es el programa más pequeño que compila y se sube a la placa. No hace nada, pero es válido:

Arduino / C++
void setup() {
}

void loop() {
}
FunciónCuándo se ejecutaPara qué sirve
setup() Una sola vez, al arrancar Configurar pines, iniciar el puerto serie, dejar el estado inicial
loop() Sin parar, en bucle La lógica del programa: leer sensores, activar salidas, decidir

Cómo funciona

setup() se ejecuta una sola vez al encender o reiniciar la placa. Ahí se configuran los pines con pinMode(), se inicializa la comunicación serie y se deja todo en su estado de partida.

loop() arranca en cuanto termina setup() y se repite indefinidamente mientras la placa tenga alimentación. Cuando llega al final vuelve a empezar por el principio, sin pausa.

Las dos funciones deben estar presentes aunque estén vacías. El sistema de Arduino las llama siempre, así que si falta alguna el programa no compila.

Un programa completo, por partes

En cuanto el proyecto crece, aparecen otras secciones. Este es el orden habitual, y es el que siguen todos los ejemplos de la serie:

Arduino / C++
// 1. Librerías externas
#include <LiquidCrystal.h>

// 2. Constantes: los pines que usa el montaje
const int LED    = 13;
const int BOTON  = A2;

// 3. Variables globales: el estado que hay que recordar
int contador = 0;

// 4. Configuración inicial, una sola vez
void setup() {
  pinMode(LED, OUTPUT);
  pinMode(BOTON, INPUT_PULLUP);
}

// 5. El bucle principal, para siempre
void loop() {
  if (digitalRead(BOTON) == LOW) {
    contador++;
    parpadear();
    delay(200);
  }
}

// 6. Funciones propias, para no repetir código
void parpadear() {
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
}
SecciónQué va ahí
Librerías#include de código externo, como el del LCD o el TM1637
ConstantesNúmeros que no cambian: los pines. Con const para no tocarlos por error
Variables globalesValores que deben sobrevivir de una vuelta del bucle a la siguiente
setup()Todo lo que se prepara una vez
loop()La lógica que se repite
Funciones propiasBloques con nombre que se llaman desde loop()

El bucle corre mucho más rápido de lo que parece

Sin ninguna espera de por medio, loop() se ejecuta miles de veces por segundo. Por eso un botón pulsado durante un instante se lee como muchísimas pulsaciones seguidas.

Es la razón de que en los ejemplos aparezca un delay(200) después de cada pulsación, o de que haga falta guardar el estado anterior del botón para detectar solo el momento del cambio.

Por qué las variables van fuera del bucle

Una variable declarada dentro de loop() se crea y se destruye en cada vuelta, así que pierde su valor constantemente. Si el programa necesita recordar algo entre una vuelta y la siguiente —un contador, un color, si el LED está encendido— la variable tiene que declararse fuera, arriba del todo.

Arduino / C++
int contador = 0;      // Global: conserva su valor

void loop() {
  int temporal = 0;    // Local: vuelve a 0 en cada vuelta

  contador++;          // 1, 2, 3, 4...
  temporal++;          // siempre 1
}

Con solo setup() y loop() ya se puede hacer parpadear un LED, leer un botón o controlar un buzzer. Todo lo demás son variaciones sobre este mismo esqueleto.