Come comandare una ESP32 tramite Bluetooth

Introduzione

Il Bluetooth è un sistema di comunicazione tra dispositivi ormai molto diffuso. Lo troviamo nei nostri cellulari, nei computer, nelle cuffiette e in tutti quei dispositivi che devono comunicare dati a breve distanza e senza fili. Uno dei nostri dispositivi preferiti, la NodeMCU ESP32, dispone di questo tipo di comunicazione in maniera nativa (oltre al ben noto WiFi).

Abbiamo già incontrato un dispositivo Bluetooth in un precedente articolo: Come fare un datalogger bluetooth per temperatura e umidità con Arduino MEGA. In quel caso abbiamo usato un modulo HC-05 che comunica con Arduino tramite la porta seriale. Nel caso della ESP32 invece, il suo controller Bluetooth scambia i dati sulla porta seriale senza bisogno di dispositivi esterni. Ciò semplifica decisamente la sua gestione che avviene tramite una apposita libreria.

Per avere un esempio pratico delle potenzialità di questo tipo di comunicazione con la ESP32, useremo un sensore DHT22 per misurare la temperatura e l’umidità ambientali e due diodi LED rossi che comanderemo in due modi diversi:

  • un LED potrà essere solo acceso o spento
  • l’altro LED potrà essere regolato in luminosità da un valore minimo (LED spento) ad un valore massimo (LED acceso alla massima luminosità) passando per i valori intermedi

Con la comunicazione Bluetooth potremo leggere i valori di temperatura ed umidità rilevati dal DHT22 e modificare le variabili che controllano lo stato dei due LED (una booleana che comanda il led che può essere solo acceso o spento e l’altra intera per comandare la luminosità dell’altro LED) tramite una applicazione per cellulare (quella usata qui è per Android) che si collegherà via Bluetooth al nostro dispositivo.

Di quali componenti abbiamo bisogno?

La lista dei componenti non è particolarmente lunga:

Realizzazione 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

Useremo il GPIO 14 per collegare il sensore DHT22.

Il pinout del sensore DHT22 è il seguente:

Il sensore DHT22 e la sua piedinatura
Il sensore DHT22 e la sua piedinatura

Per collegare i LED useremo invece i GPIO 16 e 17.

Il LED collegato al pin 17 è quello che può essere solo acceso o spento. Il GPIO17 verrà messo allo stato HIGH per accendere il LED e allo stato LOW per spegnerlo.

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.

I comandi per gestire i due LED verranno mandati all’ESP32 tramite una applicazione installata su cellulare.

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.

I due LED sono collegati alla ESP32 tramite due resistori da 100Ω per limitare la corrente che li attraversa ed evitare di bruciarli (e di bruciare le due uscite digitali).

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:

Schema di collegamento
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.

Delle librerie indicate installa, seguendo la procedura, la libreria DHT sensor library for ESPx by Bernd Giesecke (che viene usata per leggere i dati trasmessi dal sensore di temperatura e umidità DHT22) e lascia perdere le altre due (WiFiManager e UniversalTelegramBot).

Installa poi la libreria BluetoothSerial by Seeed come mostrato nell’immagine seguente:

Installazione della libreria BluetoothSerial
Installazione della libreria BluetoothSerial

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 = 
	beegee-tokyo/DHT sensor library for ESPx@^1.18
	mbed-seeed/[email protected]+sha.f56002898ee8

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.

Lo sketch inizia con l’inclusione delle librerie necessarie e un controllo sulla configurazione del Bluetooth:

#include <Arduino.h>
#include "DHTesp.h"
#include "BluetoothSerial.h"

/* Check if Bluetooth configurations are enabled in the SDK */
/* If not, then you have to recompile the SDK */
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

Viene poi definito l’oggetto SerialBT che gestirà il Bluetooth e la variabile BTData in cui transiteranno i dati attraverso la porta seriale:

BluetoothSerial SerialBT;
byte BTData;

Viene poi creato l’oggetto dht che serve a leggere il sensore e definito il GPIO a cui collegarlo:

DHTesp dht;
#define  DHT22_PIN 14  

e vengono definite le variabili del progetto:

float temperature;
float humidity;
int led1Status = 3;
bool led2Status = false;

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 si definisce il pin per il LED che può essere solo acceso o spento:

const int ledPinBool = 17;  // 17 corresponds to GPIO17

Le variabili:

unsigned long measureDelay = 3000;                //    NOT LESS THAN 2000!!!!!   
unsigned long lastTimeRan;

temporizzano le letture da parte del DHT22 (in questo caso la lettura avviene ogni 3 secondi). È consigliabile non scendere sotto questo valore in quanto il DHT22 impiega circa 2 secondi per fare una lettura.

A questo punto inizia la funzione setup:

Viene attivata la porta seriale:

Serial.begin(115200);
delay(2000);

Viene poi attivato il Bluetooth:

SerialBT.begin();
Serial.println("Bluetooth Started! Ready to pair...");

Se desideri assegnare un nome specifico al dispositivo Bluetooth ESP32 è necessario specificarlo come argomento della funzione SerialBT.begin(). Ad esempio, se vuoi chiamarlo myESP32BT, inserisci SerialBT.begin(“myESP32BT”).
Se lasci il comando senza un parametro, ad esempio SerialBT.begin(), verrà applicato il nome predefinito ESP32.

Subito dopo viene definito il collegamento del DHT22 alla ESP32 tramite il GPIO14:

dht.setup(DHT22_PIN, DHTesp::DHT22); // Connect DHT sensor to GPIO 14 

Infine vengono configurati i canali per i due LED:

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

pinMode(ledPinBool, OUTPUT);

Subito dopo inizia la funzione loop.

La prima parte si limita a stampare sul Serial Monitor il carattere inviato dall’applicazione sul cellulare (che vedremo in seguito) verso l’ESP32:

if(SerialBT.available())
{
  BTData = SerialBT.read();
  Serial.write(BTData);
}

Il blocco seguente si occupa della gestione dei comandi per accendere e spegnere il primo LED:

if(BTData == '1')
{
  led2Status = true;
}

if(BTData == '0')
{
  led2Status = false;
}

Quando inviamo il carattere 1, la variabile led2Status viene messa a true mentre se inviamo il carattere 0 la variabile viene messa a false.

Nel primo caso il LED si accenderà, nel secondo si spegnerà.

Il blocco successivo gestisce il valore della variabile led1Status che regola il duty cycle del segnale PWM il quale, a sua volta, regola la luminosità del secondo LED:

if(BTData == '+')
{
  led1Status++;
}

if(BTData == '-')
{
  led1Status--;
}

Quando inviamo il carattere +, la variabile led1Status viene incrementata mentre se inviamo il carattere la variabile viene decrementata.

Il blocco successivo si occupa dell’invio al cellulare dei valori di temperatura e umidità:

if(BTData == 'T')
{
  String temperatureString = "Temperature: " +  String(temperature) + "\n";
  int size = temperatureString.length();
  for(int i = 0; i < size; i++)
  {
    SerialBT.write(temperatureString[i]);
  }    
}

if(BTData == 'U')
{
  String humidityString = "Humidity: " + String(humidity) + "\n";
  int size = humidityString.length();
  for(int i = 0; i < size; i++)
  {
    SerialBT.write(humidityString[i]);
  }    
}

Se viene mandato il carattere T, il dispositivo risponde inviando il valore corrente di temperatura. Se viene mandato il carattere U, il dispositivo risponde inviando il valore corrente di umidità.

Infine inizia 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 vengono effettuate le misurazioni delle grandezze fisiche di nostro interesse e viene aggiornata la variabile lastTimeRan col valore corrente in ms:

humidity = dht.getHumidity();
temperature = dht.getTemperature();

lastTimeRan = millis();

Subito dopo vengono settati gli stati dei due LED coerentemente con i valori contenuti nelle variabili led1Status e led2Status, settate tramite il comando inviato tramite Bluetooth:

ledcWrite(ledChannel, led1Status);

if(led2Status) {
  digitalWrite(ledPinBool, HIGH);
} else {
  digitalWrite(ledPinBool, LOW);
} 

A questo punto non ti resta che caricare lo sketch sulla board e vedere come usare l’applicazione di controllo.

L’applicazione Serial Bluetooth Terminal

Per mandare i comandi Bluetooth verso l’ESP32 ho scelto di usare l’applicazione Serial Bluetooth Terminal di Kai Morich. Puoi scaricarla dal Play Store.

Ora attiva il Bluetooth nel tuo smartphone e cerca i dispositivi Bluetooth. Dovresti vedere un elenco di Dispositivi associati e Dispositivi disponibili. Vai su Dispositivi disponibili.

Seleziona ESP32 nel caso tu abbia lasciato nello sketch la riga SerialBT.begin() senza parametro, altrimenti scegli il dispositivo col nome che hai messo come parametro in quella riga. Il tuo cellulare ti chiederà se vuoi accoppiarlo con ESP32 (o col nome che gli hai impostato). A questo punto dai OK. Non c’è bisogno di password.

Apri l’applicazione Serial Bluetooth Terminal e clicca nel punto indicato nell’immagine seguente:

Clicca nel punto indicato per far uscire il menu
Clicca nel punto indicato per far uscire il menu

Seleziona la voce Devices come indicato nella figura sotto:

Seleziona la voce Devices
Seleziona la voce Devices

Si aprirà un altro menu dal quale dovrai selezionare il tuo dispositivo (per esempio ESP32):

Seleziona il dispositivo
Seleziona il dispositivo

Clicca ora nel punto indicato nell’immagine seguente per connettere l’applicazione al dispositivo selezionato:

Connetti l'applicazione al dispositivo
Connetti l’applicazione al dispositivo

Se tutto va bene dovrebbe stabilirsi la connessione:

Connessione avvenuta
Connessione avvenuta

A questo punto devi registrare i comandi da inviare al dispositivo con delle macro nell’applicazione. Tieni premuto il tasto M1. Si aprirà il menu per editarlo:

Realizziamo la prima macro
Realizziamo la prima macro

Al posto di M1, nel campo Name metti il carattere + e riempi il campo Value sempre con il carattere +, poi salva premendo nel punto indicato:

La prima macro è pronta
La prima macro è pronta

Ripetendo la stessa identica procedura esegui le seguenti associazioni:

  • su M2 metti il carattere nei campi Name e Value
  • su M3 metti la scritta ON nel campo Name e il carattere 1 nel campo Value
  • su M4 metti la scritta OFF nel campo Name e il carattere 0 nel campo Value
  • su M5 metti la scritta TEMP nel campo Name e il carattere T nel campo Value
  • su M6 metti la scritta HUM nel campo Name e il carattere U nel campo Value

Alla fine dovresti avere una schermata come questa:

Ecco come appare la schermata dopo aver registrato tutte le macro
Ecco come appare la schermata dopo aver registrato tutte le macro

A questo punto puoi usare l’applicazione.

Premendo il tasto + aumenterai la luminosità del LED comandato dal PWM mentre premendo il tasto la diminuirai.

Premendo il tasto ON accenderai l’altro LED, premendo il tasto OFF lo spegnerai.

Premendo il tasto TEMP vedrai apparire sullo schermo dell’applicazione la temperatura rilevata dal DHT22 mentre premendo il tasto HUM vedrai apparire l’umidità rilevata dal sensore.

Ecco un esempio di come appaiono:

L'applicazione in funzione che comunica con l'ESP32 via Bluetooth
L’applicazione in funzione che comunica con l’ESP32 via Bluetooth

Video dimostrativo del funzionamento

Il video qui sotto mostra il funzionamento generale:

Dimostrazione pratica del funzionamento

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