Il comparatore LM393 è uno di quei componenti che rendono un progetto con Arduino molto più pulito quando serve una decisione secca: sopra soglia o sotto soglia. Lo uso spesso con moduli per suono, luce, vibrazioni o barriere, perché converte un segnale analogico in un’uscita digitale semplice da leggere. Qui vedo come funziona davvero, come si collega senza errori, come si regola la soglia e quando conviene lasciarlo perdere in favore di analogRead().
I punti da tenere subito a mente
- Il LM393 è un doppio comparatore, non un amplificatore operazionale.
- L’uscita è open collector: per avere il livello alto serve una pull-up, interna o esterna.
- Su molti moduli il segnale digitale è attivo LOW, quindi la logica va letta al contrario.
- Se il segnale oscilla vicino alla soglia, servono isteresi o un filtro software di 10-20 ms.
- Per una semplice soglia il LM393 è più pratico dell’ADC; per un valore proporzionale è meglio
analogRead().
Che cosa fa davvero il LM393 con Arduino
Nel datasheet onsemi il LM393 è descritto come un doppio comparatore pensato per lavorare con alimentazione singola. In pratica confronta due tensioni e cambia stato quando una supera l’altra. La parte davvero importante, però, è l’uscita open collector: non genera da sola un livello alto, ma tira a massa la linea quando interviene. Per questo, con Arduino, io lo tratto sempre come un interruttore intelligente e non come un piccolo amplificatore.
Questa distinzione conta più di quanto sembri. Un op-amp serve a rinforzare o modellare un segnale; un comparatore decide. Il LM393 è utile proprio quando vuoi trasformare una misura lenta, rumorosa o variabile in un evento netto: luce presente o assente, suono oltre soglia o no, magnete vicino o lontano.
Nei moduli da hobbistica trovi spesso anche un trimmer per regolare la soglia e un LED di stato. È comodo, ma crea anche un equivoco frequente: molti pensano di avere un sensore “che misura”, mentre in realtà hanno un circuito che decide quando una condizione è stata superata. Da qui parte quasi sempre il collegamento corretto, e da lì il cablaggio diventa la parte più delicata.

Come collegarlo senza inciampare nell’uscita open collector
Il collegamento di base è semplice, ma solo se chiarisci subito quale versione stai usando: il chip nudo o un modulo già pronto. Con una schedina completa di solito hai VCC, GND, DO per l’uscita digitale e, in alcuni casi, AO per il segnale analogico grezzo del sensore. Il pin davvero importante per Arduino è quasi sempre DO, perché è quello generato dal comparatore.
| Pin del modulo | Dove va | Nota pratica |
|---|---|---|
VCC |
5 V o 3,3 V | Dipende dal modulo, non solo dal chip. |
GND |
Massa comune | Senza massa condivisa la lettura è inaffidabile. |
DO |
Un pin digitale, per esempio D2 | Spesso è attivo LOW quando la soglia viene superata. |
AO |
Un ingresso analogico, per esempio A0 | Presente solo su alcuni moduli, bypassa la decisione del comparatore. |
Se usi il LM393 “nudo”, la pull-up non va dimenticata: senza di lei l’uscita resta flottante quando il transistor interno è spento. Una resistenza da 4,7 kΩ o 10 kΩ verso VCC è una scelta solida. Per prove veloci può bastare anche INPUT_PULLUP sull’ingresso Arduino, ma è una soluzione più debole e meno robusta su cavi lunghi o in ambienti rumorosi.
C’è poi un’altra regola che evita guai banali: se il tuo microcontrollore lavora a 3,3 V, non tirare l’uscita a 5 V per abitudine. Il vantaggio dell’open collector è proprio la flessibilità di interfaccia, ma solo se tieni coerenti alimentazione, pull-up e livelli logici. Una volta che i collegamenti sono corretti, il comportamento del modulo si legge in poche righe di codice.
Codice minimo per leggere il segnale
La documentazione Arduino ricorda che digitalRead() restituisce HIGH o LOW. Sembra banale, ma con il LM393 evita molta confusione, perché l’evento spesso arriva come LOW attivo. Io parto quasi sempre da un sketch essenziale, verifico il comportamento sul Serial Monitor e solo dopo aggiungo la logica applicativa.
const byte pinDo = 2;
const byte pinLed = 13;
const byte pinAo = A0; // solo se il modulo espone anche l'uscita analogica
void setup() {
pinMode(pinDo, INPUT_PULLUP);
pinMode(pinLed, OUTPUT);
Serial.begin(115200);
}
void loop() {
int stato = digitalRead(pinDo);
digitalWrite(pinLed, stato == LOW ? HIGH : LOW);
int valore = analogRead(pinAo); // rimuovi questa riga se il modulo non ha AO
Serial.print("DO=");
Serial.print(stato);
Serial.print(" AO=");
Serial.println(valore);
delay(20);
}Questo esempio mostra due cose utili. La prima è che l’uscita digitale del comparatore può essere letta come un normale interruttore, con la sola accortezza dell’inversione logica. La seconda è che l’eventuale uscita analogica non è la stessa cosa del DO: se la usi, stai leggendo il sensore grezzo, non la soglia del comparatore.
Se il modulo non ha AO, non forzare il codice a tutti i costi: elimina la parte analogica e lavora solo sul digitale. Se invece vuoi capire meglio come cambia il segnale, tieni entrambe le letture per qualche minuto; spesso il confronto tra i due valori rivela subito perché un trigger scatta troppo presto o troppo tardi. Se però il segnale vibra vicino alla soglia, il problema non è il codice ma il modo in cui stai tarando il comparatore.
Tarare la soglia e tenere fermo il segnale
Il trimmer blu dei moduli LM393 è comodo proprio perché permette di spostare la soglia senza riprogettare nulla. Io lo regolo sempre con uno stimolo alla volta: prima imposto un valore chiaramente basso, poi porto il sistema vicino al punto di attivazione e solo dopo rifinisco. Girare il trimmer “a caso” quasi sempre porta a una soglia che sembra giusta in un momento e sballata dieci secondi dopo.
Il limite più comune è il rimbalzo vicino alla soglia. Quando il segnale oscilla intorno al punto di commutazione, il comparatore può cambiare stato più volte in pochi millisecondi. La soluzione migliore è una piccola isteresi, cioè una differenza tra soglia di salita e soglia di discesa; se il modulo non la prevede, puoi compensare con il software.
- Usa una media mobile di 5-10 campioni se il segnale è lento.
- Filtra gli eventi troppo ravvicinati con una finestra di 10-20 ms per i casi semplici.
- Aggiungi un condensatore da 100 nF vicino al modulo se l’alimentazione è rumorosa.
- Riduci la lunghezza dei cavi quando lavori con sensori molto sensibili.
- Se il trimmer è troppo “nervoso”, sposta la soglia più lontano dal punto di rumore.
Qui conviene essere onesti: il LM393 non fa miracoli. Se il sensore di partenza è instabile, il comparatore lo trasformerà solo in un instabile più pulito. La soglia si può stabilizzare abbastanza bene per applicazioni hobbistiche, ma se ti serve una misura fine, ripetibile e numerica, devi spostarti verso una lettura analogica o verso una catena di condizionamento del segnale più seria. Ed è proprio lì che conviene capire in quali scenari questo componente dà il meglio.
Dove il LM393 rende davvero il progetto più semplice
Il punto forte del LM393 è la sua naturalezza nei casi in cui ti serve un “sì” o “no”. Nei moduli da laboratorio o nei classici kit hobbistici lo trovi spesso sotto forma di schede per suono, luce, interruzione di fascio, vibrazione o rilevazione magnetica. Il bello non è solo il costo basso: è che ti evita di scrivere codice per interpretare una curva quando ti basta un evento.
| Scenario | Cosa legge Arduino | Perché il LM393 aiuta | Attenzione a |
|---|---|---|---|
| Soglia sonora |
DO su un pin digitale |
Trasforma un segnale audio in un trigger netto | Falsi positivi se il microfono è troppo vicino alla sorgente |
| Barriera IR | DO |
Restituisce una transizione pulita quando il fascio si interrompe | Allineamento meccanico tra emettitore e ricevitore |
| Rilevazione magnetica |
DO o AO
|
Permette un evento on/off immediato | Distanza reale del magnete e orientamento |
| Vibrazione o urto | DO |
Comodo per allarmi, contatori o avvisi rapidi | Montaggio meccanico troppo morbido |
In questi casi il comparatore fa esattamente ciò che serve: comprime il problema in una soglia. Il risultato è un codice più corto, una logica più chiara e meno tempo perso a decidere se un valore “quasi giusto” debba essere trattato come vero o falso. Nei moduli con LED di stato, poi, la diagnostica è immediata: guardi il LED, capisci se la soglia è stata superata e puoi correggere al volo.
Quando però il tuo obiettivo cambia e ti serve confrontare il LM393 con altre strade, la scelta diventa più interessante che “giusta” in assoluto. Da qui la domanda vera diventa se il comparatore sia la soluzione migliore o solo la più comoda.
Quando preferisco LM393, ADC o comparatore interno
Se devo essere pratico, io scelgo il LM393 quando voglio una soglia netta e poco codice. Scelgo l’ADC quando mi serve un numero, non un evento. E valuto il comparatore interno del microcontrollore solo quando voglio ridurre l’hardware e sono disposto a spendere più tempo nella configurazione. Sulla carta sembrano varianti simili, ma nella pratica cambiano molto per tempi, rumore e facilità di integrazione.
| Soluzione | Vantaggio principale | Limite principale | Quando la scelgo |
|---|---|---|---|
| Modulo LM393 | Soglia pronta e cablaggio semplice | Può oscillare vicino al punto di commutazione | Allarmi, barriere, rilevazioni on/off |
analogRead() |
Ti dà il valore grezzo da 0 a 1023 sull’UNO, come ricorda la documentazione Arduino | Richiede interpretazione software | Livelli, trend, letture proporzionali |
| Comparatore interno del microcontrollore | Nessun modulo esterno | Configurazione più tecnica e meno immediata | Progetti compatti o ottimizzati |
Nel caso di Arduino Uno, il vantaggio dell’ADC è evidente quando vuoi sapere “quanto” e non solo “se”. Il vantaggio del LM393, invece, è la rapidità mentale: leggi una soglia e reagisci. Il comparatore interno ha senso quando lavori su microcontrollori che lo espongono bene e hai bisogno di ridurre componenti, ma non lo considero la prima scelta per un progetto hobbistico rapido. In una guida pratica, la soluzione giusta è quasi sempre quella che ti fa arrivare a un test affidabile nel minor tempo possibile.
Con questi criteri il componente smette di essere un jolly da kit e diventa una scelta consapevole: utile quando vuoi un evento pulito, meno adatto quando vuoi una misura continua.
I controlli finali che mi evitano i falsi trigger
Prima di chiudere un prototipo con il LM393, faccio sempre gli stessi controlli. Sono banali, ma tagliano via gran parte dei comportamenti strani che fanno perdere tempo in debug.
- Massa comune tra modulo e Arduino.
- Pull-up coerente con la tensione di alimentazione.
- Soglia regolata con lo stimolo reale, non con il modulo “a vuoto”.
- Presenza di un piccolo filtro temporale se il segnale è rumoroso.
- Verifica della logica attiva LOW nel Serial Monitor prima di scrivere la parte finale del codice.
Se parti da qui, il LM393 smette di essere una fonte di sorprese e diventa quello che dovrebbe essere: un blocco affidabile, economico e molto utile quando il tuo progetto Arduino ha bisogno di una decisione chiara invece che di una lettura complicata.