Sensor TCRT5000 Arduino: conexión, código y tacómetro infrarrojo
Sensor TCRT5000 con Arduino: LED IR y fototransistor, detección de blanco y negro, salida AO/DO, umbral, rango de 1–15 mm, diferencia con el FC-51 y tacómetro.
El TCRT5000 es un pequeño sensor infrarrojo de reflexión que se usa en proyectos con Arduino para detectar una línea negra en el suelo, una marca en un eje que gira o una superficie a pocos milímetros delante de él. Usar el TCRT5000 con Arduino es muy fácil: conectas el módulo a 5V, GND y un solo pin de señal; no necesitas ninguna librería, basta con analogRead() o digitalRead(). Como en una misma cápsula hay un LED infrarrojo que emite la luz y un fototransistor que mide la luz reflejada, es el ojo común de los robots seguidores de línea, de las impresoras que detectan el papel y de los tacómetros que miden revoluciones.
En este artículo aprenderás cómo trabajan juntos el LED IR y el fototransistor del TCRT5000, por qué distingue tan fácilmente una superficie negra de una blanca, en qué se diferencian la salida analógica (AO) y la digital (DO) del módulo y cómo se ajusta el umbral con el potenciómetro y por software. También verás paso a paso, con código para Arduino Uno, ESP32 y Raspberry Pi Pico, la distancia de trabajo de 1–15 mm, el efecto de la luz ambiental y una técnica de medida que lo elimina, la diferencia con el sensor de obstáculos FC-51 y cómo construir un tacómetro (medidor de RPM) con el TCRT5000.

¿Qué es el TCRT5000 y cómo funciona?
El TCRT5000 es un sensor óptico reflectivo desarrollado por Vishay. En un lado de la cápsula hay un LED que emite luz infrarroja y en el otro un fototransistor sensible a esa luz; los dos miran en la misma dirección, hacia el frente del sensor. La pared de plástico que los separa impide que la luz del LED llegue directamente al fototransistor; la luz solo se detecta si choca con una superficie delante y rebota. Un fototransistor es un transistor que deja pasar más corriente por su colector cuanta más luz cae sobre su zona de base: cuanta más luz refleja la superficie, mayor es la corriente de colector. La lente negra es un filtro de luz diurna; bloquea la mayor parte de la luz visible y solo deja pasar longitudes de onda cercanas al infrarrojo.
| Característica | Valor (hoja de datos de Vishay) |
|---|---|
| Construcción | LED infrarrojo + fototransistor, cápsula que bloquea la luz visible |
| Longitud de onda del LED | 950 nm (infrarrojo invisible) |
| Distancia de trabajo óptima | 2,5 mm |
| Rango de trabajo | 0,2–15 mm (señal por encima del 20 % de su máximo) |
| Tensión directa del LED | Típica 1,25 V, máx. 1,5 V (a 60 mA) |
| Corriente continua máx. del LED | 60 mA |
| Fototransistor | VCEO 70 V, corriente de colector máx. 100 mA |
| Corriente de oscuridad | Típica 10 nA, máx. 200 nA |
| Tamaño | 10,2 × 5,8 × 7 mm; el TCRT5000L es la versión de patas largas (15 mm) |
| Temperatura de funcionamiento | De −25 a +85 °C |
Arduino no puede leer directamente la corriente del fototransistor; para convertirla en tensión se conecta una resistencia de carga al colector. En los módulos suele ser de 10 kΩ y lleva el colector a VCC. La tensión en el colector se obtiene con V = VCC − Ic × R. Si una superficie blanca hace circular unos 0,4 mA por el fototransistor, la caída en los 10 kΩ es de 4 V y la salida baja a 1 V. Si sobre negro la corriente cae a 20 µA, la caída es solo de 0,2 V y la salida se queda en 4,8 V. Es decir, en el módulo TCRT5000 el blanco da una tensión baja y el negro una alta; esta lógica invertida confunde al principio, pero es la consecuencia natural del circuito. Con una resistencia de carga mayor el sensor es más sensible pero más lento; con una menor es más rápido, pero ya no distingue las reflexiones débiles.
¿Cómo distingue el TCRT5000 el negro del blanco?
El papel blanco devuelve la mayor parte de la luz infrarroja que recibe, dispersándola en todas direcciones; la pintura negra mate, el tóner o la cinta negra absorben casi toda la luz y la convierten en calor. El TCRT5000 transforma esta diferencia en una gran diferencia de corriente en el fototransistor. Pero el sensor no ve los colores como el ojo humano; lo que le importa es cuánto refleja la superficie a 950 nm. Eso trae sorpresas: algunas impresiones de inyección de tinta parecen negrísimas a simple vista pero son casi transparentes en infrarrojo, y el sensor las toma por blanco. La cinta aislante negra brillante puede devolver la luz como un espejo cuando el sensor la mira de frente. Las superficies rojas, naranjas y amarillas suelen leerse casi como blanco. Por eso, prueba siempre con el sensor el material de la línea y del suelo antes de decidirte. La tabla muestra valores de ejemplo tomados a 5 V y a unos 3 mm de altura; tus lecturas pueden variar según el sensor y el entorno.
| Superficie | Reflexión infrarroja | AO (Uno, 0–1023) | DO (la mayoría de módulos) |
|---|---|---|---|
| Papel blanco | Muy alta | Unos 30–200 | LOW, LED de estado encendido |
| Madera clara o mesa | Alta | Unos 100–400 | Normalmente LOW |
| Cinta negra mate o impresión láser | Muy baja | Unos 600–1000 | HIGH, LED de estado apagado |
| Cinta aislante negra brillante | Depende del ángulo | Inestable | Inestable |
| Sin superficie debajo (a más de 2 cm) | Sin reflexión | Cerca de 1000 | HIGH, como el negro |
El módulo TCRT5000: salida analógica (AO) y digital (DO)
Casi siempre se usa un módulo ya montado en lugar del TCRT5000 suelto. Junto al sensor, la placa lleva un comparador LM393, un potenciómetro azul de ajuste, una resistencia que limita la corriente del LED IR, la resistencia de carga de 10 kΩ del fototransistor y dos pequeños LED: uno de alimentación y otro de estado que muestra la salida DO. El pin AO está conectado directamente al colector del fototransistor y entrega la tensión en bruto que calculaste antes. El LM393 compara esta tensión con la del cursor del potenciómetro y escribe el resultado en el pin DO. En los módulos habituales, DO pasa a LOW sobre blanco y el LED de estado se enciende; sobre negro, o sin nada delante, pasa a HIGH y el LED se apaga. Como en algunas placas la lógica está invertida, lo primero es comprobar en el Monitor Serie cómo se comporta tu módulo. La mayoría de los módulos de un canal tienen 4 pines (VCC, GND, DO, AO); también existen versiones de 3 pines solo con DO y regletas de 3 y 5 sensores para seguidores de línea. Un módulo consume unos 15–40 mA a 5 V, según la resistencia del LED IR.
| Característica | AO (analógica) | DO (digital) |
|---|---|---|
| Qué indica | Cuánta luz se refleja | Si está por encima o por debajo del umbral |
| Lectura en el Uno | analogRead(): 0–1023 | digitalRead(): HIGH o LOW |
| Umbral | Lo fijas tú en el código | Potenciómetro de la placa |
| Sobre blanco | Baja (unos 30–200) | LOW |
| Sobre negro | Alta (unos 600–1000) | HIGH |
| Mejor uso | Estimar distancia, seguir líneas con PID, calibración | Contar RPM con interrupciones, decisiones simples de sí/no |
Distancia de trabajo: cómo aprovechar el rango de 1–15 mm
Según la hoja de datos del TCRT5000, la señal alcanza su máximo a 2,5 mm y se mantiene por encima del 20 % de ese valor entre 0,2 y 15 mm. En la práctica el sensor funciona entre 1 y 15 mm, pero la diferencia entre negro y blanco se reduce rápidamente al aumentar la distancia. La curva distancia-señal tampoco es de un solo sentido: por debajo de 2 mm la señal vuelve a bajar, porque el cono de luz del LED y el campo de visión del fototransistor solo se superponen sobre la superficie a partir de cierta distancia. Si pegas el sensor a una superficie, hasta el papel blanco se lee oscuro. Así que el mismo valor analógico puede aparecer a 1 mm y a 5 mm; si quieres estimar distancias, usa solo la zona de un solo sentido, más allá de 3 mm.
| Distancia | ¿Qué ocurre? | Uso adecuado |
|---|---|---|
| 0–1 mm | El cono de luz y el campo de visión no se cruzan, incluso el blanco se lee débil | Evítalo; no dejes que el sensor roce el suelo |
| 2–3 mm | Señal más fuerte y mayor diferencia entre negro y blanco | Seguir líneas, detectar papel y marcas |
| 3–8 mm | La señal baja, pero la diferencia sigue siendo clara | Montaje seguro bajo un robot, tacómetro |
| 8–15 mm | Solo se notan superficies blancas y brillantes | Detección de proximidad, objeto presente o ausente |
| Más de 15 mm | La señal se pierde en el ruido ambiental | Elige otro sensor, como el FC-51 o el HC-SR04 |
Con el TCRT5000 también puedes medir distancias cortas: como sobre la misma superficie el valor analógico cambia de forma regular con la distancia, puedes medir en varios puntos, por ejemplo 3, 5, 8 y 12 mm, crear una tabla e interpolar linealmente entre ellos. Pero esta medida depende del color de la superficie: un sensor calibrado sobre papel blanco creerá que una superficie gris está más lejos de lo que está. Por eso, piensa en el TCRT5000 no como una regla, sino como un sensor de proximidad que responde a «¿se acerca o se aleja?» sobre la misma superficie. Para medir centímetros, el sensor de distancia HC-SR04 es mucho más adecuado.
Conexión del módulo TCRT5000: Arduino Uno, ESP32 y Pico
| Pin del módulo | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 | 3V3(OUT), pin 36 |
| GND | GND | GND | GND, pin 38 |
| DO | D2 (pin de interrupción) | GPIO 27 | GP15, pin 20 |
| AO | A0 | GPIO 34 (ADC1) | GP26 / ADC0, pin 31 |
¿Cómo se conecta un TCRT5000 suelto, sin módulo?
El sensor suelto tiene cuatro patas: las dos del lado azul son el ánodo y el cátodo del LED IR, y las dos del lado negro son el colector y el emisor del fototransistor. La forma más fácil de identificarlas es el modo diodo del multímetro: en las dos patas del lado azul leerás unos 1,0–1,2 V en un solo sentido; la pata que toca la punta roja en ese momento es el ánodo. Conectar el fototransistor al revés no lo daña, porque la resistencia de 10 kΩ limita la corriente; simplemente no funciona. Si la lectura no cambia con la luz, intercambia las dos patas del lado negro.
Debes limitar la corriente del LED IR con una resistencia. Se calcula con R = (VCC − VF) / I: para 5 V, 1,2 V de tensión directa y 20 mA sale (5 − 1,2) / 0,02 = 190 Ω; el valor normalizado más cercano, 220 Ω, deja pasar unos 17 mA, una corriente que un pin de Arduino entrega sin problema. También puedes hacer este cálculo con la herramienta resistencia para LED. Conecta el emisor del fototransistor a GND, el colector a 5V a través de una resistencia de 10 kΩ y lleva el colector a A0. Para distinguir superficies más lejanas o más oscuras puedes subir la resistencia de carga a 47 kΩ; el blanco se satura antes, pero las pequeñas diferencias en la zona oscura se hacen mayores.
| Pata del TCRT5000 | Conexión (Arduino Uno) |
|---|---|
| Ánodo (lado azul) | A 5V a través de 220 Ω; a D7 en vez de a 5V para medir la luz ambiental |
| Cátodo (lado azul) | GND |
| Colector (lado negro) | A A0 y a 5V a través de 10 kΩ |
| Emisor (lado negro) | GND |
Paso a paso: detectar superficies blancas y negras con Arduino
- Conecta el pin VCC del módulo al pin 5V del Arduino y GND a GND.
- Conecta el pin AO a A0 y el pin DO a D2.
- Para probar, pega una tira de cinta negra mate de 2 cm de ancho sobre una hoja de papel blanco.
- Sujeta o fija el sensor a unos 3 mm de la superficie y perpendicular a ella.
- Sube el código de abajo y abre el Monitor Serie a 9600 baudios.
- Durante los primeros 5 segundos, pasa el sensor varias veces sobre la cinta negra y el papel blanco; el código busca el valor más bajo y el más alto y calcula el umbral por sí solo.
- Mueve el sensor entre el negro y el blanco; el LED L de la placa debe encenderse sobre negro y apagarse sobre blanco.
1// TCRT5000 ile siyah-beyaz zemin algılama / Black-white surface detection with TCRT5000
2const int SENSOR_AO = A0; // modülün AO pini / module AO pin
3const int SENSOR_DO = 2; // modülün DO pini / module DO pin
4const int LED_PIN = 13; // kart üzerindeki L LED'i / onboard L LED
5const int HYST = 40; // histerezis payı / hysteresis margin
6
7int threshold = 450; // varsayılan eşik / default threshold
8bool onBlack = false;
9
10void setup() {
11 Serial.begin(9600);
12 pinMode(SENSOR_DO, INPUT); // modülde çekme direnci var / the module has its own pull-up
13 pinMode(LED_PIN, OUTPUT);
14
15 Serial.println(F("5 sn: sensoru siyah ve beyazin uzerinden gecir / sweep over black and white"));
16 digitalWrite(LED_PIN, HIGH); // kalibrasyon sürüyor / calibrating
17 int lo = 1023, hi = 0;
18 unsigned long start = millis();
19 while (millis() - start < 5000) {
20 int v = analogRead(SENSOR_AO);
21 if (v < lo) lo = v; // en beyaz / whitest
22 if (v > hi) hi = v; // en siyah / blackest
23 }
24 digitalWrite(LED_PIN, LOW);
25 if (hi - lo >= 100) {
26 threshold = (lo + hi) / 2; // eşik = (beyaz + siyah) / 2 / threshold = (white + black) / 2
27 } else {
28 Serial.println(F("Fark cok az, varsayilan esik / Too little contrast, default threshold"));
29 }
30 Serial.print(F("Beyaz/White: ")); Serial.print(lo);
31 Serial.print(F(" Siyah/Black: ")); Serial.print(hi);
32 Serial.print(F(" Esik/Threshold: ")); Serial.println(threshold);
33}
34
35void loop() {
36 int raw = analogRead(SENSOR_AO); // beyazda düşük, siyahta yüksek / low on white, high on black
37 bool doBlack = digitalRead(SENSOR_DO) == HIGH; // çoğu modülde siyahta HIGH / HIGH on black on most modules
38
39 if (!onBlack && raw > threshold + HYST) onBlack = true; // siyaha geçti / moved onto black
40 if (onBlack && raw < threshold - HYST) onBlack = false; // beyaza geçti / moved onto white
41
42 digitalWrite(LED_PIN, onBlack ? HIGH : LOW);
43 Serial.print(F("AO: ")); Serial.print(raw);
44 Serial.print(F(" DO: ")); Serial.print(doBlack ? F("SIYAH/BLACK") : F("BEYAZ/WHITE"));
45 Serial.print(F(" Kod/Code: ")); Serial.println(onBlack ? F("SIYAH/BLACK") : F("BEYAZ/WHITE"));
46 delay(100);
47}El código calcula el umbral como (mínimo + máximo) / 2: si lees 80 sobre blanco y 820 sobre negro, el umbral es 450. En lugar de un único umbral usa dos límites: pasa a negro cuando el valor supera 490 y vuelve a blanco cuando baja de 410. Gracias a esta histéresis, la salida no parpadea cuando el sensor está justo en el borde de la línea. Si durante la calibración la diferencia queda por debajo de 100, el código usa el umbral por defecto de 450 y te avisa; normalmente significa que el sensor está demasiado alto o que solo lo pasaste sobre un color. La columna DO muestra la misma decisión tomada por el potenciómetro del módulo; ver ambas juntas es una buena forma de comprobar el ajuste del potenciómetro.
Ajuste del umbral: ¿potenciómetro o software?
Si usas la salida DO, el umbral se fija con el potenciómetro de la placa. La tensión en el cursor del potenciómetro es la referencia del comparador; en cuanto la tensión AO la cruza, DO cambia de estado. Para un buen ajuste sigue estos pasos:
- Coloca el sensor sobre una superficie blanca a la altura a la que lo vayas a usar y gira el potenciómetro hasta que se encienda el LED de estado.
- Desliza el sensor sobre la línea negra y comprueba que el LED se apaga; si no, gira un poco el potenciómetro en sentido contrario.
- Busca las dos posiciones extremas en las que el LED está claramente encendido sobre blanco y claramente apagado sobre negro, y deja el potenciómetro en el punto medio.
- Para un ajuste más fino, mide AO sobre blanco y sobre negro con un multímetro y ajusta la tensión del cursor del potenciómetro a la mitad de ambos valores; por ejemplo, unos 2,4 V para 0,6 V y 4,2 V.
- Haz siempre el ajuste donde va a funcionar el robot o el montaje, con la misma iluminación.
El efecto de la luz ambiental y cómo eliminarlo
El filtro de luz diurna de la lente negra bloquea la luz visible, pero no el infrarrojo, porque el propio sensor trabaja con infrarrojo. La luz del sol y las bombillas incandescentes y halógenas emiten mucho infrarrojo alrededor de 950 nm; cuando esa luz llega al fototransistor, hasta una superficie negra se lee como blanca. Con sol directo el fototransistor puede saturarse por completo y el sensor no distingue nada. Las lámparas LED y fluorescentes, en cambio, emiten muy poco infrarrojo; por eso el mismo robot puede funcionar perfecto en clase y confundirse junto a una ventana. Estas son las soluciones, de la más sencilla a la más elaborada:
- Dale sombra: Pon alrededor del sensor una falda negra, un tubo termorretráctil o espuma negra; bloquea la luz que entra por los lados.
- Mantenlo bajo: Acerca el sensor a 2–4 mm de la superficie; la luz reflejada se hace más fuerte y el peso de la luz ambiental, menor.
- Calibra en el sitio: Fija siempre el umbral en el entorno real y vuelve a medir al arrancar si la iluminación cambia.
- Mide la diferencia: Con el sensor suelto, controla el LED IR desde un pin de Arduino y haz dos lecturas, una con el LED apagado y otra encendido. La luz ambiental es la misma en ambas, así que la diferencia es solo la reflexión del LED.
1// Ortam ışığını çıkaran ölçüm (çıplak TCRT5000) / Ambient-light-cancelling reading (bare TCRT5000)
2const int IR_LED = 7; // 220 Ω üzerinden IR LED anoduna / to the IR LED anode via 220 Ω
3const int SENSOR = A0; // kolektör, 10 kΩ ile 5V'a / collector, 10 kΩ pull-up to 5V
4const int SETTLE_US = 500; // fototransistörün oturma süresi / phototransistor settling time
5
6int readReflection() {
7 digitalWrite(IR_LED, LOW);
8 delayMicroseconds(SETTLE_US);
9 int ambient = analogRead(SENSOR); // yalnız ortam ışığı / ambient light only
10 digitalWrite(IR_LED, HIGH);
11 delayMicroseconds(SETTLE_US);
12 int lit = analogRead(SENSOR); // ortam + yansıma / ambient + reflection
13 digitalWrite(IR_LED, LOW);
14 return ambient - lit; // ışık arttıkça gerilim düşer / voltage drops as light rises
15}
16
17void setup() {
18 Serial.begin(115200);
19 pinMode(IR_LED, OUTPUT);
20}
21
22void loop() {
23 long sum = 0;
24 for (int i = 0; i < 8; i++) sum += readReflection(); // 8 ölçümün ortalaması / average of 8 readings
25 int reflection = sum / 8;
26 Serial.println(reflection); // büyük değer = beyaz ya da yakın / large = white or near
27 delay(50);
28}El fototransistor no responde al instante; con una resistencia de carga de 10 kΩ puede tardar cientos de microsegundos en estabilizarse en su nuevo valor, por eso el código espera 500 µs antes de cada lectura. Si las lecturas son inestables, sube SETTLE_US a 1000. Cuanto mayor es la diferencia, más blanca o más cercana es la superficie. Este método no puede vencer del todo al sol: si la luz ambiental ya ha saturado el fototransistor, encender el LED no cambia nada y la diferencia cae a cero; entonces la única solución es darle sombra al sensor. Los mandos a distancia aplican la misma idea mucho más rápido enviando la luz en ráfagas de 38 kHz, y el receptor solo escucha esa frecuencia; lo tienes explicado en el artículo receptor IR y mando a distancia.
TCRT5000 vs sensor de obstáculos FC-51: ¿cuál es la diferencia?
Se confunden a menudo porque los dos tienen un LED infrarrojo y un receptor que mide la luz reflejada, y ambos llevan un comparador LM393. La diferencia está en su finalidad: el TCRT5000 reúne emisor y receptor en una sola cápsula, apuntando a un pequeño punto a pocos milímetros delante. El FC-51, en cambio, usa un LED IR y un receptor separados, uno junto al otro, y busca la luz que vuelve de un obstáculo a varios centímetros. Por eso el FC-51 no distingue con fiabilidad una línea fina en el suelo, y el TCRT5000 no ve una pared a 10 cm.
| Característica | Módulo TCRT5000 | Sensor de obstáculos FC-51 |
|---|---|---|
| Construcción | LED y fototransistor en una cápsula, con pared entre ellos | LED IR y receptor separados, uno junto al otro |
| Distancia de detección | Unos 1–15 mm (óptima a 2,5 mm) | Unos 2–30 cm (ajustable) |
| Zona de detección | Un punto estrecho | Cono de unos 35° |
| Salidas | Normalmente AO + DO | Solo DO (LOW con obstáculo) |
| Uso típico | Seguir líneas, tacómetro, detectar papel y marcas | Robot que esquiva obstáculos, detección de manos u objetos |
| Luz ambiental | Más robusto gracias a la corta distancia | En pleno sol su alcance baja mucho |
Contar revoluciones con el TCRT5000 (tacómetro)
Una de las tareas más útiles y menos conocidas del TCRT5000 es medir a qué velocidad gira algo; la propia hoja de datos de Vishay pone el sensor de posición para encoders de eje en primer lugar de su lista de aplicaciones. La idea es sencilla: pegas una marca blanca en un disco o eje pintado de negro; cada vez que la marca pasa frente al sensor, la salida DO pasa una vez a LOW. Contando estos pulsos puedes calcular las RPM de dos formas:
- Método de conteo: RPM = número de pulsos × 60 / (número de marcas × tiempo de medida en segundos). Si se contaron 25 pulsos en 1 segundo y el disco tiene 1 marca, el resultado es 25 × 60 = 1500 RPM. Es muy preciso a altas velocidades, pero con una ventana de 1 segundo y una sola marca su resolución es de 60 RPM.
- Método del periodo: RPM = 60.000.000 / (microsegundos entre dos pulsos × número de marcas). Si entre dos pulsos pasan 40.000 µs (40 ms), el resultado es 60.000.000 / 40.000 = 1500 RPM. Da un resultado nuevo y preciso con cada pulso, incluso a bajas velocidades.
- Número de marcas: Poner 2 o 4 marcas igualmente espaciadas en el disco mejora la resolución del método de conteo; no olvides cambiar el número de marcas en la fórmula.
- Pinta de negro mate el eje o la rueda que quieres medir, o cúbrela con cinta negra mate.
- Pega encima una etiqueta de papel blanco de unos 5 × 5 mm; la marca debe ser más ancha que el punto al que mira el sensor.
- Fija el sensor a 3–5 mm de la marca, de forma que no vibre.
- Gira el eje despacio con la mano y comprueba que el LED DO parpadea cada vez que pasa la marca; ajusta el potenciómetro si hace falta.
- Conecta el pin DO a uno de los pines de interrupción del Uno (D2 o D3) y sube el código de abajo.
1// TCRT5000 ile takometre (devir ölçer) / Tachometer with TCRT5000
2const byte SENSOR_DO = 2; // DO -> D2 (kesme pini / interrupt pin)
3const byte MARKS = 1; // diskteki beyaz işaret sayısı / white marks on the disc
4const unsigned long MIN_GAP_US = 500; // daha sık darbeler titreşimdir / closer pulses are glitches
5
6volatile unsigned long pulseCount = 0;
7volatile unsigned long lastPulseUs = 0;
8volatile unsigned long periodUs = 0;
9
10void onPulse() {
11 unsigned long now = micros();
12 unsigned long gap = now - lastPulseUs;
13 if (gap < MIN_GAP_US) return; // sınırdaki titreşimi ele / filter edge chatter
14 if (lastPulseUs != 0) periodUs = gap; // iki darbe arası süre / time between pulses
15 lastPulseUs = now;
16 pulseCount++;
17}
18
19void setup() {
20 Serial.begin(115200);
21 pinMode(SENSOR_DO, INPUT);
22 attachInterrupt(digitalPinToInterrupt(SENSOR_DO), onPulse, FALLING); // beyaz işarette LOW olur / goes LOW on the white mark
23}
24
25void loop() {
26 static unsigned long lastPrint = 0;
27 if (millis() - lastPrint < 1000) return; // saniyede bir hesapla / calculate once per second
28 lastPrint = millis();
29
30 noInterrupts(); // paylaşılan değişkenleri güvenle kopyala / copy shared variables safely
31 unsigned long count = pulseCount;
32 pulseCount = 0;
33 unsigned long period = periodUs;
34 unsigned long last = lastPulseUs;
35 interrupts();
36
37 float rpmCount = count * 60.0 / MARKS; // sayma yöntemi / counting method
38 float rpmPeriod = 0;
39 if (period > 0 && micros() - last < 2000000UL) { // 2 sn darbe yoksa durmuş say / stopped after 2 s without pulses
40 rpmPeriod = 60000000.0 / (period * (float)MARKS); // periyot yöntemi / period method
41 }
42 Serial.print(F("Sayma/Count: "));
43 Serial.print(rpmCount, 0);
44 Serial.print(F(" rpm Periyot/Period: "));
45 Serial.print(rpmPeriod, 1);
46 Serial.println(F(" rpm"));
47}Los pulsos se capturan con attachInterrupt(): haga lo que haga el procesador en loop(), onPulse() se ejecuta en cuanto DO baja, así que no se pierde ningún pulso. Las variables que comparten la rutina de interrupción y loop() se declaran volatile, y loop() las copia entre noInterrupts() e interrupts(); si no, la interrupción podría saltar mientras se lee un número de 4 bytes y obtendrías un valor a medio actualizar. La salida del LM393 puede rebotar varias veces en el borde entre negro y blanco; MIN_GAP_US lo filtra ignorando los pulsos que llegan con menos de 500 µs de separación. Con una sola marca, este filtro permite medir hasta 120.000 RPM, así que en la práctica no pone ningún límite para motores de hobby. Para saber más sobre interrupciones, consulta el artículo interrupciones en Arduino.
Cómo usar el TCRT5000 con el ESP32
En el ESP32 funciona la misma lógica, pero ten en cuenta tres diferencias. Primera: el módulo se alimenta a 3V3. Segunda: la entrada analógica es de 12 bits y da valores de 0 a 4095; conecta AO solo a pines ADC1 (GPIO 32–39), porque los pines ADC2 no se pueden leer con el Wi-Fi activo. Tercera: la rutina de interrupción se marca con IRAM_ATTR y, como el ESP32 tiene dos núcleos, las variables compartidas se protegen con una sección crítica portMUX. El código de abajo cuenta las dos marcas del disco e imprime cada medio segundo las RPM y el valor analógico. Si el ESP32 es nuevo para ti, echa antes un vistazo a ¿Qué es el ESP32?.
1// ESP32 + TCRT5000: devir ölçer ve analog okuma / tachometer and analog reading
2const int SENSOR_DO = 27; // DO -> GPIO 27
3const int SENSOR_AO = 34; // AO -> GPIO 34 (ADC1)
4const int MARKS = 2; // diskteki beyaz işaret sayısı / white marks on the disc
5const uint32_t MIN_GAP_US = 300; // daha sık darbeler titreşimdir / closer pulses are glitches
6
7volatile uint32_t pulseCount = 0;
8volatile uint32_t lastPulseUs = 0;
9portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
10
11void IRAM_ATTR onPulse() { // kesme kodu IRAM'de durur / ISR lives in IRAM
12 uint32_t now = micros();
13 portENTER_CRITICAL_ISR(&mux);
14 if (now - lastPulseUs >= MIN_GAP_US) {
15 lastPulseUs = now;
16 pulseCount++;
17 }
18 portEXIT_CRITICAL_ISR(&mux);
19}
20
21void setup() {
22 Serial.begin(115200);
23 pinMode(SENSOR_DO, INPUT);
24 analogReadResolution(12); // 0-4095
25 attachInterrupt(digitalPinToInterrupt(SENSOR_DO), onPulse, FALLING);
26}
27
28void loop() {
29 static uint32_t lastMs = 0;
30 uint32_t nowMs = millis();
31 if (nowMs - lastMs < 500) return; // yarım saniyede bir / every half second
32 uint32_t elapsed = nowMs - lastMs;
33 lastMs = nowMs;
34
35 portENTER_CRITICAL(&mux); // iki çekirdeğe karşı koruma / protection across both cores
36 uint32_t pulses = pulseCount;
37 pulseCount = 0;
38 portEXIT_CRITICAL(&mux);
39
40 float rpm = pulses * 60000.0 / (elapsed * (float)MARKS); // dev/dk / revolutions per minute
41 int raw = analogRead(SENSOR_AO); // siyahta yüksek, beyazda düşük / high on black, low on white
42 Serial.printf("RPM: %.0f AO: %d\n", rpm, raw);
43}Como la ventana de medida es de medio segundo, el código mide con exactitud el tiempo transcurrido con millis() y lo usa en la fórmula: RPM = pulsos × 60.000 / (ms transcurridos × número de marcas). Mostrar las RPM en una página web por Wi-Fi o enviar un aviso al móvil cuando bajan de cierto valor es lo que de verdad aporta el ESP32 a este proyecto. Como el valor analógico se lee al mismo tiempo, también puedes vigilar si cambia la distancia del disco al sensor, es decir, si el eje cabecea.
Cómo usar el TCRT5000 con Raspberry Pi Pico y MicroPython
En el Pico, alimenta el módulo desde el pin 3V3(OUT), conecta AO a GP26 (ADC0) y DO a GP15. read_u16() devuelve un valor de 0 a 65535; se lee bajo sobre blanco y alto sobre negro. El código de abajo detecta la superficie y además calcula las RPM contando con una interrupción los pulsos de la línea DO. Las interrupciones de MicroPython no son tan rápidas como en C; funcionan bien hasta unos cientos de pulsos por segundo, así que para motores muy rápidos es mejor un Arduino o un ESP32. Para la instalación y los primeros pasos, consulta ¿Qué es la Raspberry Pi Pico?.
1# Raspberry Pi Pico: TCRT5000 ile zemin algılama ve devir sayma
2# Raspberry Pi Pico: surface detection and RPM counting with TCRT5000
3from machine import Pin, ADC
4import machine
5import time
6
7ao = ADC(26) # AO -> GP26 (ADC0)
8do = Pin(15, Pin.IN) # DO -> GP15
9led = Pin("LED", Pin.OUT) # kart üzerindeki LED / onboard LED
10
11MARKS = 1 # diskteki beyaz işaret sayısı / white marks on the disc
12MIN_GAP_US = 500 # daha sık darbeler titreşimdir / closer pulses are glitches
13count = 0
14last_us = time.ticks_us()
15
16def on_pulse(pin):
17 global count, last_us
18 now = time.ticks_us()
19 if time.ticks_diff(now, last_us) < MIN_GAP_US:
20 return # sınırdaki titreşimi ele / filter edge chatter
21 last_us = now
22 count += 1
23
24do.irq(trigger=Pin.IRQ_FALLING, handler=on_pulse) # beyaz işarette DO LOW olur / DO goes LOW on white
25
26while True:
27 time.sleep(1)
28 state = machine.disable_irq() # sayacı güvenle oku / read the counter safely
29 pulses = count
30 count = 0
31 machine.enable_irq(state)
32
33 raw = ao.read_u16() # 0-65535: beyazda düşük, siyahta yüksek / low on white, high on black
34 on_white = do.value() == 0 # çoğu modülde beyazda LOW / LOW on white on most modules
35 led.value(on_white)
36 rpm = pulses * 60 / MARKS
37 print("AO:", raw, "Zemin/Surface:", "BEYAZ/WHITE" if on_white else "SIYAH/BLACK", "RPM:", rpm)Ideas de proyectos con el TCRT5000
- Robot seguidor de línea: Un robot que sigue una línea negra con una regleta de 2, 3 o 5 sensores; la colocación de los sensores y el ajuste PID están en el artículo Robot seguidor de línea.
- Robot que detecta el borde de la mesa: Pon delante un TCRT5000 mirando hacia abajo; al llegar al borde de la mesa la señal pasa a «negro» y el robot se detiene antes de caer. Para el chasis y los motores, consulta la guía Cómo hacer un coche robot con Arduino.
- Indicador de RPM de un motor: Combina el código del tacómetro con una pantalla OLED y muestra las RPM en números grandes.
- Encoder de rueda y cuentakilómetros: Pega de 8 a 20 sectores blancos y negros en la cara interior de una rueda, cuenta los pulsos, divide entre el número de sectores y multiplica por la circunferencia de la rueda para obtener la distancia recorrida. Si también necesitas el sentido de giro, coloca dos sensores desplazados medio sector, como en un encoder rotativo.
- Contador de piezas: Cuenta las cajas blancas o las hojas que pasan por una pequeña cinta transportadora y muestra el total en una pantalla.
- Aviso de fin de papel: Apunta el sensor a la parte trasera de un rollo de etiquetas o de impresora; en cuanto se acaba el papel, desaparece la reflexión y suena un zumbador.
- El mismo principio, encapsulado: Compara el TCRT5000 con un optoacoplador, en el que un LED y un fototransistor van sellados en una misma cápsula opaca, para entender mejor cómo se transmite una señal con luz.
Errores frecuentes y cómo solucionarlos
| Síntoma | Causa probable | Solución |
|---|---|---|
| AO se queda en torno a 1000 y no cambia | Sensor demasiado lejos de la superficie, LED IR apagado o AO en el pin equivocado | Acerca el sensor a 3 mm, comprueba el LED IR con la cámara del móvil, revisa el cableado |
| Las superficies negras se leen como blancas | Luz solar o incandescente, cinta brillante o tinta que deja pasar el infrarrojo | Dale sombra al sensor, usa cinta mate o impresión láser, ajusta el umbral en el sitio |
| El LED DO nunca cambia | Potenciómetro girado hasta un extremo | Busca el punto en el que el LED conmuta y ajusta el potenciómetro en consecuencia |
| El tacómetro marca el doble de las RPM reales | Un segundo punto brillante en el disco o rebotes en el borde | Deja el disco totalmente mate, sube MIN_GAP_US y revisa el valor de MARKS |
| En el ESP32 el valor analógico es siempre 0 o inestable | AO está en un pin ADC2 y el Wi-Fi está activo | Pasa AO a un pin ADC1 entre GPIO 32 y 39 |
| Los motores siguen girando al levantar el robot | Sin superficie debajo, el sensor lee negro | Añade una regla de seguridad que pare los motores cuando todos los sensores vean negro a la vez |
El TCRT5000 es un sensor barato, pequeño y muy didáctico: con una sola pieza aprendes sobre fototransistores, comparadores, umbral e histéresis, interrupciones y cómo lidiar con la luz ambiental. Empieza por conocer los valores de tu sensor con el código de detección de superficie, mide después velocidades con el tacómetro y, por último, combina varios sensores bajo un robot. Si te interesa otra forma sencilla de medir con luz, echa también un vistazo al artículo sensor de luz LDR. En la app BlueGrays encontrarás los proyectos TCRT5000 detección de suelo blanco y negro y TCRT5000 medición de distancia, además del coche controlado por Bluetooth con L298N y el robot que esquiva obstáculos, todos paso a paso con esquema de conexión y código.
Preguntas frecuentes
¿Para qué sirve el sensor TCRT5000?
El TCRT5000 es un sensor de reflexión que combina un LED infrarrojo y un fototransistor en una misma cápsula. Mide cuánta luz infrarroja refleja una superficie situada a pocos milímetros, así que puede distinguir el negro del blanco, contar marcas en un disco que gira o notar un objeto muy cercano. Se usa sobre todo en robots seguidores de línea, tacómetros y detección de papel.
¿Qué distancia detecta el TCRT5000?
El TCRT5000 trabaja en milímetros, no en centímetros. Según su hoja de datos, la señal más fuerte se obtiene a 2,5 mm y el sensor se puede usar entre unos 0,2 y 15 mm; en la práctica el rango más fiable es de 2 a 8 mm. Para distancias mayores, elige el sensor de obstáculos infrarrojo FC-51 o el sensor ultrasónico HC-SR04.
¿El TCRT5000 da HIGH o LOW sobre negro?
En los módulos TCRT5000 habituales, la salida DO pasa a LOW sobre blanco y el LED de estado se enciende; sobre negro, o sin superficie delante, pasa a HIGH. La salida AO también da un valor bajo sobre blanco y alto sobre negro. Como en algunas placas la lógica está invertida, lo mejor es comprobar tu módulo en el Monitor Serie.
¿Qué diferencia hay entre el TCRT5000 y el FC-51?
El TCRT5000 es un sensor de reflexión con emisor y receptor en una misma cápsula que trabaja a distancias muy cortas, de 1 a 15 mm aproximadamente; es ideal para seguir líneas y contar RPM. El FC-51 usa un LED IR y un receptor separados, detecta obstáculos a unos 2–30 cm y solo tiene salida digital. En resumen, el TCRT5000 mira al suelo y el FC-51 mira hacia delante.
¿El TCRT5000 puede detectar colores?
No, el TCRT5000 solo mide cuánta luz infrarroja de unos 950 nm se refleja y no conoce el color. Algunos colores se comportan de forma inesperada en infrarrojo: las superficies rojas y amarillas suelen leerse casi como blanco, mientras que algunas impresiones negras de inyección de tinta son casi transparentes. Para distinguir colores, usa un sensor de color como el TCS3200 o el TCS34725.
¿Funciona el TCRT5000 con el ESP32 y 3,3 V?
Sí, los módulos TCRT5000 funcionan entre 3,3 y 5 V, y en el ESP32 y la Raspberry Pi Pico deben alimentarse desde el pin 3V3. Así las salidas AO y DO nunca superan los 3,3 V y los pines de la placa quedan protegidos. A 3,3 V el LED IR consume menos corriente y la distancia de detección se acorta un poco; en el ESP32 recuerda conectar AO a un pin ADC1.
Proyectos para hacer después de leer esto
Ver todos los proyectos
TCRT5000 Detección de superficie blanca y negra
Con el pequeño sensor que hace de ojo en los robots sigue líneas, sabrás si el suelo es negro o blanco. El TCRT5000 lanza una luz invisible hacia el suelo y mira cuánta vuelve; sobre blanco se enciend

Lectura de reflexión (proximidad) con TCRT5000
Con un pequeño sensor que emite luz invisible y mide cuánta rebota, detectas la superficie que tiene delante. Cuanto más se acerca un objeto o una superficie clara, más luz vuelve, y el Arduino escrib

Medir la intensidad de luz con LDR
¿Quieres ver en números cuánta luz hay en tu habitación? El LDR, una pequeña pieza sensible a la luz, mide la luz ambiente y el Arduino escribe el valor en la pantalla del ordenador cada medio segundo

HC-SR04 Medición de distancia (pantalla en serie)
El sensor HC-SR04 funciona igual que un murciélago que se orienta en la oscuridad: emite un sonido que no puedes oír, escucha el eco y mide a qué distancia está el objeto que tiene delante. El Arduino

Coche controlado por Bluetooth con L298N
Convierte tu móvil en un mando y conduce tu propio coche robot. El Arduino recibe por un módulo Bluetooth las órdenes de una app de control remoto en el móvil y mueve las ruedas con un controlador de

Robot para evitar obstáculos
¿Qué le parece construir un vehículo inteligente que encuentre su propio camino? El Robot Evitador de Obstáculos explora constantemente su entorno gracias al sensor ultrasónico que lleva delante. Cuan

Sistema de alerta láser
Montas una valla de rayos invisible, como en las películas. Un láser apunta a un sensor de luz al otro lado; en cuanto alguien pasa y corta el rayo, se enciende el LED y suena el zumbador, y cuando el

Contador con display de 7 segmentos y botones
Un contador sencillo con tres botones: con uno el número de la pantalla sube de uno en uno, con otro baja, y el tercero lo devuelve a cero. La pantalla de 7 segmentos de un solo dígito cuenta del 0 al
Más artículos
App BlueGrays
Monta este circuito paso a paso en tu teléfono
Esquema, código y lista de piezas en una sola pantalla. Más de 160 proyectos de Arduino, ESP32 y Pico listos para montar.
Escanea con tu teléfono
Apunta la cámara al código y se abrirá la tienda de apps de tu teléfono.
o ábrela en la tienda

