Progetti - PIC

 

Un termometro a tre cifre.


Un termometro a microcontroller che utilizza un minimo numero di componenti.


Descrizione.

Un microcontroller può risolvere circuiti altrimenti complessi con un minimo numero di componenti. 
E' il caso di questo termometro, proposto per una esercitazione nella cui specifica erano compresi questi elementi:
- lettura della temperatura ambiente con un errore di +/- 1°C o migliore
- massima semplicità senza ridurre la sicurezza operativa
- funzionamento anche a batteria  (quindi con consumo minimo)
- display ben visibile in condizioni di luminosità ridotta

Ne è risultato un circuito che utilizza solamente:
- il sensore di temperatura
- il microcontroller
- 3 display a 7 segmenti
oltre a 9 resistenze e 4 condensatori.
L' alimentazione minima varia tra 2.5 e 5V non stabilizzati, quindi anche con 2 o 3 batterie (3-4.5V) alcaline o 3-4 ricaricabili (3.6-4.8V).  

Nella ampia gamma dei sensori di temperatura disponibili è stato scelto MCP9700 di Microchip, a stato solido con uscita analogica, che ha il vantaggio di poter essere interfacciato direttamente al microcontroller senza la necessità di un circuito intermedio di condizionamento del segnale richiesto da altri e, come vedremo, di matematica complessa, per rendere in temperatura il valore della conversione AD.
MCP9700 fornisce una risposta di 10mV/°C, con un offeset di 500mV a 0°C, in un range tra -40°C e +125°C con un errore tipico alle estremità entro 2°C; siccome l' uso è quello di termometro ambiente, nell' arco delle temperature -10°C/+40°C ci si può aspettare una precisione migliore del grado senza operare linearizzazioni.

formati; qui è stato usato il tipo in TO-92.
Da 

Da notare che esiste un MCP9700 e un MCP9700A; quest'ultimo è una revisione con una maggiore precisione.
 
In una conversione AD riveste una fondamentale importanza la tensione di riferimento. E' tipico nei microcontroller utilizzare la Vdd/Vss come Vref, il che può essere accettabile nel caso di una alimentazione con uno stabilizzatore, genere 7805. Ma nel nostro caso va previsto anche un funzionamento a batteria e sappiamo che la tensione diminuisce a mano a mano che la batteria si esaurisce. Quindi è esclusa la possibilità di utilizzare la Vdd/Vss come riferimento della conversione.

La soluzione corrente è quella di inserire nel circuito un voltage reference, genere LM4040, LM385, ecc.. Questo permette di avere un riferimento Vref+ costante con il variare della tensione fornita dalle pile, ma vuol anche dire:
- aggiungere un componente, il che contrasta con le specifiche
- dedicare un pin alla Vref esterna, il che, usando chip a basso numero di pin, non è cosa sempre possibile.

Però Microchip dispone di vari PIC della famiglia Enhanced Midrange e 18F che offrono una soluzione integrata, avendo a bordo l' FVR, Fixed Voltage Reference.

Questo modulo offre la possibilità di programmare un riferimento interno di precisione a

  • 1.024V
  • 2.048V
  • 4.096V

che sono valori ideali per la conversione.

Inoltre si può impostare da programma la tensione di riferimento del modulo ADC collegandolo non solo a Vd/Vss o a pin analogici, ma anche, direttamente, all' uscita dell' FVR (PVCFG<1:0> =  10); questo esclude la necessità di utilizzare un pin esterno.

La tensione di riferimento negativa sarà sempre la Vss (NVCFG<1:0> = 00).

In altri chip il riferimento interno è a 0.6V oppure ha una uscita a due canali, uno dedicato all' ADC, l' altro al comparatore. Un rapido sguardo al foglio dati del componente permette di indentificare le caratteristiche del modulo FVR integrato.
 

 

La gamma della tensione di uscita del sensore varia tra 100mV (-40°C) e 1.750V (125°C), per cui il riferimento a 2.048V è adeguato. Con un ADC a 10 bit fornisce una risoluzione di:

2048/1024 = 2mV per step

che, per MCP9700 si riflette in una risoluzione teorica di 0.2°C.

Tra l' altro, la presenza dell' FVR permette di monitorare la batteria senza richiedere un pin dedicato alla conversione e quindi risolve anche il problema della verifica dello stato di carica.

Tra le varie possibilità, la scelta è stata indirizzata ad un 18F13K22 , chip in package a 20 pin.

Sarebbe possibile utilizzare anche qualsiasi altro Enhanced Midrange (16F1820,1540, ecc. ), ma si è preferito questo 18F per le seguenti ragioni:

  • 18 pin sarebbero sufficienti, ma con 20 è possibile disporre dei pin in più per ICD, il che è essenziale per il debug e consente di avere un mezzo didattico notevole. La disponibilità del motore ICD integrato permette di usufruire di uno strumento di debug molto potente, estremamente superiore e per nulla comparabile con le limitazioni dei simulatori (che molti insistono ad utilizzare, con ben scarso vantaggio) ed estremamente fruttuoso sia per la didattica che per il lavoro. 

  • 18F13K22 è facilmente reperibile, anche nella versione LF

  • la differenza di costo tra 18F e 16F è minima

  • scrivere Assembly per i 16F, con pagine e banchi, è molto meno gradevole che con i 18F, che sono senza pagine e con l' Access Bank. 

Per quanto riguarda la presentazione della temperatura rilevata, la scelta di display a 7 segmenti è ideale per un apparecchio alimentato dalla rete e dove, come in questo caso, le cifre necessarie sono poche: un modulo LCD sarebbe sprecato. 
La scelta, però, è meno ottimale per un apparecchio alimentabile a batteria.
Per contro, i LED offrono una visibilità molto maggiore anche in condizioni di luminosità ambiente scarsa e un LCD retro illuminato, se di per se consuma pochissimo, finisce per assorbire una corrente simile (se non maggiore!) a quella dei 7 segmenti multiplexati quanto si attiva la retro illuminazione.
Dato che è inutile accendere le cifre se non quando è richiesta una lettura, per economizzare le batterie, è stata implementata la seguente struttura:

  • se il termometro è alimentato da rete, il display può essere lasciato acceso costantemente. Il consumo tipico è attorno a 15mA utilizzando display a bassa corrente. Con display ordinari il consumo sale a 25-30mA

  • se il termometro è alimentato a batteria, la presentazione sul display avviene a seguito della pressione di un pulsante, per un tempo programmabile; dopo questo, il microcontroller passa in modalità sleep e abbatte il consumo a livello di microampere, eliminando la necessità di un interruttore alle batterie.

18F13K22 è operativo tra 2.3 e 5.5V, mentre 18LF13K22 è funzionante tra 1.8 e 3.6V. E' stato scelto il primo in quanto MCP9700 non è utilizzabile al di sotto dei 2.3V e FVR, per una tensione di 2.048V richiede una Vdd minima di 2.5V, che sarà la minima ammissibile. Questo permette di alimentare il tutto sia con  il solito 5V che con 3.3V oppure con 3 batterie alcaline o NiMH o litio (3.6V), ma anche con due batterie alcaline (3V a piena carica). L'inserimento di un monitor della Vdd genera un avviso quando essa scende al di sotto dei 2.5V circa. Questo livello di intervento è facilmente modificabile nel firmware. 


Schema elettrico.

Lo schema risultante è il seguente:

I tre display sono collegati per il solito multiplex, con i catodi comuni. Utilizzando display a basso consumo (ad es. HDSP-5553, HDSP-7513 e simili, con corrente tipica 1-3 mA) è possibile collegare i catodi direttamente ai pin del micro, dato che la corrente erogata con tutti i segmenti accesi è minore dei 25mA erogabili. Le resistenze in serie ai segmenti limitano questa corrente. Vanno bene valori tra 680 e 820 ohm, a seconda delle caratteristiche del display e della luminosità che si vuole ottenere (ricordando che più luminosità=maggiore corrente).
Nel caso si disponga di display comuni da 10-20mA, le resistenze di limitazione saranno da 220 a 560 ohm, a seconda del display usato; da tenere presente che per un uso generico, un display che dichiara 10 mA per segmento probabilmente fornirà una illuminazione adeguata anche con soli 5-6mA. Quindi è inutile pompare corrente se non serve, sopratutto alla luce della necessità di limitare il consumo di un apparato a batterie.
Si potranno utilizzare anche display ad anodo comune, agendo esclusivamente sul firmware con l' inversione della maschera dei segmenti e dei comandi sugli anodi.


Nell' uso di display a corrente più elevata, saranno necessari 3 piccoli MOSFET (tipo 2N7002) per comandare i catodi. Ovviamente i pin vanno alti per comandare il gate del MOSFET e vanno bassi se si comanda direttamente il catodo.  

Se si intendono usare display ad anodo comune con correnti elevate, occorrerà prevedere dei transistor per il comando degil anodi.

Il sensore entra nel port AN2; un condensatore C1 (typ. 100nF) è necessario sull' alimentazione, molto vicino ai pin dell' MCP, mentre C2, più vicino al micro, ha lo scopo di migliorare la misura sulla linea analogica; il suo valore potrà essere 100nF o più.
PA3 è utilizzato come MCLR e PA4 viene impiegato come definizione della modalità in questo modo:

  • pin a massa = display sempre acceso - alimentazione da rete

  • pin flottante = display acceso per 20" - alimentazione a batterie

In effetti il pin non è floating, ma è agganciato alla Vdd con un weak pull up integrato.

Il micro lavora con il clock interno a 1MHz; dato che il compito da svolgere non è per nulla impegnativo si potrebbero usare anche clock più bassi, nell' ottica di ridurre il consumo. Però, poichè la maggior parte della corrente è impegnata sui display, il default a 1MHz è adeguato.
Il multiplex dei display è eseguito in interrupt con cadenza di 4ms, marcato dal Timer0.

Il consumo rilevato a 4.5V è circa 15-25mA con il display acceso e 20-25uA in sleep. Ulteriore miglioramento della corrente in sleep si potrà avere con una cura maggiore dei dettagli. 

Il pin MCLR è utilizzato per wakeup dalla condizione di sleep: era inutile prevedere un ulteriore pulsante, con l' uso di un altro pin.

PA0 e PA1 sono riservati alla connessione con un Pickit o REALICE per il debug in circuiti o la riprogrammazione. Questo era essenziale per la parte didattica. 
I pin PB5 e PB7 sono disponibili in quanto ne è stata realizzata una variante che può comunicare con l' esterno su seriale.
Se non si utilizza nè ICD, nè si prevedono espansioni, un chip a 18 pin può essere più che sufficiente.


Il Firmware. 

Il programma è in Assembly, ma è commentato ampiamente. Con l' uso intensivo di macro si riduce la lunghezza del sorgente e se ne aumenta la leggibilità.  

Durante lo sviluppo è stata usata convenientemente una demoboard specifica per PIC in packages 8/16/20 pin, di dimensioni molto contenute.
E' dotata di display, pulsanti, LED, buzzer, zoccolo per l'MCP9700/9701 e il DS1820, segnali analogici e presa dedicata per le comunicazioni seriali, a cui si aggiunge un comodo ZIF per una rapida sostituzione dei microcontroller in valutazione.

La disponibilità della connessione ICSP e del motore integrato di debug ICD ha permesso uno sviluppo rapido, consentendo uno studio accurato delle varie funzioni.

Come tools di debug e di programmazione è utilizzato il PICkit3.

 Per facilitare la comprensione del sorgente, questo è il flowchart , che è stato disegnato rapidamente con Diagram Designer:

 

Vediamo più dettagli di alcuni particolari. Il primo riguarda la conversione. 

Va considerato (cosa che sfugge assai spesso) che una conversione a 10 bit comincia a richiedere cure particolari sul segnale di ingresso (bassa impedenza, assenza di rumore, ecc) e che dipende dal layout dello stampato, dal disacccoppiamento dell' alimentazione del microcontroller, dalla tensione di riferimento e dal rumore digitale in generale.

Nel nostro caso, il sensore viene  semplicemente letto a burst di 8 volte consecutive, delle quali viene effettuata la media aritmetica, allo scopo di minimizzare errori di lettura o indesiderabili saltelli dell' ultima cifra. Si potrebbe provare anche qualche altro algoritmo, come l' Olympic Average o più complessi, ma, in generale, dove la conversione sia molto saltellante, occorre per prima cosa cercare di migliorare la struttura hardware del segnale da convertire. Si può, poi, anche ricorrere a "trucchi" software come quello grossolano di scartare bit meno significativi , o, più raffinato, di mandare in sleep il micro all' inizio della conversione, in modo da minimizzare il rumore digitale del circuito (il che, però, richiede una più complessa struttura della gestione del multiplex del display per evitare sfarfallio).

Il risultato della somma delle conversioni viene shiftato a destra due volte, dividendolo per 4 e ottenendo direttamente il valore in millivolt. Vediamo come è possibile.
Il sensore rende 500mV a 0°C, con una variazione di 10mV/°C. Questo vuol dire 1750mV a 125°C e 100 mV a -40°C.
Il riferimento della conversione è fissato dal modulo interno a 2.048V, il che rende una granularità della conversione (1024 step) di 2mV/step: il risultato della conversione, per ottenere i mV corrispondenti, va quindi moltiplicato per 2.
La lettura utile andrà da 50 step (32h=100mV=-40°C) a 875 step (36Bh=170mV=125°C).
Se prendiamo il risultato della somma 8 conversioni consecutive abbiamo un valore pari a conversione*8.
Se facciamo due shift a destra, dividiamo il valore per 4, ovvero abbiamo conversione*2, che corrisponde al valore in mV della lettura.
Da questo valore basterà togliere l' offset a 0°C per ottenere la temperatura in °C.

Facciamo un esempio: il sensore rende 700mV da cui la la lettura ADC di 15Eh. Questo valore per 2 dà  2BCh, ovvero 700 decimale, che è il valore della tensione in mV.  Sottraendo 500, che è l' offset per 0°C, ottengo 200, ovvero il valore in °C corrispondente alla tensione di ingresso. Dato che la resa è 10mV/°C, il risultato è la temperatura in gradi per 10. Nella presentazione su display viene inserito il punto decimale che consente di trasformare la lettura di 700mV in 20.0.
Se la temperatura è inferiore allo 0°C, ad esempio -10°C, la tensione di uscita di MCP9700 sarà 400mV, il che rende C8h.
Per 2 dà 190h, ovvero 400 decimale. Se ora sottraiamo dall' offeset, otteniamo 500-400 = 100, ovvero 10.0, che considereremo negativo essendo la lettura minore di 500mV. 
Questa soluzione, molto pragmatica, evita l' uso di matematica, sempre pesante in Assembly (e che non era compresa nel livello dell' esercitazione) e permette di osservare come sia possibile risolvere con semplicità problemi relativi alle conversioni AD ed alla relativa presentazione dei risultati.

La conversione è eseguita molto più lentamente di quanto possibile, dato che il compito del programma non è per niente critico. Inoltre, tra una lettura e l' altra del burst viene inserita una buona attesa per permettere una completa stabilizzazione delle tensioni, mentre la cadenza del ciclo è imposta a circa 1 secondo attraverso l' inserimento di un' altra attesa.
Questo permette anche di allontanare la sonda dal circuito con un breve tratto di cavo; per sicurezza, è stata implementata una verifica del valore della conversione per indicare eventuali problemi al sensore:

  • se il valore reso dalla conversione è inferiore ad un minimo, si deve supporre che il sensore sia in corto o danneggiato; viene presentato a display LLL.

  • se il valore supera un massimo, si deve supporre che il sensore sia danneggiato o cortocircuitato alla Vdd; viene presentato a display HHH.

Il risultato della conversione viene diminuito dell' offset come accennato prima:

  • se il valore è inferiore a FAh (250 decimale, ovvero 500mV) viene operata una sottrazione offset-valore, che rende le temperature negative senza la necessità di complementare i numeri. 

  • se il valore è superiore, l' operazione è valore-offset. 

Un ulteriore problema che andava superato era quello della disponibilità di sole tre cifre per la lettura ed è stato risolto in questo modo:

  • se la temperatura è negativa, il display presenta  "-tt", dove tt è il valore preceduto dal segno -, ad esempio -30. Sono scartati i decimi di grado

  • se la temperatura è positiva, ma inferiore a 100, il display presenta "tt.t", rendendo i decimi di grado, ad esempio 20.8

  • se la temperatura supera i 100, il display è "ttt", ad esempio 107. Sono scartati i decimi di grado.

Nelle misure agli estremi della banda i decimi avrebbero senso solo a seguito di una linearizzazione e una taratura, cosa che qui è esclusa. Quindi la loro eliminazione non è arbitraria.
Invece sono mantenuti nella fascia centrale. Questo consente di non rinunciare a tutta la risoluzione di lettura del sensore, pur privilegiando al massimo la zona tipica delle temperature di un ambiente chiuso.
Gli zeri non significativi sono aboliti, per cui si leggerà - 8 e non -08, oppure 0.5 e non 00.5.

L' entrata in modalità Sleep è preceduta dallo spegnimento di tutte le periferiche che sono state accese e dal congelamento a livello 0 degli I/O digitali, allo scopo di minimizzare la corrente. Il risveglio dallo Sleep avviene con il pulsante collegato a MCLR; nel caso in cui lo Sleep sia sospeso per un evento inaspettato (ad esempio un disturbo di alimentazione) viene forzato un reset via istruzione.

Il multiplex è gestito in una semplice routine di interrupt, guidata dal Timer0.  Una macchina a stati rinfresca il contenuto del display alla cadenza di 4ms per digit, il che assicura una accensione senza sfarfallio. La conversione tra dato e maschera dei segmenti è effettuata con una semplice lookup table del tipo RETLW, facilmente portabile anche sui PIC16F.

Un particolare riguarda la struttura del sorgente: la memoria RAM è definita con la direttiva UDATA a cui fa seguito assegnazioni GLOBAL con il solo scopo di visualizzare le variabili nelle finestre di Watch di MPLAB durante i debug con ICD.

Per quanto riguarda la precisione, anche se teoricamente possiamo apprezzare 0.2°C, va detto che, in questo caso come peraltro nell' uso di tutti i sensori elettronici con uscita analogica (e anche in quelli con uscita digitale, anche se meno), una lettura con approssimazione anche solo di 0.5°C richiede una calibrazione accurata del sistema e, se la precisione va estesa a tutta la banda, è richiesta una correzione dell' errore, sia via formule che con una algoritmo piece wise.  Le soluzione richiedono matematica che, come detto, era al di fuori dell' esercitazione. Inoltre, anche considerando di implementare queste linearizzazioni, vanno tenuti presenti alcuni punti fondamentali del progetto:

  • MCP9700 è un sensore low cost, che va calibrato nella gamma che interessa e che, come tutti i componenti elettronici, presenta parametri di dispersione dovuti ai processi costruttivi. 

  • inoltre, come tutti i sensori a stato solido, presenta un auto riscaldamento che, secondo il foglio dati, crea una variazione nella lettura di almeno 0.176V

  • e, molto importante, FVR è un riferimento preciso, ma molto meno di un voltage reference esterno ed è sensibile sia alla variazione della temperatura che della tensione di alimentazione

Di conseguenza, l' insieme delle variabili fa si che, per ottenere la massima precisione, si debba tarare singolarmente il sistema. Accontentandosi della precisione che è valutabile attorno ai soliti +/- 1°C nell' area della temperatura ambiente, non è stata implementata alcuna linearizzazione. 
Risultati migliori si potranno ottenere con i complessi metodi indicati e descritti nell' AN981 e AN1001 .

Per quanto riguarda verifica della tensione di batteria, essa è effettuata nel ciclo principale e produce un display del messaggio "bat" quando il valore scende al di sotto di quello limite (2.5V, parametro vblimit), che potrà essere variato a seconda delle necessità, tenendo presente che FVR e MCP9700 hanno minimi di alimentazione, indicati all' inizio. Questo limite va bene per l' uso con due batterie; se si usano tre batterie sarà conveniente portarlo a 3V. Nel caso di accumulatori si fisserà il limite alla tensione di scarica.

Per una descrizione del metodo di lettura indiretta della tensione Vdd attraverso la FVR, rimando all' articolo
Valutazione dalla Vdd attraverso FVR.

Il tempo di permanenza del display dipende dal parametro timeout. Una lettura ragionevole prevede i 20 secondi fissati nel sorgente, ma potrà essere variato come si desidera entro i limiti dei due byte di ampiezza di timeout (max. 65535 pari a 262 secondi circa): esso infatti serve a conteggiare i passaggi in interrupt, che avvengono ogni 4ms. Non è un dato di precisione assoluta in quanto si usa l' oscillatore inteno su cui non è operata alcuna calibrazione, ma sue eventuali variazioni anche ampie non hanno effetti apprezzabili nel funzionamento.

Per chi vuole avere l' oggetto funzionante senza dover compilare,  è disponibile un hex per la programmazione diretta del chip (Pickit3 o superiore richiesto). La versione è quella con MOSFET sui catodi. 
L' intero programma occupa circa 600 locazioni di memoria.

Il programma è facilmente portabile sui vari 16F Enhanced  o comunque su qualsiasi altro PIC (con una Vref esterna), sostituendo le istruzioni tipiche dei 18F.


La realizzazione pratica.

 E' stato disegnato un circuito stampato a singola faccia con il solito Eagle:

 Una realizzazione casalinga è possibile in poche decine di minuti con una fotoincisione. 

Con lastre pre sensibilizzate di buona qualità e un percorso di incisione semplice, ma ben definito si possono realizzare stampati per montaggi SMD anche di una certa compattezza, senza particolari problemi.

In questo caso il circuito è stato stagnato (stagno chimico a freddo) allo scopo di:
- facilitare la saldatura degli SMD
- per proteggere le piste dalla corrosione.

E' stato usato l' AR17 di CIF (reperibile da Farnell, p/n 4208584), che fino ad ora si è dimostarto il prodotto più affidabile per stagnare a freddo.

Agisce bene per temperature ambiente maggiori di 20°C e in un minuto circa stende uno strato di stagno brillante. Occorre, come dovrebbe essere evidente, operare su rame molto ben pulito, come quello che si ha dopo l'eliminazione del solder fotografico e un buon lavaggio in acqua distillata. 

Le dimensioni sono studiate per inserirlo in una scatoletta Teko TB.7. 

 

 La maggior parte dei componenti è sul lato rame; sul lato opposto ci sono i display, il pulsante, C4 e il sensore di temperatura.

  • LED1/2/3 = HDSP5553, TR362 ed equivalenti

  • R1-R8 = 330-820 ohm, size 1206 (a seconda della sensibilità del display)

  • R9 = 47-100 k size 1206

  • C1/2/3 = 100nF, size 1206

  • C4 = 4.7uF tantalio a goccia

  • IC1 = PIC18F13K22, MSOP

  • IC2 = MCP9700/9700A, TO-92

  • Q1/2/3 = 2N7002, BS170 ed equivalenti, SOT23

  • 1 pulsante

  • 1 strip 6 poli passo 2.54 per ICSP

Il sensore, in un package TO-92, di temperatura esce dalla scatola attraverso un foro. Volendo, è possibile remotarlo con un breve tratto di cavo a tre poli (meglio se schermato in caso di ambiente elettricamente disturbato).
Il sensore esiste anche in altri packages per SMD e può essere disposto diversamente, sempre ricordando che la linea analogica va protetta contro possibili interferenze che falserebbero i bit meno significativi della conversione. 

 Lo stesso inserito nella scatoletta, con 3 pile AAA. 

E la vista frontale 

 

Ovviamente è possibile qualunque altra soluzione costruttiva, data la semplicità del circuito e la sua non criticità.

Una versione con 2 pile può stare in una Teko RC124 o simile.
Miniaturizzando ulteriormente, con display HSP7513 o simili, si può dimezzare la superficie usata.

Il termometro può andare a far parte di altre apparecchiature, dove la sua inserzione è generalmente trascurabile dal puntio di vista del consumo di corrente; con una alimentazione esterna si collegherà a massa il pin -mode- per avere l' accensione costante del display.

Un elemento da considerare, se si utilizza l' alimentazione a pile e la modalità sleep è la scelta dei condensatori, che devo avere il minimo leakage e la disposizione la realizzazione che non deve presentare elementi di dispersione della corrente a riposo.

Un ulteriore riduzione del consumo in sleep potrà essere implementato alimentando MCP9700 non dalla Vdd, ma attraverso un pin del micro che verrà portato a livello alto prima della lettura.

 

Download.

Il sorgente thermo3.asm.

L' hex, versione per alimentazione con tre pile alcaline e display con catodi comuni, comandati da MOSFET

Il circuito stampato (Eagle 5.6 o successivi).


 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 25/02/18.