▷ Structs en Arduino: Organización de Datos para Proyectos Eficientes

Los structs (estructuras) son una herramienta fundamental en programación que te permite agrupar variables relacionadas bajo un mismo nombre. En Arduino, los structs son especialmente útiles para organizar datos de sensores, configuraciones y estados de manera lógica y eficiente.

¿Qué es un Struct?

Un struct es un tipo de dato personalizado que agrupa varias variables relacionadas, posiblemente de diferentes tipos, bajo un único nombre. Piensa en él como una "caja" que contiene información relacionada.

Definición básica de un Struct

// Definir un struct para representar un sensor
struct Sensor {
  int pin;                      // Pin del sensor
  float valor;                  // Valor leído
  float umbral;                 // Umbral de activación
  bool activado;                // Estado de activación
  unsigned long ultimaLectura;  // Tiempo de la última lectura
};

Ventajas de usar Structs en Arduino

  • Organización: Agrupa datos relacionados de manera lógica
  • Legibilidad: El código se vuelve más claro y comprensible
  • Mantenibilidad: Es más fácil modificar y extender el código
  • Paso de datos: Puedes pasar grupos de datos completos a funciones
  • Reutilización: Puedes crear múltiples instancias de la misma estructura

Cómo usar Structs en Arduino

Declaración y uso de Structs

// Definir el struct
struct Punto {
  int x;
  int y;
  int z;
};

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

  // Crear una instancia del struct
  struct Punto origen;

  // Acceder a los miembros del struct
  origen.x = 0;
  origen.y = 0;
  origen.z = 0;

  // Crear e inicializar en una línea
  struct Punto destino = { 10, 20, 5 };

  // Mostrar los valores
  Serial.print("Origen: ");
  Serial.print(origen.x);
  Serial.print(", ");
  Serial.print(origen.y);
  Serial.print(", ");
  Serial.println(origen.z);

  Serial.print("Destino: ");
  Serial.print(destino.x);
  Serial.print(", ");
  Serial.print(destino.y);
  Serial.print(", ");
  Serial.println(destino.z);
}

void loop() {
  // El loop puede estar vacío para este ejemplo
}

Ejemplo Práctico: Sistema de Monitoreo con Múltiples Sensores

Gestión de múltiples sensores usando Structs

// Definir un struct para los sensores
struct SensorDatos {
  int pin;
  float valor;
  float umbral;
  bool activado;
  unsigned long ultimaLectura;
};

// Crear array de sensores
const int NUM_SENSORES = 3;
struct SensorDatos sensores[NUM_SENSORES] = {
  { A0, 0.0, 2.5, false, 0 },  // Sensor 0
  { A1, 0.0, 3.0, false, 0 },  // Sensor 1
  { A2, 0.0, 2.0, false, 0 }   // Sensor 2
};

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

  // Configurar pines de los sensores
  for (int i = 0; i < NUM_SENSORES; i++) {
    pinMode(sensores[i].pin, INPUT);
  }

  Serial.println("Sistema de monitoreo inicializado");
}

void loop() {
  // Leer todos los sensores
  for (int i = 0; i < NUM_SENSORES; i++) {
    leerSensor(&sensores[i]);  // Pasar dirección del struct
  }

  // Mostrar datos
  mostrarDatosSensores();

  delay(1000);  // Esperar 1 segundo entre lecturas
}

// Función para leer un sensor
void leerSensor(struct SensorDatos *sensor) {
  // Leer valor analógico y convertirlo a voltaje
  sensor->valor = analogRead(sensor->pin) * (5.0 / 1023.0);
  sensor->ultimaLectura = millis();

  // Verificar si supera el umbral
  sensor->activado = (sensor->valor > sensor->umbral);
}

// Función para mostrar datos de todos los sensores
void mostrarDatosSensores() {
  Serial.println("=== DATOS DE SENSORES ===");

  for (int i = 0; i < NUM_SENSORES; i++) {
    Serial.print("Sensor ");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(sensores[i].valor);
    Serial.print("V - ");

    if (sensores[i].activado) {
      Serial.println("ACTIVADO");
    } else {
      Serial.println("Inactivo");
    }
  }

  Serial.println();
}

Structs con Funciones Miembro

En C++ (y por lo tanto en Arduino), los structs pueden tener funciones miembro, similar a las clases:

Struct con funciones miembro

// -----------------------------------------------------------
// Estructura que define un temporizador simple basado en millis()
// -----------------------------------------------------------
struct Temporizador {
  unsigned long inicio = 0;    // Guarda el tiempo en que se inició el temporizador
  unsigned long duracion = 0;  // Duración configurada del temporizador en milisegundos

  // Inicia el temporizador con una duración específica
  void comenzar(unsigned long tiempoDuracion) {
    inicio = millis();
    duracion = tiempoDuracion;
  }

  // Verifica si el temporizador ya terminó
  bool haTerminado() const {
    return (millis() - inicio) >= duracion;
  }

  // Reinicia el temporizador desde el tiempo actual
  void reiniciar() {
    inicio = millis();
  }
};

// -----------------------------------------------------------
// Variables globales
// -----------------------------------------------------------
Temporizador miTemporizador;    // Instancia del temporizador
const int ledPin = 13;          // Pin donde está conectado el LED (pin 13 en Arduino UNO)
bool estadoLed = false;         // Estado actual del LED (false = apagado, true = encendido)

// -----------------------------------------------------------
// Configuración inicial (se ejecuta una vez al inicio)
// -----------------------------------------------------------
void setup() {
  pinMode(ledPin, OUTPUT);      // Configurar el pin del LED como salida
  Serial.begin(9600);           // Iniciar comunicación serial a 9600 baudios

  // Iniciar el temporizador con duración de 3000 ms (3 segundos)
  miTemporizador.comenzar(3000);
  Serial.println("Temporizador iniciado para parpadeo del LED");
}

// -----------------------------------------------------------
// Bucle principal (se ejecuta repetidamente)
// -----------------------------------------------------------
void loop() {
  // Si el temporizador terminó (pasaron 3 segundos)
  if (miTemporizador.haTerminado()) {
    // Cambiar el estado del LED (si estaba apagado se enciende, y viceversa)
    estadoLed = !estadoLed;
    digitalWrite(ledPin, estadoLed);

    // Mostrar el nuevo estado en el monitor serial
    Serial.print("LED ");
    Serial.println(estadoLed ? "ENCENDIDO" : "APAGADO");

    // Reiniciar el temporizador para otros 3 segundos
    miTemporizador.reiniciar();
  }

  // Nota:
  // Aquí se podrían ejecutar otras tareas sin que el temporizador bloquee
  // Por ejemplo: leer sensores, escuchar botones, manejar comunicación, etc.
}

Diferencias entre Structs y Clases

En C++, los structs y las clases son muy similares, pero tienen algunas diferencias clave:

Característica Struct Clase
Acceso por defecto Público (public) Privado (private)
Uso típico Estructuras de datos simples Objetos con comportamiento complejo
Herencia Sí (pero no se recomienda) Sí (diseñado para ello)
Polimorfismo Posible pero no común Diseñado para ello

💡 Consejo: Usa structs para agrupar datos relacionados y clases cuando necesites encapsulación fuerte, herencia o polimorfismo. En Arduino, los structs son perfectos para organizar datos de configuración, estados y lecturas de sensores.

Consejos para usar Structs en Arduino

  1. Agrupa datos relacionados: Usa structs para mantener juntos los datos que pertenecen a un mismo concepto.
  2. Pasa por referencia: Cuando pasas structs a funciones, usa referencias o punteros para evitar copiar grandes cantidades de datos.
  3. Considera el uso de memoria: Los structs grandes pueden consumir mucha memoria, importante en Arduino con recursos limitados.
  4. Documenta tus structs: Añade comentarios para explicar el propósito de cada miembro del struct.
  5. Usa arrays de structs: Para manejar múltiples instancias del mismo tipo de datos (como múltiples sensores).

Conclusión

Los structs son una herramienta poderosa en Arduino para organizar datos de manera lógica y eficiente. Te permiten agrupar variables relacionadas, mejorar la legibilidad del código y simplificar el paso de datos entre funciones.

Ya sea que estés trabajando con múltiples sensores, gestionando configuraciones complejas o simplemente organizando datos relacionados, los structs pueden hacer que tu código sea más claro, mantenible y eficiente.

0/Post a Comment/Comments