Maintenant que nous sommes capables d'utiliser les différentes sorties de l'Arduino et de contrôler, par exemple, l'allumage de LEDs, intéressons-nous aux entrées.
Il y a deux types d'entrées sur un Arduino: le type analogique et le type numérique. Nous nous consacrerons pour l'instant à la description du type numérique puisqu'il est plus simple à comprendre et suffisant pour nos applications. En quelques mots, une entrée analogique peut "lire" des valeurs de tension comprises entre 0 et 5V. Nous pourrions ainsi détecter la position d'un potentiomètre... Une entrée numérique, quant à elle, ne détecte que deux états: 0 ou 5V, soit
Identifions les ports d'entrées numériques sur l'Arduino... Et bien il s'agit des mêmes ports que les sorties numériques que nous avons utilisés dans les exemples précédents! En effet, chaque port physique peut être utilisé comme une entrée ou une sortie. C'est au moment de l'écriture du programme que nous définissons l'usage d'un port E/S.
Nous avons vu dans les exemples précédents la définition d'un port en mode sortie en utilisant l'instruction
Remarque: par défaut, un port numérique est défini comme une entrée. Il ne devrait donc pas être nécessaire d'utiliser l'instruction précédente. Cependant, pour des questions d'apprentissage et afin d'acquérir une bonne pratique de programmation, il est préférable de définir en tout temps la fonction des ports utilisés dans un programme (dans la fonction
Commençons par le petit montage suivant, constitué de deux LEDs et de leur résistance de protection, ainsi que d'un bouton poussoir. La LED rouge est connectée au port de sortie 4 et la LED verte au port de sortie 5, comme nous l'avons vu dans les premiers chapitres. Maintenant, nous ajoutons un bouton poussoir, dont une patte est connectée au port d'entrée 8 et une patte au port +5V. Ainsi, lorsque le bouton est pressé, le port 8 est en contact avec le +5V: il est à l'état
Lors de l'utilisation d'un port numérique en mode sortie, nous avons vu comment envoyer un signal
De la même façon, nous pouvons lire un état sur un port d'entrée en utilisant simplement l'instruction
int ledRouge = 4;
int ledVerte = 5;
void setup()
{
pinMode( entree, INPUT );
pinMode( ledRouge, OUTPUT );
pinMode( ledVerte, OUTPUT );
}
void loop()
{
if ( digitalRead( entree ) == HIGH )
{
digitalWrite( ledVerte, HIGH );
digitalWrite( ledRouge, LOW );
}
else
{
digitalWrite( ledVerte, LOW );
digitalWrite( ledRouge, HIGH );
}
}
Le fonctionnement "attendu" de ce programme est:
- si le bouton est pressé, alors la led verte s'allume
- sinon (le bouton est relâché) la led rouge s'allume.
Comme il n'est pas facile de détecter exactement l'état
La signification de cette résistance est simple: lorsque ce mode est activé, une résistance (interne) est automatiquement montée en série sur le port d'entrée et connectée au 5V. Ainsi, en tout temps, l'état de l'entrée par défaut est
Il suffit alors de comparer l'état à
Le montage doit être légèrement modifié, en reliant le bouton poussoir au ground (0V) plutôt qu'au +5V:
Le code source est aussi modifié, en remplaçant le test par une comparaison à
{
if ( digitalRead( entree ) == LOW )
Cependant, il ne faut pas oublier d'activer la résistance interne. Pour cela, il suffit d'envoyer une commande au port d'entrée au moment de son initialisation:
{
pinMode( entree, INPUT );
digitalWrite( entree, HIGH );
Le reste du programme est inchangé. Maintenant, le fonctionnement de notre montage a gagné en stabilité: le changement d'état est correctement détecté!
Mais nous n'en avons pas tout à fait fini avec ce montage. Il peut arriver que l'utilisation d'un bouton poussoir puisse aussi mener à une autre source d'instabilité, mais cette fois d'ordre mécanique. En effet, un tel bouton est simplement fait de deux lamelles qui se touchent. En relâchant légèrement la pression sur le bouton, celui-ci peut "ouvrir" le circuit momentanément et créer un état HIGH (puisque l'entrée n'est plus connectée au 0V). Nous allons voir comment corriger logiciellement cette imperfection.
Certes, cet exemple semble consacré uniquement à l'utilisation d'un bouton poussoir... Mais la méthode que je vais introduire maintenant est très utile dans d'autres situations, et doit devenir une bonne pratique de programmation pour les prochains projets que le lecteur voudra réaliser...
Reprenons l'exemple précédent:
int ledRouge = 4;
int ledVerte = 5;
void setup()
{
pinMode( entree, INPUT );
digitalWrite( entree, HIGH );
pinMode( ledRouge, OUTPUT );
pinMode( ledVerte, OUTPUT );
}
void loop()
{
if ( digitalRead( entree ) == LOW )
{
digitalWrite( ledVerte, HIGH );
digitalWrite( ledRouge, LOW );
}
else
{
digitalWrite( ledVerte, LOW );
digitalWrite( ledRouge, HIGH );
}
}
Nous avons vu dans les premiers chapitres que la fonction
Par exemple, si le bouton poussoir est utilisé pour changer la position d'un signal, il peut arriver que celui-ci change plusieurs fois d'état alors que la pression sur le bouton n'est pas constante... Dans le cas d'une commande de signal, cela peut devenir problématique pour la gestion du réseau...
Introduisons la notion de "debounce" ou amortissement. L'idée est bien simple: il suffit d'informer le programme que le bouton est relâché uniquement lorsque celui-ci l'est effectivement! Vous allez me dire que c'est un peu idiot de formuler cela ainsi, mais vous allez le comprendre dans l'exemple qui suit...
Normalement, nous détectons un changement d'état ainsi:
{
}
Nous allons introduire un amortissement pour être sûr que le bouton est bien relâché avant d'exécuter l'action voulu: il suffit d'attendre un peu plus longtemps... ce que nous écrivons ainsi:
{
delay( 100 );
while ( digitalRead( entree ) == LOW )
{
delay( 100 );
}
}
Si nous interprétons les lignes de code précédentes nous obtenons:
- si l'état de l'entrée est
LOW , alors attend 100ms - ensuite, tant que l'état est
LOW , attend encore 100ms (autant de fois que nécessaire) jusqu'à ce que l'état ne soit plusLOW - puis exécute l'action
Je vous encourage à utiliser cette technique ou une équivalente dans vos programmes dès que vous voudrez interagir avec l'Arduino à l'aide de boutons poussoirs...
On m'a récemment fait remarquer qu'il était possible de réaliser un debounce à l'aide de composants supplémentaires. En effet, c'est une pratique courante, mais je ne voulais pas nécessairement ajouter de notion supplémentaire en électronique, car cela s'éloigne un peu de mon objectif premier: utiliser l'Arduino le plus simplement possible.
Ceci-dit, il ne s'agit pas d'un montage bien compliqué, puisqu'il se résume à deux composants: une capacité montée en parallèle avec le bouton poussoir et une résistance en série. Dans la situation présente, la résistance est déjà "incluse" alors que nous utilisons la résistance de "pull-up" interne connectée au port d'entrée. Il ne reste donc que la capacité à ajouter, comme le montre le montage suivant:
Compte-tenu de la valeur de la résistance de "pull-up" interne qui est de l'ordre de 10k, une capacité de 100nF = 0.1uF fera l'affaire. Bien faire attention au sens de montage de la capacité puisque celle-ci est polarisée.
Nous avons vu précédemment qu'un port numérique, peut avoir deux états:
int valeur;
void setup()
{
pinMode( entree, INPUT );
}
void loop()
{
valeur = analogRead( entree );
}
Remarque: on identifiera les ports analogiques par le préfixe
Le montage suivant permet de concrétiser l'utilisation d'un port analogique. A l'aide d'un potentiomètre, on fait varier la tension en entrée sur le port
- une led de contrôle est branchée sur une sortie PWM (3) avec sa résistance de protection
- la sortie d'un potentiomètre de 10k est branchée sur l'entrée analogique A0
Note concernant les potentiomètres: Un potentiomètre est muni de 3 broches. La broche centrale est la sortie alors que les broches de chaque côté sont les références à partir desquelles la valeur de sortie est calculée. Ici, la broche gauche est branchée sur +5V (max) alors que la droite est connectée au 0V (min). Dans le cas présent, retenez seulement:
- lorsqu'on tourne la vis du potentiomètre, la valeur de sortie varie entre min et max
- si on inverse les connexions des broches de référence, alors la valeur de sortie du potentiomètre variera dans l'autre sens...
- il existe plusieurs valeurs de résistance et types de potentiomètre. Nous employons ici une résistance de 10k et le type de variation est linéaire sur un tour.
Le code correspondant à ce montage est très simple:
int led = 3;
void setup()
{
pinMode( entree, INPUT );
pinMode( led, OUTPUT );
}
void loop()
{
analogWrite( led, analogRead( entree ) / 4 );
}
Le seul commentaire que je ferai concerne la division par 4 de la valeur lue sur le port
Voilà pour une introduction très simplifiée des ports analogiques utilisés comme entrée. Nous aurons l'occasion d'y revenir au travers d'autres exemples plus "utiles"...
J'ajoute une petite note concernant ces valeurs... Je m'éloigne un peu de la volonté de garder ce dossier simple. Ce sont des détails intéressant à connaitre mais qui ne doivent pas vous empêcher de comprendre le fonctionnement d'un Arduino si vous ne les maîtrisez pas... Il suffit de prendre pour acquis qu'un port numérique gère des valeurs de 0 à 255 et un port analogique des valeurs 0 à 1023.
D'où proviennent ces valeurs? En informatique ou en électronique numérique, une information est stockée sous forme de bit ou, plus communément, 0 ou 1, soit 2 valeurs possibles. Les entrées/sorties numériques sont définis en 8 bit. Cela signifie que l'intervalle de valeurs est compris entre 0 et (2^8)-1=255. Ce sont toutes les valeurs qu'il est possible de décrire avec 8 bits... De plus, il s'agit d'entrées/sorties "tout ou rien", "haut ou bas", "
Dans le cas d'un port analogique, un convertisseur Analogique/Numérique est inséré entre le port et le processeur. Cela permet de transformer un signal électrique analogique en une information gérable par le processeur. C'est pour cela que l'on parle souvent "d'échantillonnage" du signal. Afin d'avoir une bonne précision de lecture, ce convertisseur est défini sur un espace de 10 bits. Ainsi, l'intervalle d'échantillonnage comprend les valeurs de 0 à (2^10)-1=1023.
Pourquoi est-ce plus précis? Il suffit simplement de visualiser un signal électrique comme un intervalle de 0 à 5V. Si on utilise 8 bits pour définir les valeurs d'échantillonnage du signal, alors un intervalle élémentaire a une précision de 5V / 256 = 0.02V = 20mV. Dans le cas d'un échantillonnage sur 10 bit, on a 5V / 1024 = 0.005V = 5mV, soit 4 fois plus précis...
Voilà, ce que je pouvais dire avec mes mots... Je ne m'étendrai pas plus sur le sujet. Si vous êtes intéressés à en savoir plus, je vous conseille de consulter les ressources à votre disposition sur internet.
Super
RépondreEffacerJe débute avec arduino
Merci pour le partage de votre savoir.