Come controllare un LED in base alla luminosità ambientale con la ESP32

Introduzione

In questo articolo realizzaremo un progetto abbastanza semplice: un sistema che controlla la luminosità di un LED in base alla luminosità ambientale. In pratica più la luminosità ambientale è bassa e più il LED si illumina e viceversa. Per la rilevazione della luce ambientale useremo il ben noto sensore BH1750 che abbiamo conosciuto nell’articolo Come realizzare un datalogger con la NodeMCU ESP32 collegata ad un cloud Django su Raspberry mentre il LED sarà pilotato tramite un opportuno segnale PWM. Abbiamo già visto un esempio di pilotaggio di un LED con un segnale PWM nell’articolo Come comandare una ESP32 tramite Bluetooth.

Di quali componenti abbiamo bisogno per controllare un LED in base alla luminosità ambientale?

La lista dei componenti non è particolarmente lunga:

Relizzazione del progetto

Lo schema elettrico

Prima di realizzare il circuito vero e proprio diamo un’occhiata al pinout della board:

Pinout della ESP32
Pinout della ESP32

Il pinout del BH1750 è questo:

Pinout del sensore di luminosità BH1750
Pinout del sensore di luminosità BH1750

Il sensore BH1750 è collegato ai GPIO 21 (SDA) e 22 (SCL) della ESP32. Questi pin fanno parte di un bus di comunicazione a due fili che si chiama I2C. Questo bus prevede la presenza di un dispositivo master (nel nostro caso la ESP32) che gestisce la comunicazione e uno o più dispositivi slave (il nostro sensore). I dispositivi slave hanno tutti un proprio indirizzo esadecimale in modo da far capire al master da quale dispositivo proviene un determinato messaggio o per fare in modo che il master mandi un messaggio allo slave giusto. In questo modo si evitano conflitti fra i messaggi, dato che viaggiano sullo stesso bus.

L’indirizzo del sensore BH1750 può essere settato tramite il pin ADDR. In particolare, avremo che:

  • l’indirizzo è 0x23 se la tensione al pin ADDR è inferiore a 0.7 Vcc
  • l’indirizzo è 0x5C se la tensione al pin ADDR è maggiore di 0.7V

In generale, nel caso in cui siano presenti due o più dispositivi e che abbiano lo stesso indirizzo (non modificabile) non sarà possibile collegarli allo stesso bus I2C.

Il LED collegato al pin 16 è quello la cui luminosità può essere regolata. Per ottenere questo risultato verrà pilotato dall’ESP32 tramite un segnale PWM il cui duty cycle varia al variare del valore contenuto in una variabile apposita, valore che va da 0 (LED spento) a 255 (LED completamente acceso) passando per i valori intermedi.

A questo punto puoi procedere alla realizzazione del circuito seguendo lo schema di collegamento più sotto. Purtroppo la NodeMCU ESP32 è troppo larga per stare sulla breadboard, motivo per cui sarà collegata con dei fili volanti al resto del circuito.

Il LED è collegato alla ESP32 tramite un resistore da 100Ω per limitare la corrente che lo attraversa ed evitare di bruciarlo (e di bruciare l’ uscita digitale).

Il LED ha due terminali (chiamati anodo e catodo) e, come tutti i diodi, è un componente che ha una sua polarità: fa passare la corrente quando è polarizzato direttamente (cioè la tensione all’anodo è maggiore di quella al catodo) e blocca la corrente quando è polarizzato inversamente (cioè la tensione all’anodo è minore di quella al catodo). La tensione tra anodo e catodo, che indicheremo con Vd, varia a seconda del colore della luce emessa. In particolare abbiamo che:

  • Vd = 1.8 V per il LED rosso
  • Vd = 1.9 V per il LED giallo
  • Vd = 2 V per il LED verde
  • Vd = 2 V per il LED arancio
  • Vd = 3 V per il LED blu
  • Vd = 3 V per il LED bianco

Di seguito lo schema di montaggio realizzato con Fritzing:

Lo schema di collegamento
Lo schema di collegamento

Come puoi vedere, l’alimentazione del sensore è presa dall’uscita 3.3V del NodeMCU (pin 3V3). E’ necessario alimentarlo con 3.3V in modo che anche la sua uscita sia 3.3V in quanto i pin digitali del NodeMCU non accettano tensioni superiori a 3.3V.

ATTENZIONE: nel NodeMCU ESP32 la tensione massima tollerata dagli ingressi digitali è pari a 3.3V. Qualsiasi tensione superiore lo danneggerebbe irreparabilmente!!

Come facciamo ad identificare l’anodo e il catodo del LED? Lo facciamo osservando i suoi terminali. Il più lungo corrisponde all’anodo. Inoltre il corpo del LED presenta un appiattimento in un punto del bordo che indica che il terminale vicino è il catodo.

Quindi, se un LED non si accende è possibile che sia stato collegato al contrario. In questo caso, per farlo funzionare, è sufficiente invertirne i collegamenti.

Come si calcola la resistenza da collegare al LED?

Nota Bene: questo paragrafo tratta il calcolo della resistenza di limitazione in maniera teorica e richiede un minimo di conoscenza delle basi dell’Elettrotecnica. Pertanto non è fondamentale per la comprensione del resto del progetto e può essere saltato dal lettore non interessato a tali aspetti teorici.

Come abbiamo già detto, il resistore tra il generico GPIO e il LED serve a limitare la corrente che attraversa il LED. Ma come possiamo calcolare il suo valore di resistenza? Ci viene in soccorso la Legge di Ohm la quale dice che la differenza di potenziale ai capi di un resistore (cioè la tensione misurata agli estremi del resistore) è proporzionale alla corrente I che lo attraversa e la costante di proporzionalità è proprio il valore di resistenza del resistore R:

V2 - V1 = RI

Nota Bene: per amor di precisione bisogna puntualizzare che mentre il resistore è il componente fisico (l’oggetto vero e proprio), la resistenza è il suo valore. Quindi è improprio (anche se accade di frequente) chiamare il resistore col termine resistenza.

Possiamo vedere la Legge di Ohm su un semplice circuito costituito da un generatore di tensione (il cerchio a sinistra) e un resistore:

Rappresentazione della Legge di Ohm
Rappresentazione della Legge di Ohm

La tensione (o differenza di potenziale) V2 – V1 impressa dal generatore di tensione sul resistore è uguale al prodotto di R per I.

Vediamo ora uno schema leggermente più complesso dove sono presenti il solito generatore di tensione, il resistore e un LED rosso:

Circuito per il calcolo del resistore di limitazione della corrente sul LED
Circuito per il calcolo del resistore di limitazione della corrente sul LED

Nel nostro caso la Vg rappresenta la tensione presente all’uscita digitale della ESP32 quando è HIGH ed è pari quindi a 3.3V.

La Vd è la tensione ai capi del diodo (tra anodo e catodo) quando questo è polarizzato direttamente (cioè quando fa scorrere la corrente). Avendo scelto un LED rosso, sappiamo, dalla tabella precedente, che Vd = 1.8V.

Dobbiamo determinare il valore R del resistore. Abbiamo ancora una incognita: il valore della corrente I che deve scorrere nel circuito quando il pin è in stato HIGH.

Nota Bene: quando il pin digitale è nello stato LOW la sua tensione (cioè la Vg) è nulla, ne consegue che anche la corrente I nel circuito è nulla.

I LED in genere non sopportano correnti maggiori di 20mA, quindi imponiamo una corrente massima di 15mA per stare sul sicuro.

Per la Legge di Kirchhoff alle maglie (detta anche Legge di Kirchhoff delle tensioni) , abbiamo che:

Vg - Vr - Vd = 0

Da cui ricaviamo che:

Vr = Vg - Vd 

Passando ai valori reali, abbiamo che:

Vr = 3.3V - 1.8V

Ne risulta che:

Vr = 1.5V

Ma, per la Legge di Ohm, abbiamo che:

Vr = RI

da cui:

R = Vr / I

Sostituendo i valori reali:

R = 1.5V / 0.015A

Ne deriva un valore di R pari a 100Ω.

Lo sketch

Creiamo il progetto PlatformIO

Abbiamo già visto la procedura di creazione di un progetto PlatformIO nell’articolo Come creare un progetto per NodeMCU ESP8266 con PlatformIO.

Anche se si riferisce alla board ESP8266, la procedura è simile.
Semplicemente, nella scelta della piattaforma, dovrai scegliere la AZ-Delivery ESP-32 Dev Kit C V4.

Non installare le librerie indicate in quell’articolo perché non ci servono in questo progetto. Però devi, seguendo la procedura indicata nell’articolo, installare la libreria BH1750 by claws:

Installa la libreria BH1750 sul progetto PlatformIO
Installa la libreria BH1750 sul progetto PlatformIO

Ora modifica il file platformio.ini per aggiungere queste due righe:

monitor_speed = 115200
upload_speed = 921600

in modo che il file abbia un aspetto del genere:

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
monitor_speed = 115200
upload_speed = 921600
framework = arduino
lib_deps = claws/BH1750@^1.3.0

Ovviamente puoi scaricare il progetto dal link seguente:

Sostituisci il file main.cpp del progetto che hai creato con quello presente nel file zip.

Vediamo ora come funziona lo sketch.

Inizia con l’inclusione delle librerie necessarie:

#include <Arduino.h>
#include <BH1750.h>

Vengono poi definiti il pin in cui collegare il LED controllato col PWM e i parametri di funzionamento del segnale PWM:

// set the pin for the PWM LED
const int ledPinPWM = 16;  // 16 corresponds to GPIO16

// set the PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;

Poi prosegue con la creazione dell’oggetto relativo al sensore di luminosità e la definizione delle variabili per il controllo del LED e la rilevazione della luminosità da parte del sensore:

BH1750 brightnessMeasure;

uint8_t ledPower = 0;
uint8_t brightness;

Le variabili:

unsigned long measureDelay = 2000;               
unsigned long lastTimeRan;

temporizzano le letture da parte del sensore (in questo caso la lettura avviene ogni 2 secondi).

A questo punto inizia la funzione setup:

Viene attivata la porta seriale:

Serial.begin(115200);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found

delay(1500); 

Viene poi configurato il PWM con i suoi parametri e collegato il canale del PWM al GPIO in cui è collegato il LED.

// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
  
// attach the channel to the GPIO to be controlled
ledcAttachPin(ledPinPWM, ledChannel);

Infine vengono inizializzati il bus di comunicazione I2C e il sensore:

Wire.begin();           

brightnessMeasure.begin();

Alla fine dello sketch si trova la funzione loop.

Subito incontriamo un blocco if che contiene alcune funzioni al suo interno.

La condizione all’interno dell’if determina la cadenza temporale con cui vengono fatte le misurazioni:

if (millis() > lastTimeRan + measureDelay)  {

Quindi gli eventi descritti avvengono ogni measureDelay ms grazie a questa condizione.

Proseguendo nell’if, vediamo che viene effettuata la misurazione della luminosità ambientale e viene aggiornata la variabile lastTimeRan col valore corrente in ms:

brightness = brightnessMeasure.readLightLevel();
lastTimeRan = millis();

Subito dopo viene calcolato il valore (compreso fra 0 e 255) da dare al PWM per regolare la luminosità del LED e salvato nella variabile ledPower:

ledPower = 255 - brightness * 3;

È possibile modificare il coefficiente di conversione 3 in modo da adattare il sistema alla sensibilità del sensore.

In questo modo avremo che:

  • ledPower = 0 quando la luminosità ambientale è massima. In questo caso il LED sarà spento;
  • ledPower = 255 quando la luminosità ambientale è minima. In questo caso il LED sarà acceso alla massima luminosità.

Segue una serie di istruzioni che stampano i vari valori sul Serial Monitor:

Serial.print(brightness);
Serial.print("  ");
Serial.print(brightness * 3);
Serial.print("  ");
Serial.print(ledPower);
Serial.print("\n");

Infine viene comandato il PWM col valore contenuto nella variabile ledPower in modo da regolare la luminosità del LED:

ledcWrite(ledChannel, ledPower);

Video dimostrativo

Funzionamento del progetto

Osservazioni finali

Come vedi questo progetto è molto semplice sia come realizzazione che come funzionamento. È sicuramente utile per vedere come collegare e far funzionare un sensore di luminosità come il BH1750 e per capire come pilotare un LED con un segnale PWM. In realtà, con opportune modifiche, può essere interfacciato ad un gruppo di LED ad alta luminosità frapponendo un buffer di potenza (come un ponte H) tra l’uscita PWM dell’ESP32 e il gruppo di LED in modo da realizzare un efficace sistema di illuminazione a LED comandato dalla luminosità ambientale. In questo caso sarebbe opportuno tenere lontani i LED dal sensore in quanto influenzerebbero le sue misurazioni.

Newsletter

Se vuoi essere aggiornato sui nuovi articoli, iscriviti alla newsletter. Prima dell’iscrizione alla newsletter leggi la pagina Privacy Policy (UE)

Se ti vuoi disiscrivere dalla newsletter clicca sul link che troverai nella mail della newsletter.

Inserisci il tuo nome
Inserisci la tua email
0 0 votes
Valutazione articolo
guest
0 Commenti
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
Torna in alto