Caso práctico: Barrera de luz con LDR para contar objetos

Esquemático — Caso práctico: Barrera de luz con LDR para contar objetos

Objetivo y caso de uso

Qué construirás: Una barrera de luz con LED emisor y LDR en divisor resistivo conectada a un Arduino para detectar interrupciones del haz y contar objetos. Mostrará el conteo por puerto serie y un LED indicador de estado.

Para qué sirve

  • Contar piezas en una cinta transportadora artesanal (p. ej., tapas, tornillos).
  • Llevar conteo de envases que salen de una impresora 3D (resina o FDM) en un alimentador.
  • Detectar entradas/salidas de objetos en una caja clasificadora casera.
  • Controlar el número de sobres que pasan por una plegadora doméstica.

Resultado esperado

  • Señal analógica en A0 (V_A0) con dos niveles distinguibles: iluminado ≈ 3.5–4.8 V; haz interrumpido ≈ 0.2–1.2 V.
  • Umbral de detección estable (ADC_A0) con histéresis: conteo sin falsos disparos.
  • Mensaje por objeto en el puerto serie: “OBJETO n=<conteo> t_ms=<timestamp>”.
  • Latencia típica 30–80 ms; conteo fiable hasta ~10 objetos/s si el bloqueo dura ≥70 ms.
  • LED indicador en D3 encendido mientras el haz esté interrumpido.

Público objetivo: Personas que inician en electrónica con Arduino; Nivel: Básico

Arquitectura/flujo: LED emisor→LDR→Divisor→ADC (Arduino)→Umbral e histéresis

Materiales

  • 1× LDR (fotoresistencia) tipo GL5528 o similar.
  • 1× Resistencia R1 10 kΩ (divisor).
  • 1× Condensador C1 100 nF (filtro en el nodo de la LDR).
  • 1× LED D2 de alta luminosidad (emisor del haz).
  • 1× Resistencia R3 330 Ω (limitadora para el LED emisor).
  • 1× LED D1 (indicador de detección).
  • 1× Resistencia R2 220 Ω (limitadora para el LED indicador).
  • 1× Arduino Uno/Nano (o compatible con ADC en A0).
  • 1× Protoboard y 10–15 jumpers.
  • 1× Cable USB para alimentar/programar el Arduino.
  • Tubo termorretráctil o pequeño tubo opaco (opcional, para colimar y evitar luz ambiente).

Guía de conexionado

  • Conecta [LDR1] entre +5V y VA node.
  • Conecta [R1] 10 kΩ entre VA node y GND.
  • Conecta [C1] 100 nF entre VA node y GND.
  • Conecta un cable desde VA node hasta el pin analógico A0 del Arduino (A0 node).
  • Conecta el pin 5V del Arduino a +5V y GND del Arduino a GND del circuito.
  • Conecta [R2] 220 Ω entre D3 node y VB node.
  • Conecta [D1] LED entre VB node y GND (ánodo a VB node, cátodo a GND).
  • Conecta el pin digital D3 del Arduino a D3 node.
  • Conecta [R3] 330 Ω entre +5V y el ánodo de [D2] LED EMISOR.
  • Conecta [D2] LED EMISOR entre la salida de [R3] y GND (ánodo hacia R3, cátodo a GND).
  • Alinea el LED emisor (D2) frente a la LDR de modo que el haz la ilumine directamente; separa ambos 3–10 cm.

Esquemático

                  +5V
                  |
               [LDR1] LDR
                  |
        o VA node-+----------------[C1] 100nF----GND
                  |
                [R1] 10kΩ
                  |
                 GND

A0 node o------------------------o VA node

D3 node o----[R2] 220Ω----o VB node
                            |
                          [D1] LED
                            |
                           GND

+5V ---[R3] 330Ω---[D2] LED EMISOR---GND
                            ---
Esquemático (ASCII)

Firmware de ejemplo (Arduino)

  • Idea: autocalibrar el nivel “iluminado” al arrancar, usar histéresis y una ventana de guarda (100 ms) para evitar dobles conteos.
// Barrera de luz con LDR para contar objetos
const byte PIN_ADC = A0;
const byte PIN_LED_IND = 3;

unsigned long conteo = 0;
bool hazPresente = true;
unsigned long tUltimoEvento = 0;

int baseIluminado = 800;   // se estimará en setup
int margen = 200;          // ajustable según montaje
int umbralAlta, umbralBaja;

void recalcularUmbrales() {
  umbralBaja = baseIluminado - margen;     // cruzar hacia abajo = objeto
  umbralAlta = baseIluminado - (margen/2); // volver arriba = haz restablecido
}

void setup() {
  pinMode(PIN_LED_IND, OUTPUT);
  digitalWrite(PIN_LED_IND, LOW);
  Serial.begin(115200);
  delay(300);

  // Autocalibración (asume haz NO bloqueado durante 1–2 s)
  long suma = 0;
  const int N = 300;
  for (int i = 0; i < N; i++) {
    suma += analogRead(PIN_ADC);
    delay(5);
  }
  baseIluminado = (int)(suma / N);
  margen = constrain(margen, 80, 400); // seguro
  recalcularUmbrales();

  Serial.print("Base iluminado: "); Serial.println(baseIluminado);
  Serial.print("UmbralBaja: "); Serial.println(umbralBaja);
  Serial.print("UmbralAlta: "); Serial.println(umbralAlta);
}

void loop() {
  int adc = analogRead(PIN_ADC);

  // Adaptación lenta del baseline cuando el haz está presente
  if (hazPresente) {
    baseIluminado = (int)(0.995 * baseIluminado + 0.005 * adc);
    recalcularUmbrales();
  }

  unsigned long ahora = millis();

  // Detección con histéresis y ventana de guarda
  if (hazPresente && adc < umbralBaja && (ahora - tUltimoEvento) > 100) {
    hazPresente = false;
    conteo++;
    tUltimoEvento = ahora;
    digitalWrite(PIN_LED_IND, HIGH);
    Serial.print("OBJETO n="); Serial.print(conteo);
    Serial.print(" t_ms="); Serial.println(ahora);
  } else if (!hazPresente && adc > umbralAlta) {
    hazPresente = true;
    digitalWrite(PIN_LED_IND, LOW);
  }

  // Telemetría opcional (comentar si no se necesita)
  // Serial.println(adc);
  delay(2); // ~500 lecturas/s
}
Esquemático (ASCII)

Consejos de calibración:
– Si ves falsos positivos por luz ambiente, aumenta margen a 250–300 o acerca el LED emisor a la LDR.
– Si no detecta, reduce margen a 120–150 o reorienta la alineación LED–LDR.

Mediciones y pruebas

  • Referencias y nomenclatura:

    • V_A0: tensión en VA node respecto a GND (se mide con multímetro entre VA node y GND).
    • ADC_A0: lectura de analogRead(A0) en cuentas (0–1023).
    • t_evento: marca de tiempo en ms (millis) al detectar un objeto.
  • Verificación eléctrica básica:

    • Conecta el multímetro entre +5V y GND: debe medir 4.8–5.1 V.
    • Mide V_A0 con el haz iluminando la LDR: esperado 3.5–4.8 V.
    • Mide V_A0 bloqueando el haz con un cartón: esperado 0.2–1.2 V.
    • Criterio de éxito: diferencia V_A0_iluminado − V_A0_bloqueado ≥ 2.0 V.
  • Validación del divisor y filtro:

    • Observa ADC_A0 en el Monitor Serie (descomenta Serial.println(adc)).
    • Con el haz presente: ADC_A0 estable (variación < ±10 cuentas).
    • Al bloquear: caída rápida (> 200–400 cuentas).
    • C1 100 nF debe reducir el ruido; prueba a quitarlo para apreciar su efecto.
  • Prueba funcional de conteo:

    • Haz pasar un objeto por la barrera: el LED en D3 debe encenderse durante el bloqueo.
    • El puerto serie debe imprimir “OBJETO n=… t_ms=…”.
    • Repite 20 veces a ritmo humano; criterio de éxito: ≥ 20/20 detecciones correctas.
  • Rendimiento (latencia y velocidad):

    • Usa objetos finos y muévelos rápido para acortar el tiempo de bloqueo.
    • Observa t_evento y compara con el momento real (cronómetro).
    • Latencia típica: 30–80 ms.
    • Frecuencia máxima fiable: ~10 objetos/s si el bloqueo dura ≥70 ms (limitación por la respuesta de la LDR).
  • Robustez a luz ambiente:

    • Enciende/Apaga luces de la sala y mide ADC_A0 con haz presente.
    • Criterio: variación < 100 cuentas; si es mayor, acerca el emisor, añade tubo opaco o aumenta margen.

Ajustes finos y colocación

  • Alineación: el LED emisor debe “apuntar” a la LDR en línea recta; usa un tubito opaco como colimador para ambos.
  • Distancia recomendada: 3–10 cm; mayor distancia reduce margen entre niveles.
  • Fondo y entorno: evita superficies reflectantes; coloca un fondo oscuro detrás de la LDR si hay reflejos.

Errores comunes

  • No usar resistencia limitadora con el LED emisor (D2) y quemarlo.
  • Invertir el LED indicador (D1): si no enciende, gira su polaridad.
  • Umbral (margen) inadecuado: valores demasiado bajos causan falsos; demasiado altos impiden detectar.
  • Mala alineación: la LDR no recibe suficiente luz; el nivel “iluminado” queda bajo.
  • Cableado ruidoso: VA node muy largo sin C1 produce falsos disparos.

Seguridad

  • No mires fijamente LED de alta luminosidad a corta distancia; evita apuntarlo a los ojos.
  • Alimenta solo desde 5 V del Arduino; no mezcles fuentes sin masa común.
  • Sujeta firmemente LED y LDR para que no se desalineen con vibraciones.

Mejoras y ampliaciones

  • Inmunidad a luz ambiente: modular el LED emisor (p. ej., 1 kHz) y demodular por software; o usar un receptor con filtro pasa‑banda.
  • Sensor más rápido: sustituir LDR por fototransistor o fotodiodo para detectar objetos más rápidos (> 50 objetos/s).
  • Interfaz: añadir display OLED/I2C o publicar los conteos por MQTT desde un ESP32/ESP8266.
  • Mecánica: añadir soportes impresos en 3D con ranura para estabilizar el haz y guiar objetos.

Más Casos Prácticos en Prometeo.blog

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a 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.

Quiz rápido

Pregunta 1: ¿Qué componente se usa como sensor para detectar la interrupción del haz de luz?




Pregunta 2: ¿En qué pin del Arduino se mide la señal analógica V_A0?




Pregunta 3: ¿Cuál es el rango típico de V_A0 cuando la LDR está iluminada por el LED emisor?




Pregunta 4: Para contar de forma fiable hasta ~10 objetos/s, ¿cuál debe ser la duración mínima del bloqueo del haz?




Pregunta 5: ¿Cuál es la latencia típica del sistema de detección y conteo?




Pregunta 6: ¿Qué pin digital controla el LED indicador que se enciende cuando el haz está interrumpido?




Pregunta 7: ¿Qué resistencia forma el divisor con la LDR para la lectura analógica?




Pregunta 8: ¿Qué mensaje se envía por el puerto serie cuando se detecta un objeto?




Pregunta 9: ¿Cuál es la función del condensador C1 de 100 nF en el nodo de la LDR?




Pregunta 10: ¿Cuál es la arquitectura/flujo correcta del sistema?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio