Note
Bonjour et bienvenue dans la communauté SunFounder dédiée aux passionnés de Raspberry Pi, Arduino et ESP32 sur Facebook ! Plongez dans l’univers du Raspberry Pi, d’Arduino et d’ESP32 avec d’autres passionnés.
Pourquoi nous rejoindre ?
Support d’experts : Résolvez vos problèmes après-vente et relevez des défis techniques avec l’aide de notre communauté et de notre équipe.
Apprendre & Partager : Échangez des conseils et des tutoriels pour améliorer vos compétences.
Aperçus exclusifs : Accédez en avant-première aux nouvelles annonces de produits et aux avant-premières.
Réductions spéciales : Profitez de remises exclusives sur nos nouveaux produits.
Promotions festives et cadeaux : Participez à des tirages au sort et à des promotions spéciales pour les fêtes.
👉 Prêt(e) à explorer et à créer avec nous ? Cliquez sur [Ici] et rejoignez-nous dès aujourd’hui !
2.1.4 Potentiomètre
Note
Selon la version de votre kit, identifiez si vous disposez du ADC0834 ou du MCP3008 et suivez la section correspondante.
Introduction
La fonction ADC peut être utilisée pour convertir des signaux analogiques en signaux numériques. Dans cette expérience, nous utilisons l’ADC0834 pour réaliser cette conversion. Ici, nous mettons en œuvre ce processus à l’aide d’un potentiomètre. Le potentiomètre modifie la grandeur physique — la tension — qui est convertie par la fonction ADC.
Composants
Principe
ADC0834
L’ADC0834 est un convertisseur analogique-numérique 8 bits de type approximation successive équipé d’un multiplexeur multicanal configurable en entrée et d’une interface d’entrée/sortie série. L’interface série est conçue pour interagir avec des registres à décalage standard ou des microprocesseurs.
Séquence d’opération
Une conversion est lancée en mettant CS à un niveau bas, ce qui active tous les circuits logiques. CS doit être maintenu bas pendant toute la durée du processus de conversion. Une horloge d’entrée est alors envoyée par le processeur. À chaque transition de l’horloge de bas en haut, les données sur DI sont horodatées dans le registre de décalage d’adressage du multiplexeur. Le premier niveau logique haut est le bit de départ. Un mot d’affectation de 3 à 4 bits suit ce bit de départ. À chaque transition de l’horloge de bas en haut, le bit de départ et le mot d’affectation sont décalés dans le registre de décalage. Lorsque le bit de départ atteint la position de démarrage du registre du multiplexeur, le canal d’entrée est sélectionné et la conversion commence. La sortie de statut du SAR (SARS) passe à un niveau haut pour indiquer qu’une conversion est en cours, et DI est désactivé pendant toute la durée de la conversion.
Une période d’horloge est automatiquement insérée pour permettre au canal multiplexé sélectionné de se stabiliser. La sortie de données DO quitte l’état haute impédance et fournit un niveau bas initial pour cette période d’horloge de stabilisation. Le comparateur du SAR compare successivement les sorties de l’échelle résistive avec le signal analogique d’entrée. La sortie du comparateur indique si l’entrée analogique est supérieure ou inférieure à la sortie de l’échelle résistive. Au fur et à mesure que la conversion avance, les données de conversion sont simultanément sorties par la broche de sortie DO, avec le bit de poids fort (MSB) en premier.
Après huit périodes d’horloge, la conversion est terminée et la sortie SARS passe à un niveau bas. Enfin, les données sont émises en ordre du bit de poids faible après la séquence MSB en premier.
Table de contrôle d’adresse du MUX de l’ADC0834
Potentiomètre
Le potentiomètre est un composant résistif à trois bornes dont la valeur de résistance peut être ajustée selon une variation régulière. Il se compose généralement d’une résistance et d’une brosse mobile. Lorsque la brosse se déplace le long de la résistance, une certaine résistance ou tension de sortie est générée en fonction du déplacement.
Les fonctions du potentiomètre dans le circuit sont les suivantes :
Fonction de diviseur de tension.
Le potentiomètre est une résistance réglable en continu. Lorsque vous ajustez l’axe ou la poignée de glissement du potentiomètre, le contact mobile se déplace sur la résistance. À ce moment, une tension peut être émise en fonction de la tension appliquée sur le potentiomètre et de l’angle ou de la distance parcourue par le bras mobile.
Schéma de câblage
Procédures expérimentales
Étape 1 : Montez le circuit.
Note
Veuillez placer la puce en vous référant à la position correspondante indiquée sur l’image. Notez que les encoches de la puce doivent être à gauche lorsqu’elle est positionnée.
Étape 2 : Ouvrez le fichier de code.
cd ~/davinci-kit-for-raspberry-pi/c/2.1.4/
Étape 3 : Compilez le code.
gcc 2.1.4_Potentiometer.c -lwiringPi
Étape 4 : Exécutez le programme.
sudo ./a.out
Après l’exécution du code, tournez le bouton du potentiomètre et l’intensité de la LED changera en conséquence.
Note
Si cela ne fonctionne pas après l’exécution, ou s’il y a un message d’erreur indiquant : "wiringPi.h: No such file or directory", veuillez consulter Le code C ne fonctionne pas ?.
Code
#include <wiringPi.h>
#include <stdio.h>
#include <softPwm.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define ADC_CS 0
#define ADC_CLK 1
#define ADC_DIO 2
#define LedPin 3
uchar get_ADC_Result(uint channel)
{
uchar i;
uchar dat1=0, dat2=0;
int sel = channel > 1 & 1;
int odd = channel & 1;
digitalWrite(ADC_CLK, 1);
delayMicroseconds(2);
digitalWrite(ADC_CLK, 0);
delayMicroseconds(2);
pinMode(ADC_DIO, OUTPUT);
digitalWrite(ADC_CS, 0);
// Bit de démarrage
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Mode Single End
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// ODD (Impair)
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,odd); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Sélection
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,sel); delayMicroseconds(2);
digitalWrite(ADC_CLK,1);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
for(i=0;i<8;i++)
{
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
pinMode(ADC_DIO, INPUT);
dat1=dat1<<1 | digitalRead(ADC_DIO);
}
for(i=0;i<8;i++)
{
dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
}
int main(void)
{
uchar analogVal;
if(wiringPiSetup() == -1){ // lorsque l'initialisation de wiringPi échoue, afficher un message à l'écran
printf("setup wiringPi failed !");
return 1;
}
softPwmCreate(LedPin, 0, 100);
pinMode(ADC_CS, OUTPUT);
pinMode(ADC_CLK, OUTPUT);
while(1){
analogVal = get_ADC_Result(0);
printf("Current analogVal : %d\n", analogVal);
delay(100);
softPwmWrite(LedPin, analogVal);
delay(100);
}
return 0;
}
Explication du Code
#define ADC_CS 0
#define ADC_CLK 1
#define ADC_DIO 2
#define LedPin 3
Définit les broches CS, CLK et DIO de l’ADC0834, connectées respectivement à GPIO0, GPIO1 et GPIO2. Puis, la LED est attachée à GPIO3.
uchar get_ADC_Result(uint channel)
{
uchar i;
uchar dat1=0, dat2=0;
int sel = channel > 1 & 1;
int odd = channel & 1;
digitalWrite(ADC_CLK, 1);
delayMicroseconds(2);
digitalWrite(ADC_CLK, 0);
delayMicroseconds(2);
pinMode(ADC_DIO, OUTPUT);
digitalWrite(ADC_CS, 0);
// Bit de démarrage
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Mode Single End
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// ODD (Impair)
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,odd); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
// Sélection
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,sel); delayMicroseconds(2);
digitalWrite(ADC_CLK,1);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
for(i=0;i<8;i++)
{
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
pinMode(ADC_DIO, INPUT);
dat1=dat1<<1 | digitalRead(ADC_DIO);
}
for(i=0;i<8;i++)
{
dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
}
Cette fonction de l’ADC0834 effectue la conversion analogique-numérique (ADC). Le flux de travail détaillé est le suivant :
digitalWrite(ADC_CS, 0);
Met CS à un niveau bas pour commencer à activer la conversion analogique-numérique.
// Bit de démarrage
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Lors de la première transition du signal d’horloge de bas à haut, DIO est mis à 1 comme bit de démarrage. Au cours des trois étapes suivantes, 3 bits d’affectation sont envoyés.
// Mode Single End
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Lors de la deuxième transition de bas à haut du signal d’horloge, DIO est à nouveau défini à 1, ce qui active le mode Single End.
// ODD
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,odd); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
Lorsque cette opération se produit pour la troisième fois, la valeur de DIO est déterminée par la variable odd.
//Sélection
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,sel); delayMicroseconds(2);
digitalWrite(ADC_CLK,1);
Lors du quatrième changement de niveau du signal d’horloge de bas à haut, la valeur de DIO est déterminée par la variable sel.
Lorsque channel=0, sel=0, odd=0, les formules de calcul pour sel et odd sont les suivantes :
int sel = channel > 1 & 1;
int odd = channel & 1;
Pour la condition channel=1, sel=0, odd=1, référez-vous au tableau de la logique de contrôle d’adresse ci-dessous. Ici, CH1 est sélectionné, et le bit de démarrage est décalé dans la position de départ du registre du multiplexeur, et la conversion commence.
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
Ici, DIO est mis à 1 deux fois, cette opération peut être ignorée.
for(i=0;i<8;i++)
{
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
pinMode(ADC_DIO, INPUT);
dat1=dat1<<1 | digitalRead(ADC_DIO);
}
Dans la première boucle for(), dès que le cinquième changement de niveau du signal CLK de haut à bas se produit, DIO est défini en mode entrée. La conversion commence alors, et la valeur convertie est stockée dans la variable dat1. Après huit cycles d’horloge, la conversion est terminée.
for(i=0;i<8;i++)
{
dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
Dans la deuxième boucle for(), les valeurs converties sont envoyées via DO après huit autres cycles d’horloge et stockées dans la variable dat2.
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
return(dat1==dat2) ? dat1 : 0 est utilisé pour comparer la valeur obtenue pendant la conversion avec la valeur de sortie. Si elles sont égales, la valeur convertie dat1 est retournée, sinon la valeur retournée est 0. Ici, le flux de travail de l’ADC0834 est terminé.
softPwmCreate(LedPin, 0, 100);
Cette fonction permet de créer par logiciel une broche PWM, LedPin. La largeur d’impulsion initiale est fixée à 0, et la période du signal PWM est définie à 100 x 100 us.
while(1){
analogVal = get_ADC_Result(0);
printf("Current analogVal : %d\n", analogVal);
softPwmWrite(LedPin, analogVal);
delay(100);
}
Dans le programme principal, la valeur du canal 0, qui est connecté à un potentiomètre, est lue et stockée dans la variable analogVal, puis elle est écrite dans LedPin. Vous pouvez ainsi observer la variation de la luminosité de la LED en fonction de la valeur du potentiomètre.