Sensore TCRT5000 Arduino: collegamento, codice e contagiri IR
Sensore TCRT5000 con Arduino: LED IR e fototransistor, rilevamento bianco/nero, uscite AO/DO, soglia, portata 1–15 mm, differenze con l'FC-51 e contagiri.
Il TCRT5000 è un piccolo sensore a infrarossi a riflessione usato nei progetti Arduino per rilevare una linea nera sul pavimento, un segno su un albero in rotazione o una superficie a pochi millimetri davanti a sé. Usare il TCRT5000 con Arduino è semplicissimo: colleghi il modulo a 5V, GND e un solo pin di segnale; non serve nessuna libreria, bastano analogRead() o digitalRead(). Dato che in un unico contenitore ci sono un LED a infrarossi che emette la luce e un fototransistor che misura la luce riflessa, è l'occhio comune dei robot seguilinea, delle stampanti che rilevano la carta e dei contagiri.
In questo articolo imparerai come lavorano insieme il LED IR e il fototransistor del TCRT5000, perché distingue così facilmente una superficie nera da una bianca, che differenza c'è tra l'uscita analogica (AO) e quella digitale (DO) del modulo e come si regola la soglia con il potenziometro e via software. Vedrai anche, passo dopo passo e con codice per Arduino Uno, ESP32 e Raspberry Pi Pico, la distanza di lavoro di 1–15 mm, l'effetto della luce ambientale e una tecnica di misura che lo elimina, la differenza con il sensore di ostacoli FC-51 e come costruire un contagiri (tachimetro) con il TCRT5000.

Che cos'è il TCRT5000 e come funziona?
Il TCRT5000 è un sensore ottico a riflessione sviluppato da Vishay. Su un lato del contenitore c'è un LED che emette luce infrarossa, sull'altro un fototransistor sensibile a questa luce; entrambi guardano nella stessa direzione, cioè davanti al sensore. La parete di plastica tra i due impedisce alla luce del LED di raggiungere direttamente il fototransistor; la luce viene rilevata solo se colpisce una superficie davanti e torna indietro. Un fototransistor fa passare più corrente nel collettore quanta più luce cade sulla sua zona di base: più luce riflette la superficie, maggiore è la corrente di collettore. La lente nera è un filtro per la luce diurna; blocca gran parte della luce visibile e lascia passare solo le lunghezze d'onda vicine all'infrarosso.
| Caratteristica | Valore (datasheet Vishay) |
|---|---|
| Struttura | LED a infrarossi + fototransistor, contenitore che blocca la luce visibile |
| Lunghezza d'onda del LED | 950 nm (infrarosso invisibile) |
| Distanza di lavoro ottimale | 2,5 mm |
| Campo di lavoro | 0,2–15 mm (segnale oltre il 20 % del massimo) |
| Tensione diretta del LED | Tipica 1,25 V, max 1,5 V (a 60 mA) |
| Corrente continua max del LED | 60 mA |
| Fototransistor | VCEO 70 V, corrente di collettore max 100 mA |
| Corrente di buio | Tipica 10 nA, max 200 nA |
| Dimensioni | 10,2 × 5,8 × 7 mm; il TCRT5000L è la versione con terminali lunghi (15 mm) |
| Temperatura di esercizio | Da −25 a +85 °C |
Arduino non può leggere direttamente la corrente del fototransistor; per trasformarla in tensione si collega al collettore una resistenza di carico. Sui moduli è di solito da 10 kΩ e porta il collettore verso VCC. La tensione sul collettore si ricava con V = VCC − Ic × R. Se una superficie bianca fa scorrere nel fototransistor circa 0,4 mA, la caduta sui 10 kΩ è di 4 V e l'uscita scende a 1 V. Se sul nero la corrente cala a 20 µA, la caduta è di soli 0,2 V e l'uscita resta a 4,8 V. Quindi nel modulo TCRT5000 il bianco dà una tensione bassa e il nero una tensione alta; questa logica invertita all'inizio confonde, ma è la conseguenza naturale del circuito. Con una resistenza di carico più grande il sensore diventa più sensibile ma più lento; con una più piccola diventa più veloce, ma non distingue più le riflessioni deboli.
Come distingue il TCRT5000 il nero dal bianco?
La carta bianca rimanda indietro gran parte della luce infrarossa che riceve, diffondendola in tutte le direzioni; la vernice nera opaca, il toner o il nastro nero assorbono quasi tutta la luce e la trasformano in calore. Il TCRT5000 converte questa differenza in una grande differenza di corrente nel fototransistor. Il sensore però non vede i colori come l'occhio umano; per lui conta quanto la superficie riflette a 950 nm. Ne nascono alcune sorprese: certe stampe a getto d'inchiostro sembrano nerissime a occhio nudo ma sono quasi trasparenti all'infrarosso, e il sensore le scambia per bianco. Il nastro isolante nero lucido può rimandare la luce come uno specchio quando il sensore lo guarda di fronte. Le superfici rosse, arancioni e gialle vengono spesso lette quasi come bianco. Per questo prova sempre con il sensore il materiale della linea e del pavimento prima di decidere. La tabella mostra valori di esempio misurati a 5 V e a circa 3 mm di altezza; le tue letture possono variare in base al sensore e all'ambiente.
| Superficie | Riflessione infrarossa | AO (Uno, 0–1023) | DO (la maggior parte dei moduli) |
|---|---|---|---|
| Carta bianca | Molto alta | Circa 30–200 | LOW, LED di stato acceso |
| Legno chiaro o scrivania | Alta | Circa 100–400 | Di solito LOW |
| Nastro nero opaco o stampa laser | Molto bassa | Circa 600–1000 | HIGH, LED di stato spento |
| Nastro isolante nero lucido | Dipende dall'angolo | Instabile | Instabile |
| Nessuna superficie sotto (oltre 2 cm) | Nessuna riflessione | Vicino a 1000 | HIGH, come il nero |
Il modulo TCRT5000: uscita analogica (AO) e digitale (DO)
Quasi sempre si usa un modulo già pronto invece del TCRT5000 nudo. Accanto al sensore, la scheda monta un comparatore LM393, un potenziometro di regolazione blu, una resistenza che limita la corrente del LED IR, la resistenza di carico da 10 kΩ del fototransistor e due piccoli LED: uno indica l'alimentazione, l'altro lo stato dell'uscita DO. Il pin AO è collegato direttamente al collettore del fototransistor e fornisce la tensione grezza calcolata sopra. L'LM393 confronta questa tensione con quella del cursore del potenziometro e scrive il risultato sul pin DO. Nei moduli più diffusi DO va a LOW sopra il bianco e il LED di stato si accende; sopra il nero, o senza nulla davanti, va a HIGH e il LED si spegne. Dato che su alcune schede la logica è invertita, come prima cosa controlla nel Monitor seriale come si comporta il tuo modulo. La maggior parte dei moduli a un canale ha 4 pin (VCC, GND, DO, AO); esistono anche versioni a 3 pin con solo DO e barre da 3 o 5 sensori per i robot seguilinea. Un modulo assorbe circa 15–40 mA a 5 V, a seconda della resistenza del LED IR.
| Caratteristica | AO (analogica) | DO (digitale) |
|---|---|---|
| Cosa indica | Quanta luce viene riflessa | Se si è sopra o sotto la soglia |
| Lettura su Uno | analogRead(): 0–1023 | digitalRead(): HIGH o LOW |
| Soglia | La imposti tu nel codice | Potenziometro sulla scheda |
| Sul bianco | Bassa (circa 30–200) | LOW |
| Sul nero | Alta (circa 600–1000) | HIGH |
| Ideale per | Stima della distanza, seguilinea con PID, calibrazione | Conteggio dei giri con interrupt, semplici decisioni sì/no |
Distanza di lavoro: come sfruttare l'intervallo di 1–15 mm
Secondo il datasheet del TCRT5000, il segnale raggiunge il massimo a 2,5 mm e resta sopra il 20 % di quel valore tra 0,2 e 15 mm. In pratica il sensore funziona tra 1 e 15 mm, ma la differenza tra nero e bianco si riduce rapidamente all'aumentare della distanza. La curva distanza-segnale non è nemmeno a senso unico: sotto i 2 mm il segnale torna a scendere, perché il cono di luce del LED e il campo visivo del fototransistor si sovrappongono sulla superficie solo oltre una certa distanza. Se appoggi il sensore a una superficie, anche la carta bianca risulta scura. Lo stesso valore analogico può quindi comparire sia a 1 mm sia a 5 mm; se vuoi stimare una distanza, usa solo la zona a senso unico oltre i 3 mm.
| Distanza | Cosa succede? | Uso adatto |
|---|---|---|
| 0–1 mm | Cono di luce e campo visivo non si sovrappongono, anche il bianco si legge debole | Da evitare; non far strisciare il sensore sul pavimento |
| 2–3 mm | Segnale più forte, massima differenza tra nero e bianco | Seguilinea, rilevamento di carta e segni |
| 3–8 mm | Il segnale cala ma la differenza resta netta | Montaggio sicuro sotto un robot, contagiri |
| 8–15 mm | Si notano solo le superfici bianche e lucide | Rilevamento di prossimità, oggetto presente o assente |
| Oltre 15 mm | Il segnale si perde nel rumore ambientale | Scegli un altro sensore, come FC-51 o HC-SR04 |
Con il TCRT5000 puoi anche misurare brevi distanze: dato che sulla stessa superficie il valore analogico varia in modo regolare con la distanza, puoi fare misure in alcuni punti, per esempio 3, 5, 8 e 12 mm, costruire una tabella e interpolare linearmente tra di essi. Questa misura però dipende dal colore della superficie: un sensore calibrato su carta bianca crederà che una superficie grigia sia più lontana di quanto è. Pensa quindi al TCRT5000 non come a un righello, ma come a un sensore di prossimità che risponde alla domanda «si avvicina o si allontana?» sulla stessa superficie. Per misurare i centimetri il sensore di distanza HC-SR04 è molto più adatto.
Collegamento del modulo TCRT5000: Arduino Uno, ESP32 e Pico
| Pin del modulo | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 | 3V3(OUT), pin 36 |
| GND | GND | GND | GND, pin 38 |
| DO | D2 (pin di interrupt) | GPIO 27 | GP15, pin 20 |
| AO | A0 | GPIO 34 (ADC1) | GP26 / ADC0, pin 31 |
Come si collega un TCRT5000 nudo, senza modulo?
Il sensore nudo ha quattro terminali: i due dal lato blu sono l'anodo e il catodo del LED IR, i due dal lato nero il collettore e l'emettitore del fototransistor. Il modo più semplice per riconoscerli è la funzione prova diodi del multimetro: sui due terminali del lato blu leggi circa 1,0–1,2 V in un solo verso; il terminale toccato in quel momento dal puntale rosso è l'anodo. Collegare il fototransistor al contrario non lo danneggia, perché la resistenza da 10 kΩ limita la corrente; semplicemente non funziona. Se la lettura non cambia con la luce, scambia i due terminali del lato nero.
La corrente del LED IR va limitata con una resistenza. Si calcola con R = (VCC − VF) / I: con 5 V, 1,2 V di tensione diretta e 20 mA si ottiene (5 − 1,2) / 0,02 = 190 Ω; il valore standard più vicino, 220 Ω, fa passare circa 17 mA, una corrente che un pin di Arduino fornisce senza problemi. Puoi fare questo calcolo anche con lo strumento resistenza per LED. Collega l'emettitore del fototransistor a GND, il collettore a 5V tramite una resistenza da 10 kΩ e porta il collettore su A0. Per distinguere superfici più lontane o più scure puoi aumentare la resistenza di carico a 47 kΩ; il bianco va presto in saturazione, ma le piccole differenze nella zona scura diventano più grandi.
| Terminale del TCRT5000 | Collegamento (Arduino Uno) |
|---|---|
| Anodo (lato blu) | A 5V tramite 220 Ω; su D7 invece che a 5V per la misura della luce ambientale |
| Catodo (lato blu) | GND |
| Collettore (lato nero) | Su A0 e a 5V tramite 10 kΩ |
| Emettitore (lato nero) | GND |
Passo dopo passo: rilevare il bianco e il nero con Arduino
- Collega il pin VCC del modulo al pin 5V di Arduino e GND a GND.
- Collega il pin AO ad A0 e il pin DO a D2.
- Per la prova, attacca una striscia di nastro nero opaco larga 2 cm su un foglio di carta bianca.
- Tieni o fissa il sensore a circa 3 mm dalla superficie, perpendicolare a essa.
- Carica il codice qui sotto e apri il Monitor seriale a 9600 baud.
- Nei primi 5 secondi passa più volte il sensore sopra il nastro nero e la carta bianca; il codice trova il valore minimo e quello massimo e calcola da solo la soglia.
- Sposta il sensore tra nero e bianco; il LED L della scheda deve accendersi sul nero e spegnersi sul bianco.
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}Il codice calcola la soglia come (minimo + massimo) / 2: se leggi 80 sul bianco e 820 sul nero, la soglia è 450. Invece di un'unica soglia usa due limiti: passa al nero quando il valore supera 490 e torna al bianco quando scende sotto 410. Grazie a questa isteresi l'uscita non sfarfalla quando il sensore si trova proprio sul bordo della linea. Se durante la calibrazione la differenza resta sotto 100, il codice usa la soglia predefinita di 450 e ti avvisa; di solito significa che il sensore è troppo alto o che lo hai passato su un solo colore. La colonna DO mostra la stessa decisione presa dal potenziometro del modulo; vederle affiancate è un buon modo per verificare la regolazione del potenziometro.
Regolazione della soglia: potenziometro o software?
Se usi l'uscita DO, la soglia si imposta con il potenziometro sulla scheda. La tensione sul cursore del potenziometro è il riferimento del comparatore; appena la tensione AO la supera, DO cambia stato. Per una buona regolazione segui questi passaggi:
- Metti il sensore sopra una superficie bianca all'altezza a cui lo userai e gira il potenziometro finché il LED di stato si accende.
- Fai scorrere il sensore sopra la linea nera e controlla che il LED si spenga; se non succede, gira un po' il potenziometro in senso opposto.
- Trova le due posizioni estreme in cui il LED è chiaramente acceso sul bianco e chiaramente spento sul nero, e porta il potenziometro a metà tra le due.
- Per una regolazione più fine misura AO sul bianco e sul nero con un multimetro e porta la tensione del cursore a metà dei due valori; per esempio circa 2,4 V con 0,6 V e 4,2 V.
- Fai sempre la regolazione dove lavorerà il robot o il montaggio, con la stessa illuminazione.
L'effetto della luce ambientale e come eliminarlo
Il filtro per la luce diurna della lente nera blocca la luce visibile, ma non l'infrarosso, perché il sensore stesso lavora con l'infrarosso. La luce del sole e le lampadine a incandescenza e alogene emettono molto infrarosso intorno a 950 nm; quando questa luce raggiunge il fototransistor, perfino una superficie nera viene letta come bianca. Sotto il sole diretto il fototransistor può andare completamente in saturazione e il sensore non distingue più nulla. Le lampade LED e fluorescenti, invece, emettono pochissimo infrarosso; ecco perché lo stesso robot può funzionare perfettamente in classe e confondersi vicino a una finestra. Queste sono le soluzioni, dalla più semplice alla più elaborata:
- Fai ombra: Metti intorno al sensore una gonnellina nera, una guaina termorestringente o della spugna nera; blocca la luce che arriva di lato.
- Tienilo basso: Avvicina il sensore a 2–4 mm dalla superficie; la luce riflessa aumenta e il peso della luce ambientale diminuisce.
- Calibra sul posto: Imposta sempre la soglia nell'ambiente reale e ripeti la misura all'avvio se l'illuminazione cambia.
- Misura la differenza: Con il sensore nudo pilota il LED IR da un pin di Arduino e fai due letture, una con il LED spento e una con il LED acceso. La luce ambientale è la stessa in entrambe, quindi la differenza è solo la riflessione 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}Il fototransistor non reagisce all'istante; con una resistenza di carico da 10 kΩ può impiegare centinaia di microsecondi per assestarsi sul nuovo valore, per questo il codice attende 500 µs prima di ogni lettura. Se le letture sono instabili, porta SETTLE_US a 1000. Più grande è la differenza, più la superficie è bianca o vicina. Questo metodo non può battere del tutto il sole: se la luce ambientale ha già saturato il fototransistor, accendere il LED non cambia nulla e la differenza scende a zero; allora l'unica soluzione è fare ombra al sensore. I telecomandi applicano la stessa idea molto più velocemente inviando la luce a impulsi a 38 kHz, e il ricevitore ascolta solo quella frequenza; lo trovi spiegato nell'articolo ricevitore IR e telecomando.
TCRT5000 o sensore di ostacoli FC-51: qual è la differenza?
Si confondono spesso perché entrambi sono formati da un LED a infrarossi e da un ricevitore che misura la luce riflessa, ed entrambi hanno un comparatore LM393. La differenza sta nello scopo: il TCRT5000 riunisce emettitore e ricevitore in un unico contenitore, puntati su un piccolo punto a pochi millimetri davanti. L'FC-51 invece usa un LED IR e un ricevitore separati, affiancati, e cerca la luce che torna da un ostacolo a diversi centimetri. Per questo l'FC-51 non riconosce in modo affidabile una linea sottile sul pavimento, e il TCRT5000 non vede un muro a 10 cm.
| Caratteristica | Modulo TCRT5000 | Sensore di ostacoli FC-51 |
|---|---|---|
| Struttura | LED e fototransistor in un contenitore, con una parete in mezzo | LED IR e ricevitore separati, affiancati |
| Distanza di rilevamento | Circa 1–15 mm (ottimale a 2,5 mm) | Circa 2–30 cm (regolabile) |
| Area di rilevamento | Un punto stretto | Cono di circa 35° |
| Uscite | Di solito AO + DO | Solo DO (LOW in presenza di ostacolo) |
| Uso tipico | Seguilinea, contagiri, rilevamento di carta e segni | Robot che evita gli ostacoli, rilevamento di mani o oggetti |
| Luce ambientale | Più robusto grazie alla breve distanza | Sotto il sole la portata cala molto |
Contare i giri con il TCRT5000 (contagiri)
Uno degli usi più pratici ma meno conosciuti del TCRT5000 è misurare quanto velocemente gira qualcosa; perfino il datasheet di Vishay mette il sensore di posizione per encoder d'albero al primo posto tra le applicazioni. L'idea è semplice: attacchi un segno bianco su un disco o un albero verniciato di nero; ogni volta che il segno passa davanti al sensore, l'uscita DO va una volta a LOW. Contando questi impulsi puoi calcolare la velocità in due modi:
- Metodo del conteggio: giri/min = numero di impulsi × 60 / (numero di segni × tempo di misura in secondi). Se in 1 secondo sono stati contati 25 impulsi e il disco ha 1 segno, il risultato è 25 × 60 = 1500 giri/min. È molto preciso ad alte velocità, ma con una finestra di 1 secondo e un solo segno la sua risoluzione è di 60 giri/min.
- Metodo del periodo: giri/min = 60.000.000 / (microsecondi tra due impulsi × numero di segni). Se tra due impulsi passano 40.000 µs (40 ms), il risultato è 60.000.000 / 40.000 = 1500 giri/min. Fornisce un risultato nuovo e preciso a ogni impulso, anche a bassa velocità.
- Numero di segni: Mettere sul disco 2 o 4 segni equidistanti migliora la risoluzione del metodo del conteggio; non dimenticare di cambiare il numero di segni nella formula.
- Vernicia di nero opaco l'albero o la ruota da misurare, oppure coprili con nastro nero opaco.
- Attacca sopra un'etichetta di carta bianca di circa 5 × 5 mm; il segno deve essere più largo del punto che il sensore guarda.
- Fissa il sensore a 3–5 mm dal segno, in modo che non possa vibrare.
- Gira l'albero lentamente a mano e controlla che il LED DO lampeggi a ogni passaggio del segno; se serve, regola il potenziometro.
- Collega il pin DO a uno dei pin di interrupt di Uno (D2 o D3) e carica il codice qui sotto.
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}Gli impulsi vengono catturati con attachInterrupt(): qualunque cosa stia facendo il processore in loop(), onPulse() viene eseguita nell'istante in cui DO scende, e nessun impulso va perso. Le variabili condivise tra la routine di interrupt e loop() sono dichiarate volatile, e loop() le copia tra noInterrupts() e interrupts(); altrimenti l'interrupt potrebbe scattare durante la lettura di un numero da 4 byte e otterresti un valore aggiornato a metà. L'uscita dell'LM393 può oscillare alcune volte sul confine tra nero e bianco; MIN_GAP_US elimina questi rimbalzi ignorando gli impulsi distanti meno di 500 µs. Con un solo segno questo filtro consente misure fino a 120.000 giri/min, quindi in pratica non pone alcun limite ai motori hobbistici. Per saperne di più sugli interrupt, leggi l'articolo interrupt di Arduino.
Usare il TCRT5000 con l'ESP32
Sull'ESP32 funziona la stessa logica, ma fai attenzione a tre differenze. Primo, il modulo si alimenta a 3V3. Secondo, l'ingresso analogico è a 12 bit e dà valori da 0 a 4095; collega AO solo ai pin ADC1 (GPIO 32–39), perché i pin ADC2 non si possono leggere con il Wi-Fi attivo. Terzo, la routine di interrupt si contrassegna con IRAM_ATTR e, dato che l'ESP32 ha due core, le variabili condivise vengono protette con una sezione critica portMUX. Il codice qui sotto conta i due segni del disco e stampa ogni mezzo secondo i giri al minuto e il valore analogico. Se l'ESP32 è una novità per te, dai prima un'occhiata a Che cos'è l'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}Dato che la finestra di misura è di mezzo secondo, il codice misura con precisione il tempo trascorso con millis() e lo usa nella formula: giri/min = impulsi × 60.000 / (ms trascorsi × numero di segni). Mostrare la velocità su una pagina web tramite Wi-Fi o inviare una notifica al telefono quando scende sotto un certo valore è ciò che l'ESP32 aggiunge davvero a questo progetto. Poiché il valore analogico viene letto nello stesso momento, puoi anche controllare se la distanza del disco dal sensore cambia, cioè se l'albero ha un'oscillazione.
Usare il TCRT5000 con Raspberry Pi Pico e MicroPython
Sul Pico alimenta il modulo dal pin 3V3(OUT), collega AO a GP26 (ADC0) e DO a GP15. read_u16() restituisce un valore da 0 a 65535; è basso sul bianco e alto sul nero. Il codice qui sotto rileva la superficie e calcola anche i giri contando con un interrupt gli impulsi sulla linea DO. Gli interrupt di MicroPython non sono veloci come in C; funzionano in modo affidabile fino a qualche centinaio di impulsi al secondo, quindi per motori molto veloci è meglio un Arduino o un ESP32. Per installazione e primi passi consulta Che cos'è il 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)Idee di progetti con il TCRT5000
- Robot seguilinea: Un robot che segue una linea nera con una barra da 2, 3 o 5 sensori; la disposizione dei sensori e la taratura del PID sono spiegate nell'articolo Robot seguilinea.
- Robot che riconosce il bordo del tavolo: Metti davanti un TCRT5000 rivolto verso il basso; al bordo del tavolo il segnale passa a «nero» e il robot si ferma prima di cadere. Per telaio e motori consulta la guida Costruire una macchina robot con Arduino.
- Indicatore dei giri di un motore: Unisci il codice del contagiri a un display OLED e mostra i giri al minuto con cifre grandi.
- Encoder per ruota e contachilometri: Attacca da 8 a 20 settori bianchi e neri sulla faccia interna di una ruota, conta gli impulsi, dividi per il numero di settori e moltiplica per la circonferenza della ruota per ottenere la distanza percorsa. Se ti serve anche il verso di rotazione, posiziona due sensori sfalsati di mezzo settore, come in un encoder rotativo.
- Contapezzi: Conta le scatole bianche o i fogli che passano su un piccolo nastro trasportatore e mostra il totale su un display.
- Avviso di fine carta: Punta il sensore sul retro di un rotolo di etichette o di una stampante; appena la carta finisce, la riflessione scompare e suona un buzzer.
- Lo stesso principio, sigillato: Confronta il TCRT5000 con un optoisolatore, in cui un LED e un fototransistor sono sigillati insieme in un contenitore opaco, per capire meglio come si trasmette un segnale con la luce.
Errori comuni e soluzioni
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| AO resta intorno a 1000 e non cambia | Sensore troppo lontano dalla superficie, LED IR spento o AO sul pin sbagliato | Avvicina il sensore a 3 mm, controlla il LED IR con la fotocamera del telefono, verifica i collegamenti |
| Le superfici nere vengono lette come bianche | Luce solare o a incandescenza, nastro lucido o inchiostro trasparente all'infrarosso | Fai ombra al sensore, usa nastro opaco o una stampa laser, regola la soglia sul posto |
| Il LED DO non cambia mai | Potenziometro a fine corsa | Trova il punto in cui il LED commuta e regola il potenziometro di conseguenza |
| Il contagiri mostra il doppio dei giri reali | Un secondo punto lucido sul disco o rimbalzi sul bordo | Rendi il disco del tutto opaco, aumenta MIN_GAP_US, controlla il valore di MARKS |
| Sull'ESP32 il valore analogico è sempre 0 o instabile | AO è su un pin ADC2 e il Wi-Fi è attivo | Sposta AO su un pin ADC1 tra GPIO 32 e 39 |
| I motori continuano a girare quando sollevi il robot | Senza superficie sotto, il sensore legge nero | Aggiungi una regola di sicurezza che fermi i motori quando tutti i sensori vedono nero contemporaneamente |
Il TCRT5000 è un sensore economico, piccolo e molto istruttivo: con un solo componente impari a conoscere fototransistor, comparatore, soglia e isteresi, interrupt e la gestione della luce ambientale. Inizia a conoscere i valori del tuo sensore con il codice di rilevamento della superficie, poi misura la velocità con il contagiri e infine combina più sensori sotto un robot. Se ti interessa un altro modo semplice di misurare con la luce, dai un'occhiata anche all'articolo sensore di luce LDR. Nell'app BlueGrays trovi i progetti TCRT5000 rilevamento di superficie bianca e nera e TCRT5000 misura della distanza, insieme alla macchina comandata via Bluetooth con L298N e al robot che evita gli ostacoli, tutti passo dopo passo con schema elettrico e codice.
Domande frequenti
A cosa serve il sensore TCRT5000?
Il TCRT5000 è un sensore a riflessione che unisce un LED a infrarossi e un fototransistor in un unico contenitore. Misura quanta luce infrarossa riflette una superficie a pochi millimetri di distanza, così può distinguere il nero dal bianco, contare i segni su un disco che gira o accorgersi di un oggetto molto vicino. Si usa soprattutto nei robot seguilinea, nei contagiri e nel rilevamento della carta.
Quanto lontano rileva il TCRT5000?
Il TCRT5000 lavora sulla scala dei millimetri, non dei centimetri. Secondo il datasheet il segnale più forte si ottiene a 2,5 mm e il sensore si può usare da circa 0,2 a 15 mm; in pratica l'intervallo più affidabile va da 2 a 8 mm. Per distanze maggiori scegli il sensore di ostacoli a infrarossi FC-51 o il sensore a ultrasuoni HC-SR04.
Il TCRT5000 dà HIGH o LOW sul nero?
Nei moduli TCRT5000 più diffusi l'uscita DO va a LOW sopra il bianco e il LED di stato si accende; sopra il nero, o senza superficie davanti, va a HIGH. Anche l'uscita AO dà un valore basso sul bianco e alto sul nero. Dato che su alcune schede la logica è invertita, la cosa migliore è controllare il tuo modulo nel Monitor seriale.
Che differenza c'è tra TCRT5000 e FC-51?
Il TCRT5000 è un sensore a riflessione con emettitore e ricevitore nello stesso contenitore che lavora a distanze molto brevi, circa 1–15 mm; è ideale per il seguilinea e il conteggio dei giri. L'FC-51 usa un LED IR e un ricevitore separati, rileva ostacoli a circa 2–30 cm e ha solo un'uscita digitale. In breve, il TCRT5000 guarda il pavimento e l'FC-51 guarda avanti.
Il TCRT5000 può riconoscere i colori?
No, il TCRT5000 misura solo quanta luce infrarossa intorno a 950 nm viene riflessa e non conosce il colore. Alcuni colori si comportano in modo inatteso all'infrarosso: le superfici rosse e gialle vengono spesso lette quasi come bianco, mentre certe stampe nere a getto d'inchiostro sono quasi trasparenti. Per distinguere i colori usa un sensore di colore come il TCS3200 o il TCS34725.
Il TCRT5000 funziona con l'ESP32 e a 3,3 V?
Sì, i moduli TCRT5000 funzionano tra 3,3 e 5 V e con ESP32 e Raspberry Pi Pico vanno alimentati dal pin 3V3. In questo modo le uscite AO e DO non superano mai i 3,3 V e i pin della scheda restano protetti. A 3,3 V il LED IR assorbe meno corrente e la distanza di rilevamento si accorcia un po'; sull'ESP32 ricordati di collegare AO a un pin ADC1.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
TCRT5000 Rilevamento di superfici bianche e nere
Con il piccolo sensore che fa da occhio ai robot seguilinea capisci se il pavimento è nero o bianco. Il TCRT5000 manda una luce invisibile verso il pavimento e controlla quanta ne torna indietro; sul

Lettura della riflessione (prossimità) con TCRT5000
Con un piccolo sensore che manda luce invisibile e misura quanta ne torna indietro, rilevi la superficie che ha davanti. Più un oggetto o una superficie chiara si avvicina, più luce ritorna, e l'Ardui

Misurare l'intensità luminosa con LDR
Vuoi vedere quanto è luminosa la tua stanza sotto forma di numero? L'LDR, un piccolo componente sensibile alla luce, misura la luce ambiente e l'Arduino scrive il valore sullo schermo del computer ogn

HC-SR04 Misura della distanza (display seriale)
Il sensore HC-SR04 funziona come un pipistrello che trova la strada al buio: manda un suono che non puoi sentire, ne ascolta l'eco e misura quanto è lontano l'oggetto davanti a sé. L'Arduino scrive qu

Auto controllata via Bluetooth con L298N
Trasforma il telefono in un telecomando e guida la tua auto robot. L'Arduino riceve tramite un modulo Bluetooth i comandi di un'app di controllo remoto sul telefono e fa girare le ruote con un driver

Robot che evita gli ostacoli
Che ne dite di costruire un veicolo intelligente che trova la propria strada? L'Obstacle Avoiding Robot scruta costantemente l'ambiente circostante grazie al sensore a ultrasuoni posto davanti a lui.

Sistema di allarme laser
Costruisci una barriera di raggi invisibile, proprio come nei film. Un laser punta su un sensore di luce dall'altra parte; appena qualcuno passa e interrompe il raggio, il LED si accende e il buzzer s

Contatore con display a 7 segmenti e pulsanti
Un contatore semplice con tre pulsanti: con uno la cifra sul display sale di uno, con un altro scende di uno, e il terzo la riporta a zero. Il display a 7 segmenti a una sola cifra conta da 0 a 9, e q
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

