case-device-block-diagram, Qué construirás: Una baliza localizadora de herramientas por Bluetooth de Baja Energía (BLE) que se acopla al equipo, permitiendo a los usuarios activar una alarma audible y visual localizada a través del teléfono inteligente para encontrar rápidamente objetos perdidos. Audiencia: Desarrolladores de sistemas embebidos e ingenieros de IoT; Nivel: Intermedio Arquitectura/flujo: Teléfono inteligente (Cliente BLE) → Conexión de RF → ESP32 (Servidor GATT BLE) → Devolución de llamada asíncrona → Control GPIO no bloqueante (LED/Zumbador) Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema. Flujo conceptual: configuración local, emisión BLE y lectura desde el móvil. Resumen conceptual de las herramientas usadas para comprobar el proyecto ESP32 publicado. Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. Para este perfil ESP32 DevKitC, el proyecto se comprobó como proyecto PlatformIO: el validador extrajo Esta validación confirma compatibilidad sintáctica y de herramientas para el código publicado, pero no sustituye la prueba física sobre tu placa ESP32 DevKitC exacta, tu cableado, alimentación y entorno WiFi local. Este proyecto es una baliza BLE educativa de bajo voltaje, no un sistema certificado de localización, seguridad personal o inventario crítico. Verifica el pinout de tu ESP32 DevKitC, mantén los GPIO a 3,3 V, usa alimentación USB o batería adecuada y respeta la privacidad y la normativa local al emitir identificadores BLE en espacios compartidos. Para completar con éxito este tutorial, asegúrese de tener el siguiente software y conocimientos previos: Necesitará los componentes de hardware exactos que se enumeran a continuación para construir este prototipo: La configuración de hardware requiere conectar el pulsador, el zumbador piezoeléctrico y el LED de estado a pines específicos de Entrada/Salida de Propósito General (GPIO) en el ESP32 DevKitC. Utilizaremos la resistencia pull-up interna del ESP32 para el pulsador a fin de minimizar la cantidad de componentes externos. Instrucciones de cableado: Tabla resumen de conexiones: El proyecto requiere dos archivos dentro de la estructura de su proyecto de PlatformIO: el archivo de configuración ( Cree un nuevo proyecto de PlatformIO para el ESP32 DevKitC y reemplace el contenido de Reemplace el contenido de Vista pública parcial del archivo validado. El código completo se muestra a miembros y en PDF/Print. Para compilar, cargar y monitorear el código en su ESP32 DevKitC, use la CLI de PlatformIO Core. Asegúrese de que su terminal esté navegando en el directorio raíz de su proyecto (donde se encuentra Flujo de trabajo de ejecución: Siga estos puntos de control para verificar la funcionalidad de su baliza localizadora de herramientas BLE. Si encuentra problemas durante las fases de construcción o validación, consulte la siguiente tabla para ver problemas comunes y sus soluciones. Una vez que el prototipo básico esté funcionando, considere las siguientes mejoras para avanzar hacia un dispositivo listo para producción: Encuentra este producto y/o libros sobre este tema en Amazon Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.
.prometeo-educational-note,
.prometeo-device-postcode-section,
.prometeo-device-section-card {
margin: 2.4rem 0;
padding: 1.45rem 1.55rem;
border: 1px solid rgba(148, 163, 184, 0.30);
border-radius: 14px;
background:
linear-gradient(135deg, rgba(30, 41, 59, 0.50), rgba(15, 23, 42, 0.18)),
rgba(17, 24, 39, 0.48);
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.20);
}
.case-objective > h2:first-of-type,
.case-device-block-diagram > h2:first-of-type,
.prometeo-device-postcode-section > h2:first-of-type,
.prometeo-device-section-card > h2:first-of-type {
margin-top: 0;
}
.prometeo-device-section-card > :last-child,
.case-objective > :last-child,
.case-device-block-diagram > :last-child,
.prometeo-device-postcode-section > :last-child {
margin-bottom: 0;
}
.prometeo-device-section-card.prometeo-device-section-card-code {
border-left: 4px solid rgba(56, 189, 248, 0.86);
background:
linear-gradient(135deg, rgba(8, 47, 73, 0.42), rgba(15, 23, 42, 0.18)),
rgba(15, 23, 42, 0.58);
}
.prometeo-device-section-card.prometeo-device-section-card-compact {
padding: 1.2rem 1.35rem;
}
.prometeo-device-section-card pre,
.case-objective pre,
.case-device-block-diagram pre,
.prometeo-device-postcode-section pre {
max-width: 100%;
}
.prometeo-device-postcode-section .prometeo-device-flow-item {
background:
linear-gradient(135deg, rgba(15, 23, 42, 0.50), rgba(30, 41, 59, 0.28)),
rgba(15, 23, 42, 0.28);
}
@media print {
.case-objective,
.case-device-block-diagram,
.prometeo-educational-note,
.prometeo-device-postcode-section,
.prometeo-device-section-card {
background: #fff;
color: #111827;
box-shadow: none;
break-inside: avoid;
page-break-inside: avoid;
}
}
Objetivo y caso de uso
Por qué es importante / Casos de uso
Resultado esperado
0x01) en la característica BLE personalizada activa la alarma de hardware con una latencia <50ms.Diagrama de bloques conceptual
Arquitectura funcional
Ruta de validación
Nota educativa de validación
platformio.ini y src/main.cpp, creó un proyecto temporal y ejecutó pio run contra platform = espressif32, board = esp32dev y framework = arduino. También revisó la estructura del artículo, que los comandos sean copiables con guiones ASCII, y que no aparezcan stacks no soportados como ESP-IDF directo o placas ESP32 no acotadas.Evidencia de validación publicada
Nota educativa de seguridad
Requisitos previos
* PlatformIO IDE: Instalado como una extensión dentro de Visual Studio Code, o la CLI de PlatformIO Core disponible en el path de su sistema.
* Aplicación de escáner BLE: Un teléfono inteligente con Bluetooth habilitado y una aplicación de depuración BLE genérica instalada. Las aplicaciones recomendadas incluyen «LightBlue» (Punch Through) o «BLE Scanner» (Bluepixel Technologies).
* Conocimientos básicos de C++: Familiaridad con variables, funciones y estructuras de control estándar.
* Controladores USB: Controladores adecuados para el puente USB a UART del ESP32 DevKitC (comúnmente Silicon Labs CP210x o WCH CH34x) instalados en su sistema operativo.Materiales
* ESP32 DevKitC: La placa de desarrollo del microcontrolador principal con capacidades de Wi-Fi y Bluetooth.
* Pulsador: Un interruptor táctil momentáneo estándar de 4 o 2 pines.
* Zumbador piezoeléctrico: Un zumbador piezoeléctrico pasivo capaz de generar diferentes tonos mediante modulación por ancho de pulsos (PWM).
* LED de estado: Un diodo emisor de luz estándar de 5mm (por ejemplo, rojo o azul) para proporcionar retroalimentación visual.
* Resistencia (330Ω): Una resistencia limitadora de corriente para el LED de estado.
* Protoboard: Una placa de pruebas (breadboard) de prototipado estándar de tamaño medio o completo.
* Cables puente (Jumper): Cables puente macho a macho para establecer conexiones entre los componentes.
* Cable Micro-USB: Un cable USB de alta calidad con capacidad de transmisión de datos para conectar el ESP32 DevKitC a su computadora.Configuración/Conexión
1. Distribución de energía: Conecte el pin GND del ESP32 DevKitC al riel negativo (azul/negro) de su protoboard.
2. LED de estado: Coloque el LED en la protoboard. Conecte el ánodo (pata más larga) al GPIO 25 del ESP32. Conecte el cátodo (pata más corta) a un extremo de la resistencia de 330Ω. Conecte el otro extremo de la resistencia al riel GND de la protoboard.
3. Zumbador piezoeléctrico: Coloque el zumbador piezoeléctrico pasivo en la protoboard. Conecte su terminal positivo al GPIO 26 del ESP32. Conecte su terminal negativo al riel GND.
4. Pulsador: Inserte el pulsador táctil a través de la zanja central de la protoboard. Conecte un terminal del botón al GPIO 27 del ESP32. Conecte el terminal diagonalmente opuesto (o el terminal adyacente en un interruptor de 2 pines) directamente al riel GND.Componente Pin del ESP32 DevKitC Componente intermedio Destino LED de estado (Ánodo) GPIO 25 Ninguno Ánodo del LED LED de estado (Cátodo) N/A Resistencia de 330Ω Riel GND Zumbador piezoeléctrico (+) GPIO 26 Ninguno Zumbador (+) Zumbador piezoeléctrico (-) N/A Ninguno Riel GND Pulsador (Lado A) GPIO 27 Ninguno Terminal del botón Pulsador (Lado B) N/A Ninguno Riel GND Código validado
platformio.ini) y el código fuente principal en C++ (src/main.cpp).Configuración de PlatformIO
platformio.ini con la siguiente configuración. Esto establece el framework, la placa y la velocidad en baudios del monitor serie.; platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
Código fuente de la aplicación principal
src/main.cpp con el código a continuación. Este código inicializa el servidor BLE, crea un servicio y una característica personalizados, e implementa un bucle no bloqueante para manejar el estado de la alarma y las pulsaciones del botón físico.// src/main.cpp
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
// Hardware Pin Definitions
const int LED_PIN = 25;
const int BUZZER_PIN = 26;
const int BUTTON_PIN = 27;
// LEDC PWM Settings for the passive buzzer
const int PWM_CHANNEL = 0;
const int PWM_FREQ = 2000;
const int PWM_RESOLUTION = 8;
// BLE UUIDs - Generated unique identifiers for our custom service
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
// Global State Variables
bool deviceConnected = false;
bool alarmActive = false;
// Timing variables for non-blocking alarm pattern
unsigned long previousMillis = 0;
const long interval = 250; // Toggle every 250 milliseconds
bool toggleState = false;
// BLE Server Callbacks: Handle connection and disconnection events
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
Serial.println("BLE Device Connected.");
}
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
Serial.println("BLE Device Disconnected. Restarting advertising...");
// Restart advertising so the device can be found again
pServer->startAdvertising();
}
};
// BLE Characteristic Callbacks: Handle incoming write requests from the smartphone
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
Serial.print("Received Value: ");
for (int i = 0; i < value.length(); i++) {
Serial.print(value[i], HEX);
Serial.print(" ");
}
Serial.println();
// Check if the received byte is 0x01 (Start Alarm) or 0x00 (Stop Alarm)
if (value[0] == 0x01) {
alarmActive = true;
Serial.println("Alarm TRIGGERED via BLE!");
} else if (value[0] == 0x00) {
alarmActive = false;
Serial.println("Alarm STOPPED via BLE.");
// Ensure hardware is turned off immediately
digitalWrite(LED_PIN, LOW);
ledcWriteTone(PWM_CHANNEL, 0);
}
}
}
};
// ...// src/main.cpp
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
// Hardware Pin Definitions
const int LED_PIN = 25;
const int BUZZER_PIN = 26;
const int BUTTON_PIN = 27;
// LEDC PWM Settings for the passive buzzer
const int PWM_CHANNEL = 0;
const int PWM_FREQ = 2000;
const int PWM_RESOLUTION = 8;
// BLE UUIDs - Generated unique identifiers for our custom service
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
// Global State Variables
bool deviceConnected = false;
bool alarmActive = false;
// Timing variables for non-blocking alarm pattern
unsigned long previousMillis = 0;
const long interval = 250; // Toggle every 250 milliseconds
bool toggleState = false;
// BLE Server Callbacks: Handle connection and disconnection events
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
Serial.println("BLE Device Connected.");
}
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
Serial.println("BLE Device Disconnected. Restarting advertising...");
// Restart advertising so the device can be found again
pServer->startAdvertising();
}
};
// BLE Characteristic Callbacks: Handle incoming write requests from the smartphone
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
Serial.print("Received Value: ");
for (int i = 0; i < value.length(); i++) {
Serial.print(value[i], HEX);
Serial.print(" ");
}
Serial.println();
// Check if the received byte is 0x01 (Start Alarm) or 0x00 (Stop Alarm)
if (value[0] == 0x01) {
alarmActive = true;
Serial.println("Alarm TRIGGERED via BLE!");
} else if (value[0] == 0x00) {
alarmActive = false;
Serial.println("Alarm STOPPED via BLE.");
// Ensure hardware is turned off immediately
digitalWrite(LED_PIN, LOW);
ledcWriteTone(PWM_CHANNEL, 0);
}
}
}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting Tool Finder Beacon...");
// Initialize Hardware Pins
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// Configure Pushbutton with internal pull-up resistor
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Configure PWM for the passive buzzer
ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RESOLUTION);
ledcAttachPin(BUZZER_PIN, PWM_CHANNEL);
ledcWriteTone(PWM_CHANNEL, 0); // Ensure buzzer is quiet on boot
// Initialize BLE Device
BLEDevice::init("ToolFinder-Beacon");
// Create BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create BLE Characteristic (Write capability)
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // Functions that help with iPhone connections
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("BLE Advertising Started. Waiting for connections...");
}
void loop() {
// 1. Check physical pushbutton to clear the alarm locally
// Since we use INPUT_PULLUP, a pressed button reads as LOW
if (digitalRead(BUTTON_PIN) == LOW) {
if (alarmActive) {
alarmActive = false;
Serial.println("Alarm STOPPED via physical button press.");
// Immediately turn off the hardware
digitalWrite(LED_PIN, LOW);
ledcWriteTone(PWM_CHANNEL, 0);
// Simple debounce delay
delay(300);
}
}
// 2. Handle the Alarm Pattern (Non-blocking)
if (alarmActive) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
toggleState = !toggleState;
if (toggleState) {
digitalWrite(LED_PIN, HIGH);
ledcWriteTone(PWM_CHANNEL, 2500); // 2.5 kHz tone
} else {
digitalWrite(LED_PIN, LOW);
ledcWriteTone(PWM_CHANNEL, 0); // Silence
}
}
} else {
// Ensure hardware remains off when alarm is inactive
digitalWrite(LED_PIN, LOW);
ledcWriteTone(PWM_CHANNEL, 0);
}
// Small delay to yield to FreeRTOS background tasks (BLE stack)
delay(10);
}
Comandos de compilación/carga/ejecución
platformio.ini).Comando Propósito pio runCompila el proyecto para asegurar que no haya errores de sintaxis o dependencias. pio run --target uploadCompila y carga el firmware construido en el ESP32 conectado a través de USB. pio device monitorAbre el monitor serie para ver las declaraciones de impresión y los registros de depuración.
1. Conecte el ESP32 DevKitC a su computadora mediante el cable micro-USB.
2. Abra su terminal o la ventana de la CLI de PlatformIO.
3. Ejecute pio run para verificar que el código se compile limpiamente.
4. Ejecute pio run --target upload para cargar el dispositivo. Si el proceso de carga se detiene en «Connecting…», es posible que deba presionar y mantener presionado el botón «BOOT» en el ESP32 hasta que comience la carga.
5. Ejecute pio device monitor para observar la salida serie. Debería ver «Starting Tool Finder Beacon…» seguido de «BLE Advertising Started.»Validación paso a paso
pio device monitor) y presione el botón «EN» (Reinicio) en el ESP32.4fafc201...) y el monitor serie muestra «BLE Device Connected.»beb5483e...), toque el icono «Write» (Escribir, generalmente una flecha hacia arriba), seleccione «Byte Array» o «UINT8», ingrese 01 y envíe.Solución de problemas
Síntoma Causa probable Solución Falla la carga / Tiempo de espera en «Connecting…» El ESP32 no entra automáticamente en el modo gestor de arranque (bootloader). Presione y mantenga presionado el botón «BOOT» en el ESP32 DevKitC cuando el terminal muestre «Connecting…». No hay salida serie visible Velocidad en baudios incorrecta o faltan los controladores CP210x/CH34x. Asegúrese de tener monitor_speed = 115200 en platformio.ini. Verifique que los controladores USB estén instalados en el Administrador de dispositivos de su SO.El dispositivo no aparece en el escaneo BLE Problema de caché BLE del teléfono inteligente o inestabilidad de energía del ESP32. Apague y vuelva a encender el Bluetooth en su teléfono inteligente. Asegúrese de que el ESP32 esté alimentado por un puerto USB con capacidad suficiente. La aplicación se desconecta inmediatamente Falla o tiempo de espera del servidor GATT. Reinicie el ESP32. Asegúrese de que está escribiendo en la Característica, no en el descriptor del Servicio. El zumbador emite un ruido continuo, sin pulsaciones Código bloqueante (por ejemplo, delay()) utilizado dentro de la devolución de llamada BLE.Verifique que el loop() use millis() para la temporización como se proporciona en el Código validado, evitando bucles con delay().Mejoras
0x180F) para informar la energía restante del dispositivo al teléfono inteligente.
Botón local
ESP32 BLE
Paquete advertising
LED de estado
Móvil escáner
Código fuente
PlatformIO build
Flash
Monitor serie



