Je vous propose ici un tutoriel pour vous expliquer comment lire une tension présente sur une broche du PIC avec le convertisseur A/N.
Configuration :
- PIC18F46K22
- IDE : MikroC Pro for PIC Version 6.6.2
- Compilateur : Mikro prog suite fo PIC V 2.32
- Plaque Easy PIC V7
- LCD 16x2 en mode 4bits
fonctions utilisées:
- ADC_Read
- Sprintf
En effet certains PICs possèdent des convertisseurs analogique Numériques que nous appellerons ADC pour ( Analog-Digital Converter) ou CAN ( pour Convertisseur Analogique Numérique).
toutefois nous privilégierons le terme ADC afin de toujours bien spécifier qu'on parle du convertisseur car il existe un bus de communication qui s'appelle également CAN (Controller Area Network).
Il est vrai que dans certains cas cela peut s’avérer extrêmement utile d'avoir à sa disposition un convertisseur analogique/numérique :
- Valeur de la position d'un potentiomètre
- valeur de la tension d'une batterie/pile
- Et différent capteur fournissant une valeur de tension analogique variable en sortie (capteur t°, thermistances etc ..)
Même si la lecture de cette tension est extrêmement simple, Il faut tout de même veiller à bien sélectionner et configurer notre entrée en analogique. Ça normalement vous devriez savoir le faire.
RAPPEL :
- Pour le choix de la broche => rendez vous sur votre DS prenons ici comme exemple le PIC-18F46K22 en place sur ma carte EasyPIC7 .
En page 8 on trouve le sommaire succinct des broches E/S . On voit que RA1 est doté d'un convertisseur A/D, nommé ANA1 ( signifiant Analogique Channel-1).
- Ensuite en soft il nous faudra configurer cette broche en entrée analogique.
Pour cela nous utiliserons la syntaxe ANSELx:
ANalogique-SELection + nom du port
ANSELA = 0b00000010; met la broche RA1 en analogique.
- La valeur retournée sera sur 10 bits ( de 0 à 1023).
et voila le tour est joué !
Informations :
avec la fonction ADC_read il n'y a pas besoin d’initialisé le convertisseur ( contrairement à la fonction ADC_Get_Sample ).
La précision :
Dans notre exemple le PIC est alimenté sous 5V. Avec un convertisseur sur 10bit cela nous donnera 5 / 1024 ~= 0.00488V par pas.
Donc suivant la valeur de la tension arrivant sur notre broche , le PIC nous renverra une valeur allant de 0 à 1023. Pour avoir la tension exact il nous suffira de multiplier ce chiffre par notre coefficient de 0.00488 (4.88mV sera notre précision).
Si une tension de 2.50 V est présente (soit la moitié de notre tension référence), l'ADC nous indiquera comme valeur 512 ( la moitié de 1024).
- La tension à mesurer sur la broche analogique, ne devra JAMAIS dépasser la tension Vcc ! Si votre tension est supérieur à Vcc il vous faudra utiliser un pont diviseur de tension pour ajuster votre tension afin de lui permettre dans le seuil de la tension d'alim du µC !
Précision apporté par Maï : en réalité la tension max sur une broche d'entrée se trouve dans les caractéristiques électriques de votre PIC ( voir tableau sur votre DS). En général il s'agit de (Vcc+0.3V)
L'exemple :
Voici un programme permettant de faire un petit voltmètre.
Nous recevons sur la broche RA1 une tension analogique, nous allons la lire avec le convertisseur puis nous allons l’enregistrer dans une variable, elle sera donc maintenant numérique.
Ensuite nous allons la convertir pour pouvoir afficher une tension approximative tout de même .
Pour des raisons de simplicité j'utilise ici la fonction sprintf pour afficher un nombre décimal (avec virgule).
Code : Tout sélectionner
/*##################################################################################
Programme de test d'un convertisseur analogique/numérique
Fait par Jérémy sur FantasPic.fr
- Version du "13-12-2015"
- MikroC version 6.6.2
- PIC 18F46K22 FOSC a 8MHZ , Quartz 8Mhz PLL disable
- Data-Shit du PIC : http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
#################################################################################*/
// Connections de l'écran LCD
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Fin connections LCD
// Déclaration de nos variables utilisées tout au long du programme ---------------
const float coef = 0.00488; // Déclare une constante en Float
float valeur_lue = 0; // Initialisation d'une variable avec virgule flottante
char buffer[16]; // Déclaration d'un tableau de 16 cases
//##################################################################################
//######################### PROGRAMME PRINCIPAL #########################
//##################################################################################
void main() {
ANSELA = 0b00000010 ; // Configure la broche RA1 en Analogique
ANSELB = 0 ; // Configure le PORTB en digital pour le LCD
TRISA = 0b00000010; // Met RA1 pin en entrée
TRISB = 0; // PORTB en sortie
Lcd_Init(); // Initialisation du LCD
Lcd_Cmd (_LCD_CLEAR); // On efface l'écran
Lcd_Cmd (_LCD_CURSOR_OFF); // On arrête le clignotement du curseur
delay_ms(100); // Petite pause
Lcd_Out (1,1, "Valeur sur RA1 :" ) ; // Affichage d'un texte
//####################### BOUCLE INFINIE ####################################
while (1) { // Boucle infinie
valeur_lue = ADC_Read(1) ; // On enregistre la valeur lue grâce à la fonction (ADC_Read) dans une variable
valeur_lue = valeur_lue * coef; // On convertit la valeur numérique en tension
sprintf(buffer,"%.2f V",valeur_lue) ; // Avec sprintf on convertit notre nombre décimal en string.
Lcd_Out (2,1, buffer ) ; // Affichage sur la deuxième ligne du LCD
delay_ms(100); // pause entre deux lectures
}
}
Bien évidemment ce code n'est pas optimisé, et mérite certainement quelques retouches par un expert ( que je ne suis pas).
On peut par exemple moyenner notre valeur car on voit quelques petits sur-sauts à l'affichage ( du à la grande quantité de mesure et la position du potar entre deux valeurs).
Il y a encore beaucoup de choses à dire, qui se feront certainement à la suite, quand ma propre expérience me le permettra ( et mon emploi du temps ). Comme les sources de tension référence externe ou les ADC en 12bits voir 16bits afin améliorer la précision ...
La vidéo de démonstration
http://www.dailymotion.com/video/x3i25vf
Le schéma :
Sur ce montage qui n'est que la recopie de celui de ma carte EasyPIC_V7, la résistance de 220ohms n'est présente que pour éviter un accident lors des connexions du potar. Son rôle est de limiter le courant arrivant sur le l'entrée analogique du PIC en cas de court-circuit. ( Si le potar est mis en résistance variable en butée à 0 Ohms). Cette résistance est optionnelle .
Astuces :
Précision apporté par Mazertoc:
Les condensateurs permettent de filtrer (passe-bas) :
- s'affranchir des "gratouillis" d'un potar bas de gamme
- diminuer les "parasites"
- diminution apparente de la résistance de sortie du diviseur
Comme d'hab vos commentaires, remarques, ou corrections sont toujours le bienvenu !