In questo tutorial imparerai come funziona il sensore di movimento PIR HC-SR501 e come utilizzarlo con Arduino. I sensori a infrarossi passivi (PIR) sono ovunque: non sono usati solo per la sicurezza, ma anche nella maggior parte dei sistemi di illuminazione automatica.
In questo articolo ho incluso uno schema di collegamento e codici di esempio per iniziare a sperimentare con il tuo sensore. Dopo ogni esempio, spiego come funziona il codice, così potrai modificarlo facilmente secondo le tue esigenze.
Prima ti mostrerò come usare l’HC-SR501 come unità autonoma. Poi lo collegheremo a un Arduino UNO e ti spiegherò come usarlo come semplice sistema di allarme.
Questo tutorial si concentra sul sensore HC-SR501, ma puoi usare il codice fornito anche per sensori simili come il HC-SR505 o AM312. La differenza principale è che questi sensori più economici hanno un raggio di rilevamento minore e non dispongono di un potenziometro per regolare sensibilità e ritardo.
Materiale necessario
Componenti hardware
Software
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Come funziona un sensore di movimento PIR?
I sensori di movimento PIR sono composti da due parti principali: un elemento sensibile piroelettrico e una lente di Fresnel . L’elemento piroelettrico rileva la radiazione infrarossa. Tutti gli oggetti con temperatura superiore allo zero assoluto (0 Kelvin / -273,15 °C) emettono energia termica sotto forma di radiazione infrarossa, compresi i corpi umani.

Un sensore piroelettrico ha due fessure rettangolari realizzate in materiale trasparente agli infrarossi. Dietro queste ci sono due elettrodi separati, uno produce un’uscita positiva e l’altro una negativa. Questo perché si cerca una variazione nei livelli IR, non i livelli ambientali. I due elettrodi sono collegati in modo da annullarsi a vicenda. Se una metà rileva più o meno radiazione IR dell’altra, l’uscita varia in alto o in basso.
Il circuito integrato di elaborazione del segnale a bordo elabora questo segnale e imposta il pin di uscita del sensore su HIGH o LOW di conseguenza.

La cupola bianca davanti all’elemento sensibile è una lente di Fresnel. Questa lente concentra la radiazione infrarossa sul sensore.

Sensore di movimento PIR HC-SR501
Il sensore di movimento PIR HC-SR501 è basato sul circuito integrato BISS0001 Micro Power PIR Motion Detector. Questo IC è stato sviluppato appositamente per elaborare il segnale dei sensori PIR.
Rimuovendo la lente di Fresnel, si vede l’elemento piroelettrico RE200B. Sulla scheda è presente anche un regolatore di tensione integrato, quindi puoi alimentare la scheda con un ampio intervallo di tensioni DC, tipicamente 5 V.
Le specifiche dell’HC-SR501 sono riportate nella tabella sottostante; tieni presente che possono esserci piccole differenze tra i produttori.
Specifiche HC-SR501
| Tensione di funzionamento | 4,5 – 20 V |
| Corrente a riposo | 50 μA |
| Uscita livello | HIGH 3,3 V / LOW 0 V |
| Trigger | L trigger singolo / H trigger ripetuto |
| Tempo di ritardo | 3 – 300 s |
| Tempo di blocco | 2,5 s (default) |
| Trigger | L trigger singolo / H trigger ripetuto |
| Campo di misura | 3 – 7 m massimo |
| 2 mm | |
| Angolo di misura | < 110° angolo a cono |
| Dimensioni PCB | 32,5 x 24 mm |
| Fori di montaggio | 2 mm, distanza 28,5 mm |
| Dimensioni lente di Fresnel | 15 mm x 23 mm diametro |
| Temperatura di esercizio | -15 – 70 °C |
| Costo | Check price |
Per maggiori informazioni, puoi consultare i datasheet seguenti:
Regolazione dell’HC-SR501
Sul retro della scheda trovi due potenziometri e un jumper, che puoi usare per regolare diversi parametri:

Regolazione della sensibilità (portata)
L’HC-SR501 ha una distanza massima di rilevamento di 7 metri. Puoi regolare la distanza ruotando il potenziometro della sensibilità in senso orario o antiorario (vedi immagine sopra). Ruotandolo in senso orario aumenti la distanza fino a 7 metri, ruotandolo in senso antiorario la riduci fino a 3 metri.
Regolazione del ritardo temporale (Tx)
Questo potenziometro regola il tempo durante il quale l’uscita rimane HIGH dopo aver rilevato un movimento. Il ritardo minimo è di 3 secondi, il massimo di 300 secondi (5 minuti). Ruota in senso orario per aumentare il ritardo, in senso antiorario per diminuirlo.
Jumper di selezione del trigger
Il jumper (giallo) serve a selezionare una delle due modalità di trigger. Può essere impostato su L (trigger singolo) o H (trigger ripetuto):
- Trigger singolo – L’uscita diventa HIGH appena viene rilevato un movimento. Rimane HIGH per il tempo impostato dal potenziometro. Qualsiasi movimento durante questo periodo non viene considerato e non riavvia il timer.
- Trigger ripetuto – Ogni volta che viene rilevato un movimento, il timer di ritardo si riavvia.
La differenza tra modalità trigger singolo e ripetuto è mostrata nella figura sottostante.

Aggiungere un termistore e/o LDR all’HC-SR501
Come si vede nell’immagine sotto, l’HC-SR501 ha pad di saldatura per due componenti aggiuntivi, solitamente etichettati ‘RL’ e ‘RT’.

- RL – Qui puoi aggiungere un light dependent resistor (LDR) o fotoresistore che ha bassa resistenza in presenza di luce ambientale intensa. Questo fa sì che il rilevatore funzioni solo quando l’area di rilevamento è sufficientemente buia.
- RT – Questo pad è destinato a un thermistor. Aggiungendo questo componente la sensibilità del sensore dipende meno dalla temperatura ambiente.
Purtroppo nei datasheet non sono fornite ulteriori informazioni, quindi non sono sicuro dei valori dei componenti da usare.
Usare l’HC-SR501 come unità autonoma
Per molte applicazioni puoi usare l’HC-SR501 come unità autonoma. Puoi usare il segnale di uscita per attivare relè, LED e altro.
Il cablaggio è molto semplice come mostrato nella foto sotto. Collega VCC e GND a una batteria e un LED rosso tra il pin di uscita e massa. L’uscita è a 3,3 V, quindi ho aggiunto una resistenza da 68 Ω in serie al LED per limitare la corrente.

Nota che dopo aver alimentato il sensore devi aspettare 30 – 60 secondi per l’inizializzazione. Durante questo periodo il LED potrebbe lampeggiare un paio di volte. Dopo un minuto puoi agitare la mano davanti al sensore e dovresti vedere il LED accendersi.
Con questa configurazione è facile testare il funzionamento del sensore. È anche un buon momento per provare le regolazioni di sensibilità, ritardo e le due modalità di trigger.
Collegamento – Connettere il sensore PIR HC-SR501 a Arduino UNO
Collegando il sensore a un microcontrollore come Arduino UNO, puoi usarlo per controllare LED, relè, motori, buzzer ecc.
Nel diagramma di collegamento sotto puoi vedere come connetterlo ad Arduino. Puoi leggere il sensore con uno dei pin GPIO di Arduino. In questo esempio l’ho collegato al pin digitale 2. I pin VCC e GND sono collegati rispettivamente a 5 V e massa.

Le connessioni sono anche riportate nella tabella sottostante:
Connessioni sensore di movimento PIR HC-SR501
| Sensore PIR HC-SR501 | Arduino |
|---|---|
| VCC | 5 V |
| OUT | Pin 2 |
| GND | GND |
Una volta cablato il sensore, il passo successivo è caricare un codice di esempio.
Codice di esempio per sensore PIR HC-SR501 con Arduino UNO
Con il codice di esempio seguente puoi leggere il sensore e controllare il LED integrato di Arduino (collegato al pin 13). Questo codice può anche controllare relè semplici per accendere o spegnere luci più grandi.
Per far funzionare correttamente questo codice, è meglio impostare il jumper del trigger su ‘H’ (modalità trigger ripetuto). Regola anche il potenziometro del ritardo al valore più basso, ruotandolo completamente in senso antiorario.
Il codice legge lo stato del sensore (HIGH o LOW) e accende o spegne il LED integrato di conseguenza. Stampa anche un messaggio sul Monitor Seriale, accessibile da Tools o premendo (Ctrl+Shift+M).
/* Example code for HC-SR501 PIR motion sensor with Arduino.
More info: www.www.makerguides.com */
// Define connection pins:
#define pirPin 2
#define ledPin 13
// Create variables:
int val = 0;
bool motionState = false; // We start with no motion detected.
void setup() {
// Configure the pins as input or output:
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
// Begin serial communication at a baud rate of 9600:
Serial.begin(9600);
}
void loop() {
// Read out the pirPin and store as val:
val = digitalRead(pirPin);
// If motion is detected (pirPin = HIGH), do the following:
if (val == HIGH) {
digitalWrite(ledPin, HIGH); // Turn on the on-board LED.
// Change the motion state to true (motion detected):
if (motionState == false) {
Serial.println("Motion detected!");
motionState = true;
}
}
// If no motion is detected (pirPin = LOW), do the following:
else {
digitalWrite(ledPin, LOW); // Turn off the on-board LED.
// Change the motion state to false (no motion):
if (motionState == true) {
Serial.println("Motion ended!");
motionState = false;
}
}
}
Dovresti vedere il seguente output nel monitor seriale:

Spiegazione del codice:
Il codice è semplice e non richiede librerie Arduino per usare questo sensore.
Lo sketch inizia definendo il pin del sensore PIR e il pin del LED. Li ho collegati ai pin 2 e 13 di Arduino (LED integrato).
L’istruzione #define serve a dare un nome a un valore costante. Il compilatore sostituirà ogni riferimento a questa costante con il valore definito durante la compilazione. Quindi ovunque menzioni pirPin, il compilatore lo sostituirà con il valore 2 durante la compilazione.
Ho anche creato due variabili, val e motionState, che sono rispettivamente un integer e un boolean (vero/falso). La variabile val serve a memorizzare l’uscita del sensore PIR (HIGH o LOW) e motionState diventa true quando viene rilevato movimento e false quando non c’è movimento.
// Define connection pins: #define pirPin 2 #define ledPin 13 // Create variables: int val = 0; bool motionState = false; // We start with no motion detected.
Nel setup() impostiamo i pin come input o output con la funzione pinMode(pin,mode). Il pirPin è un input e il ledPin è un output. Iniziamo anche la comunicazione seriale a 9600 baud. Assicurati che il Monitor Seriale sia impostato a 9600.
void setup() {
// Configure the pins as input or output:
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
// Begin serial communication at a baud rate of 9600:
Serial.begin(9600);
}
Nel loop() leggo prima il sensore con la funzione digitalRead(pin). Questa funzione restituisce HIGH o LOW.
// Read out the pirPin and store as val: val = digitalRead(pirPin);
Quando l’uscita del sensore/val è HIGH, accendo il LED con la funzione digitalWrite(pin,value).
// If motion is detected (pirPin = HIGH), do the following:
if (val == HIGH) {
digitalWrite(ledPin, HIGH); // Turn on the on-board LED.
// Change the motion state to true (motion detected):
if (motionState == false) {
Serial.println("Motion detected!");
motionState = true;
}
}
Poi imposto motionState a true e stampo il messaggio ‘Motion detected!’ sul Monitor Seriale. Controllo prima lo stato attuale di motionState per assicurarmi che il messaggio venga stampato una sola volta per evento di movimento.
Se non c’è più movimento davanti al sensore, val cambia a LOW, il LED si spegne e viene stampato il messaggio ‘Motion ended!’ sul monitor seriale.
Creare un sistema di allarme con sensore PIR e buzzer
Con qualche modifica semplice puoi creare un sistema di allarme con l’HC-SR501 e un piezoelectric buzzer. Ho collegato il buzzer con una resistenza da 100 Ω tra il pin digitale 5 e massa. Probabilmente puoi usare il buzzer senza resistenza (sarà più forte), ma il suono sarà meno gradevole.

Il codice sotto è quasi identico all’esempio precedente. Ho aggiunto solo una funzione per creare il suono di allarme intermittente. Puoi cambiare il tono del buzzer modificando il parametro di input della funzione alarm(duration,frequency).
/* Example code to create an alarm system with HC-SR501 PIR motion sensor, buzzer and Arduino.
More info: www.www.makerguides.com */
// Define connection pins:
#define buzzerPin 5
#define pirPin 2
#define ledPin 13
// Create variables:
int val = 0;
bool motionState = false; // We start with no motion detected.
void setup() {
// Configure the pins as input or output:
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
// Begin serial communication at a baud rate of 9600:
Serial.begin(9600);
}
void loop() {
// Read out the pirPin and store as val:
val = digitalRead(pirPin);
// If motion is detected (pirPin = HIGH), do the following:
if (val == HIGH) {
digitalWrite(ledPin, HIGH); // Turn on the on-board LED.
alarm(500, 1000); // Call the alarm(duration, frequency) function.
delay(150);
// Change the motion state to true (motion detected):
if (motionState == false) {
Serial.println("Motion detected!");
motionState = true;
}
}
// If no motion is detected (pirPin = LOW), do the following:
else {
digitalWrite(ledPin, LOW); // Turn off the on-board LED.
noTone(buzzerPin); // Make sure no tone is played when no motion is detected.
delay(150);
// Change the motion state to false (no motion):
if (motionState == true) {
Serial.println("Motion ended!");
motionState = false;
}
}
}
// Function to create a tone with parameters duration and frequency:
void alarm(long duration, int freq) {
tone(buzzerPin, freq);
delay(duration);
noTone(buzzerPin);
}
Cose da considerare quando si progetta un sistema con sensore PIR
Come altri sensori PIR, l’HC-SR501 ha bisogno di tempo per inizializzarsi e adattarsi ai livelli di infrarossi nell’ambiente. Ci vogliono circa 1 minuto dopo l’accensione. Cerca di evitare movimenti davanti al sensore in questo periodo.
Vento e una fonte luminosa vicina al sensore possono causare interferenze, quindi cerca di sistemare il setup per evitarle. Inoltre, monta il sensore in orizzontale, dato che la maggior parte dei movimenti avviene nel piano orizzontale (es. camminare).
Oltre al tempo di ritardo (Tx), il sensore ha anche un ‘tempo di blocco’ (Ti). Di default è 2,5 secondi e non è facile da modificare (vedi datasheet BISS0001). Ogni volta che l’uscita passa da HIGH a LOW, inizia il periodo di blocco. Durante questo periodo il sensore non rileva movimenti.
Quando progetti un sistema basato sull’HC-SR501 devi tenere conto di questi tempi di ritardo.
Conclusione
In questo articolo ti ho mostrato come funziona il sensore di movimento PIR HC-SR501 e come usarlo con Arduino. Spero ti sia stato utile e interessante. Se hai domande, suggerimenti o pensi che manchi qualcosa in questo tutorial, lascia un commento qui sotto.

