Visualizzare una temperatura mediante conversione A/D su display a due righe con PIC MICRO

Temperatura Picmicro

In questo articolo cercherò di illustrare in modo esauriente il principio di funzionamento dei convertitori analogico digitali presenti nei microcontrollori PICMICRO della Microchip serie 16fxxx visualizzando una temperatura mediante conversione A/D su display a due righe. Vedremo anche la descrizione delle parti fondamentali del firmware da caricare nel micro, per leggere convertire e visualizzare la temperatura rilevata dal sensore.

La conversione A/D con PIC micro


I ragionamenti e le illustrazioni trattate nell’articolo potranno essere facilmente estese, per la maggior parte dei micro prodotti da Microchip, in quanto l’architettura dei dispositivi risulta pressoché simile.

Il dispositivo trattato nel seguente articolo è il pic16f876, che trova spazio in diverse applicazioni sia in campo hobbistico che in campo professionale.
Si partirà dunque da un’illustrazione teorica sul funzionamento, per poi arrivare alla gestione del convertitore a livello software in linguaggio C e con un esempio pratico di interfacciamento hardware con un comunissimo sensore di temperature LM35z.

Il convertitore A/D del PIC16F876

Il modulo di conversione A/D del pic in questione, fa capo a 5 ingressi analogici sui quali sono interconnesse delle capacità di sample-and-hold, ovvero di campionamento del segnale analogico applicato, le quali a loro volta sono collegate al convertitore interno.

Il convertitore progettato per questo dispositivo è a 10 bit ad approssimazioni successive, ciò significa che il segnale campionato su un ingresso viene poi convertito in digitale mediante una rappresentazione binaria a 10 bit.

Il convertitore ha 4 registri interni ad 8 bit ciascuno che sono:

      ADDRESH: Contiene una parte (alta - più significativa) del risultato dell’operazione di conversione

 

      ADDRESL: Contiene una parte (bassa - meno significativa) del risultato dell’operazione di conversione

 

      ADCON0: Utilizzato per la selezione dei pin analogici e della frequenza di conversione

 

    ADCON1: Utilizzato per la configurazione dei pin analogici e digitali e per le tensioni di riferimento

IL REGISTRO ADCON0


Questo è un registro fondamentale, che permette di impostare le principali caratteristiche di funzionamento del convertitore attraverso la progettazione del firmware. Come si può notare dalla figura, è un registro ad 8 bit, dove:
• Il 7 ed il 6 selezionano la frequenza di oscillazione del clock del convertitore rispetto alla frequenza di funzionamento del micro
• Da 5 a 3 vi sono i bit che ci permettono di selezionare uno o più, dei 5 ingressi analogici disponibili per la conversione tutti posizionati sulla porta A del dispositivo.
• 2 è un bit di flag. Questo bit serve per controllare lo stato attuale della conversione. In sostanza è un bit di lettura, che assume valore 1 quando la conversione risulta in progress, mentre assume valore 0 quando la conversione è terminata.
• 1 non implementato
• 0 è il bit che permette l’abilitazione o la disabilitazione del convertitore, in modo da poter ottimizzare i consumi quando necessario.

IL REGISTRO ADCON1


La tabella di sopra può risultare di difficile comprensione, ma invece riassume in modo molto semplificato le configurazioni necessarie per l’impostazione dei pin analogici. La descrizione dei bit del registro è la seguente:
• 7 è il bit che permette di selezionare in che modo verrà disposto il risultato della conversione. In sostanza se ADMF viene impostato ad 1 allora il risultato verrà scritto nei primi 8 bit del registro ADRESL e negli ultimi 2 di ADRESH, quindi i rimanenti 6 bit del registro ADRESH verranno posti a 0.
Se invece ADMF viene impostato a 0, allora il risultato verrà scritto nei primi 8 bit di ADRESH e nei primi 2 di ADRESL, mentre gli altri sei bit di ADRESL verranno posti a zero. Tenendo presente che come accennato in precedenza ADRESL ed ADRESH sono registri ciascuno ad 8 bit, la situazione al termine della conversione sarà la seguente:

ADRESL ADRESH
ADMF = 1 xxxxxxxx xx00000
ADMF = 0 000000xx xxxxxxxx

Dove con le x vengono indicati i bit relativi alla conversione a 10 bit.
• I bit 6 a 4 non sono implementati
• Da 3 a 0 si trovano invece i bit che permettono di configurare i pin come analogici, ovvero come reali pin di conversione o come pin dedicati ai valori di riferimento.

Ad esempio se volessi impostare tutti gli ingessi della porta A del PIC come analogici, basterebbe caricare nel registro ADCON1 la sequenza binaria 0000, come visibile nella prima riga della tabella bianca riportata sopra. In questo modo otterrei che i pin RA5, RA3, RA2, RA1, RA0, sarebbero impostati come ingressi analogici ed in più le tensioni di riferimento sarebbero forzate a VDD.
Caricando invece nel registro ADCON1 la sequenza binaria 1111, come visibile nell’ultima riga della tabella bianca riportata sopra, otterrei RA5 configurato come I/O digitale, RA3 ed RA2 rispettivamente Vref+ e Vref- impostabili esternamente,RA1 I/O digitale , RA0 ingresso analogico mentre RA3 ed RA2 forzati alla tensione VDD e così via.

IL SENSORE DI TEMPERATURA LM35Z

E’ un sensore molto semplice da utilizzare e trova largo spazio in parecchie applicazioni dove è necessario avere una buona linearità in uscita, con un range misurabile che va da -55°C a +155°C.
Offre una precisione di ±1/4 di risoluzione a °C nel range di temperature intorno alla temperatura ambiente e ±3/4 di risoluzione a fondo scala.

Eroga una tensione di uscita pari a 10mV/°C, quindi con 10mV d’uscita ci troveremmo ad una temperatura di 1 grado, mentre con 100mV ci troveremmo ad una temperatura di 10 gradi, fino ad un massimo di 150°C pari a 1,5 Volt.
E’ un sensore low cost, ed ha la seguente configurazione dei pin:

Considerando l’esempio pratico che vedremo prossimamente, dove il nostro PIC sarà alimentato a 5 Volt, decidendo di alimentare con la stessa tensione il sensore di temperatura, utilizzando come tensione di riferimento per L’A/D converter 0-5Volt (caso più semplice), riusciremo a coprire tranquillamente tutto il range di lavoro del sensore, in quanto alla temperatura massima di 150°C, l’uscita del sensore sarà di 1,5 Volt.

A rigor di tecnica, il segnale del sensore dovrebbe essere condizionato, in modo da sfruttare tutta la scala di conversione del convertitore, ovvero bisognerebbe fare in modo di ottenere a 0°C , 0 Volt d’ingresso al convertitore, ed a 150°C 5Volt d’ingresso al convertitore.

Per ragioni di semplicità circuitale ed anche per ragioni legate ad eventuali non linearità che si introdurrebbero con il blocco di condizionamento, per l’applicazione in esame è sufficiente interfacciare direttamente il sensore al microcontrollore per ottenere una risoluzione più che accettabile. L’unico accorgimento da usare, nel caso si debba posizionare il sensore lontano dal microcontrollore mediante un cavo di collegamento esterno al PCB, è quello di inserire come visibile nella figura seguente, una sorta di filtro passa-basso. Questo perché nel caso in cui all’interno del nostro circuito, o nell’ambiente esterno ci fossero sorgenti in commutazione veloce oppure sorgenti radio vicine, allora il cablaggio potrebbe fungere da antenna ricevente, ed il rumore potrebbe sovrapporsi al segnale utile falsando la conversione.

A questo punto non resta che illustrare lo schema elettrico del sistema, per poi nella prossima puntata illustrare le parti salienti del firmware, scritto in linguaggio C mediante il supporto dell’ambiente di sviluppo MikroC.

SCHEMA DEL CIRCUITO DI ESEMPIO

Come si può notare dallo schema, il circuito è molto semplice, ma ciò che risulterà interessante, sarà l’analisi del firmware, che potrà dare spunto per applicazioni più complesse. Questo è infatti uno stralcio di simulazione di un sistema più complesso che prevede il monitoraggio della temperatura di un sistema di riscaldamento con invio dei dati a distanza.

Prevede le impostazioni delle soglie di allarme, un trasduttore piezoelettrico controllato in PWM, per la segnalazione sonora dello stato di temperatura eccessiva, ed un display a doppia riga per la visualizzazione della temperatura in tempo reale. Il PIC ha la tipica configurazione con oscillatore quarzato, mentre il sensore (U1) come accennato precedentemente, è direttamente interfacciato al micro.

Il sistema prevede un ingresso di reset , uno di interrupt ed altri due pulsanti general pourpose . Gli ingressi dei pulsanti sono configurati in pull-up con delle resistenze da 10k.

Partirò dall'impostazione dei registri dell'ADC, per arrivare all'utilizzo delle librerie grafiche incluse nel software MikroC che permettono di visualizzare con semplicità qualunque tipo di testo.

Definizione registri ADC

Per quanto detto sopra, è facile intuire che per far funzionare il convertitore analogico digitale interno al micro, è necessario settare correttamente i registri ADCON0 e ADCON1.

In particolare nel firmware da me sviluppato, i settaggi sono stati i seguenti:
ADCON0=0x80 "esadecimale" che in binario diventa: 10000000
ADCON1=0x8E "esadecimale" che in binario diventa: 10001110

Considerando che il primo bit a sinistra è il bit7 mentre l'ultimo è il bit 0, consultando la tabella del registro ADCON0 precedente, si può vedere come in tal caso ho solo provveduto impostare la frequenza di conversione pari ad 1/32 della frequenza d'oscillazione del clock, lasciando tutti gli altri parametri come default. Essendo comodo ai fini della progettazione hardware, ho lasciato il pin A0 come ingresso analogico, infatti i bit da 5 a 3 sono a zero.

Per il registro ADCON1 invece ho impostato i bit che mi permettono di avere il pin A0 come ingresso analogico, mentre i bin A1 A2 ed A3 come I/O digitali, infatti la configurazione dei bit che vanno da 3 a 0 come 1110, guardando la tabella del registro ADCON1 corrisponde alla codifica che impone quanto detto sopra.
Oltre che l'impostazione di questi due registri, bisogna impostare il registro TRISA, che è colui che comanda la direzione dei pin del micro.Nel caso in questione, si avrà:
TRISA=0x07;//0b00000111;
Che impone il pin A0 come ingresso "analogico" ed i pin A1 ed A2 come digitali.
Di seguito si riporta il listato del firmware che esplica la definizione delle variabili e dei registri di controllo.

---------------------------------------------------------------------------
#include"built_in.h"
unsigned char ch;
unsigned int t,oldstate,m1,m2,Temp_dec,Temp_unit,
somma,somma1,AD,init,but,n,ack;
unsigned short i,flag,r_flag,flag_int;
char *tc,*pom,*name,fi;
long tlong;
char Soglia1[2];
char *buf[15];
//Definizione delle funzioni usate nel programma
void soglia(void);  //Impostazione della soglia 
oltre la quale attacca la pompa
void Memory(void);  //Routine di memorizzazione 
in EEProm della soglia impostata e di conversione A/D
void Control_min(void);//Routine di controllo superamento 
della soglia
void Allarme(void); //Routine di controllo 
superamento dei 70 °C
void Control_man(); //Routine di Controllo 
spegnimento manuale pompa e 
riaccensione con controllo superamento 70 °C
void Maschera();    //Maschera di presentazione 
Software e Progettista
void Control_min1(void);//Routine di controllo 
temperatura max = 70°C se la pompa è messa off manualmente
//************************************
void mask_radio(void);
void main() {
Soglia1[0] =0x30; //0b00110000;
Soglia1[1] =0x31; //0b00110001;
TRISB=0x01;
TRISA=0x07;//0b00000111;
TRISC=0xbb;
//Definizione registri per il convertitore ADC
ADCON0=0x80;
ADCON1=0x8E;
..
...
....
.....

Dove nelle ultime righe si pò notare quanto descritto pocanzi.

Routine di Conversione

Di seguito è riportata la routine, che permette di leggere il valore analogico presente sull'ingresso A0 del pic micro, e di convertire la cifra binaria, in uno o più caratteri alfanumerici da inviare verso il display.

Si può notare come nella riga "t  = ADC_read(0);" venga memorizzato il valore convertito.

t  = ADC_read(0);   // Legge il valore presente sul primo canale dell'ADC
LCD_Chr(1,3,223);   // Punto rappresentativo °
LCD_Out(1,4,"C  Ambiente");
LCD_Chr(2,13,40);
LCD_Chr(2,16,41);
LCD_Out(2,1,"Start Pompa");
LCD_Chr(2,14,m1);
LCD_Chr(2,15,m2);

A questo punto dopo aver convertito la grandezza analogica, otterremo un valore intero corrispondente alla temperatura convertita secondo la regola:

N=Vin*2e^(10)/Vref

Ovviamente non è possibile inviare verso un display un valore intero composto da due cifre, ad esempio 10 , per pretendere di vederlo visualizzato sui suoi segmenti, ma è necessario separare le cifre della quantità da inviare mandandole una per volta. Quindi nel caso di un valore convertito corrispondente a 10°C, noi dovremmo mandare verso il display prima la cifra uno e poi la zero.

Tutto ciò viene eseguito dalla routine di seguito, che prende un intero corrispondente al valore convertito, e separa le cifre preparandole all'invio verso il display.

tlong  = t * 5000;
asm {
MOVF STACK_2,W
MOVWF _tlong+2
MOVF STACK_3,W
MOVWF _tlong+3
}
t = tlong >> 10;
ch     = t / 1000;
ch    = (t / 100) % 10;

Nella variabile Temp_dec, vengono memorizzate le decine relative al valore convertito, per poi essere inviate al display:

Temp_dec=ch+48;
LCD_Chr(1,1,48+ch);

Nella variabile Temp_unit vengono memorizzate le unità relative al valore convertito per poi essere inviate al display:

Temp_unit=ch+48;
LCD_Chr_CP(48+ch);

Le routine di invio caratteri al display

Il software di sviluppo MikroC , tra le tante funzioni, mette anche a disposizione quelle relative alla gestione dei comunissimi display a doppia riga con controller HDD44780.

Le seguenti funzioni, permettono sia di visualizzare un testo, che un singolo carattere.

Di default il software prevede l'uso della porta B dedicata al display, utilizzando 4 pin di dati e due di controllo.

Di seguito indicherò le funzioni principali, che ho utilizzato nello sviluppo del firmware:


Lcd_Cmd(LCD_CLEAR);          //Pulizia schermo

LCD_Chr(1,1,"carattere");    //Permette di scrivere un carattere partendo dalla posizione 1,1.

Il primo uno indica la riga, mentre il secondo uno la posizione in cui verrà scritto il carattere.

Essendo il display un 2X16, ovvero 2 righe a 16 caratteri cisacuno, con questa funzione riusciremo a posizionare il carattere o numero, in qualunque posizione dello schermo.

LCD_Out(1,i,name);             //questa funzione, permette di inviare direttamente un testo, in questo caso memorizzato nella variabile name, partendo dalla posizione i-esima della riga 1.

Ci sono tante altre funzioni, di uso meno comune, che permettono di personalizzare le applicazioni che è possibile trovare nella guida del software MikroC.

Il presente articolo ha dato solo traccia delle funzioni essenziali di conversione e visualizzazione su display, inquanto sarebbe stato decisamente lungo e sicuramente poco istruttivo il commento di tutto il firmware di gestione del dispositivo. Pertanto ho deciso appositamente di focalizzare l'attenzione in modo sintetico, sulle parti essenziali del sistema, rimanendo a completa disposizione, per eventuali chiarimenti o approfondimenti.

2 Comments

  1. Doc77 26 ottobre 2015
    • Mario Mottula 27 ottobre 2015

Leave a Reply