Sylvain Mahé Le site Web Retour à l'accueil Principes Partager mes idées et mes projets librement et gratuitement. Thématiques Mécatronique du système embarqué, artisanat pluridisciplinaire, bricolage commun, esthétique logicielle et matérielle, minimalisme fonctionnel, conceptualisation alternative, rédaction technique et littéraire, partage pédagogique documenté. Contact ✆ Téléphone : 06.45.49.96.98
✉ E-mail : contact@sylvainmahe.site
✎ Site Web : sylvainmahe.site
Écriture de la page : Sylvain Mahé
Lire un potentiomètre avec la classe AnalogRead La classe AnalogRead permet de lire la tension analogique (0V à +5V) des GPIO connectées à l'ADC (pour "Analog to Digital Converter" ou convertisseur analogique/numérique) du microcontrôleur. Cette tension analogique de 0V à +5V est convertie en binaire par l'ADC avec une résolution sur 10 bits (de 0 à 1023 en base 10). Exemple d'utilisation de la classe AnalogRead : #include <AnalogRead.h> int main() { AnalogRead myPotentiometer = AnalogRead (25); while (true) { myPotentiometer.read(); //myPotentiometer.value est la valeur lue : if (myPotentiometer.value > 511.5) { //effectuer une action si la tension lue est supérieure à +2.5V } } return 0; } Dans cet exemple, un objet myPotentiometer de type AnalogRead est déclaré, en paramètre est indiqué d'utiliser le port GPIO numéro 25 de l'automate programmable en entrée, puis cet objet myPotentiometer appelle la fonction read ce qui permet de lire l'entrée analogique concernée, et donc de mettre à jour la variable value attachée à cet objet. Puis aux lignes suivantes, si cette variable est supérieure à 511.5 (+2.5V), le déroulement du programme rentre dans la condition logique. Ports des automates programmables concernés par l'ADC : Automate programmable MODULABLE 20 :
- Port GPIO 15 (PC0) = ADC0 (analog to digital converter 0)
- Port GPIO 16 (PC1) = ADC1 (analog to digital converter 1)
- Port GPIO 17 (PC2) = ADC2 (analog to digital converter 2)
- Port GPIO 18 (PC3) = ADC3 (analog to digital converter 3)
- Port GPIO 19 (PC4) = ADC4 (analog to digital converter 4)
- Port GPIO 20 (PC5) = ADC5 (analog to digital converter 5)

Automate programmable MODULABLE 32 :
- Port GPIO 25 (PA7) = ADC7 (analog to digital converter 7)
- Port GPIO 26 (PA6) = ADC6 (analog to digital converter 6)
- Port GPIO 27 (PA5) = ADC5 (analog to digital converter 5)
- Port GPIO 28 (PA4) = ADC4 (analog to digital converter 4)
- Port GPIO 29 (PA3) = ADC3 (analog to digital converter 3)
- Port GPIO 30 (PA2) = ADC2 (analog to digital converter 2)
- Port GPIO 31 (PA1) = ADC1 (analog to digital converter 1)
- Port GPIO 32 (PA0) = ADC0 (analog to digital converter 0)
Note importante concernant l'impédance de votre montage : Le circuit de conversion analogique/numérique du microcontrôleur est optimisé pour fonctionner avec une impédance en entrée de 10kΩ, et peut fonctionner correctement de 1kΩ à 100kΩ. Avec MODULE, le multiplexeur du microcontrôleur fonctionne à une fréquence de 500kHz car le pré-diviseur d'horloge est réglé sur 32 et la fréquence du microcontrôleur est de 16MHz, la période est donc de 2µs, sachant que la capacité de la ligne vers le convertisseur analogique/numérique est de 14pF, le temps pour la charger à (soit 99%) avec une impédance d'entrée de 10kΩ (valeur conseillée) est donc de :
10kΩ * 14pF * 5τ = 700ns

Ceci est largement inférieur à 2µs (la période du multiplexage), ce qui signifie qu'avec une impédance d'entrée de 10kΩ, la capacité de la ligne aura le temps de se charger au-delà de 99% sans problème.

Un autre calcul permet de connaître l'impédance maximale admissible dans cette configuration :
2µs / (14pF * 5τ) ≈ 28.571kΩ

Avec MODULE il est fortement déconseillé de dépasser une impédance d'entrée de ≈ 28.571kΩ, car dans ce cas la capacité de la ligne égale à 14pF n'aurait pas le temps de se charger au moins à 99% dans la période de 2µs.
Détection d'un niveau de batterie faible : Avec une entrée analogique disponible et un montage en pont diviseur de tension, il vous est possible aisément de détecter si votre batterie d'alimentation est déchargée. Imaginons le cas suivant, vous disposez comme alimentation électrique d'une batterie avec une tension maximale de +12V. Une précaution d'usage s'impose alors : Ne mettez jamais sur un port GPIO de l'automate programmable une tension supérieure à +5V, vous risqueriez d'endommager irrémédiablement le microcontrôleur ! Le but est donc de diviser cette tension pour qu'elle ne soit jamais supérieure à +5V accumulateur complètement chargé + tolérances de sécurité. Pour faire un pont diviseur de tension, vous devez connecter une résistance sur le pôle positif de la batterie (cathode), une autre sur le pôle négatif de la batterie (masse/anode), et relier les autres extrémités encore non connectées des deux résistances entres elles, puis relier le tout sur une broche connectée au convertisseur analogique/numérique du microcontrôleur qui va servir à mesurer et convertir cette tension. Calcul du pont diviseur de tension : Constantes :
Tension maximale de la batterie = 12V
Tension niveau de batterie faible = 6V
Tension d'alimentation du microcontrôleur = 5V
Résistance connectée à la cathode de la batterie = 10kΩ ± 1%
Résistance connectée à l'anode de la batterie = 2kΩ ± 1%
Calcul des tolérances minimales et maximales de la résistance connectée à la cathode de la batterie :
Résistance minimale = 10kΩ - ((10kΩ / 100) * 1%) = 9.9kΩ
Résistance maximale = 10kΩ + ((10kΩ / 100) * 1%) = 10.1kΩ

Calcul des tolérances minimales et maximales de la résistance connectée à l'anode de la batterie :
Résistance minimale = 2kΩ - ((2kΩ / 100) * 1%) = 1.98kΩ
Résistance maximale = 2kΩ + ((2kΩ / 100) * 1%) = 2.02kΩ
Valeurs maximales en sortie du pont diviseur de tension (lorsque la batterie d'alimentation est pleinement chargée) :
Tension maximale = (2.02kΩ / (9.9kΩ + 2.02kΩ)) * 12V ≈ 2.033V
Intensité maximale = 12V / (9.9kΩ + 1.98kΩ) ≈ 1.01mA

Valeurs minimales en sortie du pont diviseur de tension (lorsque le niveau de batterie faible est atteint) :
Tension minimale = (1.98kΩ / (10.1kΩ + 1.98kΩ)) * 6V ≈ 0.983V
Intensité minimale = 6V / (10.1kΩ + 2.02kΩ) ≈ 0.495mA

Valeur à indiquer en programmation pour le niveau de batterie faible :
Tension nominale = (2kΩ / (10kΩ + 2kΩ)) * 6V = 1V
Pour ADC 10 bits = 1024 / (5V / ((2kΩ / (10kΩ + 2kΩ)) * 6V)) ≈ 204
Avec ce montage, la tension entre la masse et l'entrée analogique du microcontrôleur n'excédera pas ≈ +2.033V, et l'intensité ne pourra être supérieure à ≈ 1.01mA lorsque la batterie d'alimentation sera pleinement chargée à +12V. Dans un autre cas, lorsque le niveau de batterie faible de +6V sera atteint, la tension entre la masse et l'entrée analogique du microcontrôleur sera au minimum de ≈ +0.983V, et l'intensité ne pourra être inférieure à ≈ 0.495mA, ce qui garantit une tension et une intensité suffisante en entrée du convertisseur analogique/numérique au moment ou la batterie sera considérée comme déchargée. Dans le code source de votre projet, le seuil de niveau de batterie faible à indiquer en programmation sera de 204 en base 10 pour ADC 10 bits, ce qui donne le programme suivant : #include <AnalogRead.h> int main() { AnalogRead myVoltage = AnalogRead (25); while (true) { myVoltage.read(); //si la tension de la batterie est inférieure à +6V : if (myVoltage.value < 204) { //niveau de batterie faible } } return 0; } Ensuite, si la tension de votre source d'alimentation fluctue de façon importante, il vous est possible de lisser la valeur à l'aide de la classe Filter, comme le montre l'exemple suivant : #include <AnalogRead.h> #include <Filter.h> int main() { AnalogRead myVoltage = AnalogRead (25); Filter myFilter = Filter (1000, false); while (true) { myVoltage.read(); myFilter.set (myVoltage.value); //si la tension filtrée de la batterie est inférieure à +6V : if (myFilter.value < 204) { //niveau de batterie faible } } return 0; } Dans ce présent cas, le filtre va effectuer une moyenne sur l'équivalent de 1000 échantillons, la tension récupérée sera alors débarrassée des fluctuations dues aux variations de la puissance consommée et au bruit électrique. Maintenant, au lieu d'indiquer la valeur de 204 dans la condition logique, ce qui n'est pas très parlant dans le programme, il est possible d'indiquer directement le seuil de +6V à ne pas dépasser en effectuant simplement un changement d'échelle de la valeur de 0 à 1023 retournée par le convertisseur analogique/numérique. Ceci mobilise la fonction curve de la classe Math. Afin de renseigner les paramètres de la fonction curve, il nous faut calculer la tension maximale d'alimentation avec toujours la même configuration en pont diviseur de tension (voir les constantes énoncées plus haut), soit le calcul suivant :
5V / (2kΩ / (10kΩ + 2kΩ)) = 30V
En indiquant +30V dans la fonction curve, nous pouvons à présent renseigner +6V dans la condition logique : #include <AnalogRead.h> #include <Filter.h> #include <Math.h> int main() { AnalogRead myVoltage = AnalogRead (25); Filter myFilter = Filter (1000, false); while (true) { myVoltage.read(); myFilter.set (Math::curve (0, myVoltage.value, 1023, 0, 30, 0)); //si la tension filtrée de la batterie est inférieure à +6V : if (myFilter.value < 6) { //niveau de batterie faible } } return 0; } Dans l'exemple ci-dessus, il est plus aisé de pouvoir fixer un seuil de tension en Volt sans avoir la contrainte de devoir tout recalculer manuellement à chaque fois. Références : Récapitulatif des fonctions et variables de cette classe : unsigned int value = 0; AnalogRead (const unsigned char PIN_ANALOG); void read();