
Las Misiones del Lince 06 Fototrampeo con Edge AI en Sierra Bermeja con ESP32-CAM y Teachable Machine
Ciencia Ciudadana MonteSTEAM · Proyecto AIDARAC
«El Lince de la Noche no tiene superpoderes. Tiene datos.»
Introducción científica
Sierra Bermeja no es una sierra cualquiera. Sus suelos de peridotita — una roca poco común en el planeta — han creado un ecosistema tan singular que alberga especies que no existen en ningún otro lugar del mundo. Entre sus pinsapares milenarios se mueve una fauna discreta, difícil de ver a simple vista: la cabra montés trepando por las laderas más escarpadas, el zorro patrullando al anochecer, el esquivo meloncillo deslizándose entre el matorral, y el gato montés, uno de los felinos más huidizos de la península.
Precisamente sobre el gato montés gira el origen de esta misión. Un naturalista colocó una cámara de fototrampeo en Sierra Bermeja con la esperanza de captar a este felino esquivo. No consiguió su foto: le robaron la cámara antes de poder recuperarla. Esa pérdida, sin embargo, nos ha dado algo: la certeza de que necesitamos herramientas más inteligentes, más baratas y más fáciles de replicar para que la ciencia ciudadana no dependa de un solo aparato caro en mitad del monte.
Ahí es donde entra el Lince de la Noche. No es un animal — es un nombre, un símbolo. En Sierra Bermeja no hay linces ibéricos, y lo decimos sin rodeos: es importante no confundir a nuestro público. Pero si cuidamos este territorio, si seguimos generando datos, conocimiento y vigilancia sobre su fauna, quizá algún día sí los haya. El Lince de la Noche no tiene superpoderes — tiene sensores, tiene datos, y tiene detrás a un equipo de estudiantes que no se rinde.
En esta misión, el Lince de la Noche se convierte en un sistema de fototrampeo con Edge AI: cámaras que se activan solas cuando detectan movimiento y un modelo de visión artificial capaz de reconocer, en el momento, qué especie ha pasado por delante.
Montaje del circuito
El corazón de una cámara de fototrampeo es simple y elegante: no despilfarra batería disparando todo el tiempo, solo reacciona cuando hay algo que fotografiar.
Componentes:
- 1 × ESP32-CAM (microcontrolador + cámara integrada)
- 1 × Sensor PIR HC-SR501 (detector de movimiento por infrarrojos)
- 1 × LDR (fotorresistencia, para saber si es de día o de noche)
- 1 × LED indicador de disparo
- Caja estanca + batería/panel solar para el despliegue real en campo
Lógica del circuito:
- El sensor PIR vigila constantemente el entorno. Cuando el calor corporal de un animal cruza su campo de detección, su salida digital pasa a HIGH.
- Esa señal llega al ESP32-CAM, que responde de dos formas posibles:
- Si la LDR indica que hay luz suficiente → dispara la cámara directamente.
- Si la LDR indica oscuridad → activa primero un foco de infrarrojos y después dispara la cámara, para no asustar al animal con luz visible.
- El LED se enciende brevemente para indicar “captura realizada”.
- El sistema vuelve a modo espera, listo para la siguiente detección.
Este es el circuito que hemos montado en Wokwi, siguiendo la misma dinámica que en la Misión 01: el alumnado de 1º/2º de Bachillerato simula el comportamiento del sensor y la lógica de disparo antes de pensar en el hardware real. En el vídeo de la misión se puede ver paso a paso cómo se conecta el PIR y la LDR al ESP32-CAM, y cómo reacciona el circuito ante distintos escenarios (día con movimiento, noche con movimiento, sin movimiento).
Conexiones del circuito (ESP32-CAM)
El ESP32-CAM tiene pocos pines libres porque la mayoría los usa la cámara, así que hay que ser preciso. Aquí van las conexiones exactas para que el alumnado no se pierda:
Sensor PIR (HC-SR501):
| Pin del PIR | Va conectado a |
|---|---|
| VCC | 5V del ESP32-CAM |
| GND | GND del ESP32-CAM |
| OUT | GPIO 13 |
Y en clase solo tenemos el HC-S404 así que:
Conexiones del HC-SR04 a la ESP32 para Wokwi:
- VCC (HC-SR04) $\rightarrow$ Pin 5V (o VIN) de la ESP32
- GND (HC-SR04) $\rightarrow$ Pin GND de la ESP32
- TRIG (HC-SR04) $\rightarrow$ Pin GPIO 5 (D5) de la ESP32
- ECHO (HC-SR04) $\rightarrow$ Pin GPIO 18 (D18) de la ESP32
Sensor de luz LDR (módulo con salida digital, comparador LM393):
| Pin del módulo LDR | Va conectado a |
|---|---|
| VCC | 3.3V del ESP32-CAM |
| GND | GND del ESP32-CAM |
| DO (salida digital) | GPIO 12 |
Usamos un módulo LDR con salida digital (no una LDR suelta) porque el ESP32-CAM tiene muy pocos pines analógicos libres una vez que la cámara está conectada. El módulo trae un potenciómetro para ajustar el umbral de “es de noche”.
LED indicador de captura:
| Pata del LED | Va conectado a |
|---|---|
| Ánodo (pata larga) | GPIO 2, a través de una resistencia de 220 Ω |
| Cátodo (pata corta) | GND |
Flash / iluminación IR nocturna:
No hace falta cablear nada extra: el ESP32-CAM ya trae un LED de flash integrado en el GPIO 4, así que ese mismo pin sirve para simular el destello infrarrojo cuando la LDR detecta oscuridad.
Resumen para la pizarra:
PIR OUT → GPIO 13
LDR DO → GPIO 12
LED + → GPIO 2 (con resistencia 220 Ω)
Flash IR → GPIO 4 (ya integrado, no se cablea)
Un par de notas para el alumnado:
- El tiempo entre disparos (
TIEMPO_ENTRE_DISPAROS, 3 segundos) evita que un mismo animal parado delante del sensor genere fotos repetidas sin parar — es lo que haría una cámara real. - La lógica de
esDeNochedepende de cómo venga calibrado el módulo LDR en Wokwi: si veis que se activa el flash de día o al revés, solo hay que invertir la condición (== LOWen vez de== HIGH). - El comentario dentro de
tomarFoto()marca exactamente dónde engancharía más adelante la clasificación con Teachable Machine — así ven claro dónde termina el circuito y dónde empieza la IA.
CÓDIGO HC-SR04
Conexiones de este código en Wokwi (ESP32):
- HC-SR04:
TRIGa GPIO 5 |ECHOa GPIO 18 |VCCa 5V/VIN |GNDa GND - Módulo LDR: Salida digital a GPIO 12
- LED Indicador: GPIO 2 (con resistencia de 220Ω)
- LED Flash: GPIO 4 (con resistencia de 220Ω)
C++
/*
Las Misiones del Lince — Misión 06: Fototrampeo con Edge AI
Ciencia Ciudadana MonteSTEAM
Circuito simulado en Wokwi (ESP32 DevKit + HC-SR04):
- Sensor Ultrasónico (HC-SR04): TRIG -> GPIO 5, ECHO -> GPIO 18
- Módulo LDR (salida digital) -> GPIO 12
- LED indicador de captura -> GPIO 2
- Flash / IR nocturno -> GPIO 4
Lógica:
1. El HC-SR04 mide la distancia. Si un objeto/animal pasa a menos del umbral (p. ej. 50 cm), se considera "presencia".
2. Si detecta presencia, la LDR decide si es de día o de noche.
3. Si es de noche, se enciende primero el flash IR antes de "disparar".
4. Se enciende el LED indicador para señalar que se ha hecho una captura.
5. Se envía un mensaje por el puerto serie simulando el aviso al Centro de Control.
*/
const int PIN_TRIG = 5; // Pin TRIG del HC-SR04
const int PIN_ECHO = 18; // Pin ECHO del HC-SR04
const int PIN_LDR = 12; // Salida digital del módulo de luz (LM393)
const int PIN_LED = 2; // LED indicador de "foto tomada"
const int PIN_FLASH = 4; // LED de flash simulado
// Umbral de distancia en centímetros para activar el disparador (ajustable)
const int UMBRAL_DISTANCIA_CM = 50;
// Tiempo mínimo entre dos disparos para evitar fotos repetidas del mismo animal
const unsigned long TIEMPO_ENTRE_DISPAROS = 3000; // milisegundos
unsigned long ultimoDisparo = 0;
int numeroDeCaptura = 0;
void setup() {
Serial.begin(115200);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
pinMode(PIN_LDR, INPUT);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_FLASH, OUTPUT);
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_FLASH, LOW);
Serial.println("=================================================");
Serial.println(" Mision 06: Fototrampeo con Edge AI - Sierra Bermeja");
Serial.println(" Camara lista. Esperando deteccion por ultrasonidos...");
Serial.println("=================================================");
}
void loop() {
// 1. Medir la distancia actual con el HC-SR04
float distanciaActual = obtenerDistanciaCM();
// 2. Determinar si hay un animal dentro del rango de detección
bool hayPresencia = (distanciaActual > 0 && distanciaActual <= UMBRAL_DISTANCIA_CM);
// 3. Comprobar si es de noche (HIGH = oscuridad en la mayoría de módulos LM393)
bool esDeNoche = digitalRead(PIN_LDR) == HIGH;
unsigned long ahora = millis();
bool puedeDisparar = (ahora - ultimoDisparo) > TIEMPO_ENTRE_DISPAROS;
if (hayPresencia && puedeDisparar) {
tomarFoto(esDeNoche, distanciaActual);
ultimoDisparo = ahora;
}
}
// Función para medir la distancia con el HC-SR04
float obtenerDistanciaCM() {
digitalWrite(PIN_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
long duracion = pulseIn(PIN_ECHO, HIGH, 30000); // Timeout de 30ms para evitar bloqueos
float distancia = duracion * 0.034 / 2;
return distancia;
}
void tomarFoto(bool esDeNoche, float distancia) {
numeroDeCaptura++;
Serial.println();
Serial.print("[Captura #");
Serial.print(numeroDeCaptura);
Serial.print("] Animal detectado a ");
Serial.print(distancia);
Serial.println(" cm.");
if (esDeNoche) {
Serial.println(" -> Es de noche: activando flash infrarrojo...");
digitalWrite(PIN_FLASH, HIGH);
delay(200); // Tiempo para que el flash ilumine antes del disparo
}
// Simulación del disparo de la cámara y clasificación mediante Edge AI
Serial.println(" -> ¡Foto tomada! Procesando con Teachable Machine...");
digitalWrite(PIN_LED, HIGH);
delay(300);
digitalWrite(PIN_LED, LOW);
if (esDeNoche) {
digitalWrite(PIN_FLASH, LOW);
}
}

CÓDIGO HC-SR501
/*
Las Misiones del Lince — Misión 07: Fototrampeo con Edge AI
Ciencia Ciudadana MonteSTEAM
Circuito simulado en Wokwi (ESP32-CAM):
– Sensor PIR (HC-SR501) -> GPIO 13
– Módulo LDR (salida digital) -> GPIO 12
– LED indicador de captura -> GPIO 2 (con resistencia 220 ohm)
– Flash / IR nocturno -> GPIO 4 (LED de flash integrado del ESP32-CAM)
Lógica:
1. El PIR vigila si hay movimiento.
2. Si detecta movimiento, la LDR decide si es de día o de noche.
3. Si es de noche, se enciende primero el flash IR antes de “disparar”.
4. Se enciende el LED indicador para señalar que se ha hecho una captura.
5. Se envía un mensaje por el puerto serie simulando el aviso al
Centro de Control (aquí es donde luego conectaríais la
clasificación con Teachable Machine / LearningML).
*/
const int PIN_PIR = 13; // salida digital del sensor de movimiento
const int PIN_LDR = 12; // salida digital del módulo de luz (LM393)
const int PIN_LED = 2; // LED indicador de “foto tomada”
const int PIN_FLASH = 4; // LED de flash integrado del ESP32-CAM
// Tiempo mínimo entre dos disparos, para no saturar la cámara
// con el mismo animal parado delante del sensor.
const unsigned long TIEMPO_ENTRE_DISPAROS = 3000; // milisegundos
unsigned long ultimoDisparo = 0;
int numeroDeCaptura = 0;
void setup() {
Serial.begin(115200);
pinMode(PIN_PIR, INPUT);
pinMode(PIN_LDR, INPUT);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_FLASH, OUTPUT);
digitalWrite(PIN_LED, LOW);
digitalWrite(PIN_FLASH, LOW);
Serial.println(“=================================================”);
Serial.println(” Mision 07: Fototrampeo con Edge AI – Sierra Bermeja”);
Serial.println(” Camara lista. Esperando movimiento…”);
Serial.println(“=================================================”);
}
void loop() {
bool hayMovimiento = digitalRead(PIN_PIR) == HIGH;
bool esDeNoche = digitalRead(PIN_LDR) == HIGH; // ajustar según el modulo:
// HIGH = oscuridad en la mayoria
// de modulos LM393
unsigned long ahora = millis();
bool puedeDisparar = (ahora – ultimoDisparo) > TIEMPO_ENTRE_DISPAROS;
if (hayMovimiento && puedeDisparar) {
tomarFoto(esDeNoche);
ultimoDisparo = ahora;
}
}
void tomarFoto(bool esDeNoche) {
numeroDeCaptura++;
Serial.println();
Serial.print(“[Captura #”);
Serial.print(numeroDeCaptura);
Serial.println(“] Movimiento detectado.”);
if (esDeNoche) {
Serial.println(” -> Es de noche: activando flash infrarrojo…”);
digitalWrite(PIN_FLASH, HIGH);
delay(200); // tiempo para que el flash ilumine antes del disparo
}
// Aquí, en el sistema real/simulador, se capturaría el fotograma
// y se enviaría al modelo de Teachable Machine / LearningML para
// clasificar la especie.
Serial.println(” -> ¡Foto tomada! Enviando al Centro de Control.”);
digitalWrite(PIN_LED, HIGH);
delay(300);
digitalWrite(PIN_LED, LOW);
if (esDeNoche) {
digitalWrite(PIN_FLASH, LOW);
}
}
Simulación y ciencia de datos
Aquí es donde el proyecto da el salto de la electrónica a la inteligencia artificial. El propio alumnado entrena su modelo de clasificación de fauna con Teachable Machine o LearningML, herramientas de aprendizaje automático en el navegador que no requieren programar redes neuronales desde cero: se suben fotos de cada especie, el modelo aprende a distinguirlas, y queda listo para clasificar imágenes nuevas.
Nuestro simulador recrea el ciclo completo de una red de cámaras trampa:
- Un mapa real de Sierra Bermeja con varias cámaras colocadas en puntos estratégicos (zonas de paso entre el pinsapar y el matorral, cercanías de arroyos, sendas de fauna).
- Cada cierto tiempo, una cámara “dispara” una foto simulada de una de las cuatro especies.
- El sistema de IA la clasifica — y no acierta siempre. Igual que un modelo real, tiene un margen de error, y eso es precisamente lo que lo hace honesto: no fingimos una precisión perfecta que no existe.
- Con cada clasificación, se actualiza un contador de avistamientos por especie y por cámara, construyendo poco a poco un inventario digital de fauna de Sierra Bermeja.
Ese inventario es ciencia ciudadana real: los mismos datos que generaría una red de fototrampeo profesional, pero construidos por estudiantes, con material accesible y un circuito que cabe en una caja de zapatos.
Prompt para que el alumnado genere el simulador con Claude
Aquí tienes un prompt listo para copiar y pegar. Está escrito para que lo peguen ellos mismos en una conversación con Claude y puedan iterar sobre el resultado:
Quiero que crees un simulador interactivo en HTML de una red de
cámaras de fototrampeo en Sierra Bermeja (Málaga), como parte del
proyecto "Las Misiones del Lince" (Ciencia Ciudadana MonteSTEAM).
Contexto: las cámaras se activan solas cuando detectan movimiento
(sensor PIR) y un sistema de inteligencia artificial clasifica qué
animal ha pasado por delante, pero no acierta siempre.
Especies a clasificar (con emoji o icono simple para cada una):
1. Cabra montés 🐐
2. Zorro 🦊
3. Meloncillo 🐾
4. Gato montés 🐱
Quiero que el simulador tenga:
1. Un mapa (puedo subirte una imagen de fondo) con 5-8 cámaras
colocadas como iconos, en posiciones fijas.
2. Cada pocos segundos, una cámara aleatoria "dispara": aparece un
destello o animación breve sobre esa cámara.
3. El sistema "clasifica" la especie: la mayoría de las veces acierta
la especie real que le asigno al disparo, pero a veces se equivoca
(dame un porcentaje de acierto ajustable, por defecto 80%).
4. Un panel lateral con un contador total por especie y otro por
cámara, que se actualiza en tiempo real con cada disparo.
5. Un botón para pausar/reanudar la simulación y otro para reiniciar
los contadores.
6. Que se pueda hacer clic en una cámara para ver su historial de
últimos disparos.
Estilo visual: que encaje con un proyecto de ciencia ciudadana sobre
naturaleza (tonos verdes/tierra), limpio y fácil de leer para
estudiantes de Bachillerato. No hace falta que sea realista al
100%, es una simulación educativa.
Enlace al simulador (para verlo más grande)
https://montesteam.org/wp-content/uploads/simuladores/mision06-animales.html
Conclusión
El robo de una cámara podría haber sido el final de una historia. En cambio, ha sido el punto de partida de esta misión. Cada vez que el PIR detecta movimiento, cada vez que la IA acierta — o falla y aprende — el Lince de la Noche recuerda su lema: no necesita superpoderes, necesita datos. Y los datos, bien cuidados, son la mejor herramienta que tenemos para que Sierra Bermeja siga siendo un lugar donde la fauna pueda esconderse, sobrevivir y, algún día, quizás, sorprendernos con una especie que hoy solo existe en nuestra esperanza.
Etiqueta:aprendizaje automático ESP32, cámara trampa visión artificial, conservación biodiversidad Estepona, ESP32-CAM Teachable Machine, fauna Sierra Bermeja, fototrampeo con IA en secundaria, fototrampeo Edge AI, inteligencia artificial en el borde, Misión 06 del Lince, proyecto MonteSTeam, robótica educativa STEAM



