Tema 5

Diagnóstico de Averías en Sistemas ESP32

ESP32 - Diagnóstico y Localización

Duración: 20 horas | Evaluación: 2ª Evaluación

Resultados de Aprendizaje y Criterios de Evaluación

RA 5: Detecta averías en equipos y sistemas, utilizando técnicas de diagnóstico y localización.

Criterios de Evaluación:

Puntuación Total RA 5: 1,7 puntos

5.1 Identificación de Síntomas

5.1.1 Síntomas de Conectividad

Detección automática de problemas de conectividad:

#include "WiFi.h" #include "esp_wifi.h" enum TipoSintoma { SINTOMA_NORMAL, SINTOMA_DISMINUCION_POTENCIA, SINTOMA_AUSENCIA_MODULACION, SINTOMA_INTERFERENCIAS, SINTOMA_ALARMAS, SINTOMA_DESCONEXION }; struct SintomaConectividad { TipoSintoma tipo; int32_t rssi; uint8_t canal; bool wifi_conectado; int fallos_consecutivos; unsigned long tiempo_ultima_conexion; }; void identificarSintomasConectividad() { Serial.println("=== Identificación de Síntomas de Conectividad ==="); SintomaConectividad sintoma; sintoma.rssi = WiFi.RSSI(); sintoma.canal = WiFi.channel(); sintoma.wifi_conectado = (WiFi.status() == WL_CONNECTED); sintoma.tiempo_ultima_conexion = millis(); // Analizar síntomas if (!sintoma.wifi_conectado) { sintoma.tipo = SINTOMA_DESCONEXION; Serial.println("SÍNTOMA: Desconexión WiFi"); } else if (sintoma.rssi < -80) { sintoma.tipo = SINTOMA_DISMINUCION_POTENCIA; Serial.println("SÍNTOMA: Disminución de potencia (RSSI bajo)"); } else if (sintoma.rssi < -70) { sintoma.tipo = SINTOMA_INTERFERENCIAS; Serial.println("SÍNTOMA: Posibles interferencias"); } else { sintoma.tipo = SINTOMA_NORMAL; Serial.println("Estado: Normal"); } // Mostrar detalles Serial.printf("RSSI: %d dBm\n", sintoma.rssi); Serial.printf("Canal: %d\n", sintoma.canal); Serial.printf("WiFi conectado: %s\n", sintoma.wifi_conectado ? "Sí" : "No"); // Recomendar acciones recomendarAcciones(sintoma); } void recomendarAcciones(SintomaConectividad sintoma) { Serial.println("=== Recomendaciones ==="); switch (sintoma.tipo) { case SINTOMA_DESCONEXION: Serial.println("• Verificar configuración WiFi"); Serial.println("• Comprobar alcance de la red"); Serial.println("• Reiniciar módulo WiFi"); break; case SINTOMA_DISMINUCION_POTENCIA: Serial.println("• Verificar antena"); Serial.println("• Comprobar orientación"); Serial.println("• Medir ROE"); break; case SINTOMA_INTERFERENCIAS: Serial.println("• Cambiar canal WiFi"); Serial.println("• Analizar espectro"); Serial.println("• Verificar fuentes de interferencia"); break; default: Serial.println("• Continuar monitoreo"); break; } }

5.1.2 Síntomas de Rendimiento

Detección de problemas de rendimiento del sistema:

struct SintomaRendimiento { float cpu_usage; int memoria_libre; int memoria_minima; float temperatura; unsigned long uptime; int reinicios; }; void identificarSintomasRendimiento() { Serial.println("=== Identificación de Síntomas de Rendimiento ==="); SintomaRendimiento sintoma; sintoma.memoria_libre = ESP.getFreeHeap(); sintoma.memoria_minima = ESP.getMinFreeHeap(); sintoma.temperatura = temperatureRead(); sintoma.uptime = millis() / 1000; sintoma.reinicios = esp_reset_reason(); // Calcular uso de CPU (aproximado) sintoma.cpu_usage = calcularUsoCPU(); // Mostrar síntomas Serial.printf("Memoria libre: %d bytes\n", sintoma.memoria_libre); Serial.printf("Memoria mínima: %d bytes\n", sintoma.memoria_minima); Serial.printf("Temperatura: %.2f °C\n", sintoma.temperatura); Serial.printf("Uptime: %lu segundos\n", sintoma.uptime); Serial.printf("Uso CPU: %.2f%%\n", sintoma.cpu_usage); // Analizar problemas if (sintoma.memoria_libre < 10000) { Serial.println("SÍNTOMA: Memoria baja"); } if (sintoma.temperatura > 80.0) { Serial.println("SÍNTOMA: Temperatura alta"); } if (sintoma.cpu_usage > 90.0) { Serial.println("SÍNTOMA: CPU sobrecargada"); } if (sintoma.reinicios > 0) { Serial.printf("SÍNTOMA: %d reinicios detectados\n", sintoma.reinicios); } } float calcularUsoCPU() { // Simulación del cálculo de uso de CPU static unsigned long ultima_medicion = 0; static int contador_idle = 0; static int contador_total = 0; unsigned long ahora = millis(); if (ahora - ultima_medicion > 1000) { float uso = ((float)(contador_total - contador_idle) / contador_total) * 100.0; contador_idle = 0; contador_total = 0; ultima_medicion = ahora; return uso; } contador_total++; if (millis() % 10 == 0) { contador_idle++; } return 0.0; }

5.2 Medición de Parámetros Críticos

5.2.1 Medición de Alimentación

Verificación del sistema de alimentación:

#include "esp_adc_cal.h" #include "driver/adc.h" #define ADC_PIN ADC1_CHANNEL_0 #define VOLTAGE_DIVIDER_RATIO 11.0 struct MedicionAlimentacion { float voltaje_entrada; float voltaje_3v3; float voltaje_5v; float corriente_total; bool alimentacion_ok; }; void medirAlimentacion() { Serial.println("=== Medición de Alimentación ==="); MedicionAlimentacion medicion; // Configurar ADC adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC_PIN, ADC_ATTEN_DB_11); // Medir voltaje de entrada int adcValue = adc1_get_raw(ADC_PIN); medicion.voltaje_entrada = (adcValue * 3.3) / 4095.0 * VOLTAGE_DIVIDER_RATIO; // Medir voltaje 3.3V interno medicion.voltaje_3v3 = 3.3; // Valor nominal // Medir voltaje 5V (si está disponible) medicion.voltaje_5v = 5.0; // Valor nominal // Calcular corriente (aproximada) medicion.corriente_total = calcularCorrienteTotal(); // Evaluar alimentación medicion.alimentacion_ok = evaluarAlimentacion(medicion); // Mostrar resultados Serial.printf("Voltaje entrada: %.2f V\n", medicion.voltaje_entrada); Serial.printf("Voltaje 3.3V: %.2f V\n", medicion.voltaje_3v3); Serial.printf("Voltaje 5V: %.2f V\n", medicion.voltaje_5v); Serial.printf("Corriente total: %.3f A\n", medicion.corriente_total); Serial.printf("Alimentación: %s\n", medicion.alimentacion_ok ? "OK" : "ERROR"); // Diagnosticar problemas diagnosticarAlimentacion(medicion); } float calcularCorrienteTotal() { // Simulación del cálculo de corriente // En la práctica, esto requeriría un sensor de corriente return 0.150; // 150mA típico } bool evaluarAlimentacion(MedicionAlimentacion medicion) { // Verificar rangos de voltaje if (medicion.voltaje_entrada < 3.0 || medicion.voltaje_entrada > 5.5) { return false; } if (medicion.voltaje_3v3 < 3.0 || medicion.voltaje_3v3 > 3.6) { return false; } if (medicion.corriente_total > 0.5) { // 500mA máximo return false; } return true; } void diagnosticarAlimentacion(MedicionAlimentacion medicion) { Serial.println("=== Diagnóstico de Alimentación ==="); if (!medicion.alimentacion_ok) { if (medicion.voltaje_entrada < 3.0) { Serial.println("PROBLEMA: Voltaje de entrada bajo"); Serial.println("SOLUCIÓN: Verificar fuente de alimentación"); } else if (medicion.voltaje_entrada > 5.5) { Serial.println("PROBLEMA: Voltaje de entrada alto"); Serial.println("SOLUCIÓN: Verificar regulador de voltaje"); } if (medicion.corriente_total > 0.5) { Serial.println("PROBLEMA: Consumo excesivo"); Serial.println("SOLUCIÓN: Verificar cortocircuitos"); } } else { Serial.println("Alimentación: Normal"); } }

5.2.2 Medición de Potencia de Salida

Verificación de la potencia de transmisión:

#include "esp_wifi.h" struct MedicionPotencia { int8_t potencia_tx; int32_t rssi; float potencia_medida; bool potencia_ok; }; void medirPotenciaSalida() { Serial.println("=== Medición de Potencia de Salida ==="); MedicionPotencia medicion; // Obtener potencia de transmisión configurada esp_wifi_get_max_tx_power(&medicion.potencia_tx); // Medir RSSI (como indicador de potencia) medicion.rssi = WiFi.RSSI(); // Calcular potencia medida (aproximada) medicion.potencia_medida = calcularPotenciaMedida(medicion.rssi); // Evaluar potencia medicion.potencia_ok = evaluarPotencia(medicion); // Mostrar resultados Serial.printf("Potencia TX configurada: %d dBm\n", medicion.potencia_tx); Serial.printf("RSSI medido: %d dBm\n", medicion.rssi); Serial.printf("Potencia medida: %.2f dBm\n", medicion.potencia_medida); Serial.printf("Potencia: %s\n", medicion.potencia_ok ? "OK" : "ERROR"); // Diagnosticar problemas diagnosticarPotencia(medicion); } float calcularPotenciaMedida(int32_t rssi) { // Conversión aproximada de RSSI a potencia // En la práctica, esto requeriría calibración return rssi + 20.0; // Ajuste empírico } bool evaluarPotencia(MedicionPotencia medicion) { // Verificar que la potencia esté en rango if (medicion.potencia_medida < 10.0 || medicion.potencia_medida > 20.0) { return false; } // Verificar que no haya gran diferencia con la configurada float diferencia = abs(medicion.potencia_medida - medicion.potencia_tx); if (diferencia > 5.0) { return false; } return true; } void diagnosticarPotencia(MedicionPotencia medicion) { Serial.println("=== Diagnóstico de Potencia ==="); if (!medicion.potencia_ok) { if (medicion.potencia_medida < 10.0) { Serial.println("PROBLEMA: Potencia de salida baja"); Serial.println("SOLUCIÓN: Verificar amplificador de potencia"); } else if (medicion.potencia_medida > 20.0) { Serial.println("PROBLEMA: Potencia de salida alta"); Serial.println("SOLUCIÓN: Verificar limitador de potencia"); } float diferencia = abs(medicion.potencia_medida - medicion.potencia_tx); if (diferencia > 5.0) { Serial.println("PROBLEMA: Desviación de potencia"); Serial.println("SOLUCIÓN: Recalibrar sistema"); } } else { Serial.println("Potencia: Normal"); } }

5.3 Visualización de Señales

5.3.1 Análisis de Señales Digitales

Visualización y análisis de señales digitales:

#include "driver/uart.h" struct AnalisisSenal { uint8_t* buffer; size_t tamano; float frecuencia_muestreo; float amplitud_maxima; float amplitud_minima; float valor_promedio; }; void analizarSenalDigital() { Serial.println("=== Análisis de Señal Digital ==="); AnalisisSenal analisis; analisis.tamano = 1024; analisis.buffer = (uint8_t*)malloc(analisis.tamano); analisis.frecuencia_muestreo = 1000000.0; // 1 MS/s // Capturar señal capturarSenal(analisis.buffer, analisis.tamano); // Analizar señal analizarCaracteristicas(analisis); // Mostrar resultados Serial.printf("Tamaño: %d muestras\n", analisis.tamano); Serial.printf("Frecuencia muestreo: %.0f Hz\n", analisis.frecuencia_muestreo); Serial.printf("Amplitud máxima: %.2f V\n", analisis.amplitud_maxima); Serial.printf("Amplitud mínima: %.2f V\n", analisis.amplitud_minima); Serial.printf("Valor promedio: %.2f V\n", analisis.valor_promedio); // Detectar problemas detectarProblemasSenal(analisis); // Liberar memoria free(analisis.buffer); } void capturarSenal(uint8_t* buffer, size_t tamano) { // Simulación de captura de señal for (size_t i = 0; i < tamano; i++) { buffer[i] = 128 + 50 * sin(2 * PI * i / 100.0); // Señal senoidal } } void analizarCaracteristicas(AnalisisSenal& analisis) { float suma = 0; analisis.amplitud_maxima = 0; analisis.amplitud_minima = 255; for (size_t i = 0; i < analisis.tamano; i++) { float valor = analisis.buffer[i]; suma += valor; if (valor > analisis.amplitud_maxima) { analisis.amplitud_maxima = valor; } if (valor < analisis.amplitud_minima) { analisis.amplitud_minima = valor; } } analisis.valor_promedio = suma / analisis.tamano; } void detectarProblemasSenal(AnalisisSenal analisis) { Serial.println("=== Detección de Problemas ==="); // Verificar amplitud if (analisis.amplitud_maxima < 100) { Serial.println("PROBLEMA: Amplitud baja"); } if (analisis.amplitud_maxima > 200) { Serial.println("PROBLEMA: Amplitud alta"); } // Verificar valor promedio if (analisis.valor_promedio < 100 || analisis.valor_promedio > 150) { Serial.println("PROBLEMA: Valor promedio anómalo"); } // Verificar rango dinámico float rango_dinamico = analisis.amplitud_maxima - analisis.amplitud_minima; if (rango_dinamico < 50) { Serial.println("PROBLEMA: Rango dinámico bajo"); } }

5.3.2 Análisis de Espectro de Emisión

Análisis del espectro de emisión para detectar distorsiones:

struct AnalisisEspectro { float* espectro; int tamano; float frecuencia_central; float ancho_banda; float potencia_fundamental; float potencia_armonicos; float thd; // Total Harmonic Distortion }; void analizarEspectroEmision() { Serial.println("=== Análisis de Espectro de Emisión ==="); AnalisisEspectro analisis; analisis.tamano = 512; analisis.espectro = (float*)malloc(analisis.tamano * sizeof(float)); analisis.frecuencia_central = 2400.0; // MHz analisis.ancho_banda = 20.0; // MHz // Generar espectro simulado generarEspectro(analisis.espectro, analisis.tamano); // Analizar espectro analizarCaracteristicasEspectro(analisis); // Mostrar resultados Serial.printf("Frecuencia central: %.1f MHz\n", analisis.frecuencia_central); Serial.printf("Ancho de banda: %.1f MHz\n", analisis.ancho_banda); Serial.printf("Potencia fundamental: %.2f dBm\n", analisis.potencia_fundamental); Serial.printf("Potencia armónicos: %.2f dBm\n", analisis.potencia_armonicos); Serial.printf("THD: %.2f%%\n", analisis.thd); // Detectar distorsiones detectarDistorsiones(analisis); // Liberar memoria free(analisis.espectro); } void generarEspectro(float* espectro, int tamano) { // Simulación de espectro con armónicos for (int i = 0; i < tamano; i++) { float frecuencia = (float)i / tamano; // Señal fundamental float fundamental = 10.0 * exp(-pow((frecuencia - 0.5) * 10, 2)); // Armónicos float armonico2 = 2.0 * exp(-pow((frecuencia - 1.0) * 10, 2)); float armonico3 = 1.0 * exp(-pow((frecuencia - 1.5) * 10, 2)); // Ruido float ruido = 0.1 * (random(100) / 100.0 - 0.5); espectro[i] = fundamental + armonico2 + armonico3 + ruido; } } void analizarCaracteristicasEspectro(AnalisisEspectro& analisis) { // Encontrar pico fundamental float max_potencia = 0; int indice_fundamental = 0; for (int i = 0; i < analisis.tamano; i++) { if (analisis.espectro[i] > max_potencia) { max_potencia = analisis.espectro[i]; indice_fundamental = i; } } analisis.potencia_fundamental = max_potencia; // Calcular potencia de armónicos analisis.potencia_armonicos = 0; for (int i = 0; i < analisis.tamano; i++) { if (i != indice_fundamental) { analisis.potencia_armonicos += analisis.espectro[i]; } } // Calcular THD analisis.thd = (analisis.potencia_armonicos / analisis.potencia_fundamental) * 100.0; } void detectarDistorsiones(AnalisisEspectro analisis) { Serial.println("=== Detección de Distorsiones ==="); if (analisis.thd > 10.0) { Serial.println("PROBLEMA: THD alto"); Serial.println("SOLUCIÓN: Verificar amplificador"); } if (analisis.potencia_armonicos > analisis.potencia_fundamental * 0.1) { Serial.println("PROBLEMA: Armónicos excesivos"); Serial.println("SOLUCIÓN: Verificar filtros"); } // Verificar espurias for (int i = 0; i < analisis.tamano; i++) { if (analisis.espectro[i] > analisis.potencia_fundamental * 0.05) { float frecuencia = analisis.frecuencia_central + (i - analisis.tamano/2) * analisis.ancho_banda / analisis.tamano; Serial.printf("PROBLEMA: Espuria en %.1f MHz\n", frecuencia); } } }

5.4 Herramientas de Diagnóstico

5.4.1 Herramientas Software

Sistema de diagnóstico automático:

#include "esp_log.h" #include "esp_system.h" static const char* TAG = "DIAGNOSTICO"; enum TipoDiagnostico { DIAGNOSTICO_WIFI, DIAGNOSTICO_BLUETOOTH, DIAGNOSTICO_MEMORIA, DIAGNOSTICO_ALIMENTACION, DIAGNOSTICO_TEMPERATURA, DIAGNOSTICO_GPIO }; struct ResultadoDiagnostico { TipoDiagnostico tipo; bool resultado; String mensaje; int codigo_error; }; void ejecutarDiagnosticoCompleto() { Serial.println("=== Diagnóstico Completo del Sistema ==="); ResultadoDiagnostico resultados[6]; int total_diagnosticos = 6; int diagnosticos_exitosos = 0; // Ejecutar diagnósticos resultados[0] = diagnosticarWiFi(); resultados[1] = diagnosticarBluetooth(); resultados[2] = diagnosticarMemoria(); resultados[3] = diagnosticarAlimentacion(); resultados[4] = diagnosticarTemperatura(); resultados[5] = diagnosticarGPIO(); // Mostrar resultados for (int i = 0; i < total_diagnosticos; i++) { Serial.printf("Diagnóstico %d: %s\n", i+1, resultados[i].mensaje.c_str()); if (resultados[i].resultado) { diagnosticos_exitosos++; } } // Resumen Serial.printf("Diagnósticos exitosos: %d/%d\n", diagnosticos_exitosos, total_diagnosticos); if (diagnosticos_exitosos == total_diagnosticos) { Serial.println("ESTADO: Sistema funcionando correctamente"); } else { Serial.println("ESTADO: Se detectaron problemas"); generarReporteProblemas(resultados, total_diagnosticos); } } ResultadoDiagnostico diagnosticarWiFi() { ResultadoDiagnostico resultado; resultado.tipo = DIAGNOSTICO_WIFI; if (WiFi.status() == WL_CONNECTED) { int rssi = WiFi.RSSI(); if (rssi > -80) { resultado.resultado = true; resultado.mensaje = "WiFi: OK (RSSI: " + String(rssi) + " dBm)"; resultado.codigo_error = 0; } else { resultado.resultado = false; resultado.mensaje = "WiFi: RSSI bajo (" + String(rssi) + " dBm)"; resultado.codigo_error = 1; } } else { resultado.resultado = false; resultado.mensaje = "WiFi: Desconectado"; resultado.codigo_error = 2; } return resultado; } ResultadoDiagnostico diagnosticarMemoria() { ResultadoDiagnostico resultado; resultado.tipo = DIAGNOSTICO_MEMORIA; int memoria_libre = ESP.getFreeHeap(); int memoria_minima = ESP.getMinFreeHeap(); if (memoria_libre > 50000 && memoria_minima > 10000) { resultado.resultado = true; resultado.mensaje = "Memoria: OK (" + String(memoria_libre) + " bytes libres)"; resultado.codigo_error = 0; } else { resultado.resultado = false; resultado.mensaje = "Memoria: Baja (" + String(memoria_libre) + " bytes libres)"; resultado.codigo_error = 3; } return resultado; } ResultadoDiagnostico diagnosticarTemperatura() { ResultadoDiagnostico resultado; resultado.tipo = DIAGNOSTICO_TEMPERATURA; float temperatura = temperatureRead(); if (temperatura < 70.0) { resultado.resultado = true; resultado.mensaje = "Temperatura: OK (" + String(temperatura, 1) + " °C)"; resultado.codigo_error = 0; } else { resultado.resultado = false; resultado.mensaje = "Temperatura: Alta (" + String(temperatura, 1) + " °C)"; resultado.codigo_error = 4; } return resultado; } void generarReporteProblemas(ResultadoDiagnostico* resultados, int total) { Serial.println("=== Reporte de Problemas ==="); for (int i = 0; i < total; i++) { if (!resultados[i].resultado) { Serial.printf("PROBLEMA %d: %s\n", resultados[i].codigo_error, resultados[i].mensaje.c_str()); // Sugerir soluciones switch (resultados[i].codigo_error) { case 1: Serial.println(" SOLUCIÓN: Verificar antena y orientación"); break; case 2: Serial.println(" SOLUCIÓN: Verificar configuración WiFi"); break; case 3: Serial.println(" SOLUCIÓN: Optimizar uso de memoria"); break; case 4: Serial.println(" SOLUCIÓN: Verificar ventilación"); break; } } } }

5.4.2 Herramientas Hardware

Integración con herramientas de medición externas:

// Interfaz con herramientas hardware externas void configurarHerramientasHardware() { Serial.println("=== Configuración de Herramientas Hardware ==="); // Configurar comunicación con osciloscopio configurarOsciloscopio(); // Configurar comunicación con analizador de espectro configurarAnalizadorEspectro(); // Configurar comunicación con multímetro configurarMultimetro(); Serial.println("Herramientas hardware configuradas"); } void configurarOsciloscopio() { Serial.println("Configurando osciloscopio..."); // Configurar parámetros de osciloscopio float escala_tiempo = 1e-3; // 1ms/div float escala_voltaje = 1.0; // 1V/div float frecuencia_muestreo = 1e6; // 1 MS/s Serial.printf("Escala tiempo: %.0f ms/div\n", escala_tiempo * 1000); Serial.printf("Escala voltaje: %.1f V/div\n", escala_voltaje); Serial.printf("Frecuencia muestreo: %.0f MS/s\n", frecuencia_muestreo / 1e6); } void configurarAnalizadorEspectro() { Serial.println("Configurando analizador de espectro..."); // Configurar parámetros de analizador float frecuencia_central = 2400.0; // MHz float ancho_banda = 20.0; // MHz float resolucion = 0.1; // MHz Serial.printf("Frecuencia central: %.1f MHz\n", frecuencia_central); Serial.printf("Ancho de banda: %.1f MHz\n", ancho_banda); Serial.printf("Resolución: %.1f MHz\n", resolucion); } void configurarMultimetro() { Serial.println("Configurando multímetro..."); // Configurar parámetros de multímetro String modo = "DC Voltage"; float rango = 20.0; // V int precision = 4; // dígitos Serial.printf("Modo: %s\n", modo.c_str()); Serial.printf("Rango: %.1f V\n", rango); Serial.printf("Precisión: %d dígitos\n", precision); } void ejecutarMedicionesHardware() { Serial.println("=== Ejecutando Mediciones Hardware ==="); // Medir con osciloscopio float amplitud = medirConOsciloscopio(); Serial.printf("Amplitud medida: %.2f V\n", amplitud); // Medir con analizador de espectro float potencia = medirConAnalizadorEspectro(); Serial.printf("Potencia medida: %.2f dBm\n", potencia); // Medir con multímetro float voltaje = medirConMultimetro(); Serial.printf("Voltaje medido: %.2f V\n", voltaje); } float medirConOsciloscopio() { // Simulación de medición con osciloscopio return 3.3; // V } float medirConAnalizadorEspectro() { // Simulación de medición con analizador de espectro return 15.0; // dBm } float medirConMultimetro() { // Simulación de medición con multímetro return 3.28; // V }

5.5 Protección Radioeléctrica y Electrostática

5.5.1 Medidas de Protección

Implementación de medidas de protección:

void implementarProtecciones() { Serial.println("=== Implementando Medidas de Protección ==="); // Protección electrostática configurarProteccionElectrostatica(); // Protección radioeléctrica configurarProteccionRadioelectrica(); // Protección de sobretensión configurarProteccionSobretension(); Serial.println("Protecciones implementadas"); } void configurarProteccionElectrostatica() { Serial.println("Configurando protección electrostática..."); // Configurar GPIO para detección ESD pinMode(0, INPUT_PULLUP); // Pin de detección ESD // Configurar interrupción para ESD attachInterrupt(0, detectarESD, FALLING); Serial.println("Protección electrostática configurada"); } void configurarProteccionRadioelectrica() { Serial.println("Configurando protección radioeléctrica..."); // Configurar límites de potencia esp_wifi_set_max_tx_power(20); // 20 dBm máximo // Configurar canales permitidos esp_wifi_set_channel(6, WIFI_SECOND_CHAN_NONE); // Configurar modulación esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); Serial.println("Protección radioeléctrica configurada"); } void configurarProteccionSobretension() { Serial.println("Configurando protección de sobretensión..."); // Configurar ADC para monitoreo de voltaje adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // Configurar interrupción para sobretensión attachInterrupt(0, detectarSobretension, RISING); Serial.println("Protección de sobretensión configurada"); } void detectarESD() { Serial.println("ALERTA: Descarga electrostática detectada"); // Registrar evento registrarEventoESD(); // Aplicar medidas de protección aplicarMedidasProteccionESD(); } void detectarSobretension() { Serial.println("ALERTA: Sobretensión detectada"); // Medir voltaje int adcValue = adc1_get_raw(ADC1_CHANNEL_0); float voltaje = (adcValue * 3.3) / 4095.0; Serial.printf("Voltaje medido: %.2f V\n", voltaje); if (voltaje > 3.6) { Serial.println("CRÍTICO: Voltaje excesivo, apagando sistema"); apagarSistema(); } } void registrarEventoESD() { // Registrar evento en log Serial.println("Evento ESD registrado en log"); // Incrementar contador de eventos static int contador_esd = 0; contador_esd++; Serial.printf("Total eventos ESD: %d\n", contador_esd); } void aplicarMedidasProteccionESD() { // Desactivar periféricos sensibles esp_wifi_stop(); esp_bt_controller_disable(); // Esperar estabilización delay(1000); // Reactivar periféricos esp_wifi_start(); esp_bt_controller_enable(); Serial.println("Medidas de protección ESD aplicadas"); } void apagarSistema() { Serial.println("Apagando sistema por seguridad..."); // Guardar estado guardarEstadoSistema(); // Apagar periféricos esp_wifi_stop(); esp_bt_controller_disable(); // Entrar en modo de bajo consumo esp_deep_sleep_start(); }

5.6 Documentación de Intervención

5.6.1 Sistema de Documentación

Documentación automática de las intervenciones:

#include "ArduinoJson.h" #include "SPIFFS.h" struct DocumentoIntervencion { String fecha; String hora; String tecnico; String tipo_intervencion; String sintomas_detectados; String medidas_realizadas; String componentes_reemplazados; float costo_materiales; float costo_mano_obra; float costo_total; String observaciones; bool intervencion_exitosa; }; void generarDocumentoIntervencion() { Serial.println("=== Generando Documento de Intervención ==="); DocumentoIntervencion documento; // Llenar información básica documento.fecha = "2025-01-01"; documento.hora = "12:00:00"; documento.tecnico = "Carlos Víllora"; documento.tipo_intervencion = "Diagnóstico de averías"; // Llenar síntomas detectados documento.sintomas_detectados = "RSSI bajo, desconexiones intermitentes"; // Llenar medidas realizadas documento.medidas_realizadas = "Medición de parámetros RF, análisis de espectro, verificación de antena"; // Llenar componentes reemplazados documento.componentes_reemplazados = "Antena WiFi 2.4 GHz"; // Calcular costos documento.costo_materiales = 25.50; documento.costo_mano_obra = 45.00; documento.costo_total = documento.costo_materiales + documento.costo_mano_obra; // Llenar observaciones documento.observaciones = "Sistema funcionando correctamente después de la intervención"; // Resultado de la intervención documento.intervencion_exitosa = true; // Generar documento JSON String documentoJson = generarDocumentoJSON(documento); // Guardar documento guardarDocumento(documentoJson); // Mostrar resumen mostrarResumenIntervencion(documento); } String generarDocumentoJSON(DocumentoIntervencion documento) { DynamicJsonDocument doc(2048); doc["fecha"] = documento.fecha; doc["hora"] = documento.hora; doc["tecnico"] = documento.tecnico; doc["tipo_intervencion"] = documento.tipo_intervencion; doc["sintomas_detectados"] = documento.sintomas_detectados; doc["medidas_realizadas"] = documento.medidas_realizadas; doc["componentes_reemplazados"] = documento.componentes_reemplazados; doc["costos"]["materiales"] = documento.costo_materiales; doc["costos"]["mano_obra"] = documento.costo_mano_obra; doc["costos"]["total"] = documento.costo_total; doc["observaciones"] = documento.observaciones; doc["intervencion_exitosa"] = documento.intervencion_exitosa; String documentoJson; serializeJson(doc, documentoJson); return documentoJson; } void guardarDocumento(String documento) { if (!SPIFFS.begin(true)) { Serial.println("Error montando SPIFFS"); return; } String nombreArchivo = "/intervencion_" + String(millis()) + ".json"; File file = SPIFFS.open(nombreArchivo, "w"); if (file) { file.println(documento); file.close(); Serial.println("Documento guardado: " + nombreArchivo); } else { Serial.println("Error guardando documento"); } } void mostrarResumenIntervencion(DocumentoIntervencion documento) { Serial.println("=== Resumen de Intervención ==="); Serial.println("Fecha: " + documento.fecha); Serial.println("Hora: " + documento.hora); Serial.println("Técnico: " + documento.tecnico); Serial.println("Tipo: " + documento.tipo_intervencion); Serial.println("Síntomas: " + documento.sintomas_detectados); Serial.println("Medidas: " + documento.medidas_realizadas); Serial.println("Componentes: " + documento.componentes_reemplazados); Serial.printf("Costo total: %.2f €\n", documento.costo_total); Serial.println("Observaciones: " + documento.observaciones); Serial.println("Resultado: " + String(documento.intervencion_exitosa ? "Exitoso" : "Fallido")); }

Materiales Necesarios

Actividades Teóricas

Prácticas de Laboratorio

Práctica 5.1: Identificación de Síntomas

Objetivo: Implementar sistema de identificación automática de síntomas.

Duración: 3 horas

Entregables: Sistema de detección, código fuente, informe técnico

Práctica 5.2: Medición de Parámetros Críticos

Objetivo: Medir alimentación, potencia de salida y espectro de emisión.

Duración: 4 horas

Entregables: Mediciones, análisis de resultados, informe técnico

Práctica 5.3: Visualización de Señales

Objetivo: Visualizar y analizar señales en diferentes bloques funcionales.

Duración: 3 horas

Entregables: Análisis de señales, gráficos, informe técnico

Práctica 5.4: Herramientas de Diagnóstico

Objetivo: Utilizar herramientas software y hardware de diagnóstico.

Duración: 4 horas

Entregables: Sistema de diagnóstico, mediciones, informe técnico

Práctica 5.5: Protección y Seguridad

Objetivo: Implementar medidas de protección radioeléctrica y electrostática.

Duración: 3 horas

Entregables: Sistema de protección, pruebas de seguridad, informe técnico

Práctica 5.6: Documentación de Intervención

Objetivo: Generar documentación completa de la intervención.

Duración: 3 horas

Entregables: Documento de intervención, valoración económica, informe final

Criterios de Evaluación

Instrumentos de evaluación:

Entregables obligatorios:

Recursos Adicionales