Arrays Claude C++ Arduino
Estructuras de Datos en Arduino: Arrays para Smart Cities
1. Introducción a los Arrays
Un array (o arreglo) es una colección de variables del mismo tipo almacenadas en posiciones de memoria contiguas. En el contexto de Smart Cities, los arrays son fundamentales para:
- Almacenar lecturas históricas de sensores (temperatura, humedad, calidad del aire)
- Gestionar múltiples dispositivos (semáforos, farolas, sensores de aparcamiento)
- Procesar datos antes de enviarlos a la nube
2. Declaración y Tipos de Arrays
2.1. Array unidimensional
// Declaración con tamaño fijo
int lecturas[10]; // Array de 10 enteros
// Declaración con inicialización
int temperaturas[5] = {22, 24, 23, 25, 21};
// El compilador deduce el tamaño
float humedad[] = {65.5, 70.2, 68.0, 72.1}; // Array de 4 elementos
2.2. Acceso a elementos
Los índices empiezan en 0:
int valores[4] = {10, 20, 30, 40};
int primero = valores[0]; // 10
int tercero = valores[2]; // 30
valores[1] = 25; // Modifica el segundo elemento
2.3. Constantes para tamaños
Buena práctica para evitar errores:
const int NUM_SENSORES = 5;
int lecturas[NUM_SENSORES];
3. Operaciones Comunes con Arrays
3.1. Recorrer un array
const int TAMANO = 6;
int datos[TAMANO] = {12, 45, 23, 67, 34, 89};
void setup() {
Serial.begin(9600);
// Recorrido con for
for (int i = 0; i < TAMANO; i++) {
Serial.print("Elemento ");
Serial.print(i);
Serial.print(": ");
Serial.println(datos[i]);
}
}
void loop() {
}
3.2. Calcular media aritmética
Aplicación típica: promedio de lecturas de sensor para filtrar ruido.
const int NUM_LECTURAS = 10;
int lecturas[NUM_LECTURAS];
float calcularMedia(int arr[], int tamano) {
long suma = 0; // long para evitar desbordamiento
for (int i = 0; i < tamano; i++) {
suma += arr[i];
}
return (float)suma / tamano;
}
3.3. Encontrar máximo y mínimo
int encontrarMaximo(int arr[], int tamano) {
int maximo = arr[0];
for (int i = 1; i < tamano; i++) {
if (arr[i] > maximo) {
maximo = arr[i];
}
}
return maximo;
}
int encontrarMinimo(int arr[], int tamano) {
int minimo = arr[0];
for (int i = 1; i < tamano; i++) {
if (arr[i] < minimo) {
minimo = arr[i];
}
}
return minimo;
}
4. Buffer Circular (Concepto Avanzado Simplificado)
En Smart Cities, necesitamos almacenar las últimas N lecturas sin llenar la memoria. Un buffer circular sobrescribe los datos más antiguos:
const int TAMANO_BUFFER = 5;
int buffer[TAMANO_BUFFER];
int indice = 0;
void agregarLectura(int nuevaLectura) {
buffer[indice] = nuevaLectura;
indice = (indice + 1) % TAMANO_BUFFER; // Vuelve a 0 tras llegar al final
}
El operador módulo (%) hace que el índice “dé la vuelta”:
- Si
indice = 4yTAMANO_BUFFER = 5:(4 + 1) % 5 = 0
5. Ejercicios Prácticos
Ejercicio 1: Monitor de temperatura con histórico
Objetivo: Leer temperatura cada 2 segundos, almacenar las últimas 10 lecturas y mostrar estadísticas.
Componentes:
- Sensor de temperatura LM35 o TMP36
- Arduino UNO
Circuito: Sensor conectado a pin A0, VCC a 5V, GND a GND.
const int PIN_SENSOR = A0;
const int NUM_LECTURAS = 10;
float temperaturas[NUM_LECTURAS];
int indiceLectura = 0;
bool bufferLleno = false;
void setup() {
Serial.begin(9600);
Serial.println("=== Monitor de Temperatura Smart City ===");
Serial.println("Recopilando datos...\n");
}
void loop() {
// Leer sensor (TMP36: 10mV/°C, offset 500mV)
int valorADC = analogRead(PIN_SENSOR);
float voltaje = valorADC * (5.0 / 1023.0);
float temperatura = (voltaje - 0.5) * 100.0;
// Almacenar en el array
temperaturas[indiceLectura] = temperatura;
indiceLectura++;
// Verificar si el buffer está lleno
if (indiceLectura >= NUM_LECTURAS) {
indiceLectura = 0;
bufferLleno = true;
}
// Mostrar lectura actual
Serial.print("Lectura actual: ");
Serial.print(temperatura, 1);
Serial.println(" °C");
// Si tenemos suficientes datos, mostrar estadísticas
if (bufferLleno) {
mostrarEstadisticas();
}
delay(2000);
}
void mostrarEstadisticas() {
float suma = 0;
float maximo = temperaturas[0];
float minimo = temperaturas[0];
for (int i = 0; i < NUM_LECTURAS; i++) {
suma += temperaturas[i];
if (temperaturas[i] > maximo) {
maximo = temperaturas[i];
}
if (temperaturas[i] < minimo) {
minimo = temperaturas[i];
}
}
float media = suma / NUM_LECTURAS;
Serial.println("--- Estadísticas (últimas 10 lecturas) ---");
Serial.print("Media: ");
Serial.print(media, 1);
Serial.println(" °C");
Serial.print("Máxima: ");
Serial.print(maximo, 1);
Serial.println(" °C");
Serial.print("Mínima: ");
Serial.print(minimo, 1);
Serial.println(" °C");
Serial.println();
}
Ejercicio 2: Sistema de semáforo múltiple
Objetivo: Controlar 3 semáforos usando arrays para sus pines y tiempos.
Componentes:
- 9 LEDs (3 rojos, 3 amarillos, 3 verdes)
- 9 resistencias de 220Ω
// Arrays para organizar los pines de cada semáforo
const int NUM_SEMAFOROS = 3;
// Cada fila: {rojo, amarillo, verde}
int pinesSemaforos[NUM_SEMAFOROS][3] = {
{2, 3, 4}, // Semáforo 1
{5, 6, 7}, // Semáforo 2
{8, 9, 10} // Semáforo 3
};
// Tiempos en milisegundos para cada fase
int tiempos[3] = {5000, 1500, 4000}; // Rojo, Amarillo, Verde
void setup() {
Serial.begin(9600);
// Configurar todos los pines como salida
for (int semaforo = 0; semaforo < NUM_SEMAFOROS; semaforo++) {
for (int led = 0; led < 3; led++) {
pinMode(pinesSemaforos[semaforo][led], OUTPUT);
}
}
Serial.println("Sistema de semáforos iniciado");
}
void loop() {
// Ciclo para cada semáforo
for (int activo = 0; activo < NUM_SEMAFOROS; activo++) {
ejecutarCicloSemaforo(activo);
}
}
void ejecutarCicloSemaforo(int semaforoActivo) {
Serial.print("Semáforo ");
Serial.print(semaforoActivo + 1);
Serial.println(" en VERDE");
// El semáforo activo en verde, los demás en rojo
for (int s = 0; s < NUM_SEMAFOROS; s++) {
if (s == semaforoActivo) {
encenderLed(s, 2); // Verde (índice 2)
} else {
encenderLed(s, 0); // Rojo (índice 0)
}
}
delay(tiempos[2]); // Tiempo verde
// Semáforo activo pasa a amarillo
encenderLed(semaforoActivo, 1);
delay(tiempos[1]);
}
void encenderLed(int semaforo, int colorIndex) {
// Apagar todos los LEDs de ese semáforo
for (int i = 0; i < 3; i++) {
digitalWrite(pinesSemaforos[semaforo][i], LOW);
}
// Encender solo el indicado
digitalWrite(pinesSemaforos[semaforo][colorIndex], HIGH);
}
Ejercicio 3: Detector de patrones en sensores de aparcamiento
Objetivo: Detectar cuántas plazas libres hay y alertar si el parking está casi lleno.
Componentes:
- 4 sensores de ultrasonidos HC-SR04 (simulamos con valores)
- 1 buzzer
- 1 LED rojo
const int NUM_PLAZAS = 4;
const int DISTANCIA_LIBRE = 100; // cm: si hay más distancia, está libre
// Pines de los sensores (Trigger, Echo)
int pinesTrigger[NUM_PLAZAS] = {2, 4, 6, 8};
int pinesEcho[NUM_PLAZAS] = {3, 5, 7, 9};
// Estado de cada plaza: true = ocupada, false = libre
bool estadoPlazas[NUM_PLAZAS];
const int PIN_BUZZER = 10;
const int PIN_LED_ALERTA = 11;
void setup() {
Serial.begin(9600);
for (int i = 0; i < NUM_PLAZAS; i++) {
pinMode(pinesTrigger[i], OUTPUT);
pinMode(pinesEcho[i], INPUT);
estadoPlazas[i] = false;
}
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_LED_ALERTA, OUTPUT);
Serial.println("=== Sistema de Parking Inteligente ===\n");
}
void loop() {
// Leer todos los sensores
for (int i = 0; i < NUM_PLAZAS; i++) {
int distancia = medirDistancia(i);
estadoPlazas[i] = (distancia < DISTANCIA_LIBRE);
}
// Contar plazas libres
int plazasLibres = contarPlazasLibres();
// Mostrar estado
Serial.println("Estado del parking:");
for (int i = 0; i < NUM_PLAZAS; i++) {
Serial.print(" Plaza ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(estadoPlazas[i] ? "OCUPADA" : "LIBRE");
}
Serial.print("Plazas libres: ");
Serial.print(plazasLibres);
Serial.print("/");
Serial.println(NUM_PLAZAS);
// Alerta si queda 1 o menos plazas
if (plazasLibres <= 1) {
activarAlerta();
} else {
desactivarAlerta();
}
Serial.println();
delay(3000);
}
int medirDistancia(int sensorIndex) {
digitalWrite(pinesTrigger[sensorIndex], LOW);
delayMicroseconds(2);
digitalWrite(pinesTrigger[sensorIndex], HIGH);
delayMicroseconds(10);
digitalWrite(pinesTrigger[sensorIndex], LOW);
long duracion = pulseIn(pinesEcho[sensorIndex], HIGH);
int distancia = duracion * 0.034 / 2;
return distancia;
}
int contarPlazasLibres() {
int libres = 0;
for (int i = 0; i < NUM_PLAZAS; i++) {
if (!estadoPlazas[i]) { // Si NO está ocupada
libres++;
}
}
return libres;
}
void activarAlerta() {
digitalWrite(PIN_LED_ALERTA, HIGH);
tone(PIN_BUZZER, 1000, 200);
}
void desactivarAlerta() {
digitalWrite(PIN_LED_ALERTA, LOW);
noTone(PIN_BUZZER);
}
Ejercicio 4: Sensor de calidad del aire con filtro de media móvil
Objetivo: Filtrar el ruido de un sensor de gas MQ-135 usando las últimas 5 lecturas.
const int PIN_MQ135 = A0;
const int VENTANA = 5;
int lecturas[VENTANA];
int indiceLectura = 0;
int totalLecturas = 0;
void setup() {
Serial.begin(9600);
// Inicializar array a 0
for (int i = 0; i < VENTANA; i++) {
lecturas[i] = 0;
}
Serial.println("Sensor de calidad del aire - Smart City");
Serial.println("Calentando sensor (30 segundos)...");
delay(30000);
Serial.println("Listo!\n");
}
void loop() {
// Leer sensor
int nuevaLectura = analogRead(PIN_MQ135);
// Agregar al buffer circular
lecturas[indiceLectura] = nuevaLectura;
indiceLectura = (indiceLectura + 1) % VENTANA;
if (totalLecturas < VENTANA) {
totalLecturas++;
}
// Calcular media móvil
int suma = 0;
for (int i = 0; i < totalLecturas; i++) {
suma += lecturas[i];
}
int mediaMovil = suma / totalLecturas;
// Mostrar valores
Serial.print("Lectura cruda: ");
Serial.print(nuevaLectura);
Serial.print(" | Media móvil: ");
Serial.print(mediaMovil);
// Evaluar calidad
Serial.print(" | Calidad: ");
if (mediaMovil < 200) {
Serial.println("BUENA");
} else if (mediaMovil < 400) {
Serial.println("MODERADA");
} else {
Serial.println("MALA - ¡ALERTA!");
}
delay(1000);
}
6. Ejercicios para Resolver (Autoevaluación)
Ejercicio A: Contador de vehículos
Crea un programa que:
- Use un array de 24 elementos (uno por hora del día)
- Simule lecturas de un sensor de paso
- Almacene el conteo de vehículos por hora
- Muestre la hora con más tráfico
Ejercicio B: Sistema de riego inteligente
Diseña un programa que:
- Tenga un array con los umbrales de humedad para 4 zonas de jardín
- Lea 4 sensores de humedad
- Active el riego (LEDs) solo en las zonas que estén por debajo de su umbral
Ejercicio C: Alerta de temperatura múltiple
Programa un sistema que:
- Almacene las últimas 20 lecturas de temperatura
- Calcule si hay una tendencia ascendente (las últimas 5 lecturas suben respecto a las 5 anteriores)
- Active una alarma si detecta tendencia de calentamiento
7. Errores Comunes y Cómo Evitarlos
| Error | Problema | Solución |
|---|---|---|
int arr[5]; arr[5] = 10; | Índice fuera de rango (válidos: 0-4) | Usar índices de 0 a TAMANO - 1 |
int arr[]; | Array sin tamaño definido | Especificar tamaño o inicializar |
| No inicializar valores | Contienen “basura” de memoria | Inicializar con {0} o bucle |
Usar sizeof(arr) en función | Devuelve tamaño del puntero, no del array | Pasar el tamaño como parámetro |
8. Conexión con Smart Cities
Los arrays que habéis practicado son la base de sistemas reales:
- Monitorización ambiental: Estaciones meteorológicas almacenan miles de lecturas para análisis de tendencias
- Gestión de tráfico: Arrays bidimensionales representan mapas de semáforos y su sincronización
- Eficiencia energética: Históricos de consumo permiten predecir demanda y optimizar la red eléctrica
- Seguridad: Sistemas de cámaras almacenan patrones de movimiento para detectar anomalías
Cuando estos datos se envían a la nube (próximo tema: comunicaciones IoT), los arrays se transforman en estructuras JSON o bases de datos, pero el concepto de “colección ordenada de datos” permanece.
Etiqueta:arduino, arrays, c++, ies monterroso
