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 sensorstruct Sensor {int pin; // Pin del sensorfloat valor; // Valor leídofloat umbral; // Umbral de activaciónbool activado; // Estado de activaciónunsigned 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 structstruct Punto {int x;int y;int z;};void setup() {Serial.begin(9600);// Crear una instancia del structstruct Punto origen;// Acceder a los miembros del structorigen.x = 0;origen.y = 0;origen.z = 0;// Crear e inicializar en una líneastruct Punto destino = { 10, 20, 5 };// Mostrar los valoresSerial.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 sensoresstruct SensorDatos {int pin;float valor;float umbral;bool activado;unsigned long ultimaLectura;};// Crear array de sensoresconst 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 sensoresfor (int i = 0; i < NUM_SENSORES; i++) {pinMode(sensores[i].pin, INPUT);}Serial.println("Sistema de monitoreo inicializado");}void loop() {// Leer todos los sensoresfor (int i = 0; i < NUM_SENSORES; i++) {leerSensor(&sensores[i]); // Pasar dirección del struct}// Mostrar datosmostrarDatosSensores();delay(1000); // Esperar 1 segundo entre lecturas}// Función para leer un sensorvoid leerSensor(struct SensorDatos *sensor) {// Leer valor analógico y convertirlo a voltajesensor->valor = analogRead(sensor->pin) * (5.0 / 1023.0);sensor->ultimaLectura = millis();// Verificar si supera el umbralsensor->activado = (sensor->valor > sensor->umbral);}// Función para mostrar datos de todos los sensoresvoid 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 temporizadorunsigned long duracion = 0; // Duración configurada del temporizador en milisegundos// Inicia el temporizador con una duración específicavoid 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 actualvoid reiniciar() {inicio = millis();}};// -----------------------------------------------------------// Variables globales// -----------------------------------------------------------Temporizador miTemporizador; // Instancia del temporizadorconst 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 salidaSerial.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 serialSerial.print("LED ");Serial.println(estadoLed ? "ENCENDIDO" : "APAGADO");// Reiniciar el temporizador para otros 3 segundosmiTemporizador.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
- Agrupa datos relacionados: Usa structs para mantener juntos los datos que pertenecen a un mismo concepto.
- Pasa por referencia: Cuando pasas structs a funciones, usa referencias o punteros para evitar copiar grandes cantidades de datos.
- Considera el uso de memoria: Los structs grandes pueden consumir mucha memoria, importante en Arduino con recursos limitados.
- Documenta tus structs: Añade comentarios para explicar el propósito de cada miembro del struct.
- 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.
Publicar un comentario