Débuter avec Arduino

Partie 3 : variables et signaux

Tutoriels, exercices, documentations et références


SECONDAIRE | DIFFICULTÉ MOYENNE | 6 À 8 HEURES


Si vous êtes rendus à la partie 3 c'est que vous maîtrisez les points suivant :
  1. Vous avez réussi les 2 défis précédents : K2000 et "l'aveugle".
  2. Vous avez compris qu'un programme est divisé en 2 parties : "Void Setup" et "Void Loop".
  3. Vous avez compris l'utilité de chacun des "Void" : initialisation ("Setup") et programme ("Loop").
  4. Vous avez compris ce qu'est une fonction et un argument
  5. Vous maîtrisez les fonctions pinMode(), digitalWrite() et delay().

Dans cette partie, vous allez apprendre à lire des signaux numériques et découvrir le monde incontournable des "variables".
Au travail !


Lire un signal numérique.


Voici un circuit et un programme simple permettant d'allumer une DEL grâce à un interrupteur. Essayez la simulation et observez le circuit et le programme.


Le circuit.

Le circuit consite en une DEL, branchée sur la prise 3, et un interrupteur, branché sur la prise 2.
Constatez qu'avec Arduino, chaque composant est branché indépendamment. Un circuit électronique programmable est différent d'un circuit électrique tel que vous les voyez en classe. Il faut penser différemment !

Voici un circuit électrique en série.
schéma
Notez que la pile, la DEL et l'interrupteur sont tous branchés les uns après les autres: c'est un circuit en série. Ce circuit n'est pas programmable. La DEL ne peut prendre que 2 valeurs : allumée ou éteinte (ON ou OFF : l'interrupteur bloque ou laisse passer le courant).
Voici un circuit électronique.
schéma
Notez que chaque composant est branché indépendamment sur Arduino : l'un sur la prise 2, l'autre sur la prise 3. Dans ce cas le circuit est programmable et nous pouvons faire ce que nous voulons avec la DEL : la faire clignoter, faire varier son intensité, etc.
L'avantage d'un circuit programmable (avec Arduino) est que l'interrupteur peut jouer un autre rôle que ON/OFF (contrairement au circuit électrique en série) : il pourra déclencher une action de la DEL au choix du programmeur (exemple : dans une position la DEL est allumée, dans une autre position la DEL clignote).
Revenons aux branchements :
  • Pour la DEL : pas de surprise, vous savez déjà la brancher.
  • Pour l'interrupteur : le branchement est différent du circuit électrique en série. Les pattes extérieures sont branchées sur +5Volts et GND (le sens importe peu) et la patte centrale est branchée sur la prise 2 d'Arduino : c'est le signal.
    Ce signal ne peut prendre que 2 valeurs : HIGH ou LOW (signal numérique - voir partie 1).

Observons le fonctionnement de l'interrupteur de plus près.
Sur l'image de gauche (A), l'interrupteur fait le pont entre le fil rouge (+5Volts) et le fil jaune (signal lu par la prise 2 d'Arduino). C'est donc une tension de 5 Volts qui traversera l'interrupteur, passera dans le fil jaune et aboutira dans Arduino. Arduino lira dans ce cas un signal +5Volts : signal HIGH.
Sur l'image de gauche (B), l'interrupteur fait le pont entre le fil noir (GND, 0Volt) et le fil jaune. C'est donc une tension nulle (0Volt) qui traversera l'interrupteur et aboutira dans la prise 2 d'Arduino. Arduino lira dans ce cas un signal 0Volt : signal LOW.

L'interrupteur permet de générer 2 signaux : HIGH ou LOW, en laissant passer ou pas le courant. C'est un signal numérique : il ne prend que 2 valeurs, 0 ou 5 Volts.
Maintenant, voyons comment programmer Arduino afin qu'il soit capable de lire ce signal, qui nous permettra de déclencher plein d'actions différentes !

Le programme.


Tout d'abord la partie "Setup".

  void setup()
  {
    pinMode(3, OUTPUT);
    pinMode(2, INPUT);
  }
  

Rien de très compliqué : il faut indiquer à Arduino où sont branchés les composants et si ce sont des entrées ou des sorties.
On y indique :
  • Que la prise 3 doit se comporter comme une "sortie" (pinMode (3, OUTPUT);) : c'est là que nous branchons la DEL.
  • Que la prise 2 doit se comporter comme une "entrée" (pinMode (2, INPUT);) : c'est là que nous branchons l'interrupteur.
C'est tout : 2 composants, 2 lignes !

Maintenant la partie "Loop".

  void loop()
  {
    int var = digitalRead(2);
    digitalWrite (3, var);
  }
  

Il y a ici une petite nouveauté pour vous : int var = digitalRead (2);.
Décomposons ensemble cette ligne afin de mieux la comprendre.
  • digitalRead(2) : en toute logique cette commande indique à Arduino de lire le signal au niveau de la prise 2 (par analogie avec "digitalWrite"). Le signal est-il HIGH ? Est-il LOW ? Grâce à cette commande Arduino le saura.
  • Arduino peut lire un signal numérique avec la commande digitalRead() sur les prises 0 à 13.
  • int var = : voici la grande nouveauté ! Nous sommes ici en train de déclarer une variable. Une sorte de petite valise dans laquelle nous demandons à Arduino de stocker quelque chose. Concrètement le programme dit au microcontrôleur de réserver un petit espace en mémoire pour y stocker des données.
    Pour simplifier la chose, on donne un nom à cet espace mémoire (ou petite valise). Ici, je l'ai appelé "var", comme "variable". J'aurai pu la nommer comme je le veux.
    Arduino va donc lire l'état de la prise 2 et mettre cette lecture en mémoire (dans une petite valise) qui s'appelle "var".
Je vous laisse comprendre la suite, la ligne digitalWrite (3, var);.
La variable "var" ne pouvant prendre que 2 valeurs (rappelez-vous, HIGH ou LOW, provenant de la lecture de l'interrupteur), cette ligne prendra 2 valeurs en fonction de la position de l'interrupteur :
  • digitalWrite (3, HIGH); si var = HIGH (défini grâce à la ligne int var = digitalRead(2);, lorsque la position de l'interrupteur fait le pont entre 5Volts et Signal).
  • digitalWrite (3, LOW); si var = LOW (défini grâce à la ligne int var = digitalRead(2);, lorsque la position de l'interrupteur fait le pont entre 0Volt et Signal).
En résumé, la ligne int var = digitalRead(2); permet de stocker la valeur "digitalRead(2)" (HIGH ou LOW) dans un espace mémoire (une petite valise) nommée "var". À n'importe quel moment du programme, on peut aller voir dans la valise "var" sa valeur et l'utiliser pour faire ce que l'on veut. Ici, pour allumer ou éteindre une DEL, on va regarder dans la valise "var" si var = HIGH ou var = LOW.
On aurait pu s'abstenir d'utiliser une variable, dans ce cas nous aurions dû écrire digitalWrite (3, digitalRead(2));. Essayez pour voir si ça fonctionne ! Ceci dit cela rend la lecture du code plus complexe et en programmation, plus c'est simple, plus c'est mieux !

Bravo, vous avez compris à quoi sert une variable !
Mais pourquoi est-ce que j'ai écrit int var et pas seuleument var ? Bonne question ! Il existe plusieurs types de variables et "int" est-un type de variable parmi d'autre.
Voyons cela en détails !

Les variables.


Qu'est-ce qu'une variable ?

Commençons par l'éternelle définition Wikipedia !
En informatique, les variables sont des symboles qui associent un nom à une valeur. Le nom est unique. Dans la plupart des langages, les variables peuvent changer de valeur au cours du temps. Dans un langage de programmation, une variable est un espace de stockage pour un résultat.
Une variable, c'est une donnée qui est stockée dans la mémoire du microcontrôleur
On l'appelle "variable" car sa valeur peut changer durant le déroulement d'un programme.
Par exemple, si vous programmiez un jeu video, nous aurions une variable "vie" qui correspond au nombre de vies du joueur. À chaque fois que le joueur perd, la variable "vie" diminue de 1 jusqu'à arriver à 0. Si nous devions écrire le programme, chaque fois que le joueur perd il faudrait éxecuter une ligne semblable à vie = vie-1;.
Dans notre exemple ci-dessus, "var" peut prendre plusieurs valeurs : HIGH ou LOW, en fonction de la position de l'interrupteur. C'est donc en effet une "variable".
Cependant, la mémoire informatique n'est pas une ressource illimitée et tout programmeur tente de l'économiser au maximum afin d'avoir les meilleures performances de la machine.
Il y a des variables très grandes à stocker (exemple : le nombre π qui est infini, mais c'est un exemple car aucune machine n'a une mémoire infinie) et des variables très petites (exemple : l'état HIGH ou LOW d'un interrupteur, soit 0 ou 1).
C'est ce qu'on appelle des types de variable, qu'il faut indiquer au programme afin qu'il réserve la bonne quantité de mémoire dans la machine.

Les types de variables et leur déclaration.


Les types de variables.

Il existe en effet tout un tas de type de variable. Chaque fois que l'on créé une variable dans un programme Arduino (en langage C), il faut spécifier son type.
Le type de variable est entre autre déterminé par les caractéristiques mathématiques d'un nombre :
  • Nombre entier (en anglais, integer).
  • Nombre à virgule (en anglais, float).
  • Constantes (en anglais, constant).
Chaque type de variable occupera un espace mémoire différent dans le microcontrôleur. Par exemple, une variable de type "integer" (nombre entier) occupera deux octets (2 bytes) de mémoire, alors qu'une variable de type "float" (nombre à virgule) occupera 4 octets (4 bytes) de mémoire).

Voici les prinicipales variables que nous utiliserons.


Nom de la variable (à titre d'exemple)
schéma schéma schéma schéma
Valeur(s) prise(s) par la variable HIGH ou LOW
TRUE ou FALSE
1 ou 0
Nombre entier Nombre à virgule Chaîne de caractères
Type de variable boolean
(état logique)
integer float character
Exemple de déclaration bool etatLed = 0; int temps = 0; float pi = 3.141569; char pierre = IloveArduino;

Il existe encore bien d'autre types de variables. Si vous désirez aller plus loin que ce tutoriel avec Arduino, vous devriez les connaître. Consultez la documentation officielle d'Arduino. Ce document est la bible, vous y trouverez toutes les fonctions, les variables et les structures de programme !

La déclaration des variables.

Une variable doit être déclarée. C'est à dire que l'on doit indiquer au programme son nom, son type et sa valeur initiale.
Le nom d'une variable ne doit pas comporter d'espaces ni de caractères spéciaux (dont les accents).
Une variable peut être déclarée soit dans la partie "loop", soit en amont du programme, avant la partie "setup".

Voici 3 exemples de programmes (le programme de la simulation précédente) dans lesquels les variables sont déclarées différemment. Tous ces programmes fonctionnent.
Vous pouvez les copier-coller dans Tinkercad Circuits pour les essayer.
Voyez-vous les différences ?

  int var = 0;
  
  void setup(){
    pinMode (2, INPUT);
    pinMode (3, OUTPUT);
  }
  void loop(){
    var = digitalRead(2);
    digitalWrite (3, var);
  }
  
  void setup(){
    pinMode (2, INPUT);
    pinMode (3, OUTPUT);
  }
  void loop(){
    int var = 0;
    var = digitalRead(2);
    digitalWrite (3, var);
  }
  
  void setup(){
    pinMode (2, INPUT);
    pinMode (3, OUTPUT);
  }
  void loop(){
    int var = digitalRead(2);
    digitalWrite (3, var);
  }
  

Exercices.


Voici un quiz afin de tester vos connaissances et votre compréhension du concept de variables.
Faites-le autant de fois que nécessaire pour bien comprendre. La notion de variable sera primordiale pour la suite.



Avez-vous obtenu un bon score ? Les variables n'ont plus de secrets pour vous ? Formidable !
Je vous propose alors maintenant la simulation suivante. Il y a 4 erreurs (liées à des variables bien sur !). À vous de les corriger pour que le programme fonctionne !


Vous pouvez remarquer que j'ai utilisé des variables pour nommer les prises sur lesquelles les composants sont branchés :
  • int del = 3;
  • int interrupteur = 2;
Ce qui signifie que dans toute la suite du programme on peut remplacer les nombres 2 et 3 par "interrupteur" et "del". Donc, au lieu d'écrire digitalRead (2);, nous écrirons digitalRead (interrupteur);, étant donnée que nous avons spécifié au programme que le nombre entier "2" s'appelera désormais "interrupteur".
Pourquoi déclarer les numéros de pin commes des variables ? Imaginez que votre programme est long et que vous y citez souvent les numéros de pin (beaucoup de "digitalWrite" ou de "digitalRead" par exemple). Puis à un moment donné vous réalisez que vous devez rebrancher vos composants électroniques : il va falloir changer les numéros de prise dans tout le programme, ça peut être long. Cependant, si les prises sont déclarées en variables au début du programme, vous n'aurez à modifier qu'une seule ligne !
De plus, si le nom des variables est bien explicite, vous saurez dès les premières lignes sur quelles prises sont branchés les composants. Si votre programme commence par int del = 2;, je sais dès le début qu'il y une DEL branchée sur la prise 2.


Résumé de la partie 3.


Voici ce que vous devez retenir de ce chapitre :
  • La fonction digitalRead() permet de lire un signal numérique.
  • Arduino peut lire un signal numérique sur les prises 0 à 13.
  • La fonction digitalRead() prend un argument entre ses parenthèses : le nom ou le numéro de la prise à lire.
  • Un circuit électronique programmable est différent d'un circuit électrique : les notions de circuits en parallèle ou en série ne sont pas utiles en programmation, chaque composant étant contrôlé indépendament par Arduino.
  • Une variable permet de stocker une donnée dans la mémoire d'Arduino afin de la réutiliser plus tard.
  • Une variable doit être déclarée en début du programme ou dans la partie "void loop".
  • Il existe plusieurs type de variable en fonction du type de donnée à stocker : des nombres entiers ("int" - integer), des nombres à virgules ("float"), des caractères ("char" - character), des états logiques (tels que TRUE, FALSE, HIGH, LOW, 1, 0 grâce à "bool" - boolean) et des constantes ("const" - constant).
  • La valeur d'une variable peut changer au cours du programme.

Le tableau suivant résume les fonctions apprises durant ce chapitre :

Syntaxe Emplacement Utilisation Argument(s)
digitalRead (a) setup() Lecture d'un signal numérique a = nom ou # de la prise numérique (0 à 13) lue


Commentaires ?