- Elettronica Open Source - https://it.emcelettronica.com -

Misurare la temperatura con un termistore NTC mediante espertino

L'ESP32-wroom integra due ADC (Analog to Digital Converter) a 12 bit di tipo SAR (Successive Approximation Register) che permettono fino a 18 diverse misurazioni. Questo articolo vuole mostrare come attraverso la lettura di un canale ADC della scheda ESPertino [1], possiamo ricavare una misura della temperatura, impiegando un termistore NTC. Verrà realizzato uno sketch di esempio in ambiente Arduino utilizzando una libreria realizzata appositamente, che si basa  sulle API offerte dalle official development framework for ESP32 da parte dell'azienda produttrice Espressif Systems.

Misuriamo la temperatura utilizzando la libreria ESP32_ADC

Il primo passo da compiere è aggiornare la libreria per arduino, operazione già spiegata nell'articolo [1]di qualche tempo fa, per cui dal seguente link [2], apparirà la schermata come in Figura 1:

Aggiornamento libreria per ESPertino

Figura 1: Aggiornamento libreria per ESPertino

arduino-esp32-master.zip

La scelta di aggiornare le librerie, è duplice, da un lato installare l’ultima versione, permette di tenere un software in cui sono risolti una serie di bug rilevati nel tempo, e dall’altro, accantonare ad esempio delle funzioni dichiarate deprecated, e utilizzare al loro posto altre più efficienti come indicato dalla documentazione ufficiale.

La misurazione della temperatura con un termistore, avviene attraverso la lettura di un canale ADC, e poiché  espertino [4] possiede 18 canali suddivisi in due gruppi ADC1 e ADC2, i primi 8 possono essere sempre utilizzati, i restanti al momento della stesura di quest'articolo,non sono ancora supportati. Dalla documentazione ufficiale, sono evidenziate le limitazioni dell’uso dei canali ADC2,  in particolare è indicato espressamente che non possono essere utilizzati questi canali, quando è avviata la parte riguardante il modulo WIFI.

La mappatura dei canali ADCs, con le porte sono le seguenti:

ADC1_CHANNEL_0 = 0, ADC1 channel 0 is GPIO36
ADC1_CHANNEL_1,     ADC1 channel 1 is GPIO37
ADC1_CHANNEL_2,     ADC1 channel 2 is GPIO38
ADC1_CHANNEL_3,     ADC1 channel 3 is GPIO39
ADC1_CHANNEL_4,     ADC1 channel 4 is GPIO32
ADC1_CHANNEL_5,     ADC1 channel 5 is GPIO33
ADC1_CHANNEL_6,     ADC1 channel 6 is GPIO34
ADC1_CHANNEL_7,     ADC1 channel 7 is GPIO35

ADC2_CHANNEL_0 = 0, ADC2 channel 0 is GPIO4
ADC2_CHANNEL_1,     ADC2 channel 1 is GPIO0
ADC2_CHANNEL_2,     ADC2 channel 2 is GPIO2
ADC2_CHANNEL_3,     ADC2 channel 3 is GPIO15
ADC2_CHANNEL_4,     ADC2 channel 4 is GPIO13
ADC2_CHANNEL_5,     ADC2 channel 5 is GPIO12
ADC2_CHANNEL_6,     ADC2 channel 6 is GPIO14
ADC2_CHANNEL_7,     ADC2 channel 7 is GPIO27
ADC2_CHANNEL_8,     ADC2 channel 8 is GPIO25
ADC2_CHANNEL_9,     ADC2 channel 9 is GPIO26

Comunque è da sottolineare nuovamente che i canali relativi all'ADC2, al momento non sono supportati, ma lo saranno in futuro, e in quel caso, aggiornerò la libreria per un loro immediato utilizzo.

Mi sono proposto di usare direttamente le API (basate su quelle del 24 aprile 2018) messe a disposizione dall’ultimo rilascio ufficiale da parte di Espressif, e quindi ho realizzato un wrapper che faciliti l'utilizzo delle diverse funzionalità per i canali ADC1, scaricabile al seguente link ESP32_ADC.zip [5].

Un po' di teoria

Benché  i concetti di base per gli ADC e termistori sono noti a molti, ritengo cosa utile fare un piccolo ripasso, rivolto soprattutto per chi si avvicina al loro utilizzo per la prima volta, mediante una trattazione semplificata.

Il primo problema da affrontare è la scelta della risoluzione dell’ADC (l'ESP32 wroom permette le risoluzioni 9,10,11,12 bit), ed in tale fase possono essere d’aiuto degli esempi  in Figura 2,Figura 3,Figura4:

 

[6]

Figura 2: ADC 10 bit risoluzione

 

[7]

Figura 3: ADC 11 bit risoluzione

[8]

Figura 4: ADC 12 bit risoluzione

La loro importanza è notevole, in quanto indicano, una volta fissata la risoluzione, come varia la grandezza letta dall’ADC con la tensione misurata, al variare delle diverse attenuazioni.

Lo schema classico da utilizzare per i nostri scopi come in Figura 5, è quello di porre una resistenza nota (10KΩ) in serie al termistore:

[9]

Figura 5: Partitore di tensione

Per cui è fondamentale comprendere, quale sia il punto di funzionamento del circuito, che risulta stabilito attraverso la misura della tensione ai capi della resistenza in serie, ed in base a questa:

Dove come tensione di fondo scala, si intende il valore massimo che può essere letto dall'ADC, e questo valore è strettamente legato alla sua risoluzione:

Per quanto riguarda il termistore, esso non è altro che un resistore, il cui valore di resistenza è dipendente fortemente dalla temperatura dell’ambiente che lo circonda, ne possiamo trovare di due tipi NTC e PTC, dove le sigle indicano:

-NTC  (Negative Temperature Coefficient) dipendenza negativa della temperatura ovvero, al crescere di essa il valore della resistenza diminuisce, come si osserva dalla Figura 6.

[10]

Figura 6: Caratteristica di un termistore NTC

-PTC (Positive Temperature Coefficient) dipendenza positiva della temperatura ovvero, al crescere di essa il valore della resistenza aumenta, come si osserva dalla Figura 7.

[11]

Figura 7: Caratteristica di un termistore PTC

In questo circuito è stato utilizzato un termistore M52 NTC, la cui natura è descritta da una relazione matematica, in cui vi è un legame della resistenza con la temperatura di questo tipo:

[12]Dove:

Siccome, il legame tra la temperatura kelvin e gradi centigradi è il seguente:

K= °C + 273,15

Si ricava la temperatura del termistore:

[13]Da cui dal partitore di tensione, si ha:

[14]Per cui risolvendo rispetto alla Rt, otteniamo :

[15]

Supponendo che il termistore si trova esattamente alla temperatura di 25°C, esso assume un valore pari a quella di Rs,cioè 10KΩ, e si ottiene considerando che Vin = 3.3V:

[16]

Ipotizzando che il termistore deve essere utilizzato in un ambiente in cui il range di temperature sia pare a [-10°C,50°C],possiamo calcolare il valore della sua resistenza applicando la formula:

R-10°C = 47018,618 Ω

R50°C = 4064,112 Ω

E quindi la caduta di tensione sul termistore calcolata agli estremi del range di utilizzo è:

[17]

[18]

Se ne deduce che il range in cui varia la tensione che insiste sul termistore Vt è compreso nell’intervallo  [0.95V, 2.72V]. Osservando le curve caratteristiche dell’ADC mostrate in precedenza, si comprende facilmente che dovendo utilizzarle nel tratto lineare, la scelta cade verso:

Nella Figura 8, è indicato in giallo, l’area in cui la tensione varia:

[19]

Figura 8: Come scegliere la risoluzione dell'ADC

Sebbene la curva relativa a 11db risulta essere affetta leggermente da rumore, questa resta congruente con il ragionamento condotto sino a questo punto, comunque è consigliabile lavorare con attenuazioni 2.5db/6db.

Schema di cablaggio

Il circuito di test, mostrato in Figura 9, è molto semplice:

 

[20]

Figura 9: Schema di cablaggio

 

Sketch

Una volta assemblato il tutto, ed installata la libreria ESP32_ADC.zip [5] indicata precedentemente, passiamo a commentare lo sketch di prova, scaricabile al seguente link ESP32_ADC_Test.zip [21].

Cominciamo osservando la parte iniziale:

/****************************************************************
** File name:   ESP_ADC_test.ino
** Descrizione: Misurazione della temperatura mediante
**              un termistore
** Versione:    1.0             
** E-mail: us.newsoft@gmail.com
** Autore: Salvatore Urciuolo
** Data:   06/06/2018 
****************************************************************/
#include <ESP32_ADC.h> // riferimento della libreria ESP32_ADC
 
//creazione di una istanza dell'oggetto ADC di tipo ESP32_ADC
ESP32_ADC ADC;

//dichiarazione di variabili
float Vs;
float Rt;
float tempC;

Poi la parte di inizializzazione:

void setup() 
{
   Serial.begin(115200); //si configura la velocità della seriale
   Serial.println("");
 
   Serial.print("");
   Serial.println(ADC.getVersion());
 
   //configura ADC1 la risoluzione in bit 
   //imposta il canale e la sua attenuazione 
   //ed il numero di campioni necessari, nella fase di subsampling
   int iEsito= ADC.init(ADC_WIDTH_12Bit,ADC1_CHANNEL_5,ADC_11db,64);
 
   Serial.print("esito init ADC =");
   Serial.println(iEsito);
 
   //pausa di almeno un secondo
   delay(1000);
}

Ed infine la parte di elaborazione:

void loop() 
{
  //lettura della tensione ai capi della resistenza nota
  // di 10 KOhm              
  Vs=ADC.readVoltage();
  
  Serial.print("Valore letto dal canale ADC [V]: "); 
  Serial.println(Vs);
 
  //calcolo della resistenza del termistore
  Rt = 10000.00*(3.30-Vs)/Vs;  
  
  Serial.print("Resistenza termistore [Ohm]: ");
  Serial.println(Rt);
 
  //calcolo della temperatura rilevata dal termistore
  tempC = (3470./(log(Rt/10000.)+(3470./(298.15)))) - 273.15;
   
   Serial.print("temperatura [°C]: ");
   Serial.println(tempC); 
   Serial.println("---------------------------------");
   
   //si attende 5 secondi
   delay(5000);
}

Conclusioni

Al termine della lettura di quest’articolo, saremo in grado di aggiornare con le dovute cautele, le librerie ufficiali ESP32 per arduino, da utilizzare per il nostro “espertino”, ma soprattutto si è acquisita una maggiore familiarità sull’utilizzo della parte relativa di ADC e di termistori. Spero che i concetti illustrati nell'articolo siano chiari e solo una base di partenza per applicazioni più complesse, magari arricchendo con altri elementi come led, buzzer, display... insomma basta dare via libera alla propria fantasia, per divertirsi con tanti altri avvincenti progetti.