Come utilizzare il sensore di temperatura TMP36
La conversione di grandezze fisiche in elettriche è un aspetto che prima o poi viene affrontato quando iniziamo a realizzare piccoli esperimenti con Arduino. Oggi la sensoristica è ricca di dispositivi capaci di svolgere questa conversione (come il sensore di temperatura TMP36).
Nello specifico, per quanto riguarda la misura della temperatura abbiamo in commercio dispositivi di ogni sorta, da quelli ultrasensibili a quelli con precisioni dell’ordine del centesimo di grado, dai costi contenuti ai costi esorbitanti. A tal proposito ho in precedenza utilizzato sia il sensore di temperatura analogico MCP9700 sia il sensore digitale MCP9803.
Il segnale di conversione di questi sensori può essere sia analogico (variazione di tensione in funzione della variazione della temperatura) sia digitale (con convertitore analogico digitale ed invio dei dati su linea I2C, SPI o 1Wire).
Per i nostri esperimenti ci accontenteremmo di un sensore molto diffuso, dal costo contenuto e dal semplice utilizzo, il sensore TMP36 prodotto da Analog Device.
Il TMP36 permette di acquisire temperature comprese nell’intervallo tra -40°C e +125°C restituendo in uscita valori di tensione lineari tra circa 0.1Vdc e 1.7Vdc. Una variazione di grado produce una variazione della tensione di uscita pari a 10mV; alla temperatura di 0°C il sensore eroga una tensione di 500mV.
Il circuito che ho realizzato è molto banale, si limita a collegare il sensore direttamente ad Arduino UNO tramite la porta analogica A0:
guardando frontalmente il TMP36 troviamo sul lato sinistro il pin di alimentazione, sul pin centrale il segnale in uscita e sul pin destro il collegamento a massa.
Il primo sketch di esempio legge dalla porta analogica A0 il valore di tensione che eroga il TMP36:
void setup() { //Init Seriale Serial.begin(9600); } void loop() { delay(500); int val_ADC = analogRead(0); //invio il dato acquisito al pc Serial.println(val_ADC); }
Il codice precedente non fa altro che convertire in forma digitale la tensione presente sul piedino A0, generata dal TMP36. Questo valore deve essere ora interpretato in modo da ottenere direttamente il valore in °C. Per far ciò abbiamo bisogno del datasheet del componente, e precisamente il grafico di conversione °C/Vdc, rappresentato anche nella figura seguente:
come possiamo osservare dal grafico (per il TMP36 la linea b evidenziata in rosso) per una tensione di uscita di 0.5Vdc il sensore rileva la temperatura di 0°C. Questo dato ci permette subito di intuire che tensioni inferiori a 0.5Vdc indicano una temperatura sotto lo zero. Inoltre sapiamo che una variazione di grado si ripercuote con una variazione di tensione di 10mV. Quindi, passando agli esempi, se sul pin A0 sono presenti 510mV significa che il sensore sta rilevando una temperatura di 1°C (510mV – 500mV = 10 mV variazione di 1°C).
Non ci resta che interpretare i dati a nostra disposizione e scrivere uno sketch che restituisca il valore in °C:
//variabili globali int val_Adc = 0; float temp = 0; void setup() { //init seriale Serial.begin(9600); } void loop() { //leggo dalla porta A0 val_Adc = analogRead(0); //converto il segnale acquisito in un valore //espresso in gradi centigradi temp = ((val_Adc * 0.00488) - 0.5) / 0.01; //invio il dato sulla seriale Serial.println(temp); //ritardo di mezzo secondo delay(500); }
la formula che converte il valore acquisito in gradi centigradi è la seguente
°C = ((valoreADC * PrecisioneADC) – TensioneZeroGradi) / stepGradoTensione
dove
°C = valore della temperatura in gradi centigradi
valoreADC = valore della conversione analogico digitale restituito da analogRead
PrecisioneADC = questo valore è ottenuto dividendo la tensione di riferimento dell’ADC (default 5Vdc) e il numero massimo restituito dalla conversione (1024). (5Vdc /1024 = 0.00488)
TensioneZeroGradi = indica la tensione di uscita dal sensore quando rileva una temperatura di 0°C
stepGradoTensione = indica la variazione di tensione per ogni variazione di grado (0.01 = 10 mV)
Come aumentare la risoluzione nelle letture del TMP36
Eseguendo l’ultimo sketch ci accorgiamo che i valori di temperatura non sono proprio quelli che ci aspettiamo. Considerando la precisione del sensore TMP36 che si attesta a +/- 2°C per tutta la scala, otteniamo comunque dei valori che differiscono di circa 5-7°C dal valore reale. Questo ‘errore’ dipende da diversi fattori tra cui imprecisione dell’ADC, rumore del segnale e approssimazione dei valori nei calcoli.
Per limitare questi errori possiamo adottare due tecniche, la prima è quella di usare il pin AREF dell’Arduino UNO per dare al convertitore analogico digitale dell’ATmega328 un riferimento di tensione più basso (di default è 5Vdc), l’altra tecnica è quella di effettuare diverse letture ed eseguire una media dei valori letti.
Nello schema seguente viene indicato come collegare il pin AREF al pin power di 3.3Vdc:
Anche via software dobbiamo indicare al microcontrollore che intendiamo usare il pin AREF per le operazioni di conversione A-D. l’istruzione è la analogReference() e viene impiegata in questo modo:
//variabili globali int val_Adc = 0; float temp = 0; void setup() { //init seriale Serial.begin(9600); //utilizzando l'istruzione analogReference //indico al convertitore AD che deve impiegare //la tensione presente sul pin AREF come //valore di riferimento per la conversione analogReference(EXTERNAL); }
Usando la tensione di 3.3Vdc come riferimento per la conversione analogico digitale otteniamo che il valore PrecisioneADC nella formula precedente cambia da 0.00488 a 0.0032 (3.3Vdc / 1024 = 0.0032), aumentando così la precisione della formula.
Impieghiamo anche la lettura multipla di valori per cercare di minimizzare le fluttuazioni, come descritto nel codice seguente:
int val_Adc = 0; float temp = 0; void setup() { //init seriale Serial.begin(9600); //utilizzando l istruzione analogReference //indico al convertitore AD che deve impiegare //la tensione presente sul pin AREF come //valore di riferimento per la conversione analogReference(EXTERNAL); } void loop() { //ritardo di mezzo secondo delay(500); //init variabile val_Adc = 0; //eseguo un ciclo for(byte Ciclo = 0; Ciclo < 100; Ciclo++) { //acquisisco il valore e lo sommo alla //variabile val_Adc += analogRead(0); //questo ritardo serve per dare il tempo //all ADC di eseguire correttamente //la prossima acquisizione delay(10); } //eseguo la media dei 100 valori letti val_Adc /= 100; //calcolo la temperatura in °C temp = ((val_Adc * 0.0032) - 0.5) / 0.01; //invio i dati al computer Serial.println(temp); }
in questo modo otterremmo delle misure di temperatura che si avvicineranno molto al valore reale.
Related posts
14 Comments
Lascia un commento Annulla risposta
Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.
Articoli popolari
Sorry. No data so far.
.Net micro framework Arduino Arduino Webserver Domotica Flyport I2C IOT Netduino OpenPicus raspberry RTC Speed Test
nello schema hai collegato il sensore di temp a +5v (e relativa uscita analogico), e aref a 3.3v, ma non sballano i valori di lettura dell’analogico?
Assolutamente si, per questo nell’ultimo blocco di codice la formula per calcolare i gradi centigradi è diversa. La variabile PrecisioneADC cambia da 0.00488 (AREF a 5Vdc) a 0.0032 (AREF a 3.3Vdc)
Marco
Ciao e complimenti per i tutorial. Ho seguito il secondo esempio, ma mi restituisce sempre e solo due valori che oscillano da 17,32 a 17,84, valore che ovviamente non risulta reale.
Cosa può essere secondo te? Può essere il sensore difettoso?
Ciao Marco
grazie dei complimenti. Nel secondo sketch ti sei anche assicurato di collegare con un filo il pin 3.3V al pin Aref della scheda?
saluti
Sì assolutamente, lo schema è identico al tuo, solo che è stato fatto sullo shield ethernet. Può dipendere da quello? Oggi provo a sostituire il sensore, magari è difettoso. Ho provato con un phon a mandare aria calda, e con grosso stupore il valore si abbassa sotto i 9, per poi tornare a regime di c.ca 17.52 °C.
se hai un altro sensore prova subito a fare la sostituzione così vai per esclusione. Sia lo sketch che lo schema di esempio del tutorial sono stati provati e verificati.
Se usi il primo sketch di esempio del tutorial i valori sono diversi rispetto al secondo?
Si, si attestano attorno ai 20°C ma non ho provato oggettivamente a fare test come con il secondo schema, questa sera provo ad effettuare un test con un sensore nuovo e ti faccio sapere!
O.T. Sto sviluppando un progetto di domotica usando Arduino come REST controller implementando un’applicazione Java Spring per controllare il tutto. Obiettivamente Arduino UNO rev3 è un po’ limitato per numero di I/O e memoria, cosa mi consiglieresti per utilizzare un Arduino unico che mi supporti almeno 6 sensori e che mi supporti le librerie network, SD, autenticazione e le altre mie personalizzate?
Ciao, bellissimo tutorial. Però ho un problema. La mia temperatura sul monitor seriale è segnata con il segno meno e non so se è normale e poi oscilla in casa tra i 19,50 e i 19.90 che è molto reale. Il problema è quando magari lo porto all’esterno a una temperatura magari di 10 sulla porta seriale inizia a salire oltre i 25 gradi. Sa dirmi come mai?
Ciao
sei sicuro di aver collegato correttamente il sensore? Hai la possibilità di verificare il circuito con un altro sensore? Mandami il codice del tuo sketch via mail
a presto
Marco
Ciao Marco,
sto cercando di seguire il progetto 3 del manuale di Arduino e anch’io, come l’altro utente, ottengo valori negativi. Ho provato a collegare il sensore nella direzione opposta ma vengono solo sballati di più. Per caso avete trovato una soluzione al problema?
A presto
Ciao, ho fatto il circuito uguale e avviato il tutto con lo stesso programma.
Monitorando il tutto con il serial monitor noto che il sensore TMP36 satura e dalla temperatura reale salefino a 50 gradi e passa.
Toccando il componente noto che bolle, come mai?
PS: ho provato anche ad invertire il componente ma niente
AZZ! Leggendo questi post comprendo il perché questo forum si sia insabbiato. Ciauz.
Ciao Marco se copio e incollo su Tinkercad non funziona e mi da sempre la stessa temperatura e alcuni codici mi danno degli errori, grazie attendo risposta buona giornata.
Ciao, ho notato un errore di battitura nel codice. L’ho corretto e provato. Fai un altro tentativo e fammi sapere. Saluti.