Voltmetro/Amperometro con Pic16F785

1 di 8
Voltmetro/Amperometro con Pic16F785
Ciao a tutti,
molto spesso su grix vedo molti progetti con pic 16F84 che ormai e' un pic costoso e con poche periferiche
rispetto all' ultima generazioni di pic16F come il mitico 16F690 (20 pin), o come quello che vi propongo oggi il
pic16F785(20 pin). Il costo dei nuovi pic e' molto contenuto e in hardware hanno gia' molte periferiche.
Descrizione
Qualche settimana fa in un momento di relax , ho deciso di aggiungere ad un alimentatore autocostruito ( con
lm317 limitazione in corrente e transistor di potenza per elevare la corrente massima disponibile a 2A e tensioni
da 1,5Volt a 30volt) , un bel voltmetro e amperometro su display LCD Alfanumerico ,utilizzando cio' che avevo
in casa e con il numero minore di componenti.
Rovistando nella mia cassettina dei sample , ho trovato questo bel pic16HV785, che rispetto a tutti i suoi fratelli
della serie 16F , ha un bel regolatore interno ( una specie di Zener di precisione ) che grazie a una resistenza
esterna, permette di alimentare questo pic in modo semplice e senza regolatori esterni ( non serve un 7805) .
Un'altra peculiarita' di questo pic e' di avere al suo interno 2 Amplificatori Operazionali con buone caratteristiche
che per l'uso che ne volevo fare si sono dimostrati ottimi.
Per chi e' andato a scuola qualche anno fa come il sottoscritto ricordo brevemente le poche equazioni che
descrivono il funzionamento di un amplificatore operazionale in modalita' amplificatore di differenze ( nel mio
caso devo misurare una tensione quindi una differenza di potenziale)
Queste equazioni si ricavano facilmente con il teorema della sovrapposizione degli effetti essendo tutti i
componenti del circuito lineari.
Se impongo l'uguaglianza dei rapporti R2/R1=R4/R3
Si ottiene che Vout = (R2/R1) ( Vi+
-
Vi-)
Per realizzare un Amperometro , si misura la tensione ai capi di una resistenza di piccole dimensioni in serie al
carico.Si vuole che il resistore per tale misura sia il piu' piccolo possibile (0,1 ohm o meno),quindi la tensione ai
suoi capi e' di basso valore e quindi non leggibile con un ADC del pic. Per utilizzare tutta la precisione degli
ADC del Pic che ricordo che per questo modello e' di 10bit (quindi di 1024 livelli di quantizzazione) la tensione
ai capi della resistenza viene amplificata con un operazionale ( in questo caso interno al pic ) in configurazione
di amplificatore di differenze , in quanto la massa del pic e il riferimento a tensione piu' bassa dell' amperometro
non sono la stessa cosa.L'amplificatore Operazionale interno al Pic16HV785 funziona tranquillamente con
tensione non duale, (come lm358) ma la sua uscita non puo' arrivare alla tensione Vcc di alimentazione , ma si
ferma a Vcc-0,1 Volt ( come accade spesso ad operazionali rail-to-rail non speciali). Cio' significa che se utilizzo
VCC anche come riferimento per il convertitore analogico digitale ADC del pic , non riesco ad utilizzare tutti i 10
21/11/2009 7.00
2 di 8
bit dell ADC. Per ovviare a questo , ho utilizzato un lm385 che e' uno zener di precisione a 2,5 volt , che viene
utilizzato come riferimento per l'ADC , mentre tutto il resto del circuito e' alimentato a 5 volt prevenienti dal
regolatore interno del pic 16HV785.
Con l'accorgimento del lm385 , riesco ad utilizzare gli ADC con la massima precisione possibile.
Le equazioni che regolano l'amperometro sono:
Resistenza di shunt 0,11 ohm ( il convento passava 2 resistenze da 0,22 ohm collegate in parallelo)
L'amplificatore di differenze è costituito da R4 R6 R9 R10 e dall' operazionale OP2 del pic16HV785,
il rapporto di amplificazione e' R10/R6=R9/R4 = 10.
L'ADC ha come tensione di riferimento 2,5 V forniti dal riferimento di tensione LM385
Tensione massima di ingresso (I+ I-) per il fondoscala e' di 2,5V/10 = 250 mV
La corrente massima misurata e' quindi I=V/R che risulta I=0,25/0,11= 2,27 Ampere
La minima corrente misurabile e' semplicemente Imax/(numero passi quantizzazione dell' ADC)
Imin=2,27/1024 = 0,00221946 A che corrispondono a 2,21 mA , da qui la risoluzione dell' amperometro e'
di 2,21 mA
Per quanto riguarda il voltmetro si utilizza l'altro operazionale OP1 all' interno del pic ,sempre in configurazione
amplificatore differenziale , ( posso misurare la tensione senza avere lo stesso riferimento di massa ) , ma in
questo caso invece di amplificare ho un partitore di tensione 1/12 in modo da poter misurare 2,5x12 e cioe'
con 30 fondo scala.
Le equazioni che regolano il voltmetro con Fondo Scala 30 volt:
Amplificatore differenze formato da OP1 interno al pic e R3 R5 R7 R8
il rapporto di amplificazione e' R3/R8=R5/R7 = 1/12.
L'ADC ha come tensione di riferimento 2,5 V forniti dal riferimento di tensione LM385
21/11/2009 7.00
3 di 8
Tensione massima di ingresso (V+ V-) per il fondoscala e' di 2,5V/(1/12) = 30 V
La minima corrente misurabile e' semplicemente Vmax/(numero passi quantizzazione dell' ADC)
Vmin=30/1024 = 0,002929 V che corrispondono a 29,29 mV che corrisponde alla minima risoluzione del
voltmetro.
Circuito dell' Alimentatore
Questo e' il circuito dell' alimentarore stabilizzato regolabile in tensione con 5 livelli limitazione di
corrente, costruito attorno all famoso lm317 ( non raccontero' questo circuito , visto piu' volte
anche su grix e descritto egregiamente da i2viu il Sig. Crepella, noto frequentatore di questo sito)
che ho costruito tempo addietro e ho aggiornato con il voltmetro/amperometro , aggiungendo il
Transistor PNP darlington TIP 145 ( correttamente alettato) che amplifica in corrente LM317
consentendo al circuito di raggiungere comodamente i 2 Ampere di uscita. Il convento forniva il TIP
145 , ma si puo' utilizzare qualsiasi PNP o PNP darlington che supporti una corrente maggiore di 5
Ampere ( per garantire i 2 Ampere di uscita massimi).
Se si utilizza un PNP non darlington R1 va abbassata di valore a valori intorno ai 2 - 4 ohm a seconda
del beta del transistror in questione.
Nota:
per calcolare i valori di resistenza R5-R9 secondo le proprie esigenze , basta utilizzare questa
semplice equazione:
Rx=0,7Volt/(Corrente limite)
dove , 0,7 corrisponde alla tensione di accensione del tranistor NPN Q2 BC237 ( va bene qualsiasi NPN
per piccoli segnali ) e la corrente Limite esperessa in Ampere.
Es Voglio limitare la corrente a 100mA
Rx=0,7/0,1=70 Ohm che e' approssimata al valore 68Ohm della serie standard dei resistori.
Realizzazione
Per i puristi , nel progetto allegato c'e' anche il file DRB ( formato Eagle) per costruirsi un circuito
21/11/2009 7.00
4 di 8
stampato ( Il disegno dello stampato l'ho fatto di corsa e solo come aiuto per realizzarne uno su
millefori).
Per comodita' e velocita' ho realizzato il circuito ( che e' veramente semplice e con pochissimi
componeti con una piccola basetta millefori . Il convento mi ha passato dei resistori da 150Kohm e
non da 120Kohm quindi nel software le formule per il voltmetro hanno un rapporto di guadagno di
1/15 e non 1/12.
Per i primi esperimenti con il pic16F785 ho utilizzato una scheda di prototipazione della microchip
che e' in kit con il programmatore pickit2 . Questa board monta a bordo di solito un 16F690 ( che non
ha gli amplificatori operazionali a bordo), che ha le stesse pedinature del 16F785 ( per alimentazione e
programmazione ).
Il display LCD utilizzato (reciclato da una vecchia console di allarme) e' a una sola riga 16 Caratteri,
compatibile con hd4480 . Per puro caso il display e' mappato su due righe di 8 caratteri allineate ( non
chiedetemi il perche' non ho il datasheet del display) quindi nei sorgenti mi sposto sia sulla prima
riga che sulla seconda.
Il TIP 145 e sotto alla basetta millefori con il LM317 , l'aletta di raffreddamento e' recuperata da una
vecchia CPU da PC . Tra aletta e TIP145 c'e' come di consueto un isolante in mica e la vite di fissaggio
e' isolata dal corpo del TP145. Tra l'aletta di Raffreddamento e la lastra di alluminio su cui e' fissato il
circuito e TIP145 c'e' un bel velo di pasta termoconduttiva al silicone per abbassare la
resistenza termica al valore piu' basso possibile.
21/11/2009 7.00
5 di 8
Firmware
Passiamo ora alla descrizione del software. Vedo spesso firmware in assembler , complicati e criptici
per i non addetti ai lavori, quindi ho deciso per chiarezza e velocita' di scrivere il programma in
linguaggio C , utilizzando il complicatore Hitech C che e' free nella versione lite( scaricabile
gratuitamente e integrata nell' MPLAB della microchip ).
Il Pic16HV785 ha solo 2Kbyte di flash , quindi non ho potuto utilizzare la funzione printf per scrivere a
display la tensione come numero a virgola mobile in quanto la libreria printf per i float occupa troppo
spazio per essere contenuta nei 2 kbyte di flash. Ho fatto una veloce ricerca nelle mie librerie per
Pic18F (dove la printf non ha i float ) e ho trovato una bella funzione che stampa i float e non occupa
tanta flash.Ho allegato anche una funzione per stampare un valore intero a 16 bit ( unsigned int ) che
rappresenta la corrente.
Il programma inizializza i vari registri , setta la velocita' di clock del pic , inizializza il display , abilita
21/11/2009 7.00
6 di 8
gli amplificatori operazionali interni , poi si entra in un loop infinito che legge tensione e corrente
tramite l'AN2 e AN0 , converte il valore letto tramite le formule di conversione e le strampa sull' LCD
alfanumerico 16x2 ( compatibile HD4480)
Mettero' per semplicita' la funzione Main e per i piu' curiosi c'e' in allegato tutto i sorgenti software.
#include <pic.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "delay.h"
#include "xlcd.h"
#include "adc.h"
__CONFIG (INTIO
FCMEN ) ;
& WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & DUNPROTECT & BOREN &
#define SetClock() { OSCCON = OSCCON | 0b01100000 ; }
void putch(unsigned char byte)
{
WriteDataXLCD(byte);
}
char * mset(char * str,char ch,char len)
{
while (len--){
str[len]=ch;
}
return str;
}
void reverse(char s[])
{
unsigned char i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
void _itoa(unsigned n, char s[])
{
char i;
i = 0;
do {
/* generate digits in reverse order */
s[i++] = n % 10 + '0';
/* get next digit */
} while ((n /= 10) > 0);
/* delete it */
s[i] = '';
reverse(s);
}
unsigned char *ftoa (float x, unsigned char *str,char prec,char format);
char buffer[9];
int main(void)
{
unsigned int v,i,vref;
21/11/2009 7.00
7 di 8
double vout,iout;
SetClock();
//785
ANSEL0 = ANSEL0 & 0x00;
ANSEL1 = ANSEL1 & 0x00;
CM1CON0 = 0 ;
CM2CON0 = 0 ;
TRISA=0xFF;
TRISB=0xFF;
TRISC=0xFF;
DelayMs(100);
OpenXLCD(0);
ClrXLCD();
ADIF=0;
ADIE=0;
GIE=0;
OPA1ON=1;
OPA2ON=1;
// Abilito Amplificatori Operazionali interni
while (1){
DelayMs(250);
i=a0();
v=a2();
vout= v * 0.036621093;
//
//
//
//
//
Leggo ADC0
Leggo ADC2
Vref 2.5 Volt
in volt
(2,5Volt/1024)*15 dove 15 e' il rapporto di
attenuazione
iout= i * 2.21946;
2.21 mA
// in mA con 0.11 ohm di Shunt
ogni bit corrisponde a
// (((2.,5Volt/1024)/10)/0.11)*1000
// con 10 rapporto di amplificazione e
// 0.11 Resistenza di shunt per la misura della corrente
mset(buffer,' ',8);
i=(unsigned)iout;
i = ( (i>6) ? i-6 : 0);
// Pulisco il Buffer
// Azzero L'offset del OP interno
_itoa(i,buffer);
buffer[strlen(buffer)]=' ';
buffer[5]='m';buffer[6]='A';
ClrXLCD();
gotoxyXLCD(0,DIPLAY_LINE_2); // Scrivo mA
putsXLCDHex(buffer,8);
mset(buffer,' ',8);
ftoa(vout,buffer,2,'f'); // Scrivo il valore a virgola mobile sul buffer 2 cifre
dopo la virgola
buffer[5]=' ';buffer[6]='V'; //
gotoxyXLCD(0,DIPLAY_LINE_1);
putsXLCDHex(buffer,8);
}
}
21/11/2009 7.00
8 di 8
Conclusioni
Sorgenti del Software e Schemi elettrici (eagle) e pcb
21/11/2009 7.00