Volt-Amperometro con PIC18F252 ed LCD

Millenium Datawarewww.mdsrl.itSemplice Schema per Misurare la Tensione in un Punto, la Corrente in un Ramo e Visualizzare i Valori su un Display LCD. Si Realizza Grazie a un PIC, un LCD e un Integrato per Misurare la Corrente…

 
 
 
 




 
INTRO

Per misurare la tensione di un nodo tramite un PIC, si sfrutterà l’ADC interno, mentre, per misurare la corrente in un ramo bisogna passare da un segnale di corrente a un segnale di tensione, per fare ciò si usa quindi un integrato per la misura di corrente, come l’ADM4073F illustrato in un articolo precedente.

In ogni caso ne esistono molti modelli differenti di integrati per la misura della corrente.

Una volta ottenuti i segnali che rappresentano corrente e tensione, vanno convertiti e dopo di che vanno condizionati, ovvero bisogna convertire prima il segnale tramite l’ADC, poi da binario a valore decimale e poi bisogna convertire il valore decimale nell’opportuno valore di corrente o tensione.

Una volta ottenuto il valore bisogna visualizzarlo sul diplay LCD.

 




 

MISURA DELLE GRANDEZZE

La misura della tensione è molto semplice. Se si ha una tensione da misurare minore o uguale a Vcc questa si può convertire direttamente tramite l’ADC, quindi connettere direttamente al pin 0 ad esempio dell’ADC. Se la tensione è molto piccola, ad esempio 500mV questa va amplificata, se invece è superiore a Vcc la tensione va divisa tramite un partitore. Se si connette direttamente la tensione all’ADC si ha una costante di conversione Kv=1, se si usa un amplificatore si avrà un Kv<1 con Kv=1/A dove A è l’amplificazione. Per dividere la tensione invece si usa un partitore resistivo e il Kv sarà dato dalla partizione.

Ricordando che si usa un ADC a 10bit, si ha un valore massimo di 1023 in decimale,  che equivale ad avere una tensione in ingresso pari a Vcc. Supponendo di usare Vcc=5V, per passare dal valore decimale, al valore effettivo, ovvero 5V, bisogna moltiplicare per 0.0048876. Si avrà:

1

Per quanto riguarda la corrente si userà un integrato apposito, detto current  sensing amplifier. Bisogna dimensionare la resistenza di sensing e il Ka, ovvero il valore per la conversione del valore in valore di corrente, si calcolerà in base alla resistenza di sensing, all’integrato usato e in base al fatto se si vuole avere la corrente in Amperre o milliAmperre. Si avrà:

Ad esempio se si usa un partitore con R2=3K e R1=1K si avrà Kv=1/4=0.25, mentre per la corrente, usando un integrato con un guadagno G=50 e Rsensing=0.2Ω si ottiene Kc[A]=0.1 mentre Kc[mA]=100.

 

CODICE

Il codice è il seguente:

sbit LCD_RS at RB0_bit;                     //Configurazione Pin LCD
sbit LCD_EN at RB1_bit;                     //RB0 -> RS
sbit LCD_D4 at RB2_bit;                     //RB1 -> EN
sbit LCD_D5 at RB3_bit;                     //RB2 -> D4
sbit LCD_D6 at RB4_bit;                     //RB3 -> D5
sbit LCD_D7 at RB5_bit;                     //RB4 -> D6
                                            //RB5 -> D7
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;

unsigned char cifra;                        //Variabile cifra dei valori
unsigned int conversion;                    //Variabile valore convertito
long value;                                 //varibile valore tensione corrente
unsigned short int kv = 1;                  //Costante conversione tensione
unsigned short int kc = 133;                //Costante conversione corrente

void main (){                               //Programma principale

TRISA = 0b00000011;                         //AN0 e AN1 ingressi
Lcd_Init();                                 //Inizializza LCD
Lcd_Cmd(_LCD_CURSOR_OFF);                   //Cursore non visibile
Lcd_Cmd(_LCD_CLEAR);                        //Pulisci LCD

    while (1) {                             //Ciclo infinito

        conversion = ADC_Read(1);           //Converti AN1
        value = (long)conversion * 5000;    //*(5000/1023) = * 4.8876
        value = value / 1023;               //Trasformo il valore da binario a decimale
        value = value * (long)kc;           //Moltiplico per la costante di corrente

        Lcd_Chr(1, 1, 'C');                 //Scrivo "Corrente" sulla prima riga
        Lcd_Chr(1, 2, 'o');                 //partendo dalla posizione 1
        Lcd_Chr(1, 3, 'r');
        Lcd_Chr(1, 4, 'r');
        Lcd_Chr(1, 5, 'e');
        Lcd_Chr(1, 6, 'n');
        Lcd_Chr(1, 7, 't');
        Lcd_Chr(1, 8, 'e');                 //fino alla posizione 8
        Lcd_Chr(1, 9, ' ');                 //Lascio uno spazio vuoto

//Questa estrazione delle cifre vale per la corrente espressa in mA
//Se si vuole la corrente in A bisogna sostituire il codice con quello per la tensione
//Ovviamente si cambia la stringa

        cifra = value / 100000;             //Cifra delle centinaia di mA
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        cifra = (value / 10000) % 10;       //Cifra delle decine di mA
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        cifra = (value / 1000) % 10;        //Cifra delle unità di mA
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        Lcd_Chr_CP('m');                    //Scrivi "mA"
        Lcd_Chr_CP('A');

        Delay_ms(10);

        conversion = ADC_Read(0);           //Converti AN0
        value = (long)conversion * 5000;    //*(5000/1023) = * 4.8876
        value = value / 1023;               //Trasformo il valore da binario a decimale
        value = value * (long)kv;           //Moltiplico per la costante di tensione

        Lcd_Chr(2, 1, 'T');                 //Scrivo "Tensione" sulla seconda riga
        Lcd_Chr(2, 2, 'e');                 //partendo dalla posizione 1
        Lcd_Chr(2, 3, 'n');
        Lcd_Chr(2, 4, 's');
        Lcd_Chr(2, 5, 'i');
        Lcd_Chr(2, 6, 'o');
        Lcd_Chr(2, 7, 'n');
        Lcd_Chr(2, 8, 'e');                 //fino alla posizione 8
        Lcd_Chr(2, 9, ' ');                 //Lascio uno spazio vuoto

        cifra = value / 10000;              //Cifra decine di Volt
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        cifra = (value / 1000) % 10;        //Cifra unità di Volt
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        Lcd_Chr_CP('.');                    //Scrivi "."

        cifra = (value / 100) % 10;         //Cifra centinaia di mV
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        cifra = (value / 10) % 10;          //Cifra decine di mV
        cifra = cifra + 48;                 //Trasformazione in codice ASCII
        Lcd_Chr_CP(cifra);                  //Scrivi le centinaia

        Lcd_Chr_CP('V');                    //Scrivi "V"

        Delay_ms(2000);                     //Delay di 2Sec
    }
}

Per ottenere il codice si è partiti dal presupposto che  bisogna misurare due valore di tensione e visualizzarli su un display LCD. Quindi, prima di tutto, si è indicato come viene connesso l’LCD al microcontrollore, e poi sono state inizializzate alcune variabili, una per inserire il dato convertito, una per il dato elaborato e l’altro per contenere le cifre dei valori da visualizzare. Le altri due variabili sono due costanti, una per la conversione da valore numerico a valore di corrente e l’altra per la conversione numerica del valore convertito a valore di tensione, i valori di queste variabili si inizializzano calcolandoli come visto prima.

Nel programma principale vengono segnati i pin 2 e 3 come ingressi, viene inizializzato LCD e l’ADC.

Nel ciclo infinito viene convertito il valore, elaborato e visualizzato. Prima di tutto viene convertito il valore con l’ADC e il valore convertito viene moltiplicato per 5000 (alimentazione a 5V) e poi diviso per 1023 per passare da un valore binario a un valore effettivo di tensione, ad esempio la tensione in ingresso all’ADC è 5V il convertitore ritorna 1023 in binario, moltiplicato per 5000 e poi diviso per 1023 ritorna il valore 5000 ovvero 5000mV.

Questo valore viene poi moltiplicato per la costante Kc o la costante Kv se si tratta di tensione.

Dopo di che si mostra una lettera alla volta sulla prima riga la stringa “corrente”, sulla seconda riga la stringa “tensione”, a queste stringe si aggiunge uno spazio e poi sempre una cifra alla volta i valori di tensione e corrente. I valori e le stringhe sono stati così visualizzati perché usando altre stringhe della libreria LCD, il display dava errore di visualizzazione.

Analizziamo il primo caso, nel caso di corrente, il valore massimo sarà 5000*20=100000 ovvero 100mA. Per isolare questo valore divido quindi prima per 100000 per isolare l’1, poi gli sommo 48 per convertirlo in ASCII e poi scrivo sul display LCD subito dopo lao spazio la prima cifra.

Poi divido per 10000 e ne faccio il modulo 10 per isolare le decine e successivamente rifaccio la stessa operazione dividendo per 1000. Infine scrivo mA.

Se il valore di Kc è più grande di 133 è possibile che il valore massimo sia più grande, bisogna quindi utilizzare una visualizzazione simile a quella che si fa per la tensione oppure dividere per  1000000, poi per 100000, 10000 e infine per 1000 ottenendo una cifra in più.

Per la tensione si è sempre moltiplicato per 5000 e poi diviso per 1023 e successivamente rimoltiplicato per il valore di Kv. Questa volta si è utilizzata una visualizzazione diversa, supponendo di avere in ingresso 5V, si ottiene 1023 dall’ADC, poi moltiplicando e dividendo per 5000 e 1023 si ottiene 5000. Questo valore si divide prima per 10000 ottenendo la prima cifra ovvero le decine di volt, in questo caso sempre 0, ma se kv è ad esempio è uguale a 4 il valore massimo è 20V quindi la prima cifra può essere 1 o 2 oltre a zero.

Poi si divide per  1000 e si fa il modulo 10 ottenendo le unità di volt, si visualizza questo valore dopo le decine e poi si scrive un “.”. Rimangono da visualizzare i centesimi di Volt e le decimi di Volt, e questo si fa dividendo prima per 100 e poi per 10 visualizzando ogni volta il valore sul display. Se si vogliono anche i millesimi di Volt, ottenendo una precisione maggiore, bisogna prendere il valore elaborato e farne modulo 10 e visualizzare anch’esso subito dopo i decimi di Volt.

Infine vi è un delay di 2 secondi in modo tale che si possa leggere il valore sul display senza che esso vari per 2 secondi.

La configurazione dei fuses è la seguente:

fuses

 




 

SCHEMA

Lo schema è il seguente:

schema-768x458 Come circuito di prova, per misurare corrente tensione si usa una batteria al litio. Visto che la tensione massima è 4.2V posso connettere direttamente la tensione positiva della batteria all’ADC, mentre per la corrente uso un ADM4073F con una resistenza di sensing di 1Ω supponendo che la corrente massima sia 100mA e il guadagno sia 50. Come oscillatore si usa un cristallo da 4MHz con due condensatori di stabilità da 22pF. La R3 da 2.2K è una resistenza di pull-up per evitare che il PIC si resetti. Il PIC è alimentato con 5V continui e anche il display LCD. La connessione tra LCD e PIC è quella indicata nelle prime righe del codice, mentre la resistenza variabile RV1 serve per regolare ilcontrasto dell’LCD.
Lo schema montato su breadboard ha la seguente forma:

Breadboard

 

DOWNLOAD

Il file Mikroc, il file .HEX e la simulazione del circuito sono scaricabili dal seguente LINK!!!



 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

3 pensieri su “Volt-Amperometro con PIC18F252 ed LCD

  1. Veramente ottimo!!
    Volevo realizzarlo ma non riesco a trovare l’integrato ADM4073F, potete cortesemente indicarmi dove lo posso trovare oppure l’equivalente?
    Grazie

    • Ciao, puoi usare un qualsiasi High-Side, Current Output Current Sense Amplifier con guadagno 50V/V oppure a guadagno regolabile come l’INA138

Rispondi a Giuliano Annulla risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *