Skip to Content

Sensor de Ocupación de Habitaciones con Edge AI usando ESP32 y Detección de Personas

Sensor de Ocupación de Habitaciones con Edge AI usando ESP32 y Detección de Personas

En este tutorial usaremos Edge AI para detectar el número de personas en una habitación (ocupación) con un XIAO ESP32-S3-Sense y un ESP32 lite. Si no has usado el XIAO-ESP32-S3 Sense antes, echa un vistazo al Getting started with XIAO-ESP32-S3-Sense tutorial primero.

Desplegaremos un modelo de detección de personas en el XIAO ESP32-S3-Sense usando la plataforma SenseCraft AI. El modelo se ejecutará en el ESP32 sin necesidad de interactuar con un servidor para realizar la detección o el conteo de personas.

Un sensor de ocupación de habitaciones tiene una amplia gama de aplicaciones prácticas tanto en entornos DIY como profesionales. En hogares inteligentes, puede ajustar la iluminación, calefacción y sistemas de seguridad según la presencia. En oficinas, escuelas y espacios comerciales, ayuda a monitorizar el uso de las salas, gestionar la eficiencia energética y mejorar la utilización del espacio. Tiendas y espacios públicos pueden usarlo para conteo de personas, gestión de colas y cumplimiento de seguridad.

¡Vamos a empezar!

Partes necesarias

Necesitarás una placa XIAO ESP32-S3-Sense y un segundo ESP32. Ten en cuenta que el XIAO ESP32-S3-Sense puede calentarse mucho bajo alta carga computacional. Recomiendo que le coloques un pequeño Heatsink en la parte trasera de la placa (ver la pieza listada abajo).

Para el segundo ESP32, elegí un ESP32 lite antiguo, pero cualquier otro ESP32 o un Arduino funcionará perfectamente.

Seeed Studio XIAO ESP32-S3-Sense

ESP32 lite Lolin32

ESP32-lite

OLED display

Pantalla OLED

Cable USB C

Pequeño disipador 9×9 mm

Dupont wire set

Juego de cables Dupont

Half_breadboard56a

Protoboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Arquitectura del sensor de ocupación

Nuestro sistema de sensor de ocupación estará compuesto por las siguientes partes: un XIAO ESP32S3 Sense con cámara que ejecuta un modelo de detección de personas, un ESP32-lite que analiza las detecciones para contar personas y un OLED para mostrar el contador de personas.

Architecture of Room Occupancy Sensor System
Arquitectura del sistema de sensor de ocupación de habitación

Los dos ESP32 y el OLED se comunican vía I2C. El ESP32 lo programaremos usando el Arduino IDE y el modelo de detección de personas se desplegará en el XIAO ESP32S3 Sense desde el SenseCraft AI platform. Si quieres aprender más sobre el XIAO ESP32-S3-Sense, consulta el Getting started with XIAO-ESP32-S3-Sense tutorial.

La razón por la que necesitamos el segundo ESP32-lite es porque esencialmente no podemos (fácilmente) ejecutar otro código en el XIAO ESP32S3 Sense aparte del modelo de detección de personas. Esto tiene la ventaja de que no necesitas escribir código para la detección y no tienes que preocuparte por carga computacional adicional en el XIAO ESP32S3 Sense. La desventaja es que no tienes control total sobre el modelo de detección (y necesitas el segundo ESP32).

La siguiente foto muestra el sistema montado en una protoboard con una powerbank como fuente de alimentación:

Room Occupancy Sensor System on Breadboard
Sistema de sensor de ocupación en protoboard

Como puedes ver, fijé la protoboard a un pequeño soporte para que la cámara quede mirando hacia adelante. En la siguiente sección desplegaremos el modelo de detección de personas en el XIAO ESP32S3 Sense.

Desplegar modelo de detección de personas

Ve a la página de selección de modelos de SenseCraft en https://sensecraft.seeed.cc/ai/model. En la pestaña «Pretrained Models» en la barra lateral selecciona bajo Task: «Detection» y bajo Supported Devices: «XIAO ESP32S3 Sense». Luego escribe «Person» en la barra de búsqueda para filtrar modelos de detección de personas:

Model Selection
Selección de modelo

A julio de 2025 solo hay una coincidencia. Haz clic en el modelo Person Detection–Swift YOLO (marcado en amarillo) a la derecha.

Esto abrirá una nueva página con la descripción del modelo de detección y un botón verde «Deploy Model» a la derecha:

Description of selected Person Detection Model
Descripción del modelo de detección de personas seleccionado

Conecta tu placa XIAO ESP32-S3-Sense vía USB a tu ordenador y luego haz clic en «Deploy Model». Sigue los pasos. Si necesitas más ayuda, consulta el Face Detection with XIAO ESP32-S3-Sense and SenseCraft AI tutorial, que describe el proceso de despliegue con más detalle.

Prueba el modelo de detección de personas

Una vez desplegado, el modelo se inicia automáticamente y envía imágenes con cuadros delimitadores alrededor de las personas detectadas a tu navegador web, donde puedes ver una transmisión en vivo en la sección Preview. En la esquina superior derecha de Preview hay un botón «Stop» para detener el modelo en ejecución. La imagen abajo muestra la ventana Preview con detecciones de personas:

Preview of detected persons
Vista previa de personas detectadas

Para probar el modelo, simplemente coloqué la siguiente imagen con personas frente a la cámara.

Imagen de personas en una habitación (source)

Puedes ver que el modelo detecta la mayoría de las personas en la imagen, pero no es perfecto. Hay dos ajustes (Confidence e IoU threshold) bajo la ventana Preview que puedes modificar para mejorar la precisión de la detección.

Si el sistema detecta pocas personas, baja el umbral de confianza; si detecta objetos como personas, sube el umbral.

Si notas que una misma persona está cubierta por varios cuadros de detección, baja el umbral IoU. Por otro lado, si los cuadros son muy grandes, sube el umbral IoU. Para más detalles, consulta el Face Detection with XIAO ESP32-S3-Sense and SenseCraft AI tutorial.

En la siguiente sección escribiremos el código para contar las personas en la habitación. Este código se ejecutará en el ESP32-lite.

Conectando ESP32-S3-Sense con ESP32-lite

Como se mencionó, el modelo de detección corre en el XIAO ESP32-S3-Sense. Podemos comunicarnos con él vía I2C. El siguiente diagrama de conexiones muestra cómo conectar el XIAO ESP32-S3-Sense al ESP32-lite:

Connecting XIAO ESP32-S3-Sense to ESP32 lite via I2C
Conexión de XIAO ESP32-S3-Sense a ESP32-lite vía I2C

Los pines I2C en el ESP32-lite son SDA=GPIO19 y SCL=GPIO23. Los pines correspondientes en el ESP32-S3-Sense son SDA=D4/GPIO5 y SCL=D5/GPIO4. Nota que el diagrama muestra la parte trasera de las placas, donde están etiquetadas las salidas digitales (D0…D10).

ESP32-liteXIAO
SDAGPIO19D4 / GPIO5
SCLGPIO23D5 / GPIO4

Si usas otro ESP32 o Arduino, los pines hardware I2C serán diferentes. Asegúrate de conectar a los pines correctos, de lo contrario la comunicación fallará.

En la siguiente sección probaremos esta conexión recuperando las detecciones del XIAO ESP32-S3-Sense y mostrándolas en el ESP32-lite.

Código para comunicación serial

Para que el siguiente código funcione, primero debes instalar la Seeed_Arduino_SSCMA biblioteca. Abre el LIBRARY MANAGER, busca «Seeed_Arduino_SSCMA» y haz clic en INSTALL:

Installing Seeed_Arduino_SSCMA library
Instalando la biblioteca Seeed_Arduino_SSCMA

Luego conecta el ESP32-lite a tu ordenador vía USB y carga el siguiente código:

#include <Wire.h>
#include <Seeed_Arduino_SSCMA.h>

SSCMA detector;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  detector.begin(&Wire);
  Serial.println("running...");
}

void loop() {
  if (!detector.invoke(1, false, false)) {
    for (int i = 0; i < detector.boxes().size(); i++) {
      boxes_t &b = detector.boxes()[i];
      Serial.printf("Box[%d] conf=%d [%3d %3d %3d %3d]\n",
                    i, b.score, b.x, b.y, b.w, b.h);
    }
  }
}

Este código invoca el detector de personas que corre en el ESP32-S3-Sense e imprime las puntuaciones de confianza y los cuadros de detección para cada persona detectada en el Monitor Serial. Consulta el Face Detection with XIAO ESP32-S3-Sense and SenseCraft AI, si tienes dudas sobre este código.

Si todo está correctamente conectado y funcionando, deberías ver los resultados de detección impresos en el Monitor Serial así:

Person detection results on Serial Monitor
Resultados de detección de personas en Monitor Serial

En la siguiente sección escribiremos el código para contar el número de personas.

Código para ocupación de habitación

Una vez que tenemos los cuadros delimitadores de las personas detectadas, calcular la ocupación de la habitación es sencillo. Solo hay que contar el número de cuadros de detección.

Pero sería bueno ver este número en una pantalla para hacer el sistema independiente de una conexión USB a un PC. Por eso añadimos un pequeño OLED al circuito para mostrar el número de personas en la habitación. La imagen abajo muestra el diagrama de conexiones:

Connecting OLED to ESP32-lite
Conexión del OLED al ESP32-lite

Solo conecta la alimentación del ESP32 (3.3V y GND) al OLED y luego conecta SCL y SDA en paralelo a la conexión I2C existente.

El siguiente código corre en el ESP32-lite. Se comunica con el detector de personas en el ESP32-S3-Sense vía I2C. Invoca el detector, recupera el número n de cuadros de detección y muestra ese número en el OLED:

#include <Wire.h>
#include <Seeed_Arduino_SSCMA.h>
#include <Adafruit_SSD1306.h>

SSCMA detector;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);

void setup() {
  Wire.begin();
  detector.begin(&Wire);

  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.setRotation(3);
  oled.setTextSize(6);
  oled.setTextColor(WHITE);
}

void loop() {
  if (!detector.invoke(1, false, false)) {
    int n = detector.boxes().size();
    oled.clearDisplay();  
    oled.setCursor(10, 20);
    oled.printf("%d", n);  
    oled.display();
  }
}

Ten en cuenta que el código usa la Adafruit_SSD1306 biblioteca, que puedes instalar vía Library Manager como de costumbre. Veamos el código más de cerca.

Bibliotecas

Primero incluimos la biblioteca Wire para comunicación I2C, Seeed_Arduino_SSCMA para comunicarnos con el modelo de detección y Adafruit_SSD1306 para controlar el OLED.

#include <Wire.h>
#include <Seeed_Arduino_SSCMA.h>
#include <Adafruit_SSD1306.h>

Objetos

Luego creamos el objeto detector y el objeto oled:

SSCMA detector;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);

Setup

En la función setup iniciamos el detector y el OLED:

void setup() {
  Wire.begin();
  detector.begin(&Wire);

  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.setRotation(3);
  oled.setTextSize(6);
  oled.setTextColor(WHITE);
}

Ten en cuenta que la dirección I2C del OLED que uso es 0x3C. Si tienes un OLED con otra dirección, deberás cambiar el código aquí.

Loop

Finalmente, tenemos la función loop, donde invocamos el modelo de detección, recuperamos el número de cuadros delimitadores y mostramos ese número como conteo de personas en el OLED:

void loop() {
  if (!detector.invoke(1, false, false)) {
    int n = detector.boxes().size();
    oled.clearDisplay();  
    oled.setCursor(10, 20);
    oled.printf("%d", n);  
    oled.display();
  }
}

Si observas el detector de personas, notarás que las detecciones no son estables. Los cuadros aparecen y desaparecen, incluso con una imagen estática. En un escenario real y en vivo, donde las personas se mueven en la habitación, las oclusiones y cambios de iluminación añaden más variabilidad. Los siguientes tres ejemplos muestran esta variabilidad incluso con una imagen fija:

Unstable detection of persons
Detección inestable de personas

Estabilizando el conteo de personas

Para hacer el conteo más estable puedes calcular un promedio móvil. Las siguientes funciones promedian tres conteos consecutivos n, estabilizándolo un poco:

int average3(int n) {
  static int prev1 = 0, prev2 = 0;

  int avg = (n + prev1 + prev2 + 1) / 3; 
  prev2 = prev1;
  prev1 = n;

  return avg;
}

En la función loop lo llamas así:

void loop() {
  if (!detector.invoke(1, false, false)) {
    int n = detector.boxes().size();
    n = average3(n);
    ...
    oled.printf("%d", n);  
    oled.display();
  }
}

El compromiso es que tarda más en reaccionar a cambios en el número de personas en la habitación. Pero está bien si quieres ajustar calefacción, ventilación, iluminación o volumen de música según la cantidad de personas. Cambios muy rápidos en estas condiciones generalmente no son necesarios.

¡Y eso es todo!

Conclusiones y comentarios

En este tutorial construimos un sensor de ocupación de habitación. Nuestro sensor funciona como un dispositivo Edge AI y no necesita estar conectado a un servidor. La detección de personas y el cálculo del conteo ocurren directamente en el dispositivo.

La plataforma SenseCraft AI facilita mucho desplegar un modelo en el XIAO ESP32-S3-Sense, pero la desventaja es que necesitas un segundo microcontrolador para procesamiento adicional. Además, el control sobre el modelo es limitado y no he visto un método para recuperar las detecciones y el video en streaming.

Sin embargo, si transmites el video a un servidor de todos modos, podrías ejecutar el detector de personas allí también. Echa un vistazo a nuestros Object Detection with ESP32-CAM and YOLO y Stream Video with with XIAO-ESP32-S3-Sense tutoriales.

Debido a la limitada potencia computacional, solo puedes ejecutar modelos de IA relativamente pequeños en un microcontrolador. La precisión de la detección y por tanto de la medición de ocupación no es tan buena como la de un modelo más grande que corra en un servidor con GPU, por ejemplo.

Por otro lado, si la privacidad es importante, la comunicación Wi-Fi es inestable o quieres funcionar con batería, una solución Edge AI es mejor. Y aunque la precisión del modelo no es excelente, es suficiente para regular calefacción o ventilación de una habitación.

Si tienes preguntas, no dudes en dejarlas en la sección de comentarios.

¡Feliz bricolaje! 😉