Componentes · 20 min de leitura

TCRT5000 com Arduino: ligação do sensor IR, código e tacômetro

Use o TCRT5000 com Arduino: LED IR e fototransistor, detecção de superfície preta ou branca, saídas AO/DO, limite, alcance de 1–15 mm, FC-51 x TCRT5000 e código de RPM.

O TCRT5000 é um pequeno sensor infravermelho de reflexão usado em projetos com Arduino para detectar uma linha preta no chão, uma marca em um eixo girando ou uma superfície a poucos milímetros à sua frente. Usar o TCRT5000 com Arduino é fácil: você liga o módulo pronto a 5V, GND e um único pino de sinal; não precisa de biblioteca, analogRead() ou digitalRead() já bastam. Como um mesmo encapsulamento reúne um LED infravermelho que emite luz e um fototransistor que mede a luz refletida, ele é o olho em comum de robôs seguidores de linha, de impressoras que detectam o papel e de tacômetros que medem velocidade.

Neste artigo você vai aprender como o LED IR e o fototransistor dentro do TCRT5000 trabalham juntos, por que ele diferencia superfícies pretas e brancas com tanta facilidade, a diferença entre as saídas analógica (AO) e digital (DO) do módulo e como ajustar o limite pelo potenciômetro e pelo software. Você também vai ver, passo a passo e com código para Arduino Uno, ESP32 e Raspberry Pi Pico, a distância de trabalho de 1–15 mm do sensor, o efeito da luz ambiente e uma técnica de medição que o elimina, como ele se diferencia do sensor de obstáculos FC-51 e como montar um tacômetro (medidor de RPM) com o TCRT5000.

Sensor infravermelho de reflexão TCRT5000: LED IR azul e fototransistor preto
TCRT5000: a peça com lente azul é um LED infravermelho de 950 nm, e a peça com lente preta é um fototransistor com filtro de luz do dia; os dois ficam lado a lado no mesmo encapsulamento, separados por uma parede que bloqueia a luz.

O que é o TCRT5000 e como ele funciona?

O TCRT5000 é um sensor óptico reflexivo desenvolvido pela Vishay. Um lado do encapsulamento abriga um LED que emite luz infravermelha, o outro um fototransistor sensível à luz, e os dois apontam para a mesma direção, para a frente do sensor. A parede de plástico entre eles impede que a luz do LED chegue diretamente ao fototransistor; a luz só é detectada quando bate em uma superfície à frente e volta. Um fototransistor é um transistor que deixa passar mais corrente pelo coletor à medida que mais luz cai sobre a região da base: quanto mais luz a superfície reflete, maior a corrente de coletor. A lente preta é um filtro de luz do dia; ela bloqueia a maior parte da luz visível e só deixa passar comprimentos de onda próximos do infravermelho.

CaracterísticaValor (datasheet da Vishay)
ConstruçãoLED infravermelho + fototransistor, encapsulamento que bloqueia a luz visível
Comprimento de onda do LED950 nm (infravermelho invisível)
Melhor distância de operação2,5 mm
Faixa de operação0,2–15 mm (sinal acima de 20% do pico)
Tensão direta do LEDTípica de 1,25 V, máx. 1,5 V (a 60 mA)
Corrente contínua máx. do LED60 mA
FototransistorVCEO 70 V, corrente de coletor máx. de 100 mA
Corrente de escuroTípica de 10 nA, máx. 200 nA
Dimensões10,2 × 5,8 × 7 mm; o TCRT5000L é a versão de terminais longos (15 mm)
Temperatura de operação−25 a +85 °C

O Arduino não consegue ler a corrente do fototransistor diretamente; para transformar a corrente em tensão, um resistor de carga é ligado ao coletor. Nos módulos prontos ele costuma ser de 10 kΩ e puxa o coletor para VCC. A tensão no coletor é dada por V = VCC − Ic × R. Se uma superfície branca faz circular cerca de 0,4 mA pelo fototransistor, a queda sobre os 10 kΩ é de 4 V e a saída cai para 1 V. Se a corrente cai para 20 µA sobre uma superfície preta, a queda é de apenas 0,2 V e a saída fica em 4,8 V. Ou seja, em um módulo TCRT5000 o branco dá tensão baixa e o preto, tensão alta; essa lógica invertida confunde no começo, mas é simplesmente o funcionamento do circuito. Um resistor de carga maior deixa o sensor mais sensível, porém mais lento; um menor o deixa mais rápido, mas incapaz de distinguir reflexões fracas.

Como o TCRT5000 diferencia o preto do branco?

O papel branco espalha de volta, em todas as direções, a maior parte da luz infravermelha que o atinge; tinta preta fosca, toner ou fita absorvem a maior parte da luz e a transformam em calor. O TCRT5000 converte essa diferença em uma grande diferença na corrente do fototransistor. Mas o sensor não enxerga cores como o olho humano; o que importa para ele é quanto a superfície reflete em 950 nm. Isso traz algumas surpresas: certas impressões a jato de tinta parecem pretíssimas a olho nu, mas são quase transparentes no infravermelho, e o sensor as toma por branco. Fita isolante preta brilhante pode devolver a luz direto, como um espelho, quando o sensor olha para ela de frente. Superfícies vermelhas, laranja e amarelas muitas vezes são lidas como quase brancas. Por isso, sempre teste o material da linha e do piso com o sensor antes de se decidir. A tabela abaixo mostra valores de exemplo obtidos a 5 V e a uma altura de cerca de 3 mm; as suas leituras podem variar conforme o sensor e o ambiente.

SuperfícieReflexão infravermelhaAO (Uno, 0–1023)DO (maioria dos módulos)
Papel brancoMuito altaCerca de 30–200LOW, LED de status aceso
Madeira clara ou mesaAltaCerca de 100–400Geralmente LOW
Fita preta fosca ou impressão a laserMuito baixaCerca de 600–1000HIGH, LED de status apagado
Fita isolante preta brilhanteDepende do ânguloInstávelInstável
Nenhuma superfície embaixo (mais de 2 cm)Sem reflexãoPerto de 1000HIGH, como no preto
Não esqueça a última linha da tabela: sem nada à frente, o sensor também lê preto. É por isso que os motores de um seguidor de linha continuam girando como se tivessem “achado a linha” quando você levanta o robô da mesa. Uma regra simples que para os motores quando todos os sensores veem preto ao mesmo tempo protege tanto o seu robô quanto a sua mesa.

O módulo TCRT5000: saída analógica (AO) e digital (DO)

Na maioria das vezes se usa um módulo pronto em vez do TCRT5000 sozinho. Ao lado do sensor, a placa do módulo traz um comparador LM393, um potenciômetro azul de ajuste, um resistor que limita a corrente do LED IR, o resistor de carga de 10 kΩ do fototransistor e dois LEDs pequenos: um é o LED de alimentação, o outro um LED de status que mostra a saída DO. O pino AO é ligado diretamente ao coletor do fototransistor e fornece a tensão bruta que você calculou acima. O LM393 compara essa tensão com a tensão no cursor do potenciômetro e escreve o resultado no pino DO. Nos módulos comuns, o DO vai para LOW sobre uma superfície branca e o LED de status acende; sobre o preto, ou sem nada à frente, ele vai para HIGH e o LED apaga. Como a lógica é invertida em algumas placas, confira primeiro o comportamento do seu módulo no Monitor Serial. A maioria dos módulos de um canal tem 4 pinos (VCC, GND, DO, AO); também existem versões de 3 pinos só com DO, além de barras de sensores de linha com 3 e 5 canais. Um módulo consome cerca de 15–40 mA a 5 V, dependendo do resistor do LED IR.

CaracterísticaAO (analógica)DO (digital)
O que ela informaQuanta luz é refletidaSe está acima ou abaixo do limite
Leitura no UnoanalogRead(): 0–1023digitalRead(): HIGH ou LOW
LimiteVocê define no códigoPotenciômetro na placa
Sobre o brancoBaixa (cerca de 30–200)LOW
Sobre o pretoAlta (cerca de 600–1000)HIGH
Melhor usoEstimativa de distância, seguimento de linha com PID, calibraçãoContagem de RPM com interrupções, decisões simples de sim/não

Distância de trabalho: como aproveitar bem a faixa de 1–15 mm

Segundo o datasheet do TCRT5000, o sinal atinge o pico em 2,5 mm e fica acima de 20% desse pico entre 0,2 e 15 mm. Na prática, o sensor é utilizável de 1 a 15 mm, mas a diferença entre preto e branco diminui rápido à medida que a distância aumenta. A curva distância-sinal também não é de mão única: abaixo de 2 mm o sinal volta a cair, porque o cone de luz do LED e o campo de visão do fototransistor só se sobrepõem na superfície a partir de certa distância. Encoste o sensor em uma superfície e até o papel branco é lido como escuro. Assim, o mesmo valor analógico pode aparecer tanto a 1 mm quanto a 5 mm; se você quiser estimar distância, use só a região de mão única além de 3 mm.

DistânciaO que acontece?Indicado para
0–1 mmO cone de luz e o campo de visão não se sobrepõem; até o branco é lido fracoEvite; não deixe o sensor arrastar no chão
2–3 mmSinal mais forte, maior diferença entre preto e brancoSeguimento de linha, detecção de papel e de marcas
3–8 mmO sinal cai, mas a diferença ainda é nítidaMontagem segura embaixo de um robô, tacômetro
8–15 mmSó superfícies brancas e brilhantes são percebidasDetecção de proximidade, objeto presente/ausente
Além de 15 mmO sinal se perde no ruído ambienteEscolha outro sensor, como o FC-51 ou o HC-SR04

Também dá para medir distâncias curtas com o TCRT5000: como o valor analógico muda de forma regular com a distância sobre a mesma superfície, você pode fazer leituras em alguns pontos, como 3, 5, 8 e 12 mm, montar uma tabela e interpolar linearmente entre eles. Mas essa medição depende da cor da superfície: um sensor calibrado em papel branco vai achar que uma superfície cinza está mais longe do que realmente está. Por isso, pense no TCRT5000 não como uma régua, mas como um sensor de proximidade que responde “está chegando mais perto ou se afastando?” sobre a mesma superfície. Para medir centímetros, o sensor de distância HC-SR04 é muito mais adequado.

Ligação do módulo TCRT5000: Arduino Uno, ESP32 e Pico

Pino do móduloArduino UnoESP32Raspberry Pi Pico
VCC5V3V33V3(OUT), pino 36
GNDGNDGNDGND, pino 38
DOD2 (pino de interrupção)GPIO 27GP15, pino 20
AOA0GPIO 34 (ADC1)GP26 / ADC0, pino 31
Os pinos do ESP32 e do Pico são projetados para 3,3 V. Nessas placas, alimente o módulo TCRT5000 pelo pino 3V3, não pelo 5V nem pelo VBUS: em um módulo alimentado com 5 V, as saídas AO e DO chegam perto de 5 V sobre o preto e podem danificar o pino de entrada. A 3,3 V a corrente do LED IR diminui, então a distância de detecção fica um pouco menor; isso é normal. Se você realmente precisar alimentar o módulo com 5 V, coloque um divisor de tensão na linha AO. Você pode ver o mapa completo de pinos da sua placa na ferramenta Pinagem.

Como ligar um TCRT5000 sem módulo?

O sensor sozinho tem quatro terminais: os dois do lado azul são o ânodo e o cátodo do LED IR, e os dois do lado preto são o coletor e o emissor do fototransistor. O jeito mais fácil de identificá-los é o modo diodo do multímetro: nos dois terminais do lado azul você vai ler cerca de 1,0–1,2 V em um único sentido; o terminal tocado pela ponta de prova vermelha nesse momento é o ânodo. Ligar o fototransistor invertido não o danifica, porque o resistor de 10 kΩ limita a corrente; ele simplesmente não funciona. Se a leitura não muda com a luz, troque de lugar os dois terminais do lado preto.

É preciso limitar a corrente do LED IR com um resistor. Você o calcula com R = (VCC − VF) / I: para 5 V, tensão direta de 1,2 V e 20 mA, o resultado é (5 − 1,2) / 0,02 = 190 Ω; o valor padrão mais próximo, 220 Ω, dá cerca de 17 mA, uma corrente que um pino do Arduino fornece com folga. Você também pode fazer esse cálculo com a ferramenta Resistor para LED. Ligue o emissor do fototransistor ao GND e o coletor ao 5V por meio de um resistor de 10 kΩ, e leve o coletor até o A0. Para diferenciar superfícies mais distantes ou mais escuras, você pode aumentar o resistor de carga para 47 kΩ; as superfícies brancas saturam rápido, mas as pequenas diferenças na faixa escura ficam maiores.

Terminal do TCRT5000Ligação (Arduino Uno)
Ânodo (lado azul)Ao 5V por meio de 220 Ω; ao D7 em vez do 5V para a medição da luz ambiente
Cátodo (lado azul)GND
Coletor (lado preto)Ao A0 e ao 5V por meio de 10 kΩ
Emissor (lado preto)GND

Passo a passo: detectando superfícies pretas e brancas com Arduino

  1. Ligue o pino VCC do módulo ao pino 5V do Arduino e o GND ao GND.
  2. Ligue o pino AO ao A0 e o pino DO ao D2.
  3. Para testar, cole uma tira de fita preta fosca de 2 cm de largura em uma folha de papel branco.
  4. Segure ou fixe o sensor cerca de 3 mm acima da superfície, perpendicular a ela.
  5. Carregue o código abaixo e abra o Monitor Serial em 9600 baud.
  6. Durante os primeiros 5 segundos, passe o sensor algumas vezes, para lá e para cá, sobre a fita preta e o papel branco; o código encontra o menor e o maior valor e calcula o limite sozinho.
  7. Mova o sensor entre o preto e o branco; o LED L da placa deve acender sobre o preto e apagar sobre o branco.
C++ (Arduino IDE)
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}

O código calcula o limite como (menor + maior) / 2: se você leu 80 no branco e 820 no preto, o limite é 450. Em vez de um único limite, ele usa dois: passa para preto quando o valor sobe acima de 490 e volta para branco quando cai abaixo de 410. Graças a essa histerese, a saída não fica oscilando quando o sensor está exatamente na borda da linha. Se a diferença ficar abaixo de 100 durante a calibração, o código usa um limite padrão de 450 e avisa você; isso geralmente significa que o sensor está alto demais ou foi passado sobre uma cor só. A coluna DO mostra a mesma decisão tomada pelo potenciômetro do módulo; ver as duas lado a lado é um bom jeito de conferir o ajuste do potenciômetro.

Ajuste do limite: potenciômetro ou software?

Se você usa a saída DO, o limite é definido pelo potenciômetro da placa. A tensão no cursor do potenciômetro é a referência do comparador; no instante em que a tensão de AO a cruza, o DO muda de estado. Siga estes passos para um bom ajuste:

  1. Coloque o sensor sobre uma superfície branca, na altura em que vai usá-lo, e gire o potenciômetro até o LED de status acender.
  2. Deslize o sensor sobre a linha preta e confira se o LED apaga; se não apagar, gire o potenciômetro um pouco de volta.
  3. Encontre as duas posições extremas em que o LED fica claramente aceso sobre o branco e claramente apagado sobre o preto, e deixe o potenciômetro no meio do caminho entre elas.
  4. Para um ajuste mais fino, meça o AO sobre o branco e sobre o preto com um multímetro e ajuste a tensão no cursor do potenciômetro para o meio entre os dois valores; por exemplo, cerca de 2,4 V para 0,6 V e 4,2 V.
  5. Faça o ajuste sempre no lugar onde o robô ou a montagem vai funcionar, sob a mesma iluminação.
Um limite por software costuma ser mais flexível: você pode recalibrar quando a luz ambiente ou a tensão da bateria mudam e dar a cada um de vários sensores o seu próprio limite. A verdadeira vantagem da saída DO é a velocidade; o comparador decide em microssegundos e a saída pode ir direto para um pino de interrupção. Então use o DO para tarefas rápidas, como contar RPM, e o AO para tarefas finas, como seguimento de linha e estimativa de distância.

O efeito da luz ambiente e como resolvê-lo

O filtro de luz do dia da lente preta bloqueia a luz visível, mas não consegue bloquear o infravermelho, porque o próprio sensor funciona com infravermelho. A luz do sol e as lâmpadas incandescentes e halógenas emitem infravermelho forte em torno de 950 nm; quando essa luz chega ao fototransistor, até uma superfície preta é lida como branca. Sob sol direto, o fototransistor pode saturar por completo e o sensor não consegue diferenciar nada. Já as lâmpadas de LED e fluorescentes emitem muito pouco infravermelho, e é por isso que o mesmo robô pode funcionar perfeitamente na sala de aula e se confundir ao lado de uma janela. Estas são as soluções, da mais simples à mais difícil:

  • Faça sombra: Coloque uma saia preta, um tubo termorretrátil ou espuma preta em volta do sensor; isso bloqueia a luz que vem dos lados.
  • Mantenha baixo: Aproxime o sensor a 2–4 mm da superfície; a luz refletida fica mais forte e a parcela da luz ambiente fica menor.
  • Calibre no local: Defina o limite sempre no ambiente real e meça de novo na inicialização se a iluminação mudar.
  • Meça a diferença: Com o sensor sem módulo, acione o LED IR por um pino do Arduino e faça duas leituras, uma com o LED apagado e outra com ele aceso. A luz ambiente é a mesma nas duas leituras, então a diferença é apenas a reflexão do LED.
C++ (Arduino IDE)
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}

Um fototransistor não responde instantaneamente; com um resistor de carga de 10 kΩ, ele pode levar centenas de microssegundos para se estabilizar no novo valor, por isso o código espera 500 µs antes de cada leitura. Se as leituras estiverem instáveis, aumente SETTLE_US para 1000. Quanto maior a diferença, mais branca ou mais próxima é a superfície. Esse método não consegue vencer o sol por completo: se a luz ambiente já saturou o fototransistor, acender o LED não muda nada e a diferença cai a zero; aí a única solução é fazer sombra no sensor. Os controles remotos de TV aplicam a mesma ideia de forma muito mais rápida, enviando luz em rajadas de 38 kHz, e o receptor só escuta essa frequência; isso está explicado no artigo Receptor IR + controle remoto.

TCRT5000 x sensor de obstáculos FC-51: qual é a diferença?

Os dois são confundidos com frequência porque ambos são formados por um LED infravermelho e um receptor que mede a luz refletida, e ambos têm um comparador LM393. A diferença está na finalidade do projeto: o TCRT5000 junta emissor e receptor em um único encapsulamento, mirando um ponto pequeno a poucos milímetros à frente. Já o FC-51 usa um LED IR e um receptor separados, lado a lado, e procura a luz que volta de um obstáculo a vários centímetros de distância. É por isso que o FC-51 não consegue identificar com segurança uma linha fina no chão, e o TCRT5000 não enxerga uma parede a 10 cm.

CaracterísticaMódulo TCRT5000Sensor de obstáculos FC-51
ConstruçãoLED e fototransistor em um único encapsulamento, com uma parede entre elesLED IR e receptor separados, lado a lado
Distância de detecçãoCerca de 1–15 mm (melhor a 2,5 mm)Cerca de 2–30 cm (ajustável)
Área de detecçãoUm ponto estreitoCone de cerca de 35°
SaídasGeralmente AO + DOSó DO (LOW quando há obstáculo)
Uso típicoSeguimento de linha, tacômetro, detecção de papel e de marcasRobô que desvia de obstáculos, detecção de mão ou objeto
Luz ambienteMais resistente graças à distância curtaO alcance cai bastante sob o sol

Contando RPM com o TCRT5000 (tacômetro)

Uma das funções mais úteis, mas menos conhecidas, do TCRT5000 é medir a velocidade de algo que gira; até o datasheet da Vishay coloca sensor de posição para encoders de eixo no topo da lista de aplicações. A ideia é simples: você cola uma marca branca em um disco ou eixo pintado de preto; a cada vez que a marca passa pelo sensor, a saída DO vai para LOW uma vez. Contando esses pulsos, você pode calcular a velocidade de duas formas:

  • Método de contagem: rpm = número de pulsos × 60 / (número de marcas × tempo de medição em segundos). Se foram contados 25 pulsos em 1 segundo e o disco tem 1 marca, o resultado é 25 × 60 = 1500 rpm. É muito preciso em velocidades altas, mas, com uma janela de 1 segundo e uma única marca, a resolução é de 60 rpm.
  • Método do período: rpm = 60.000.000 / (microssegundos entre dois pulsos × número de marcas). Se passam 40.000 µs (40 ms) entre dois pulsos, o resultado é 60.000.000 / 40.000 = 1500 rpm. Ele dá um resultado novo e preciso a cada pulso, mesmo em velocidades baixas.
  • Número de marcas: Colocar 2 ou 4 marcas igualmente espaçadas no disco melhora a resolução do método de contagem; não se esqueça de alterar o número de marcas na fórmula.
  1. Pinte de preto fosco o eixo ou a roda que você quer medir, ou cubra com fita preta fosca.
  2. Cole sobre ele uma etiqueta de papel branco de cerca de 5 × 5 mm; a marca deve ser mais larga que o ponto para onde o sensor olha.
  3. Monte o sensor a 3–5 mm da marca, de forma que ele não possa vibrar.
  4. Gire o eixo devagar com a mão e confira se o LED do DO pisca a cada vez que a marca passa; ajuste o potenciômetro se necessário.
  5. Ligue o pino DO a um dos pinos de interrupção do Uno (D2 ou D3) e carregue o código abaixo.
C++ (Arduino IDE)
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}

Os pulsos são capturados com attachInterrupt(): não importa o que o processador esteja fazendo no loop(), onPulse() é executada no instante em que o DO cai, então nenhum pulso é perdido. As variáveis compartilhadas entre a rotina de interrupção e o loop() são declaradas como volatile, e o loop() as copia entre noInterrupts() e interrupts(); caso contrário, a interrupção poderia ocorrer enquanto um número de 4 bytes está sendo lido, e você obteria um valor atualizado pela metade. A saída do LM393 pode oscilar algumas vezes na borda entre preto e branco; MIN_GAP_US filtra isso ignorando pulsos que chegam com menos de 500 µs de intervalo. Com uma única marca, esse filtro permite leituras de até 120.000 rpm, então na prática não impõe limite para motores de hobby. Para saber mais sobre interrupções, veja o artigo Interrupções no Arduino.

Confira a sua montagem com um motor de velocidade conhecida: por exemplo, o motor TT amarelo com redução gira a cerca de 200 rpm sem carga a 6 V. Se a leitura sair exatamente o dobro, há um segundo ponto brilhante no disco que você não percebeu; cabeças de parafuso, cubos metálicos e bordas brilhantes também contam como marcas.

Usando o TCRT5000 com o ESP32

A mesma lógica funciona no ESP32, mas atenção a três diferenças. Primeiro, o módulo é alimentado pelo 3V3. Segundo, a entrada analógica é de 12 bits e dá valores de 0 a 4095; ligue o AO apenas a pinos ADC1 (GPIO 32–39), porque os pinos ADC2 não podem ser lidos com o Wi-Fi ligado. Terceiro, a rotina de interrupção é marcada com IRAM_ATTR e, como o ESP32 tem dois núcleos, as variáveis compartilhadas são protegidas com uma seção crítica portMUX. O código abaixo conta as duas marcas do disco e mostra o RPM e o valor analógico a cada meio segundo. Se você está começando com o ESP32, dê uma olhada antes em O que é o ESP32?.

C++ (Arduino IDE)
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 a janela de medição é de meio segundo, o código mede exatamente o tempo decorrido com millis() e o usa na fórmula: rpm = pulsos × 60.000 / (ms decorridos × número de marcas). Mostrar a velocidade em uma página web via Wi-Fi, ou enviar uma notificação para o celular quando ela cair abaixo de certo valor, é o que o ESP32 realmente acrescenta a este projeto. Como o valor analógico é lido ao mesmo tempo, você também pode observar se a distância do disco até o sensor muda, ou seja, se o eixo está balançando (descentrado).

Usando o TCRT5000 com o Raspberry Pi Pico e MicroPython

No Pico, alimente o módulo pelo pino 3V3(OUT), ligue o AO ao GP26 (ADC0) e o DO ao GP15. read_u16() retorna um valor de 0 a 65535; a leitura é baixa sobre o branco e alta sobre o preto. O código abaixo detecta a superfície e também calcula o RPM contando os pulsos da linha DO com uma interrupção. As interrupções do MicroPython não são tão rápidas quanto em C; elas funcionam com segurança até algumas centenas de pulsos por segundo, então prefira um Arduino ou um ESP32 para motores muito rápidos. Para a instalação e os primeiros passos, veja O que é o Raspberry Pi Pico?.

MicroPython
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)

Ideias de projetos com o TCRT5000

  • Robô seguidor de linha: Um robô que segue uma linha preta com uma barra de 2, 3 ou 5 sensores; a posição dos sensores e o ajuste do PID estão no artigo Robô seguidor de linha.
  • Robô que percebe a borda da mesa: Coloque um TCRT5000 voltado para baixo na frente do robô; na borda da mesa o sinal vira “preto” e o robô para antes de cair. Para o chassi e os motores, veja o guia Como fazer um carrinho robô.
  • Indicador de rotação do motor: Combine o código do tacômetro com um display OLED e mostre o RPM em dígitos grandes.
  • Encoder de roda e odômetro: Cole de 8 a 20 segmentos pretos e brancos na parte interna de uma roda, conte os pulsos, divida pelo número de segmentos e multiplique pela circunferência da roda para obter a distância percorrida. Se você também precisa do sentido, posicione dois sensores defasados em meio segmento, como em um encoder rotativo.
  • Contador de peças: Conte caixas brancas ou folhas de papel que passam em uma pequena esteira e mostre o total em um display.
  • Alarme de falta de papel: Aponte o sensor para a parte de trás de um rolo de etiquetas ou de impressora; no instante em que o papel acaba, a reflexão desaparece e um buzzer toca.
  • O mesmo princípio, fechado: Compare o TCRT5000 com um optoacoplador, em que um LED e um fototransistor ficam selados juntos em um único encapsulamento à prova de luz, para entender melhor como os sinais viajam pela luz.

Erros comuns e como corrigi-los

SintomaCausa provávelSolução
O AO fica em torno de 1000 e não mudaSensor muito longe da superfície, LED IR apagado ou AO no pino erradoAproxime o sensor a 3 mm, confira o LED IR com a câmera do celular, revise a ligação
Superfícies pretas são lidas como brancasLuz do sol ou de lâmpada incandescente, fita brilhante ou tinta que deixa o infravermelho passarFaça sombra no sensor, use fita fosca ou impressão a laser, ajuste o limite no local
O LED do DO nunca mudaPotenciômetro girado até um dos extremosEncontre o ponto em que o LED muda de estado e ajuste o potenciômetro a partir dele
O tacômetro mostra o dobro do RPM realUm segundo ponto brilhante no disco ou oscilação na bordaDeixe o disco totalmente fosco, aumente MIN_GAP_US, confira o valor de MARKS
No ESP32 o valor analógico é sempre 0 ou instávelO AO está em um pino ADC2 e o Wi-Fi está ligadoPasse o AO para um pino ADC1 entre GPIO 32 e 39
Os motores continuam girando quando o robô é levantadoSem superfície embaixo, o sensor lê pretoAdicione uma regra de segurança que pare os motores quando todos os sensores virem preto ao mesmo tempo
Você não consegue ver a olho nu se o LED IR está funcionando, mas a câmera do celular consegue: abra a câmera e aponte para o lado azul do sensor, e você deve ver um brilho branco-arroxeado na tela. Alguns celulares têm filtro infravermelho na câmera traseira; então, se não vir o brilho, tente a câmera frontal.

O TCRT5000 é um sensor barato, pequeno e muito didático: com uma única peça você aprende sobre fototransistores, comparadores, limite e histerese, interrupções e como lidar com a luz ambiente. Comece conhecendo os valores do seu próprio sensor com o código de detecção de superfície, depois meça velocidade com o tacômetro e, por fim, combine vários sensores embaixo de um robô. Se tiver curiosidade sobre outra forma simples de medir com luz, dê uma olhada também no artigo sensor de luz LDR. No app BlueGrays você encontra os projetos de detecção de superfície preta e branca com TCRT5000 e de medição de distância com TCRT5000, além do carrinho controlado por Bluetooth com L298N e do robô que desvia de obstáculos, todos com esquema do circuito e código passo a passo.

Perguntas frequentes

Para que serve o sensor TCRT5000?

O TCRT5000 é um sensor de reflexão que reúne um LED infravermelho e um fototransistor em um único encapsulamento. Ele mede quanta luz infravermelha uma superfície a poucos milímetros à frente reflete, então consegue diferenciar o preto do branco, contar marcas em um disco girando ou perceber um objeto muito próximo. É usado principalmente em robôs seguidores de linha, tacômetros e detecção de papel.

Qual é o alcance de detecção do TCRT5000?

O TCRT5000 trabalha na escala de milímetros, não de centímetros. Segundo o datasheet, o sinal mais forte fica a 2,5 mm e o sensor é utilizável de cerca de 0,2 a 15 mm; na prática, a faixa mais confiável é de 2–8 mm. Para distâncias maiores, escolha um sensor infravermelho de obstáculos FC-51 ou um sensor de distância ultrassônico HC-SR04.

O TCRT5000 dá HIGH ou LOW sobre o preto?

Nos módulos TCRT5000 comuns, a saída DO vai para LOW sobre o branco e o LED de status acende; sobre o preto, ou sem superfície à frente, ela vai para HIGH. A saída AO, da mesma forma, dá um valor baixo sobre o branco e um valor alto sobre o preto. Como a lógica é invertida em algumas placas, o melhor é conferir o seu próprio módulo no Monitor Serial.

Qual é a diferença entre o TCRT5000 e o FC-51?

O TCRT5000 é um sensor de reflexão com emissor e receptor em um único encapsulamento, que funciona a distâncias muito curtas, de cerca de 1–15 mm; é ideal para seguimento de linha e contagem de RPM. O FC-51 usa um LED IR e um receptor separados, detecta obstáculos a cerca de 2–30 cm e só tem saída digital. Resumindo: o TCRT5000 olha para o chão e o FC-51 olha para a frente.

O TCRT5000 consegue detectar cores?

Não, o TCRT5000 só mede quanta luz infravermelha em torno de 950 nm é refletida; ele não tem como saber a cor. Algumas cores se comportam de forma inesperada no infravermelho: superfícies vermelhas e amarelas muitas vezes são lidas como quase brancas, enquanto certas impressões pretas a jato de tinta são quase transparentes. Para diferenciar cores, use um sensor de cor como o TCS3200 ou o TCS34725.

O TCRT5000 funciona com o ESP32 e com 3,3 V?

Sim, os módulos TCRT5000 funcionam entre 3,3 e 5 V e, no ESP32 e no Raspberry Pi Pico, devem ser alimentados pelo pino 3V3. Assim, as saídas AO e DO nunca passam de 3,3 V e os pinos da placa ficam protegidos. A 3,3 V o LED IR consome menos corrente, então a distância de detecção fica um pouco menor; no ESP32, lembre-se de ligar o AO a um pino ADC1.

Ver todos os projetos
Detecção de superfícies pretas e brancas com TCRT5000
#78Intermediário
Premium

Detecção de superfícies pretas e brancas com TCRT5000

Com o pequeno sensor que funciona como o olho dos robôs seguidores de linha, você identifica se o piso é preto ou branco. O TCRT5000 emite luz invisível em direção ao piso e verifica quanto dela é ref

4.7(40)
49
Leitura de reflexão (proximidade) com TCRT5000
#77Intermediário
Premium

Leitura de reflexão (proximidade) com TCRT5000

Com um pequeno sensor que emite luz invisível e mede quanto dela é refletido, você detecta a superfície à frente dele. Quanto mais o sensor se aproxima de um objeto ou de uma superfície clara, mais lu

4.6(33)
43
Medição da intensidade da luz com LDR
#11Iniciante

Medição da intensidade da luz com LDR

Quer ver a luminosidade do seu quarto em números? O LDR, um pequeno componente sensível à luz, mede a luz ambiente, e o Arduino exibe o valor na tela do computador a cada meio segundo. Cubra o sensor

4.6(81)
139
Medição de distância com HC-SR04 (Monitor Serial)
#27Iniciante

Medição de distância com HC-SR04 (Monitor Serial)

O sensor HC-SR04 funciona como um morcego que se orienta no escuro: emite um som que você não consegue ouvir, escuta o eco e mede a distância até o objeto à sua frente. O Arduino escreve essa distânci

4.6(46)
71
Carrinho controlado por Bluetooth com L298N
#80Avançado
Premium

Carrinho controlado por Bluetooth com L298N

Transforme seu celular em um controle remoto e dirija seu próprio carrinho robô. O Arduino recebe os comandos de um aplicativo de controle remoto no celular por meio de um módulo Bluetooth e aciona as

5.0(38)
65
Robô que desvia de obstáculos
#81Avançado
Premium

Robô que desvia de obstáculos

Que tal construir um veículo inteligente que encontra seu próprio caminho? O robô que desvia de obstáculos monitora o ambiente constantemente com o sensor ultrassônico na parte da frente. Ao encontrar

5.0(38)
49
Sistema de alerta com laser
#22Intermediário
Premium

Sistema de alerta com laser

Você monta uma barreira de luz invisível, como nos filmes. Um laser ilumina um sensor de luz do outro lado; assim que alguém passa e interrompe o feixe, o LED acende e o buzzer soa. Quando o feixe vol

4.8(64)
83
Contador com display de 7 segmentos e botões
#43Avançado
Premium

Contador com display de 7 segmentos e botões

Um contador simples com três botões: ao pressionar um deles, o algarismo no display aumenta em um; com outro, diminui em um; e o terceiro zera a contagem. O display de 7 segmentos de um dígito conta d

4.6(35)
47