0% ont trouvé ce document utile (0 vote)
95 vues163 pages

Fonctions essentielles en Arduino

Transféré par

kamil69ali
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
95 vues163 pages

Fonctions essentielles en Arduino

Transféré par

kamil69ali
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Apprendre à écrire le programme Arduino minimum.

Arduino
3. Notion de fonction
Une fonction est un « morceau » de programme :
• qui est désigné par un nom
• reçoit des paramètres (valeurs, données)
• exécute des instructions
• renvoie un résultat
Par exemple, une fonction qui multiplie 2 nombres :
• pourra s'appeler « multiplication »
• recevra les 2 nombres à multiplier
• réalisera la multiplication des 2 nombres
• renverra le résultat

Une autre image parlante, l'exemple d'un moulin à café à manivelle :


• la fonction s'appelle « moulin à café »
• les grains de café que l'on met dedans sont les paramètres
• le rôle de la fonction c'est de moudre les grains,
• la fonction « moulin à café » renvoie du café moulu !
Le découpage du code en « morceaux » ou fonctions, est utilisé pour simplifier
la maintenance des programmes.
4. Ecrire une fonction

Le principe général d'écriture d'une fonction en langage Arduino (idem en C, en


Java...) consiste à :
• préciser le type de valeur renvoyée (valeur entière, à virgule, chaine de
caractères) : le « café moulu »
• donner un nom à la fonction qui décrit ce qu'elle fait si possible
• mettre entre parenthèses les paramètres à utiliser (ou reçus) par la
fonction : les « grains de café »
• indiquer le début du code de la fonction à l'aide d'une accolade {
• écrire ligne à ligne le code de la fonction (« moudre les grains »):
◦ les commentaires précédés d'un double //
◦ les instructions suivies d'un ;
• indiquer la fin du code de la fonction à l'aide d'une accolade }

Par convention, le nom d'une fonction commencera toujours par une minuscule.
5. La fonction la plus simple
L'utilisation la plus simple d'un « moulin à café » consiste :
• à ne rien mettre dedans = pas de grains
• à ne pas tourner la manivelle = ne pas moudre les grains = ne rien faire
• et le moulin à café ne vous donnera pas de café moulu = renverra rien !
De la même façon, la fonction la plus simple est une fonction :
• qui ne reçoit aucun paramètre : on laissera tout simplement les
parenthèses vides,
• qui n'exécute aucune instruction : l'espace entre les 2 accolades restera
vide,
• qui ne renvoie rien : le type correspondant s'appelle void

Cette fonction ne fait rien, ne renvoie rien, mais elle est correctement écrite et ne
provoquera aucune erreur de compilation.
L'important ici est de bien mémoriser cette structure de base qui sera souvent
réutilisée dans le langage Arduino :
• par les 2 fonctions de base obligatoires d'un programme Arduino comme
on va le voir juste après,
• par des fonctions plus complexes qui seront présentées en temps voulu,
• ou bien dans une forme un peu différente par certaines instructions du
langage Arduino, notamment les boucles et les conditions.
6. Les 2 fonctions de base obligatoires dans tout programme Arduino
Tout programme Arduino est structuré en 2 parties distinctes et obligatoires
qui sont en fait deux fonctions obligatoires de forme simple, à savoir :
//--- le programme minimum ---
• la fonction setup()
• la fonction loop() //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

// écrire ici les instructions à exécuter au début


Ces 2 fonctions sont de la forme simple qui :
• a un nom (setup et loop) } // fin de la fonction setup()
• ne reçoit rien : parenthèses vides
• ne renvoie rien : type void //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {

// écrire ici les instructions à exécuter en boucle


Les instructions à exécuter dans un programme devront être placées à
l'endroit voulu entre les accolades de l'une ou l'autre de ces 2 fonctions. } // fin de la fonction loop()

Un programme qui ne contient que ces 2 fonctions vides est LE programme // NB : les lignes précédées de // sont des commentaires
Arduino minimum : il ne fait rien, mais il compile sans provoquer d'erreur.
7. A vous de jouer : Ecrire et compiler le programme minimum
Cette manipulation peut se faire sur le PC sans posséder de carte Arduino. Seul le
logiciel Arduino doit être correctement installé sur votre système.
Pour compiler le programme minimum :
• Commencer par ouvrir le logiciel Arduino
• Se placer dans la fenêtre d'édition et saisir à la main le code minimum
correspondant aux 2 fonctions setup() et loop() vides.
• Une fois le code saisi, cliquer sur le bouton de compilation.
• La compilation doit se dérouler sans erreur et vous devez obtenir un
message attestant la fin de compilation.
• A noter : La console vous indique la taille qui sera utilisée dans la
mémoire Arduino par le programme ainsi compilé.
• Une fois fait, vous pouvez vous entraîner à ajouter des commentaires et à
recompiler.
• Amusez-vous également à provoquer volontairement des erreurs de
compilation en enlevant une accolade ou une parenthèse : un message
rouge apparaît dans la console !

Ce programme minimum doit vous servir de base pour toute écriture d'un
programme Arduino !
Le programme minimum est aussi disponible dans le logiciel Arduino dans :
File > Examples > Basics > BareMinimum
8. Signification des 2 boucles obligatoires setup() et loop()
La fonction setup() :
• n'est exécutée qu'une seule fois et en premier au début du programme,
• on y placera les instructions d'initialisation et de configuration du
programme.

Après toute programmation de la carte Arduino, l'exécution du programme


Arduino se lance automatiquement au début de la fonction setup().

La fonction loop() :
• est exécutée ensuite en boucle, se répétant indéfiniment tant que le
programme n'est pas interrompu.
• on y placera les instructions à exécuter de façon répétée en boucle.

Un appui sur le bouton « reset » de la carte Arduino stoppe l'exécution en cours


et fait redémarrer le programme par la fonction setup()

Truc de programmation : si l'on souhaite exécuter un programme seulement une


seule fois :
• soit mettre toutes les instructions dans la fonction setup()
• soit utiliser au sein de la fonction loop() l'instruction while(1); qui a pour
effet de bloquer l'exécution du programme à l'endroit où elle est placée.
(Cette instruction, qui sera vue ultérieurement, est exécutée « tant que 1
vaut 1 » ce qui est toujours le cas !)
9. Comment appeler une fonction dans un programme ?

On a vu le principe d'écriture d'une fonction, une fonction étant un morceau de


programme. Une fois définie, une fonction va ensuite pouvoir être appelée depuis
n'importe quel autre endroit du programme (sous réserve que cela aie un sens...)

Le principe pour appeler une fonction de la forme simple est le suivant :


• on écrit son nom
• suivi de 2 parenthèses laissées vides
• suivies d'un point virgule ;

Si une fonction utilise un ou plusieurs paramètres, ceux-ci seront mis entre les
parenthèses.

Lorsqu'une fonction sera appelée :


• le code qu'elle contient sera exécuté et une valeur sera
renvoyée. La valeur renvoyée pourra être stockée dans une variable
comme on le verra plus tard.
• Puis le programme exécutera la ligne suivante.
A savoir : les instructions du langage Arduino sont pour la plupart
des fonctions

Les instructions Arduino seront donc appelées :


• sous la forme simple par instruction();
• sous la forme avec paramètres par : instruction(val1, val2, ...);
10. Règles d'écriture (ou syntaxe) de base à connaître et à ne pas oublier !

Règle 1
Toute ligne comportant une instruction devra se terminer par un point-virgule ;

Règle 2
Toute accolade ouverte { doit être associée à une accolade de fermeture }

A savoir : lorsque le curseur est placé à proximité d'une accolade, le logiciel


Arduino signale automatiquement l'autre accolade correspondante.

Règle 3
Toute ligne commençant par un double // est un commentaire sur une ligne

Règle 4
On pourra écrire un commentaire sur plusieurs ligne en le débutant par /* et en
le terminant par */

Truc de programmation : commenter vos programmes au maximum aussi bien


pour vous que pour les autres !
Apprendre à utiliser les variables et les constantes avec le langage Arduino. Afficher des
variables numériques entières dans le Terminal Série.

Arduino
3. La notion de variable
Vous avez tous déjà rangé des objets dans des boites et collé une étiquette dessus :
alors vous allez facilement comprendre ce qu'est une variable !

Lorsque l'on écrit un programme en langage Arduino (ou dans n'importe quel
autre langage de programmation d'ailleurs), on va manipuler des nombres entiers,
des nombres à virgules, des chaines de caractères.
Pour pouvoir manipuler facilement toutes ces grandeurs, on va les mémoriser, les
stocker, ce qui revient à les «ranger chacun dans une boite » et on va « coller une
étiquette dessus ».
En programmation, une « boite mémoire » sur laquelle on colle une
« étiquette » pour y mettre quelque chose : çà s'appelle une variable !

La carte Arduino dispose d'un processeur qui sait très bien utiliser ces « boîtes »
mémoires : c'est même son principal travail !
La carte Arduino possède de nombreuses cases mémoires disponibles que vous
allez pouvoir utiliser à volonté :
• vous disposez de plus de 1000 « boîtes » (ou octets) dans lesquelles vous
allez pouvoir lire, écrire, effacer des valeurs ,
• cette « réserve » de boites, c'est la mémoire vive, ou RAM (active lorsque
Arduino est allumé et qui s'efface lorsque vous éteignez Arduino). C'est
elle que le programme Arduino utilise pour stocker les variables !
• pour info (usage avancé), la carte Arduino dispose également :
◦ d'une petite mémoire Eeprom dans laquelle on peut lire/écrire et qui
ne s'efface pas quand on éteint l'Arduino
◦ d'une très grosse mémoire FLASH qui est écrite une fois pour toute et qui
ne s'efface pas quand on éteint Arduino. On y met le programme mais on
peut aussi y mettre des données fixes (texte par exemple).
4. La notion de « type » de variables

Imaginons que vous vouliez ranger des objets de toutes sortes : vous allez vous
préparer un stock de boites de tailles diverses et ensuite vous allez ranger vos
objets de façon adaptée dans vos boites.
Par exemple :
• vous allez mettre un bijou dans une petite boite, vous mettrez des crayons
dans une boite moyenne, vous mettrez des livres dans une grosse boite,
etc...
• dans votre cuisine, vous mettrez un petit reste dans un petit tupperware,
des oeufs dans une boite à oeufs, du liquide dans une bouteille, etc...
En programmation, c'est exactement pareil :
• vous allez utilisez des « boites mémoires » différentes en fonction de la
« taille » ou de la nature de ce que vous allez mettre dedans.
•les types possibles vont être des valeurs numériques entières (1,2,3,..), des
nombres à virgules (3.14159), des caractères ('A', 'B', ..), des valeurs
binaires (0 ou 1, vrai ou faux), etc..
En programmation, la « taille » d'une « boite mémoire » (ou variable)
s 'appelle le « type ». Pour dire les choses autrement, le type d'une
variable, c'est sa catégorie, son genre .

Le langage Arduino va vous permettre :


• de créer des variables de types différents en fonction des besoins
• de les nommer
• d'y mettre les valeurs voulues
5. Principe général de déclaration d'une variable

Dans le langage Arduino, pour déclarer une variable, il faut au minimum :


• indiquer son type ( = ce que va contenir la « boîte » )
• indiquer son nom ( = l'étiquette à coller sur la « boîte » )
• finir la ligne par un point-virgule ; (= ne pas l'oublier !)
• et c'est tout !
• Noter que le contenu initial de cette variable est inconnu... ce qui n'est
jamais une bonne chose en programmation...

C'est pourquoi, le plus souvent, on préférera également fixer la valeur de


la
variable au moment de sa déclaration. Dans ce cas, il faudra :
• indiquer son type ( = ce que va contenir la « boîte » )
• indiquer son nom ( = l'étiquette à coller sur la « boîte » )
• suivi d'un signe égal = ( ce qui revient à ouvrir la boite pour mettre
quelque chose dedans...)
• suivi de la valeur initiale voulue, (= ce que vous mettez dans la
« boite »)
• et finir la ligne par un point-virgule ; (= ne pas l'oublier !)
En pratique : initialisez vos variables (= attribuez une valeur connue)
lors de la déclaration pour éviter les effets inattendus !
6. Pour info : Les principaux types de variables disponibles dans le langage Arduino
Vous connaissez déjà un type, le type void, qui est le type d'une fonction qui ne
renvoie rien. On ne peut pas déclarer une variable void, puisque par définition une
variable va contenir quelque chose.

Le type de variable le plus simple est celui d'une variable dite « binaire » qui ne
peut contenir que rien ou quelque chose, autrement dit 0 ou 1, vrai ou faux :
c'est le type boolean

Les types de variables que vous allez le plus utiliser sont les variables numériques
entières :
• le type int (pour integer = entier) pour une valeur entière comprise
entre -32536 et + 32535
• le type long pour une valeur entière comprise entre -2 147 483 648 et
+2 147 483 647
• usage avancé : on fera précéder le type int ou long du mot clé unsigned si on
souhaite n'utiliser que des valeurs positives. Ceci a pour effet de doubler la
valeur positive utilisable (de 0 à 65535 pour un int par exemple).
Une variable qui va contenir un nombre à virgule sera de type float
Une variable correspondant à un caractère sera de type char
A part, la classe String qui servira à stocker les chaines de caractères.

Les types vous sont présentés ici pour information : vous les utiliserez et les
découvrirez au fur et à mesure des besoins de vos programmes.
En pratique, au début, déclarez vos variables en type int : çà
couvrira tous les besoins courants !
7. A vous de jouer : Déclarations de variables et opérations de bases sur les variables
Exemples de déclarations de variables Exemples d'opérations de base sur les variables
Pour stocker une valeur pouvant prendre comme valeur « vrai ou faux », 1 ou Pour attribuer une valeur à une variable, on fera :
0, on pourra utiliser un boolean : maVariable=2500;
boolean maVariable=false;
Entre 2 valeurs numériques, on pourra réaliser des opérations
Pour stocker une valeur entière pouvant prendre comme valeur maximale mathématiques. Si a, b et c sont 3 variables du même type (int par exemple),
1000, on utilisera un int : on pourra faire :
int maVariable=0; a=a+b;
c=b-a;
Pour stocker une valeur entière pouvant prendre comme valeur maximale 1 c=3*(a-b);
000 000, on utilisera un long : b=a/c;
long maVariable=0;
Noter que la division renverra une valeur entière si on utilise 2 valeurs
Pour stocker une valeur décimale, on utilisera un float : entières.
float maVariable=0.0;
Usage avancé : une variable a une taille qui se mesure en « octets » (un ensemble 8
coquetiers...) Il est possible de connaître la taille d'une variable grâce à l'instruction
En pratique :déclarez vos variables en type int : çà couvrira tous sizeOf (usage avancé) selon :
les besoins courants ! initialisez vos variables lors de la
int taille = sizeof(maVariable); // récupère la taille en octets d'une variable
déclaration pour éviter les effets inattendus !

Bon à savoir : convertir un type dans un autre.


Dans certaines situations, on peut avoir besoin de transformer un type de variable dans un autre. Ceci est possible grâce à plusieurs fonctions dédiées du
langage arduino : int(x), long(x), float(x), char(x), etc... où x représente une variable de tout type.
8. Où déclarer une variable ? Notion de portée des variables
Il est possible de déclarer une variable :
• soit avant la fonction setup(), en dehors de toute fonction, dans une
partie que l'on pourra appeler « entête déclarative ». Les variables
déclarées de cette façon seront accessibles de n'importe où dans le
programme. On dit qu'elle sont « globales ».
• soit au sein d'une fonction, que ce soit la fonction setup(), loop() ou
toute autre fonction. Dans ce cas, la variable n'existe que à l'intérieur de
cette fonction : on dit qu'elle est « locale ».
• soit au sein de certaines boucles, comme nous le verrons plus tard, en
tant que variable d'incrémentation : la portée est locale et se limite alors à
l'intérieur de la boucle.
D'après ce que nous venons de voir, vous comprenez que la portée d'une
variable correspond à son « périmètre de visibilité » dans un programme :
• globale : la variable est visible et utilisable de n'importe quel
endroit du programme.
• locale : variable n'est visible et utilisable que dans une certaine
partie du programme, une fonction ou une boucle. A noter : une
variable locale est détruite entre 2 appels de la fonction qui l'utilise.
En pratique : déclarez vos variables et constantes AVANT les
fonctions setup() et loop() : elles seront ainsi globales et accessibles
de partout !

Usage avancé : La portée des variables et leur durée de vie est modifiable également par certains
mots-clés, appelé « qualificateurs », à mettre avant le type de la variable lors de la déclaration :
• static : permet de rendre une variable locale persistante entre 2 appels d'une fonction
utilisant une variable locale. Est inaccessible en dehors de la fonction qui l'utilise.
• volatile : rend persistante une variable globale quelque soit le moment où elle sera
appelée. Utile avec les interruptions.
9. Les « variables fixes » : les constantes !
Pour tous les types de variables, il existe une situation particulière : celle où le
contenu de la variable ne peut et ne doit pas changer au cours du programme.
Par exemple :
• si la variable représente le numéro d'une broche,
• si la variable représente le nombre PI, etc...
Dans cette situation particulière, on va pouvoir préciser que le contenu de la
variable ne changera pas au cours du programme en créant une constante ! (à
noter que ce n'est pas obligatoire, mais c'est mieux !)

Pour déclarer une constante, c'est simple : on ajoute le mot clé const devant type
de la variable qui devient ainsi une constante ! Exemple :
const int maBroche=13; // déclare une constante de type int valant 13
Une fois déclarée, la valeur d'une constante ne pourra plus être
modifiée !

A savoir : Le langage Arduino intègre plusieurs constantes prédéfinies :


◦ HIGH et LOW correspondant au niveau des broches numériques
◦ INPUT et OUTPUT correspondant au sens des broches numériques
◦ true et false correspondant aux états logiques VRAI et FAUX

En pratique : utiliser une constante pour renommer une broche


Arduino !
10. Variables et fonctions : 1. passer une variable en tant que paramètre d'une fonction !
Il est possible d'utiliser les variables avec les fonctions et donc avec les
instructions Arduino, de la même façon qu'on le ferait avec des valeurs
numériques brutes. On va ainsi pouvoir :
• passer une variable en tant que paramètre d'une fonction,
• récupérer le résultat renvoyé par une fonction dans une variable.

Fréquemment, on va « passer » à une fonction une variable en tant que


paramètre. Dans ce cas, il faut impérativement que la variable passée en
paramètre soit du même type que ce que la définition de la fonction
prévoit pour ce paramètre (autrement dit utiliser une variable int si la fonction
attend un paramètre de type int).
Dans le cas des instructions Arduino, la documentation indique le type attendu
pour chaque paramètre de la fonction :
• Par exemple, la fonction delay() du langage Arduino reçoit un paramètre
correspondant à la durée en millisecondes.
• La documentation nous indique que ce paramètre doit être de type int.
• On pourra ainsi déclarer une variable int et la passer à l'instruction delay()
Exemple :
int duree=1000; // déclare une variable int valant 1000
delay(duree); // exécute l'instruction delay avec la valeur de la variable

La plupart des instructions du langage Arduino supportent le type


int.
11. Variables et fonctions : 2. récupérer le résultat renvoyé par une fonction dans une variable !
A l'inverse, de nombreuses instructions ou fonctions renvoient une valeur résultat
d'un type donné (int, long, etc...) : on pourra récupérer le résultat renvoyé par
une fonction dans une variable du même type, simplement en posant
l'égalité entre la variable et la fonction.
Là encore, pour chaque fonction, la documentation du langage Arduino précise
quel est le type de la valeur renvoyée :
• Par exemple, la fonction millis() du langage Arduino renvoie une valeur
correspondant au nombre de millisecondes écoulées depuis le début du
programme.
• La documentation nous indique que la valeur renvoyée est de type long.
• On pourra ainsi déclarer une variable long et récupérer le nombre de
millisecondes écoulées depuis le début du programme dans la variable,
simplement en posant l'égalité entre la variable et la fonction !
Exemple :
long time=0; // déclare une variable time valant 0
time = millis(); // le résultat renvoyé par la fonction est mis dans la variable

Encore une fois...


Si vous n'avez pas tout compris, ne vous inquiétez pas : il s'agit ici d'une présentation de notions importantes que vous allez rencontrer souvent :
vous aurez donc tout loisir ultérieurement de tester, expérimenter à votre rythme et tranquillement tout ce que vous venez de voir...
Vous vous familiariserez progressivement avec les différentes instructions Arduino et vous comprendrez alors concrètement la signification de ces concepts.
12. Structure type d'un programme Arduino utilisant des variables et des constantes.

Souvenez-vous, la structure du programme minimum Arduino associait


successivement :
• la fonction setup() qui ne s'exécute qu'une seule fois
• suivie de la fonction loop() qui s'éxecute ensuite en boucle sans fin

A présent, la structure d'un programme Arduino « type » (que je vous conseille


vivement d'utiliser ) va s'étoffer un petit peu avec :
• une entête déclarative avant les 2 fonctions setup() et loop() au niveau
de laquelle on déclarera :
◦ les constantes dont la valeur ne changera pas et seront globales,
◦ et les variables globales qui seront accessibles de partout.
• la fonction setup() qui ne s'exécute qu'une seule fois dans laquelle on
pourra :
◦ également déclarer des variables locales si besoin,
◦ initialiser si besoin les variables globales,
◦ utiliser les constantes et les variables globales à volonté
• suivie de la fonction loop() qui s'éxecute ensuite en boucle sans fin,
dans laquelle on pourra :
◦ également déclarer des variables locales également si besoin,
◦ utiliser les constantes et les variables globales à volonté.
13. Afficher des variables dans le Terminal Série

Dans un programme qui va afficher des messages utilisant des variables dans le
Terminal série sur le PC, la structure sera la suivante :
// --- entete déclarative ---
int myInt=-123; // variable entière "petit format"
long myLong=456789; // variable entière "grand format" float
Entête déclarative myFloat=3.14159; // variable à virgule
A ce niveau, on va déclarer et initialiser les variables utilisées, par exemple : const int myConst=10; // constante entière

• une variable int void setup() { // fonction setup() : exécutée 1 seule fois en premier
• une variable long [Link](115200); // initialise la communication série
• une variable float
} // fin setup
• une constante int
void loop() { // fonction loop() : exécutée ensuite en boucle sans fin
Fonction setup()
[Link]("myInt = "), [Link](myInt); // affiche message [Link]("myLong = "),
A ce niveau, on va : [Link](myLong); // affiche message [Link]("myFloat = "), [Link](myFloat,4); //
• initialiser la communication série : affiche message [Link]("myConst = "), [Link](myConst); // affiche message
[Link](); // saut de ligne vide
• +/- afficher les messages de début de programme (1 seul affichage)
delay(1000); // pause de 1 seconde
Fonction loop()
} // fin loop
On ce niveau on va :
• afficher les messages utilisant les variables
• faire une pause de 1 seconde entre 2 passages.
Sorties numériques : contrôler 8 LEDs et réaliser des « jeux de lumière », simuler les feux de
circulation, apprendre la boucle for, la condition if, utiliser un digit.

Arduino
3. Faire clignoter 8 LEDs : le montage
Continuons, sur notre lancée avec un montage utilisant maintenant 8 LEDs
simultanément ! Pour faire clignoter 8 LEDs, on va connecter 8 LEDs chacune en
série avec une résistance sur 8 broche E/S de la carte Arduino configurées en
sortie.
Le principe sera le suivant :
• lorsque la broche sera au niveau HAUT, la LED sera allumée,
• lorsque la broche sera au niveau BAS, la LED sera éteinte.

Comme vu précédemment, si on désire une intensité de 13mA dans la LED, on utilisera,


d'après la loi d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.
4. Faire clignoter 8 LEDs en utilisant un tableau de constantes : 1ère version

Cette fois on va reprendre le même programme en utilisant cette fois un //--- entete déclarative
tableau de 8 constantes pour désigner les broches : // = déclarer ici variables et constantes globales
• un tableau de 8 constantes pour désigner les 8 broches
const int LED[8] = {2,3,4,5,6,7,8,9}; // Tableau de constantes
• et une variable pour fixer la vitesse de clignotement.
int vitesse=1000; // variable fixant la durée de la pause
Entête déclarative
On déclare :
• un tableau de 8 constantes appelé LED de type int pour désigner les //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
broches 2,3,4,5,6,7,8 et 9.
pinMode(LED[0], OUTPUT); // met la broche en sortie
• une variable de type int pour fixer la vitesse, appelée vitesse pinMode(LED[1], OUTPUT); // met la broche en sortie
pinMode(LED[2], OUTPUT); // met la broche en sortie
Fonction setup() pinMode(LED[3], OUTPUT); // met la broche en sortie
pinMode(LED[4], OUTPUT); // met la broche en sortie
A ce niveau, on va : pinMode(LED[5], OUTPUT); // met la broche en sortie
• initialiser les broches utilisées en sortie (avec les constantes LED[0], pinMode(LED[6], OUTPUT); // met la broche en sortie
LED[1], LED[2], LED[3], LED[4],LED[5],LED[6],LED[7]) pinMode(LED[7], OUTPUT); // met la broche en sortie

} // fin de la fonction setup()


(suite) Fonction loop()

//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {

digitalWrite(LED[0],HIGH); // allume la LED


digitalWrite(LED[1],HIGH); // allume la LED
A ce niveau on va : digitalWrite(LED[2],HIGH); // allume la LED
• Allumer les LEDs = mettre les broches au niveau HAUT (5V) digitalWrite(LED[3],HIGH); // allume la LED
digitalWrite(LED[4],HIGH); // allume la LED
• Attendre le temps voulu (= la valeur de la variable vitesse en digitalWrite(LED[5],HIGH); // allume la LED
millisecondes) digitalWrite(LED[6],HIGH); // allume la LED
digitalWrite(LED[7],HIGH); // allume la LED
• Eteindre les LEDs = mettre ea broches au niveau BAS (0V)
• Attendre le temps voulu (= la valeur de la variable vitesse en delay(vitesse); // pause de n millisecondes
millisecondes) digitalWrite(LED[0],LOW); // éteint la LED
• le code de la fonction loop se répète sans fin... digitalWrite(LED[1],LOW); // éteint la LED
digitalWrite(LED[2],LOW); // éteint la LED
digitalWrite(LED[3],LOW); // éteint la LED
Bon, là vous avez le droit de trouver çà bof... C'est un peu « bourrin » cette digitalWrite(LED[4],LOW); // éteint la LED
digitalWrite(LED[5],LOW); // éteint la LED
manière de programmer, mais çà marche ! digitalWrite(LED[6],LOW); // éteint la LED
Allez, on va voir comment améliorer çà ! digitalWrite(LED[7],LOW); // éteint la LED

delay(vitesse); // pause de n millisecondes

} // fin de la fonction loop()


5. La boucle For
En programmation, comme vous venez de le constater, on rencontre
fréquemment la situation où l'on doit répéter plusieurs fois l'exécution
d'un même code : pour pouvoir faire cela simplement, on utilise ce que
l'on appelle une boucle !
Imaginons par exemple que l'on veuille faire clignoter très exactement 10 fois une
LED : une boucle va nous permettre de faire cela très simplement ! Au lieu de 10,
on pourra le faire 23 fois, 252 fois, 1000 fois : c'est très pratique et précis !
Il existe plusieurs types de boucles : la plus fréquente et la plus pratique
est la boucle dite for. Cette boucle dit au microprocesseur la chose suivante :
• commencer à compter à partir de telle valeur (0 le plus souvent)
• tant que la valeur n'a pas atteint la valeur maximale
• continuer de compter en ajoutant 1 (ou plus) à la valeur
• à chaque « passage », exécuter les instructions voulues

La structure d'une boucle for s'apparente à celle d'une fonction avec


cependant quelques ajouts :
• on commence par le mot clé for (pour en anglais) suivi de la
parenthèse (
• ensuite on déclare la variable de comptage en déclarant son
type (int par exemple) et on fixe la valeur de départ. La variable
de comptage est locale limitée à la boucle. On fait suivre d'un ;
• ensuite, on fixe la valeur maximale à ne pas dépasser. On fait suivre
à nouveau d'un ;
• enfin, on indique l'incrémentation à utiliser et on ferme la
parenthèse )
• ensuite comme pour une fonction, on met le code entre {}

Explication avancée : En fait le contenu entre les parenthèses d'une boucle correspond à 3 L'opérateur d'incrémentation ++ équivaut à l'opération +1
instructions, d'où les points-virgule de séparation :
i++ équivaut à i=i+1
• la première instruction est la déclaration/initialisation d'une variable typiquement
• la seconde instruction est une condition : tant qu'elle est vraie, la boucle exécute L'opérateur de décrémentation - - équivaut à l'opération -1
la 3ème instructions i-- équivaut à i =i-1
• la troisième instruction correspond à l'opération à effectuer à chaque fois que la
condition est vraie. Noter que l'on peut utiliser toute sorte d'opération : i=i+10 par
exemple.
6. Faire clignoter 8 LEDs : 2ème version en utilisant une boucle FOR
Le plus simple pour comprendre l'intérêt d'une boucle est de l'utiliser dans un
exemple. Ici, on va reprendre tout simplement le programme précédent en
utilisant des boucles pour alléger le programme !
//--- entete déclarative
Entête déclarative // = déclarer ici variables et constantes globales
On déclare :
const int LED[8] = {2,3,4,5,6,7,8,9}; // Tableau de constantes
• un tableau de 8 constantes appelé LED de type int pour désigner les
broches 2,3,4,5,6,7,8 et 9. int vitesse=1000; // variable fixant la durée de la pause

• une variable de type int pour fixer la vitesse, appelée vitesse //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

Fonction setup() //--- met les 8 broches en sortie ---


for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
A ce niveau, on va :
OUTPUT); // met la broche en sortie
• initialiser les broches utilisées en sortie en utilisant une boucle, sous } // fin for
la forme LED[i] où i est la variable de comptage de la boucle.
} // fin de la fonction setup()
Fonction loop()
A ce niveau on va : //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
• Allumer les LEDs = mettre les broches au niveau HAUT (5V) en
// allume les 8 LEDs
utilisant une boucle pour défiler les 8 broches, for (int i=0; i<8; i++) { // répètre 8 fois le code
• Attendre le temps voulu (= la valeur de la variable vitesse en digitalWrite(LED[i],HIGH); // allume la LED
} // fin for
millisecondes)
• Eteindre les LEDs = mettre les broches au niveau BAS (0V)en utilisant delay(vitesse); // pause de n millisecondes
une boucle pour défiler les 8 broches,
//--- éteint les 8 LEDs
• Attendre le temps voulu (= la valeur de la variable vitesse en for (int i=0; i<8; i++) { // boucle for répète 8 fois
millisecondes) digitalWrite(LED[i],LOW); // éteint la LED
} // fin for
• le code de la fonction loop se répète sans fin...
delay(vitesse); // pause de n millisecondes
Remarquer comment le programme s'allège ! (il tient sur 1 seule page...)
Remarquer également que si on utilisait 20 broches, le programme n'est } // fin de la fonction loop()
quasiment pas modifié !!
En pratique, utiliser des boucles à chaque fois que vous répétez le
même code à plusieurs reprises !
7. La condition if... else...
Imaginons, à présent que l'on veuille exécuter une instruction que dans certains
cas : par exemple, au lieu de faire clignoter toutes les LEDs, on ne va en allumer
que une et défiler les LEDs une à une de cette façon.
La solution passe par ce que l'on appelle une condition qui dit au
microproccesseur :
• si telle condition est vraie, alors faire ceci
• sinon faire cela.
L'instruction utilisée pour une condition est l'instruction if … else... (si... sinon...)
que l'on écrit de la façon suivante :
• on commence par le mot clé if suivi de la condition entre ( )
• suivi des { } qui contiennent les instructions à exécuter si la condition est
vraie, chaque instructions devant être suivie d'un ;
•enoption, on peut compléter du mot clé else suivi des { } qui contiennent
les instructions à exécuter si la condition est fausse.
La condition devra être une opération logique :
• qui renverra une valeur de type boolean soit true (vrai) soit false (faux)
• on utilisera pour cela les opérateurs logiques de comparaison
• pour info, 0 est considéré comme false et toute valeur différente de 0 est
considérée comme true (ainsi, if(1) est toujours vrai !)
La condition de base utilisable est de tester si une variable vaut une certaine
valeur :
• on écrira la condition sous la forme variable==valeur (2 signes == )
• Par exemple on écrira if ( variable==2) { instructions ;} ce qui veut dire
« si la condition « variable vaut 2 » est vraie alors exécuter les
instructions »

Ne pas confondre l'opération logique de test d'égalité == avec le


signe = d'affectation : c'est une erreur fréquente de débutant et même de
programmeur expérimenté... !!
8. Pour info : les différentes syntaxes (=manières d'écrire) de la condition if.. else..
La forme if simple

La forme if .. else...

La forme if … else if... else...


9. Pour info : les opérateurs logiques et leur utilisation

Les opérateurs logiques de comparaison


• x == y : VRAI si x est égal à y
• x != y : VRAI si x est différent de y
• x < y : VRAI si x est inférieur à y
• x > y : VRAI si x est supérieur à y
• x <= y : VRAI si x est inférieur ou égal à y
• x >= y : VRAI si x est supérieur ou égal à y

Les opérateurs booléens (permettent d'enchaîner des conditions entre-elles)


• && (ET logique) : VRAI seulement si les deux conditions sont VRAI

• || ( OU logique) : VRAI si l'une des deux conditions est VRAI

• ! (NON logique) : VRAI si l'opérande est FAUX – cas particulier : !x est VRAI chaque fois que x=0 (« tordu » mais pratique !)
10. Un jeu de lumière à 8 LEDs en utilisant un tableau de variables et une boucle FOR
Allez, on continue... Ici, on va allumer une seule LED à la fois, on va faire
« défiler » et recommencer en boucle. On va donc se baser sur :
• un tableau de constantes pour désigner les broches, //--- entete déclarative
// = déclarer ici variables et constantes globales
• une boucle for de défilement pour parcourir les broches,
const int LED[8] = {2,3,4,5,6,7,8,9}; // Tableau de constantes
• une condition if pour choisir la LED à allumer
Prêt ? C'est parti ! int vitesse=50; // variable fixant la durée de la pause

Entête déclarative //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
On déclare : //--- met les 8 broches en sortie ---
• un tableau de 8 constantes appelé LED de type int pour désigner les for (int i=0; i<8; i++) { // répète 8 fois le code pinMode(LED[i],
OUTPUT); // met la broche en sortie
broches 2,3,4,5,6,7,8 et 9. } // fin for
• une variable de type int pour fixer la vitesse, appelée vitesse
} // fin de la fonction setup()
Fonction setup()
A ce niveau, on va : //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
• initialiser les broches utilisées en sortie en utilisant une boucle, sous
for (int numLED=0; numLED<8; numLED++) { // défile les 8 LEDs
la forme LED[i] où i est la variable de comptage de la boucle.
Fonction loop() // allume la LED voulue
for (int i=0; i<8; i++) { // répète 8 fois le code
A ce niveau on va :
if (i==numLED) { // si la LED est la LED courante
• Dans une boucle principale, répéter 8 fois le code suivant : digitalWrite(LED[i],HIGH); // allume la LED
◦ Parcourir 1 à 1 les LEDs à l'aide d'une boucle for }
else { // sinon
◦ A l'aide d'une condition if : digitalWrite(LED[i],LOW); // éteint la LED
}
▪ Allumer la LED courante de la boucle principale = mettre les
broches au niveau HAUT (5V) } // fin for i
▪ sinon éteindre les autres LEDs delay(vitesse); // pause de n millisecondes
◦ Attendre le temps voulu (= la valeur de la variable vitesse en
millisecondes) } // fin for numLED

• le code de la fonction loop se répète sans fin... } // fin de la fonction loop()

Une fois encore, « pensez » le déroulement de votre code :


Ici, les 8 LEDs sont parcourues successivement mais c'est tellement rapide
que c'est instantané, quasi-simultané et vous ne voyez que la LED qui reste
allumée. Retenez que le microprocesseur va très vite (plusieurs millions
d'opérations par secondes !) .
12. Encore plus fort ! Jeu de lumière à 8 LEDs : une variante à la K2000... avec une fonction !
Poursuivons nos explorations du codage... A présent, on peut compléter un //--- entete déclarative
peu ce programme, en réalisant un « aller-retour » ce qui va passer par une // = déclarer ici variables et constantes globales
boucle de « décrementation ». Essayer de la coder par vous-mêmes et si vous const int LED[8] = {2,3,4,5,6,7,8,9}; // Tableau de constantes int vitesse=20; //
n'y arrivez pas, regardez la solution que je vous propose qui utilise aussi une variable fixant la durée de la pause
fonction dédiée...
//--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
Entête déclarative
//--- met les 8 broches en sortie ---
On déclare : for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
• un tableau de 8 constantes appelé LED de type int pour désigner les OUTPUT); // met la broche en sortie
} // fin for
broches 2,3,4,5,6,7,8 et 9.
• une variable de type int pour fixer la vitesse, appelée vitesse } // fin de la fonction setup()

Fonction setup()
//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
A ce niveau, on va initialiser les broches utilisées en sortie en utilisant une
boucle, sous la forme LED[i] où i est la variable de comptage de la boucle. for (int numLED=0; numLED<8; numLED++) { // défile les 8 LEDs crescendo
allumeLED(numLED); // appelle la fonction pour allumer LED voulue delay(vitesse); //
Fonction loop() pause de n millisecondes
A ce niveau on va : } // fin for numLED

• Dans une première boucle principale, répéter 8 fois : for (int numLED=0; numLED<8; numLED++) { // défile les 8 LEDs decrescendo
allumeLED(7-numLED); // appelle la fonction pour allumer LED
◦ l'appel de la fonction chargée d'allumer la LED voulue voulue
◦ Attendre le temps voulu (= la valeur de la variable vitesse en delay(vitesse); // pause de n millisecondes
} // fin for numLED
millisecondes)
• Ensuite, on écrit le même code dans une 2ème boucle, mais cette fois } // fin de la fonction loop()
en parcourant les broches en sens inverse ! Pour ce faire, on peut : soit
//---- fonction qui allume la LED voulue
inverser la logique de la boucle, ou bien utiliser l'indice selon (7-i) (le void allumeLED (int numLEDIn) { // la fonction reçoit le numéro de le
plus simple) ! LED à allumer
• le code de la fonction loop se répète sans fin... // allume la LED voulue
Autre fonction : fonction allumeLED(broche) for (int i=0; i<8; i++) { // répètre 8 fois le code
if (i==numLEDIn) { // si la LED est la LED courante
Afin de ne pas répéter 2 fois le code pour allumer la LED voulue, on peut le digitalWrite(LED[i],HIGH); // allume la LED
mettre dans une fonction séparée qui va « renvoyer rien » , va recevoir le } // fin if
numéro de la LED et qui aura pour fonction (trop facile celle-là !...) : else { // sinon
digitalWrite(LED[i],LOW); // éteint la LED
• Parcourir 1 à 1 les LEDs à l'aide d'une boucle for } // fin else
} // fin for i
• A l'aide d'une condition if :
} // fin allumeLED
▪ Allumer la LED courante de la boucle principale = mettre les
broches au niveau HAUT (5V)
▪ sinon éteindre les autres LEDs
Il est déjà pas mal ce petit code ! Vous avez tout compris ? Bravo !
13. Jeux de lumière à LEDs : une solution plus visuelle pour coder des séquences variées !
A présent, pour ceux qui voudraient aller encore plus loin (si vous avez un peu //--- entete déclarative
de mal, vous êtes pas obligés...!), je propose ici une solution pour créer des // = déclarer ici variables et constantes globales
const int LED[8] = {2,3,4,5,6,7,8,9}; // Tableau de constantes int vitesse=100; //
« jeux de lumière » sous une forme plus visuelle. Cette solution passe par la variable fixant la durée de la pause
possibilité, en langage Arduino, d'exprimer les valeurs numériques au format
binaire, sous la forme 10010101. En faisant correspondre une LED à chaque //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
valeur 1/0, on obtient une façon simple de « visualiser » l'état des 8 LEDs... //--- met les 8 broches en sortie ---
for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
Les séquences d'effets deviennent ainsi plus facile à coder. Allez, on se lance... OUTPUT); // met la broche en sortie
} // fin for
Entête déclarative } // fin de la fonction setup()
On déclare :
• un tableau de 8 constantes appelé LED de type int pour désigner les //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
broches 2,3,4,5,6,7,8 et 9.
for (int repet=0; repet<10; repet++ ) { // repete 10 fois la séquence allumeLED(B10101010);
• une variable de type int pour fixer la vitesse, appelée vitesse // appelle la fonction pour allumer LED à
partir valeur binaire
Fonction setup() // bien utiliser 8 chiffres - B devant pour indiquer format binaire allumeLED(B01010101);
A ce niveau, on va : // appelle la fonction pour allumer LED à
partir valeur binaire
• initialiser les broches utilisées en sortie en utilisant une boucle, sous } // fin for repet
la forme LED[i] où i est la variable de comptage de la boucle.
for (int repet=0; repet<10; repet++ ) { // repete 10 fois la séquence allumeLED(B00000000);
Fonction loop() // appelle la fonction pour allumer LED à
A ce niveau on va : partir valeur binaire
allumeLED(B10000001);
• appelle ensuite la fonction de gestion des LEDs en passant une valeur allumeLED(B11000011);
sous une forme binaire, en faisant B11111111 par exemple pour allumer allumeLED(B11100111);
allumeLED(B11111111);
toutes les LEDs. Il faut simplement bien utiliser 8 chiffres ! allumeLED(B11100111);
• répéter autant de fois que voulu pour créer des séquences allumeLED(B11000011);
allumeLED(B10000001);
• le code de la fonction loop se répète sans fin... } // fin for repet

Autre fonction : fonction de gestion des LEDs } // fin de la fonction loop()


Nous allons ici à nouveau séparer le code de gestion des LEDs dans une
//fonction qui reçoit une valeur de type int non signé et ne renvoie auc une valeur
fonction séparée : void allumeLED(unsigned int valeur) { // fonction pour allumer/éteindre les LEDs voulue en
• cette fonction va recevoir la valeur binaire fonction valeur 8 bits reçue

• on défile les 8 broches et à chaque fois on met la LEDs dans l'état du for (int i=0; i<=7; i++) {
0/1 correspondant. On utilise pour cela une fonction du langage digitalWrite(LED[i],bitRead(valeur,7-i)); // met la broche LED[i]
dans l'état du bit de rang i de la variable
Arduino qui permet de lire la valeur d'un bit d'une variable, }
bitRead(valeur, bit). delay(vitesse); //pause
• puis faire une pause entre 2 appels de la fonction.
} // fin de la fonction allumeLED
Ce code est un petit peu plus « avancé » mais il rend la programmation
d'effets lumineux très simple !
14. Simuler les feux de circulation avec 6 LEDs : Le montage

Allez, on change un peu de sujet, histoire de varier les plaisirs... Cette fois, je vous
propose un petit montage didactique assez parlant : la simulation des feux de
circulation ! Une façon sympa de s'entraîner à utiliser les broches en sortie !
On va ici utiliser 6 LEDs : 2 groupes de 3 LEDs associant chacun 1 rouge, 1 jaune
et 1 verte. Chaque LED sera connectée en série avec une résistance.

Comme vu précédemment, si on désire une intensité de 13mA dans la LED, on


utilisera, d'après la loi d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.
15. Simuler les feux de circulation avec 6 LEDs : Le programme.
Bon, là, c'est à vous de jouer... Réfléchissez bien à la séquence des feux de
circulation :
• le premier feu est au vert et le 2ème est au rouge //--- le feu 2 passe à l'orange digitalWrite(VERT_2,LOW); // éteint
• puis le premier passe à l'orange puis au rouge vert feu 2 digitalWrite(ORANGE_2,HIGH); // allume orange feu 2

• Les 2 restent un peu au rouge delay (2000); // pause 2 secondes

• puis le second passe au vert, le premier restant au rouge //--- le feu 2 passe au rouge digitalWrite(ORANGE_2,LOW); //
éteint orange feu 2 digitalWrite(ROUGE_2,HIGH); // allume rouge
• puis le second passe à l'orange puis au rouge feu 2
• les 2 restent un peu au rouge puis...
delay (1000); // pause courte 1 seconde
• le premier feu est au vert et le 2ème est au rouge, etc...
//--- le feu 1 passe au vert digitalWrite(ROUGE_1,LOW); // éteint
Entête déclarative rouge feu 1 digitalWrite(VERT_1,HIGH); // allume vert feu 1
On déclare :
delay (5000); // pause longue 5 secondes
• 6 constantes de broches désignant les feux en utilisant des noms
significatifs //--- le feu 1 passe à l'orange digitalWrite(VERT_1,LOW); // éteint
vert feu 1 digitalWrite(ORANGE_1,HIGH); // allume orange feu 1
Fonction setup()
delay (2000); // pause 2 secondes
A ce niveau, on va initialiser les broches utilisées en sortie.
Fonction loop() //--- le feu 1 passe au rouge digitalWrite(ORANGE_1,LOW); //
éteint orange feu 1 digitalWrite(ROUGE_1,HIGH); // allume rouge
A ce niveau on va : feu 1

• combiner des pauses et des conditions de façon à réaliser la séquence delay (1000); // pause courte 1 seconde
voulue.
//--- le feu 2 passe au vert digitalWrite(ROUGE_2,LOW); // éteint
• Il y a plusieurs solutions. rouge feu 2 digitalWrite(VERT_2,HIGH); // allume vert feu 2

delay (5000); // pause longue 5 secondes

Essayez de coder la séquence par vous-même avant de regarder la solution :


vous serez content d'y arrivez par vous-même !
Vous avez là un bel exemple de séquence élaborée programmable
simplement.
Vous ne vous arrêterez plus au feu rouge tout à fait de la même façon...
16. Présentation du Digit
Nous allons à présent découvrir le « digit » à LEDs : vous savez, c'est cet afficheur
à chiffre rouge ou vert que l'on retrouve sur les réveils ou autres dispositifs de
mesure.
Eh bien, vous avez déjà toutes les connaissances nécessaires pour utiliser un digit
à LEDs ! Si, si, je vous assure !
En fait, un digit à LEDs n'est rien d'autre en fait que 8 LEDs de forme allongée qui
ont été mises dans un boitier plastique et disposées en 7 « segments » + 1 point
pour pouvoir afficher des chiffres : donc, si vous savez utiliser 8 LEDs, vous savez
utiliser un digit !
Ces 8 LEDs vont avoir une broche commune. Un digit aura logiquement :
• une broche par LED (7 segments et 1 point), soit 8 broches
• une broche commune, qui va en fait être dédoublée, soit 2 broches.
• Un digit aura donc 10 broches en tout...
On distingue 2 types de Digits en fonction de la broche qui est commune :
◦ à cathode commune si – commun
◦ à anode commune si + commun
17. Afficher les segments d'un digit : le montage
A ce stade, vous devriez être capable de faire le montage vous-mêmes :
• on va connecter chaque LED-segment du digit à une broche Arduino via
une résistance de série pour chaque,
• on va connecter la cathode commune au 0V.

Comme vu précédemment, si on désire une intensité de 13mA dans la LED, on utilisera, d'après la loi
d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.

Ce montage nécessite un peu de rigueur. Utiliser les broches que vous voulez pour les segments : le programme pourra être adapté en conséquence !
Notez bien sur un papier cependant quelle broche est utilisée pour chaque segment.
18. Afficher les segments d'un digit : le programme 1ère version
Donc, à présent, on va allumer puis éteindre successivement tous les segments
et le point du Digit. Nous allons reprendre une structure de programme que
nous avons déjà utilisée pour réaliser un jeu de lumière à 8 LEDs. //--- entete déclarative
// = déclarer ici variables et constantes globales
Entête déclarative const int LED[8] = {8,9,4,3,2,7,6,5}; // Tableau de constantes
// --- ordre des broches : a,b,c,d,e,f,g,pt
On déclare :
• un tableau de 8 constantes appelé LED de type int pour désigner les 7 int vitesse=200; // variable fixant la durée de la pause
broches de segments ainsi que la broche du point.
//--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
• une variable de type int pour fixer la vitesse, appelée vitesse
//--- met les 8 broches en sortie ---
Fonction setup() for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
OUTPUT); // met la broche en sortie
A ce niveau, on va : } // fin for
• initialiser les broches utilisées en sortie en utilisant une boucle, sous
la forme LED[i] où i est la variable de comptage de la boucle. } // fin de la fonction setup()

Fonction loop()
//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
A ce niveau on va :
//--- met les 8 broches en sortie ---
• à l'aide d'une boucle, allumer successivement la LED voulue puis for (int i=0; i<8; i++) { // répètre 8 fois le code
l'éteindre après une pause avant de passer à la LED suivante.
digitalWrite(LED[i], HIGH); // allume la LED
• le code de la fonction loop se répète sans fin... delay(vitesse); // pause digitalWrite(LED[i], LOW); // éteint
la LED
Remarquer tout l'intérêt d'utiliser un tableau de constantes pour désigner } // fin for
les broches : si votre montage est différent de celui proposé ici, vous n'avez
qu'à modifier la liste des broches au niveau de l'initialisation et tout le reste
du programme est inchangé ! } // fin de la fonction loop()

Une bonne habitude à prendre pour des programmes faciles à maintenir !


19. Afficher les segments d'un digit : le programme version améliorée
Comme on l'a déjà vu, on peut rendre un tel programme plus visuel en //--- entete déclarative
utilisant des expressions binaires pour fixer l'état des LEDs, technique que // = déclarer ici variables et constantes globales
const int LED[8] = {8,9,4,3,2,7,6,5}; // Tableau de constantes
nous avons déjà utilisée pour réaliser un jeu de lumière à 8 LEDs. « Y'a plus // --- ordre des broches : a,b,c,d,e,f,g,pt
qu'à... » :
int vitesse=1000; // variable fixant la durée de la pause
Entête déclarative
On déclare : //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

• un tableau de 8 constantes appelé LED de type int pour désigner les 7 //--- met les 8 broches en sortie ---
broches de segments ainsi que la broche du point. for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
OUTPUT); // met la broche en sortie
• une variable de type int pour fixer la vitesse, appelée vitesse } // fin for
Fonction setup() } // fin de la fonction setup()
A ce niveau, on va :
• initialiser les broches utilisées en sortie en utilisant une boucle, sous //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
la forme LED[i] où i est la variable de comptage de la boucle.
// --- ordre des broches : a,b,c,d,e,f,g,pt
Fonction loop() allumeLED(B10000000); // segt a allumeLED(B01000000);
// segt b allumeLED(B00100000); // segt c
A ce niveau on va :
allumeLED(B00010000); // segt d allumeLED(B00001000);
• à l'aide d'une boucle, allumer successivement la LED voulue. // segt e allumeLED(B00000100); // segt f
allumeLED(B00000010); // segt g allumeLED(B00000001);
• le code de la fonction loop se répète sans fin... // segt pt allumeLED(B00000000); // éteint tout
Autre fonction : fonction de gestion des LEDs } // fin de la fonction loop()
Nous allons ici encore une fois séparer le code de gestion des LEDs dans une
fonction séparée : //fonction qui reçoit une valeur de type int non signé et ne renvoie auc une valeur
void allumeLED(unsigned int valeur) { // fonction pour allumer/éteindre les LEDs voulue en
• cette fonction va recevoir la valeur binaire fonction valeur 8 bits reçue

• on défile les 8 broches et à chaque fois on met la LEDs dans l'état du for (int i=0; i<=7; i++) {
0/1 correspondant. On utilise pour cela une fonction du langage digitalWrite(LED[i],bitRead(valeur,7-i)); // met la broche LED[i]
Arduino qui permet de lire la valeur d'un bit d'une variable, dans l'état du bit de rang i de la variable
}
bitRead(valeur, bit). delay(vitesse); //pause
• puis faire une pause entre 2 appels de la fonction.
} // fin de la fonction allumeLED

Un petit défi, çà vous tente ?


A présent, vous êtes en mesure d'afficher tous les chiffres successivement...
Réfléchissez un peu avant de passer à la suite, et à vous de jouer !
Vous pensez avoir trouvé la solution...? Regardez la diapo suivante !
20. Principe d'affichage des chiffres sur un digit
A ce stade, vous devez avoir une petite idée du principe à suivre pour afficher des chiffres sur votre digit... Voici en image le principe à utiliser :

Ainsi :
• pour afficher le 1, on allumera les segments b et c, les autres restant éteints,
• pour afficher le 2, on allumera les segments a,b,d,e et g, les autres restant éteints,
• et ainsi de suite...

Avant de lire la suite, prenez un crayon et écrivez vous-mêmes toutes les séquences.... !
Faut bien que vous bossiez un peu quand même...
21. Afficher des chiffres sur un digit : 1ère version
Vous êtes prêts ? Allez, on se lance pour afficher nos chiffres sur le digit :
//--- entete déclarative
Entête déclarative // = déclarer ici variables et constantes globales
const int LED[8] = {8,9,4,3,2,7,6,5}; // Tableau de constantes
On déclare : // --- ordre des broches : a,b,c,d,e,f,g,pt
• un tableau de 8 constantes appelé LED de type int pour désigner les 7
int vitesse=1000; // variable fixant la durée de la pause
broches de segments ainsi que la broche du point.
• une variable de type int pour fixer la vitesse, appelée vitesse //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

Fonction setup() //--- met les 8 broches en sortie ---


for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
A ce niveau, on va : OUTPUT); // met la broche en sortie
• initialiser les broches utilisées en sortie en utilisant une boucle, sous } // fin for
la forme LED[i] où i est la variable de comptage de la boucle.
} // fin de la fonction setup()
Fonction loop()
A ce niveau on va : //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
• à l'aide d'une boucle, allumer successivement les LEDs voulues : // --- ordre des broches : a,b,c,d,e,f,g,pt
◦ B01100000 pour le 1 allumeLED(B11111100); // nombre 0
allumeLED(B01100000); // nombre 1
◦ B11011010 pour le 2 allumeLED(B11011010); // nombre 2
allumeLED(B11110010); // nombre 3
◦ B11110010 pour le 3 allumeLED(B01100110); // nombre 4
allumeLED(B10110110); // nombre 5
◦ etc... allumeLED(B10111110); // nombre 6
• le code de la fonction loop se répète sans fin... allumeLED(B11100000); // nombre 7
allumeLED(B11111110); // nombre 8
Autre fonction : fonction de gestion des LEDs allumeLED(B11110110); // nombre 9
allumeLED(B00000000); // éteint tout
Nous allons ici séparer le code de gestion des LEDs dans une fonction
séparée : } // fin de la fonction loop()
• cette fonction va recevoir la valeur binaire //fonction qui reçoit une valeur de type int non signé et ne renvoie auc une valeur
• on défile les 8 broches et à chaque fois on met la LEDs dans l'état du void allumeLED(unsigned int valeur) { // fonction pour allumer/éteindre les LEDs voulue en
fonction valeur 8 bits reçue
0/1 correspondant. On utilise pour cela une fonction du langage
Arduino qui permet de lire la valeur d'un bit d'une variable, for (int i=0; i<=7; i++) {
bitRead(valeur, bit). digitalWrite(LED[i],bitRead(valeur,7-i)); // met la broche LED[i]
dans l'état du bit de rang i de la variable
• puis faire une pause entre 2 appels de la fonction. }
Sympa ce petit code, non ? delay(vitesse); //pause

Bravo, vous savez afficher des chiffres sur un digit ! } // fin de la fonction allumeLED
Vous ne regarderez plus votre radio-réveil tout à fait de la même façon !
22. Pour info : Afficher des chiffres sur un digit en utilisant une fonction dédiée
A présent, on va essayer d'améliorer un petit peu çà (ben oui... on allait tout de
même pas s'arrêter en si bon chemin... ) On va écrire une fonction de la forme //--- entete déclarative
digit(chiffre,point) pour afficher le chiffre voulu sur le digit +/- le point ! // = déclarer ici variables et constantes globales
const int LED[8] = {8,9,4,3,2,7,6,5}; // Tableau de constantes
Entête déclarative // --- ordre des broches : a,b,c,d,e,f,g,pt
On déclare :
int vitesse=1000; // variable fixant la durée de la pause
• un tableau de 8 constantes appelé LED de type int pour désigner les 7
broches de segments ainsi que la broche du point. //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

• une variable de type int pour fixer la vitesse, appelée vitesse //---défile les 8 broches 0 à 7 ---
for (int i=0; i<8; i++) { // répètre 8 fois le code pinMode(LED[i],
Fonction setup() OUTPUT); // met la broche en sortie
} // fin for
A ce niveau, on va :
• initialiser les broches utilisées en sortie en utilisant une boucle, sous } // fin de la fonction setup()
la forme LED[i] où i est la variable de comptage de la boucle.
Fonction loop() //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
A ce niveau on va : //---défile les chiffres 0 à 9 ---
for (int chiffre=0; chiffre<=9; chiffre++) {
• à l'aide d'une boucle, on appelle successivement la fonction d'affichage
//digit(chiffre, true); // chiffre + point
des chiffres et du point avec les valeurs de 0 à 9 //digit(chiffre, false); // chiffre sans le point digit(chiffre, chiffre % 2 ); // chiffre
• le code de la fonction loop se répète sans fin... + le point allumé si
impair (reste=1)
Autre fonction 1: fonction de gestion des LEDs delay(vitesse); //pause
}
Nous allons ici séparer le code de gestion des LEDs dans une fonction séparée
qui va recevoir la valeur binaire : digit(-1, false); // éteint segments + point delay(vitesse);
//pause
• on défile les 8 broches et à chaque fois on met la LEDs dans l'état du
0/1 correspondant. On utilise pour cela une fonction du langage } // fin de la fonction loop()
Arduino qui permet de lire la valeur d'un bit d'une variable,
bitRead(valeur, bit). //fonction qui reçoit une valeur de type int non signé et ne renvoie auc une valeur
void allumeLED(unsigned int valeur) { // fonction pour allumer/éteindre les LEDs voulue en
• puis faire une pause entre 2 appels de la fonction. fonction valeur 8 bits reçue
Remarquer comment l'usage d'une fonction simplifie le code : for (int i=0; i<=7; i++) {
il suffit de passer la valeur et les segments voulus seront allumés. digitalWrite(LED[i],bitRead(valeur,7-i)); // met la broche LED[i]
dans l'état du bit de rang i de la variable
La plupart des instructions du langage Arduino sont des fonctions qui }
simplifient la programmation et exécutent un code sous-jacent parfois
complexe (dont vous n'avez pas à vous soucier d'ailleurs...). Tout ce qui
} // fin de la fonction allumeLED
compte pour vous, c'est qu'une fonction Arduino fasse ce qu'on attend elle
sans erreur.
« Bandes de petits veinards» je vous dis !

La fonction digit() page suivante...


23. Pour info : Afficher des chiffres sur un digit en utilisant une fonction dédiée (suite)
A présent, voyons le détail de la fonction digit() utilisée pour l'affichage des
segments et du point sur le digit :
Autre fonction 2: fonction d'affichage du chiffre et du point
Cette fonction appelée digit : //--- fonction qui reçoit chiffre à afficher et boolean pour afficher le point
void digit(int chiffreIn, boolean pointIn) {
• ne renvoie rien (=type void)
• reçoit 2 paramètres : // --- ordre des broches : a,b,c,d,e,f,g,pt
if (chiffreIn==0) allumeLED(B11111100); // nombre 0 if (chiffreIn==1)
• la valeur int à afficher allumeLED(B01100000); // nombre 1 if (chiffreIn==2)
allumeLED(B11011010); // nombre 2 if (chiffreIn==3)
• et la valeur boolean pour l'affichage du point allumeLED(B11110010); // nombre 3 if (chiffreIn==4)
• utilise une série de conditions pour tester la valeur du chiffre reçu et allumeLED(B01100110); // nombre 4 if (chiffreIn==5)
allumeLED(B10110110); // nombre 5 if (chiffreIn==6)
appelle la fonction de gestion des LEDs pour allumer les segments allumeLED(B10111110); // nombre 6 if (chiffreIn==7)
voulus, allumeLED(B11100000); // nombre 7 if (chiffreIn==8)
allumeLED(B11111110); // nombre 8 if (chiffreIn==9)
• si une valeur négative est reçue, cela éteint tous les segments. allumeLED(B11110110); // nombre 9
• si le 2ème paramètre :
if (chiffreIn<0) allumeLED(B00000000); // éteint tout si chiffre négatif
• vaut true, le point est allumé,
if (pointIn==true) digitalWrite(LED[7], HIGH); // allume point sans modifier les autres
• si il vaut false, le point est éteint. else digitalWrite(LED[7], LOW); // sinon éteint le point

Ce code vous est présenté à titre informatif pour vous montrer comment } // fin fonction digit
écrire une fonction qui reçoit 2 paramètres. Ce n'est pas grave si vous
n'arrivez pas à l'écrire par vous-mêmes : c'est un programme déjà un peu
avancé. Mais c'est une bonne façon pour vous d'apprendre !

24. Les digits en pratique


L'utilisation des digits à LEDs en pratique, c'est pas très pratique... :
Avec une carte Arduino, on pourra réaliser un montage avec 2 digits mais guère plus de façon simple : au-delà de 2 digits, la mise en oeuvre des Digits peut
être assez complexe et on utilisera alors des modules dédiés qui réalisent le multiplexage de l'affichage.
L'affichage des chiffres sur un Digit vous a été présenté à titre didactique, mais en pratique, pour afficher des valeurs numériques et même des lettres, il
vaudra mieux utiliser un afficheur LCD comme nous le verrons : le langage Arduino dispose de fonctions qui rendent très facile l'affichage des nombres et des
lettres !
Sorties numériques : découvrir et apprendre à utiliser les broches de la carte Arduino en
sorties numériques.

Arduino
3. Notion d'électronique numérique
L'électronique est une technique qui manipule les « électrons » sous forme de
tension ou d'intensité. On distingue 2 types d'électronique :
• L'électronique analogique qui utilise des variations continues de la
tension qui peut prendre toutes les valeurs intermédiaires (potentiomètre
= variation du minimum au maximum).
• L'électronique numérique qui utilise des variations « abruptes » de
la tension qui va prendre 2 niveaux (interrupteur = allumé ou éteint) :
l'un dit HAUT (5V), l'un dit BAS (0V).
Un microprocesseur, tel que celui de la carte Arduino, est un circuit numérique
qui va permettre de manipuler des niveaux HAUT/BAS.

Pour prendre une image de tuyauterie :


• L'électronique analogique est comparable à un robinet dont
l'écoulement va pouvoir varier entre l'absence d'eau et le débit maximum.
• L'électronique numérique est comparable à une vanne « tout ou
rien » qui va soit stopper l'écoulement, soit donner le débit maximum, les
écoulements intermédiaires n'étant pas possibles.
L'intérêt majeur d'utiliser 2 niveaux HAUT/BAS est de permettre :
• De compter et calculer en combinant les niveaux HAUT et BAS entre-eux :
c'est le comptage binaire, qui utilise les 0 et les 1,
• De commander / contrôler des dispositifs à partir de plusieurs niveaux
HAUT / BAS combinés entre eux,
• De communiquer des informations entre 2 circuits numériques en envoyant
des niveaux successifs de HAUT/BAS
• De numériser des signaux analogiques (conversion analogique-numérique) !
• De coder des instructions à exécuter par un microprocesseur.
4. Une broche numérique ne peut avoir que 2 états : HAUT ou BAS, « y'a ou y'a pas » !

Une broche numérique, dans un circuit numérique est un point du circuit


matérialisé par une broche métallique dans le cas d'un circuit intégré ou d'une
carte électronique.

Une broche numérique va être caractérisée par son état ou niveau de tension : elle
va pouvoir se trouver dans 2 états possibles seulement :
◦ soit au niveau HAUT (=5V), symbolisé par 1 ou HIGH
◦ soit au niveau BAS (=0V), symbolisé par 0 ou LOW
• noter qu'à un instant quelconque, la broche se trouve obligatoirement
dans l'un de ces 2 états.

Pour reprendre l'image d'une vanne « tout ou rien » :


• soit il y a de l'eau qui circule
• soit il n'y en n'a pas

Pour reprendre l'image d'un « interrupteur » :


• soit il y a de la lumière,
• soit il n'y en n'a pas...
5. Une broche numérique est caractérisée par son SENS : en SORTIE ou en ENTREE !
Une broche numérique est également caractérisée par son sens :
• la broche est dite en sortie d'un circuit numérique lorsque c'est le
circuit numérique qui contrôle l'état Haut/Bas de la broche. On
pourra symboliser le sens de la broche numérique en sortie par une flèche
sortante.
• la broche est dite en entrée d'un circuit numérique lorsque le circuit
numérique « reçoit » (ou « subit ») son état . L'état Haut/Bas de la
broche numérique est contrôlé par « l'extérieur ». On pourra
symboliser le sens de la broche numérique en entrée par une flèche
entrante.
• noter qu'une broche numérique qui est en sortie d'un circuit numérique
est en entrée du circuit extérieur auquel elle est connectée... et
inversement... !
Usage avancé : en interne, dans un microprocesseur, une broche numérique est associée :
• à un bit de donnée (case unitaire mémoire) qui va permettre de fixer/lire son
état
• à un bit de sens qui va définir son mode de fonctionnnement
Techniquement, il existe par ailleurs plusieurs technologies de broches numériques (TTL,
CMOS,..) qui ont des définitions différentes des niveaux de tension HAUT et BAS. Seules
des broches compatibles entre-elles pourront être utilisées/connectées ensemble.
Arduino est très souple de ce point de vue et est compatible avec la plupart des
technologies E/S !
6. Les broches numériques de la carte Arduino
La carte Arduino de base (la UNO, la Duemilanove, etc..) est une carte numérique
qui possède 20 broches d'Entrée/Sortie numérique (notées E/S)
numérotées de 0 à 19 !
Les broches 0 à 19 sont potentiellement utilisables en broches E/S !

Cependant, certaines broches ne doivent pas, dans la mesure du possible être


utilisées en broches E/S :
• les broches 0 et 1 sont utilisées par la communication USB donc, les
utiliser pourrait perturber cette communication. En pratique, ne pas les
utiliser.
• les broches 14 à 19 ont un double rôle : elles peuvent également être
utilisées en tant que broches analogiques pour réaliser des mesures. Donc,
si possible, ne pas les utiliser en broches numériques... mais si on est
obligé, on peut le faire !
A savoir : les broches numériques 14 à 19 sont numérotées de 0 à 5 (ou
désignées par A0, A1, A2, A3 et A5) lorsqu'elles sont utilisées en tant que
broches analogiques.

Remarquer également que la plupart des broches numériques ont des fonctions
particulières potentielles qui seront présentées au fur et à mesure de leur
utilisation. A titre indicatif, les fonctions disponibles sont la génération d'impulsion, la
communication SPI, la communication I2C, les interruptions externes...
D'un point de vue électrique, retenir que :
• chaque broche numérique E/S peut supporter 40 mA d'instensité en
sortie ou en entrée
• L'ensemble des broches numériques E/S ne doit pas dépasser 200mA en
entrée ou en sortie !
Usage avancé : pour des projets nécessitant de nombreuses broches E/S (= mal conçu?),
la carte Arduino Mega dispose de plus d'une 50aine de broches E/S !
7. Truc technique : les broches E/S de la carte Arduino sur borniers à vis avec un screwshield.... !

Bon à savoir :
Il existe des shields (carte d'extension) de la carte Arduino qui permettent de dédoubler les broches de
la carte Arduino sur des borniers à vis : les « screwchields » !
Très pratique pour finaliser des montages en « dur ».

2 exemples de « screwshields » : le Powerscrewshield de Snootlab et le un screwshield en 2 parties.


8. Les instructions du langage Arduino pour la gestion des broches numériques
On a donc vu qu'une broche numérique E/S est caractérisée par :
• son sens : ENTREE ou SORTIE
• son état : HAUT ou BAS
Fixer le sens E/S d'une broche numérique
La première instruction à connaître est l'instruction pinMode(broche, mode) qui
sert à fixer le sens (ou mode de fonctionnement) d'une broche numérique E/S
avec :
• broche : le numéro de la broche de 0 à 19
• mode : une des constantes prédéfinies suivantes : ETAT HAUT ETAT BAS
◦ OUTPUT : pour un fonctionnement en sortie BROCHE EN SORTIE
◦ INPUT : pour un fonctionnement en entrée pinMode(broche, digitalWrite (broche, digitalWrite (broche,
OUTPUT); HIGH); LOW);
• Cette fonction est à utiliser dans la fonction setup()
Fixer le niveau HAUT/BAS d'une broche numérique BROCHE EN ENTREE
Si la broche est configurée en SORTIE, on pourra contrôler son état (ou pinMode(broche, INPUT); digitalRead(broche); digitalRead(broche);
« écrire » sur la broche) à l'aide de la fonction digitalWrite (broche, etat) avec :
• broche : le numéro de broche de 0 à 19
• valeur : une des constantes prédéfinies suivantes :
◦ HIGH : pour mettre la broche au niveau HAUT (5V)
◦ LOW : pour mettre la broche au niveau BAS (0V)
Si la broche est configurée en ENTREE, on pourra « lire » son état à l'aide de
la fonction int digitalRead(broche) avec :
• broche : le numéro de broche de 0 à 19
• int : la valeur renvoyée par la fonction de type int
9. Ecrire un programme qui met une broche en sortie au niveau HAUT
Maintenant que l'on connaît les instructions de gestion des broches E/S, on est
capable d'écrire un programme pour mettre en sortie une broche et pour la mettre
au niveau HAUT. Dans notre exemple, nous utiliserons la broche 13 qui dispose
d'une LED intégrée sur la carte Arduino. Reprenons la structure type d'un
programme :
Entête déclarative
Aucune variable à déclarer ici.
Fonction setup()
A ce niveau, on va :
• initialiser la broche en sortie avec l'instruction pinMode()
• mettre la broche à HAUT avec l'instruction digitalWrite(). A noter que la
LED connectée à la broche s'allumera si le niveau est HAUT.
Fonction loop()
Laissée vide.

Voici le code complet :

//--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

pinMode(13,OUTPUT); // met la broche 13 en sortie

digitalWrite(13,HIGH); // met la broche 13 au niveau HAUT

} // fin de la fonction setup()

//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {

} // fin de la fonction loop()


10. Notion d'électricité élémentaire à bien connaître
Pour faire de l'électronique numérique avec Arduino, il n'y a pas beaucoup
de règles d'électricité à connaître, mais il y en a une qui est très importante à Exemple de fiche technique d'un moteur.
connaître (elle vous servira tout le temps !!) :
TOUT « DISPOSITIF » ELECTRIQUE SE CARACTERISE PAR 2
CHOSES :
UNE TENSION D'ALIMENTATION mesurée en VOLTS
UNE INTENSITE DE FONCTIONNEMENT mesurée en AMPERES

La règle qui lui est associée et qui est tout aussi importante :
TOUTE « ALIMENTATION » ELECTRIQUE SE CARACTERISE PAR 2
CHOSES :
UNE TENSION FOURNIE mesurée en VOLTS UNE
INTENSITE MAXIMALE mesurée en AMPERES

Ainsi, avant de connecter un dispositif sur une alimentation, il va falloir Exemple de fiche technique d'un bloc secteur
systématiquement se poser 2 questions :
• la tension fournie par l'alimentation correspond-elle à la tension
d'alimentation du dispositif ?
• l'intensité de fonctionnement du dispositif est-elle bien inférieure à
l'intensité maximale possible ?
Il faudra toujours répondre OUI à ces 2 questions. Exemples :
• puis-je connecter un appareil fonctionnant en 12V et consommant 1A sur
une prise de courant de 220V / 10A ? => NON (danger!)
• puis-je connecter un moteur fonctionnant en 6V et consommant 2A sur
un bloc secteur 6V/500mA ? => NON
• puis-je connecter une lampe consommant 5V/20mA sur une broche
pouvant fournir 5V/40mA ? => OUI
11. Notion de tension alternative, continue, régulée..

Tension alternative = celle du secteur 220V


La tension du secteur est une tension qui varie tout le temps en faisant des
« vagues » : la tension est dite sinusoïdale ou alternative.

Tension continue non régulée = celle d'un bloc secteur 12V


La plupart des dispositifs « basse tension » tels que les moteurs et autres petits
appareils alimentés par une alimentation externe (bloc secteur) utilise une
alimentation continue mais qui n'est pas parfaitement « plane » avec quelques
variations possibles autour de la tension théorique prévue.

Tension continue régulée = celle des circuits numériques


Les circuits numériques tels qu'une carte Arduino, ou la carte-mère (interne) d'un
ordinateur, utilisent et nécessitent des tensions continues PARFAITEMENT
STABLES qui sont obtenues à l'aide d'un composant appelé régulateur : ce sont
des alimentations dites régulées.
Les tensions régulées les plus utilisées en électronique numérique sont le 5V, le
12V et le 3.3V. La carte Arduino standard fonctionne en 5V régulé.

La tension Vin d'une carte Arduino pourra être de type continu régulé ou non, la carte Arduino disposant d'un régulateur 5V intégré.
12. Truc technique... : une alimentation régulée de « labo » à pas cher !

BON à savoir :
une alimentation de PC de récupération, dite alimentation ATX, est une alimentation régulée peu coûteuse (<10€) et qui fournit du 5V régulé sous
plusieurs ampères, du 12V régulé sous plusieurs ampères, et aussi du 3.3V régulé, du -12V régulé, etc.. Pratique !
A comparer à un bloc secteur 220V AC / 6-12V DC qui ne fournira que 0.5 à 1A dans le meilleur des cas, pour le même prix...
Avec çà, vous êtes sur de pouvoir alimenter tous vos projets, y compris (et surtout) si vous utilisez des moteurs ou de nombreux servomoteurs !

Pour activer l'alimentation, au niveau du connecteur ATX, il suffit de mettre un strap entre la broche verte (16) et la masse (0V - noir)
13. Caractéristiques électriques globales de la carte Arduino

La carte Arduino standard peut être alimentée de 2 façons :


• soit directement par le port USB (qui fournit 5V/500mA régulé)
• soit par une alimentation continue externe via le connecteur
d'alimentation (cette source s'appelle Vin) :
◦ tension continue, régulée ou non, entre 7 et 12V conseillé (jusqu'à 20V
maxi) (La carte Arduino dispose d'un régulateur 5V intégré)
◦ pouvant fournir au moins 500mA, ou plus...

La carte Arduino dispose de d'un connecteur d'alimentation qui fournit plusieurs


tensions :
• Vin qui est une reprise de la tension Vin connectée au connecteur
d'alimentation externe et a les mêmes caractéristiques que l'alimentation
utilisée. A noter que Vin est régulé si l'alimentation utilisée est régulée
(Alimentation de PC)
• 5V qui est du 5V régulé jusqu'à 500mA maximum, utilisable pour
alimenter les capteurs, modules utilisés avec la carte Arduino,
• 3V3 régulé jusqu'à 50mA (attention faible intensité max) et utilisable
pour alimenter certains composants nécessitant du 3V3. Peu utilisé en
pratique... mais il est là si besoin...
La tension Vin d'une carte Arduino pourra être de type continu régulé ou non, la
carte Arduino disposant d'un régulateur 5V intégré.
En pratique, pour alimenter votre carte Arduino avec une
alimentation externe, utiliser un bloc 220V => 6-12V cc /500mA ou
mieux 6-12V cc / 1A.
14. Caractéristiques électriques d'une broche Numérique Arduino en sortie
Une broche numérique Arduino individuelle en sortie peut-être considérée
comme une « mini »-alimentation :
• fournissant une tension de 5V régulé au niveau HAUT et 0V au niveau
BAS.
• pouvant fournir au maximum 40mA pour une seule broche en sortie.

Pour l'ensemble des broches numériques :


• l'intensité maximale cumulée ne doit pas dépasser les 200mA.
• Ainsi, pour éviter les soucis, dans l'hypothèse où l'on utilisera au
maximum une 15aine de broches en sortie simultanément, considérer que
l'on peut utiliser sans danger 200mA/15 = 13mA / broche soit en pratique
10 à 15mA par broche.
En pratique : considérer qu'une broche Arduino fournit 5V / 10-15mA

Voici quelques exemples, pour se faire une idée de ce que l'on peut connecter
directement sur une broche numérique d'une carte Arduino en sortie :
• une broche d'un autre CI numérique consommera dans les 1 mA, =>
connexion directe POSSIBLE !
• une LED en série avec sa résistance consommera dans les 10-20mA selon
la résistance utilisée, => connexion directe POSSIBLE !
• la broche de commande d'un servomoteur consommera dans les 5mA, =>
connexion directe POSSIBLE !
• un moteur CC consommera dans les 250mA => connexion directe
IMPOSSIBLE ! (Dans ce cas, on devra utiliser une interface de
puissance comme nous le verrons)
En pratique : TOUJOURS se demander « quelle intensité va être
utilisée ? »
15. Technique : Le schéma électrique interne de l'alimentation de la carte Arduino
Afin de comprendre ce que l'on fait, il est important d'avoir toujours à l'esprit les notions d'intensité et de tension de la carte Arduino. Comme on l'a dit, la carte
Arduino intègre une alimentation interne régulée de 5V rég / 500mA :
• soit en provenance du port USB
• soit à partir de l'alimentation Vin 7-12V / 500mA (ou +) (connecteur Jack)
Il est essentiel de distinguer :
• l'intensité maximale (200mA) que peut fournir le « coeur » de la carte Arduino et limité à 40mA par broche en sortie mais 200mA maximum
pour l'ensemble des broches réunies. Une LED en série avec une résistance utilisera par exemple 15mA fournis par le « coeur » Arduino.
• l'intensité maximale (500mA) que peut fournir l'alimentation +5V régulé/500mA. Cette alimentation de +5V/500mA de la carte Arduino
peut également être mise en parallèle avec une alimentation externe +5V régulée au besoin.
• l'intensité résiduelle disponible de 300mA supplémentaires maxi pour alimenter des dispositifs 5V directement à partir de
l'alimentation de la carte Arduino (mais pas à partir des broches !!)
16. Découvrir les composants et accessoires de base pour faire des montages avec la carte Arduino

La LED = Light Emitting Diode (ou DEL : diode électro-


luminescente)
Ce composant produit de la lumière. C'est une diode et donc a un sens de
connexion.

La résistance
Ce composant sert à limiter l'intensité, c'est à dire le nombre d'électrons qui
circulent dans le circuit. Sens de connexion indifférent. Se mesure en Ohms. Les
bandes colorées indiquent la valeur de la résistance.

Jumper ou Straps
Câble souple ou semi-rigide permettant de réaliser des connexions entre 2
composants. Existent dans différentes tailles et couleurs. Existent en Mâle/Mâle,
Femelle/Femelle, Mâle/Femelle.

Plaque d'essai ou « breadboard »


Plaque permettant de réaliser simplement des montages électroniques sans
soudure.

Il existe de quelques autres composants que vous découvrirez au fur et à mesure.


A la différence de l'électronique analogique, en électronique numérique, l'utilisation des composants peut être simplifiée au maximum.
17. Découvrir la résistance et son principe d'utilisation
La résistance est un composant qui réalise une sorte de « goulot d'étranglement »
pour les électrons : elle sert à limiter l'intensité qui circule dans le circuit.
La résistance :
• se mesure en Ohms , le symbole du Ohm est le Ω (Omega),
• cette valeur est indiquée par des bandes de couleurs présentes sur la
résistance et qui correspondent à un code de couleur,
• peut aussi être mesurée avec un Ohmètre (ou multimètre)
• n'a pas de sens de connexion particulier
• existe avec plusieurs degrés de précision (5%, 1%..) et de puissance (1/4w, Résistance de 10 x 1000 = 10 kΩ (dire « dix kilo-ome »)
1W, etc..) : en pratique on utilise des résistances carbone 5% en 1/4w
Pas besoin de retenir le code des couleurs !!
En pratique, on peut faire de l'électronique avec Arduino en n'utilisant que 3 ou
4 valeurs de résistances que l'on finit par connaître par coeur.
Nous utiliserons souvent la résistance 270 Ohms ( rouge – violet – marron )

On peut monter une résistance avec un autre composant :


• en série = à la queue leuleu
• en parallèle = côte à côte
Symbolisée par :

La relation mathématique fondamentale pour la résistance est la loi d'Ohm qui


dit que :
• la tension aux bornes de la résistance est égale à la résistance multipliée
par l'intensité,
• soit U = R x I
En pratique, vous n'avez pas besoin de savoir calculer la valeur d'une résistance
à utiliser dans un circuit, mais c'est bien si vous savez le faire...
18. Découvrir la LED et son principe d'utilisation
La LED (Light Emitting Diode) est un composant électronique qui comme tout le
monde le sait sert à produire de la lumière :
• la LED standard 5mm est de couleur rouge verte ou jaune
• la tension à ses bornes est constante à 1,5V environ lorsqu'elle est
en circuit
• son intensité de fonctionnement est de l'ordre de 20mA
• la LED est une diode : elle a donc un sens de connexion facile à repérer :
◦ sa patte courte doit être connectée vers le MOINS (à noter le méplat
en regard)
◦ sa patte longue doit être connectée vers le PLUS
Le montage type d'une LED standard en 5V consiste à :
• connecter la LED en série avec une résistance (La patte – de la LED devra
être tournée vers le - )
• la résistance a pour but de limiter l'intensité. Utiliser une valeur entre 200
et 300 Ohms. En pratique, j'utilise 270 Ohms / ¼ de watt.
Symbolisée par :

Pour les matheux ( on est pas du tout obligé de savoir faire ce calcul !) :
• aux bornes de la LED, la tension vaut 1,5V environ (fixe)
• la tension aux bornes de la résistance en série avec la LED, dans le cas
d'une alimentation en 5V, vaudra donc 5V-1,5V = 3.5V
• si on désire une intensité de 13mA dans la LED, on utilisera, d'après la loi
d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.
19. Principe d'utilisation d'une plaque d'essai (ou « breadboard »)
Pour réaliser des montages électroniques sans soudure, on va utiliser ce que l'on appelle une « plaque d'essai » ou « breadboard » en anglais. Une fois que l'on
a compris comment utiliser cette plaque, on pourra réaliser facilement toutes sortes de montages associés ou non à la carte Arduino.

Une bonne habitude :


Mettez le bus bleu adjacent à la zone de montage en bas et le bus rouge adjacent à la zone de montage en haut.
De cette façon, la transposition du schéma théorique en montage réel sera plus évidente.
20. Truc pratique : préparer ses composants pour une utilisation facilitée avec la plaque d'essai
Préparer une résistance Préparer une LED

Courber une patte :

Courber légèrement la patte longue de façon à obtenir la même longueur pour les
2 pattes :
Couper les 2 pattes à la même longeur :

Ainsi, la LED sera très facile à utiliser sur une plaque d'essai :

La résistance s'utilisera très simplement sur la plaque d'essai :


21. Un exemple de montage simple sur une plaque d'essai : à vous de jouer !
Dans ce montage très simple, on va monter une LED en série avec une résistance entre le 0 et le 5V. On utilisera ici le 0V et le 5V de la carte Arduino pour
alimenter la plaque d'essai. Une fois fait, la LED doit être allumée.
Votre premier montage sur plaque d'essai : la LED s'allume ? Bravo !
22. Truc technique : rendre définitif un montage sur plaque d'essai avec un proto-shield.... !

Bon à savoir :

Tous les montages que vous réaliserez sur plaque d'essai (et donc transitoires) peuvent être facilement rendus définitifs au besoin grâce au « proto-shield » ou
shield de prototypage. Ce shield (ou carte d'extension) s'insèrera broche à broche sur la carte Arduino et dispose d'une zone de pastilles à souder équivalentes à
une plaque d'essai.

Un montage que vous avez envie de rendre définitif : soudez-le sur un protoshield (de 10 à 15€ selon modèle) !

Protoshield Arduino Power Screwshield (Snootlab)


23. Faire clignoter une LED : Le montage.
A présent, votre premier montage avec la carte Arduino ne devrait pas vous poser
de problème.
Pour faire clignoter une LED, on va connecter une LED en série avec une
résistance sur une broche E/S de la carte Arduino en sortie. Le principe sera le
suivant :
• lorsque la broche sera au niveau HAUT, la LED sera allumée,
• lorsque la broche sera au niveau BAS, la LED sera éteinte.

Comme vu précédemment, si on désire une intensité de 13mA dans la LED, on


utilisera, d'après la loi d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.
24. Faire clignoter une LED : Le programme.
A présent, nous allons ré-écrire par nous mêmes le fameux programme « Blink »
qui fait clignoter une LED. Avec tout ce que vous savez, cela ne devrait pas vous
poser de problème :
Entête déclarative
Aucune variable à déclarer ici.
//--- entete déclarative
Fonction setup() // = déclarer ici variables et constantes globales
A ce niveau, on va :
//--- la fonction setup() : exécutée au début et 1 seule fois pinMode(2, OUTPUT);
• initialiser la broche utilisée en sortie (la broche 2) avec l'instruction
void setup() {
pinMode()
// met la broche en sortie
Fonction loop()
A ce niveau on va : } // fin de la fonction setup()
• Allumer la LED = mettre la broche 2 au niveau HAUT (5V) avec
l'instruction digitalWrite() //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
• Attendre 1 seconde (=1000 millisecondes) avec l'instruction delay()
digitalWrite(2,HIGH); // allume la LED
• Eteindre la LED = mettre la broche 2 au niveau BAS (0V) avec
l'instruction digitalWrite() digitalWrite(2,LOW);
delay(1000); // pause // éteintseconde
d'une la LED
delay(1000); // pause d'une seconde
• Attendre 1 seconde (1000 millisecondes) avec l'instruction delay()
} // fin de la fonction loop()
• le code de la fonction loop se répète sans fin...

A vous de jouer (la solution suit...) :


faire la même chose en utilisant une constante pour désigner la broche et une
variable pour la vitesse de clignotement
25. Prendre de bonnes habitudes : nommer les broches et utiliser des variables globales !
Ok, alors cette fois on va reprendre le même programme mais en utilisant :
• une constante pour désigner la broche
• et une variable pour fixer la vitesse de clignotement.
//--- entete déclarative
Entête déclarative // = déclarer ici variables et constantes globales
On déclare :
const int LED=2; // constante désignant la broche de la LED
• une constante de type int pour désigner la broche 2, appelée LED int vitesse=250; // variable fixant la durée de la pause en ms
• une variable de type int pour fixer la vitesse, appelée vitesse //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
Fonction setup() pinMode(LED, OUTPUT); // met la broche en sortie
A ce niveau, on va :
} // fin de la fonction setup()
• initialiser la broche utilisée en sortie (avec la constante LED) avec
l'instruction pinMode()
//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
Fonction loop()
A ce niveau on va : digitalWrite(LED,HIGH); // allume la LED delay(vitesse); //
pause de n millisecondes digitalWrite(LED,LOW); // éteint
• Allumer la LED = mettre la broche au niveau HAUT (5V) avec la LED delay(vitesse); // pause de n millisecondes
l'instruction digitalWrite()
} // fin de la fonction loop()
• Attendre le temps voulu (= la valeur de la variable vitesse en
millisecondes)
// NB : les lignes précédées de // sont des commentaires
• Eteindre la LED = mettre la broche au niveau BAS (0V)
• Attendre le temps voulu (= la valeur de la variable vitesse en
millisecondes) avec l'instruction delay()
• le code de la fonction loop se répète sans fin...
En pratique, pour écrire des programmes « propres » : Renommer vos
broches dans l'entête déclarative avec des constantes ! Pour toutes les
valeurs qui reviennent souvent, utiliser des variables !

Note : En utilisant des constantes pour désigner les broches, les programmes sont plus simples à modifier et la fonction des broches est plus
claire ! Vos codes sont également plus faciles à réutiliser dans un autre programme ou une fonction.
26. Faire clignoter 4 LEDs : le montage
Pour faire clignoter 4 LEDs, on va connecter 4 LEDs chacune en série avec une
résistance sur 4 broche E/S de la carte Arduino configurées en sortie. Le principe
sera le suivant :
• lorsque la broche sera au niveau HAUT, la LED sera allumée,
• lorsque la broche sera au niveau BAS, la LED sera éteinte.

Comme vu précédemment, si on désire une intensité de 13mA dans la LED, on


utilisera, d'après la loi d'ohm, une résistance de R=U/I = 3,5V/0,013A= 270 Ohms.
27. Faire clignoter 4 LEDs : le programme
Ok, alors cette fois on va reprendre le même programme mais en réalisant
quelques adaptations : //--- entete déclarative
// = déclarer ici variables et constantes globales
• une constante pour désigner chaque broche
const int LED1=2; // constante désignant la broche de la LED const int LED2=3;
• et une variable pour fixer la vitesse de clignotement. // constante désignant la broche de la LED const int LED3=4; // constante
désignant la broche de la LED const int LED4=5; // constante désignant la
Entête déclarative broche de la LED
On déclare :
int vitesse=1000; // variable fixant la durée de la pause
• 4 constantes de type int pour désigner les broches 2,3,4 et 5, appelées
LED1, LED2,LED3,LED4. //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

• une variable de type int pour fixer la vitesse, appelée vitesse pinMode(LED1, OUTPUT); // met la broche en sortie
pinMode(LED2, OUTPUT); // met la broche en sortie
Fonction setup() pinMode(LED3, OUTPUT); // met la broche en sortie
A ce niveau, on va : pinMode(LED4, OUTPUT); // met la broche en sortie

• initialiser les broches utilisées en sortie (avec les constantes LED1, } // fin de la fonction setup()
LED2, LED3, LED4)
Fonction loop() //--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
A ce niveau on va : digitalWrite(LED1,HIGH); // allume la LED
digitalWrite(LED2,HIGH); // allume la LED
• Allumer les LEDs = mettre les broches au niveau HAUT (5V) digitalWrite(LED3,HIGH); // allume la LED
• Attendre le temps voulu (= la valeur de la variable vitesse en digitalWrite(LED4,HIGH); // allume la LED
millisecondes)
delay(vitesse); // pause de n millisecondes
• Eteindre les LEDs = mettre les broches au niveau BAS (0V)
digitalWrite(LED1,LOW); // éteint la LED
• Attendre le temps voulu (= la valeur de la variable vitesse en
digitalWrite(LED2,LOW); // éteint la LED
millisecondes) digitalWrite(LED3,LOW); // éteint la LED
• le code de la fonction loop se répète sans fin... digitalWrite(LED4,LOW); // éteint la LED

Apprenez à « penser » le déroulement de votre code : delay(vitesse); // pause de n millisecondes


Ici, les 4 LEDs sont allumées successivement mais c'est tellement rapide que
} // fin de la fonction loop()
c'est instantané, quasi-simultané. Retenez que le microprocesseur va très
vite.
28. Déclarer un tableau de variables
Imaginez maintenant que l'on veuille non pas 4, mais 8 LEDs : le code va
sensiblement s'alourdir. D'où l'idée de pouvoir simplement « répéter » pour
chaque variable le même code. Ceci sera rendu possible grâce à une boucle comme
on va le voir.

Mais pour parcourir une liste de variables à l'aide d'une boucle, il faut au
préalable créer un tableau de variables. Le principe : toutes les variables ont le
même nom,
le nom du tableau, mais sont numérotées de 0 à n-1 dans le tableau.
Exemple
Indice d'un0tableau appelé LED désignant les broches 2 à 9 :
1 2 3 4 5 6 7
Variable LED[0] LED[1] LED[2] LED[3] LED[4] LED[5] LED[6] LED[7]
Valeur 2 3 4 5 6 7 8 9

Par exemple, si on déclare un tableau de 8 variables LED :


• on déclarera un tableau de 8 variables appelé LED en faisant int LED[8]
(pour un tableau de constantes, idem avec const avant)
• on initialise le tableau sous la forme {2, 3,4,5,6,7,8,9} (On doit initialiser
autant de valeurs qu'il y a de variables !) Exemples
• chaque élément du tableau sera accessible sous la forme LED[i] où i est
l'indice dans le tableau.
• Ainsi, LED[0] sera la première variable, LED[1] la 2ème, etc... BIEN
NOTER LE DECALAGE -1: 1er élément a l'index 0, etc.. !

Ne pas oublier : la première variable d'un tableau a l'indice 0, la


2ème, l'indice 1... la n-ième, l'indice n-1
29. Faire clignoter 4 LED en utilisant un tableau de constantes
Cette fois on va reprendre le même programme mais en utilisant, comme nous
venons de le voir, un tableau de constantes pour désigner les broches :
//--- entete déclarative
• un tableau de 4 constantes pour désigner les 4 broches // = déclarer ici variables et constantes globales

• et une variable pour fixer la vitesse de clignotement. const int LED[4] = {2,3,4,5}; // Tableau de constantes
Entête déclarative int vitesse=1000; // variable fixant la durée de la pause
On déclare :
• un tableau de 4 constantes appelé LED de type int pour désigner les //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
broches 2,3,4 et 5.
pinMode(LED[0], OUTPUT); // met la broche en sortie
• une variable de type int pour fixer la vitesse, appelée vitesse pinMode(LED[1], OUTPUT); // met la broche en sortie
Fonction setup() pinMode(LED[2], OUTPUT); // met la broche en sortie
A ce niveau, on va :
pinMode(LED[3], OUTPUT); // met la broche en sortie
• initialiser les broches utilisées en sortie (avec les constantes LED[0],
LED[1], LED[2], LED[3]) } // fin de la fonction setup()

Fonction loop()
//--- la fonction loop() : exécutée ensuite en boucle sans fin void loop() {
A ce niveau on va :
• Allumer les LEDs = mettre les broches au niveau HAUT (5V) digitalWrite(LED[0],HIGH); // allume la LED
digitalWrite(LED[1],HIGH); // allume la LED
• Attendre le temps voulu (= la valeur de la variable vitesse en digitalWrite(LED[2],HIGH); // allume la LED
millisecondes)
• Eteindre les LEDs = mettre ea broches au niveau BAS (0V) digitalWrite(LED[3],HIGH); // allume la LED
• Attendre le temps voulu (= la valeur de la variable vitesse en
delay(vitesse); // pause de n millisecondes
millisecondes) digitalWrite(LED[1],LOW); // éteint la LED
• le code de la fonction loop se répète sans fin... digitalWrite(LED[0],LOW); // éteint la LED
digitalWrite(LED[3],LOW); // éteint la LED
En utilisant un tableau de variables pour désigner un ensemble de broches : on digitalWrite(LED[2],LOW); // éteint la LED
simplifie et on allège d'une part le code et on permet de plus une adaptation
simplifiée du programme, seule la ligne d'initialisation du tableau des broches
utilisées étant à modifier si on change de broches !

delay(vitesse); // pause de n millisecondes

} // fin de la fonction loop()


Broches numériques en entrée : utiliser le bouton poussoir.

Ateliers Arduino
3. Rappel : Une broche numérique ne peut avoir que 2 états : HAUT ou BAS, « y'a ou y'a pas » !
Une broche numérique, dans un circuit numérique est un point du circuit
matérialisé par une broche métallique dans le cas d'un circuit intégré ou d'une
carte électronique.

Une broche numérique va être caractérisée par son état ou niveau de tension :
elle va pouvoir se trouver dans 2 états possibles seulement :
• soit au niveau HAUT (=5V), symbolisé par 1 ou HIGH
• soit au niveau BAS (=0V), symbolisé par 0 ou LOW
• noter qu'à un instant quelconque, la broche se trouve obligatoirement
dans l'un de ces 2 états.

Pour reprendre l'image d'une vanne « tout ou rien » :


• soit il y a de l'eau qui circule
• soit il n'y en n'a pas

Pour reprendre l'image d'un « interrupteur » :


• soit il y a de la lumière,
• soit il n'y en n'a pas...
4. Rappel : Une broche numérique est caractérisée par son SENS : en SORTIE ou en ENTREE !
Une broche numérique est également caractérisée par son sens :
• la broche est dite en sortie d'un circuit numérique lorsque c'est le
circuit numérique qui contrôle l'état Haut/Bas de la broche.
On pourra symboliser le sens de la broche numérique en sortie par
une flèche sortante.
• la broche est dite en entrée d'un circuit numérique lorsque le circuit
numérique « reçoit » (ou « subit ») son état . L'état Haut/Bas de la
broche numérique est contrôlé par « l'extérieur ». On pourra
symboliser le sens de la broche numérique en entrée par une flèche
entrante.
• noter qu'une broche numérique qui est en sortie d'un circuit
numérique est en entrée du circuit extérieur auquel elle est
connectée... et inversement... !
Usage avancé : en interne, dans un microprocesseur, une broche numérique
est associée :
• à un bit de donnée (case unitaire mémoire) qui va permettre de fixer/lire
son état
• à un bit de sens qui va définir son mode de fonctionnnement
Techniquement, il existe par ailleurs plusieurs technologies de broches numériques
(TTL, CMOS,..) qui ont des définitions différentes des niveaux de tension HAUT et
BAS. Seules des broches compatibles entre-elles pourront être utilisées/connectées
ensemble. Arduino est très souple de ce point de vue et est compatible avec la
plupart des technologies E/S !
5. Rappel : Les broches numériques de la carte Arduino
La carte Arduino de base (la UNO, la Duemilanove, etc..) est une carte
numérique qui possède 20 broches d'Entrée/Sortie numérique (notées
E/S) numérotées de 0 à 19 !
Les broches 0 à 19 sont potentiellement utilisables en broches E/S
!

Cependant, certaines broches ne doivent pas, dans la mesure du possible être


utilisées en broches E/S :
• les broches 0 et 1 sont utilisées par la communication USB donc, les
utiliser pourrait perturber cette communication. En pratique, ne pas
les utiliser.
• les broches 14 à 19 ont un double rôle : elles peuvent également être
utilisées en tant que broches analogiques pour réaliser des mesures.
Donc, si possible, ne pas les utiliser en broches numériques... mais si
on est obligé, on peut le faire !
A savoir : les broches numériques 14 à 19 sont numérotées de 0 à 5 (ou
désignées par A0, A1, A2, A3 et A5) lorsqu'elles sont utilisées en tant que
broches analogiques.

Remarquer également que la plupart des broches numériques ont des


fonctions particulières potentielles qui seront présentées au fur et à mesure de
leur utilisation. A titre indicatif, les fonctions disponibles sont la génération
d'impulsion, la communication SPI, la communication I2C, les interruptions
externes...
D'un point de vue électrique, retenir que :
• chaque broche numérique E/S peut supporter 40 mA d'instensité en
sortie ou en entrée
• L'ensemble des broches numériques E/S ne doit pas dépasser 200mA
en entrée ou en sortie !
Usage avancé : pour des projets nécessitant de nombreuses broches E/S (=
mal conçu?), la carte Arduino Mega dispose de plus d'une 50aine de broches
E/S !
6. Truc technique : les broches E/S de la carte Arduino sur borniers à vis avec un screwshield.... !

Bon à savoir :
Il existe des shields (carte d'extension) de la carte Arduino qui permettent de dédoubler les broches de
la carte Arduino sur des borniers à vis : les « screwchields » !
Très pratique pour finaliser des montages en « dur ».

2 exemples de « screwshields » : le Powerscrewshield de Snootlab et le un screwshield en 2 parties.


7. Rappel: Les instructions du langage Arduino pour la gestion des broches numériques
On a donc vu qu'une broche numérique E/S est caractérisée par :
• son sens : ENTREE ou SORTIE
• son état : HAUT ou BAS
Fixer le sens E/S d'une broche numérique
La première instruction à connaître est l'instruction pinMode(broche, mode) qui
sert à fixer le sens (ou mode de fonctionnement) d'une broche numérique E/S
avec :
• broche : le numéro de la broche de 0 à 19
• mode : une des constantes prédéfinies suivantes : ETAT HAUT ETAT BAS
• OUTPUT : pour un fonctionnement en sortie BROCHE EN SORTIE
• INPUT : pour un fonctionnement en entrée pinMode(broche, digitalWrite (broche, digitalWrite (broche,
OUTPUT); HIGH); LOW);
• Cette fonction est à utiliser dans la fonction setup()
Fixer le niveau HAUT/BAS d'une broche numérique BROCHE EN ENTREE
Si la broche est configurée en SORTIE, on pourra contrôler son état (ou pinMode(broche, INPUT); digitalRead(broche); digitalRead(broche);
« écrire » sur la broche) à l'aide de la fonction digitalWrite (broche, etat) avec :
• broche : le numéro de broche de 0 à 19
• valeur : une des constantes prédéfinies suivantes :
• HIGH : pour mettre la broche au niveau HAUT (5V)
• LOW : pour mettre la broche au niveau BAS (0V)
Si la broche est configurée en ENTREE, on pourra « lire » son état à l'aide de
la fonction int digitalRead(broche) avec :
• broche : le numéro de broche de 0 à 19
• int : la valeur renvoyée par la fonction de type int
8. Découvrir le bouton poussoir
Description Principe d'utilisation sur une plaque d'essai
Le bouton poussoir est un composant très simple : il s'agit d'un contacteur Le bouton poussoir s'enfiche à cheval entre 2 colonnes sur la plaque d'essai, le
déclenché par l'appui sur un bouton : « plat » des broches tourné vers le bus d'alimentation : lorsque l'on appuie sur
• lorsque le bouton est appuyé, le contact est établi et le courant passe. le bouton poussoir, le contact est établi entre les 2 colonnes.
• lorsque le bouton est relâché, le contact n'est pas établi et le courant
ne passe pas.
Un bouton poussoir miniature dipose de 4 broches typiquement qui sont
connectées 2 à 2 : à l'appui, le contact est établi entre les 2 broches « à plat
» lorsque le bouton est tourné vers soi.

Schéma théorique
Le schéma théorique du bouton poussoir est très simple : Pour utiliser facilement le bouton poussoir sur une plaque d'essai, il peut
être utile d'aplatir légèrement les pattes avec une pince de façon à ce qu'il
s'insère facilement sur la plaque d'essai.
9. Principe d'utilisation d'un bouton poussoir avec une carte Arduino : notion de « rappel au plus ».
Principe général La solution : une résistance de « rappel au plus »
Comme on l'a déjà dit, une broche numérique utilisée en entrée va permettre Vous comprenez que dans ces conditions, il sera impossible d'analyser l'état de
de « lire » l'état de la broche. la broche numérique en entrée !!
D'où l'idée, très simple, de connecter un bouton poussoir entre la broche en Pour contourner ce problème, on « attache » au +5V (ou au 0V) la broche
entrée et le 0V afin d'interagir avec la carte Arduino. numérique en entrée à l'aide d'une résistance assez élevée, de l'ordre de
Ainsi : 10KOhms (la valeur exacte n'a pas grande importance, seul l'ordre de
grandeur est à respecter...) : on appelle cela le « rappel au plus ».
• lorsque le bouton est appuyé, le contact est établi et la broche sera
connectée au 0V. Du coup, lorsque la broche ne sera pas connectée, elle sera parfaitement
maintenue à 5V et l'enregistrement de la broche non-connectée deviendra :
• lorsque le bouton est relâché, le contact n'est pas établi et la broche ne
sera pas connectée au 0V
Etat d'une broche numérique en entrée non connectée...
Si vous êtes attentif, vous allez vous poser cette question : « dans quel état sera
la broche numérique en entrée lorsqu'elle ne sera connectée à rien, c'est à dire
lorsque le bouton poussoir sera relâché ? »
En effet, lorsque le bouton poussoir est relâché, la broche numérique en entrée
restera non connectée et lorsque Arduino lira son état, quel sera-t-il ?? On
pourrait intuitivement penser que dans ce cas la broche sera à 1... En fait, dans
cette situation, la broche va se comporter comme une petite antenne... et va Truc : Utiliser les résistances de « rappel au plus » internes
osciller en permanence au gré des interférences électro-magnétiques Les concepteurs de microprocesseur savent que vous allez utiliser un bouton
ambiantes. Si on enregistrait l'état de la broche, on obtiendrait quelque chose poussoir sur une broche en entrée et pour résoudre ce problème, ils ont prévus
comme çà : en interne des résistances de rappel au plus (ou pull-up) internes. Arduino
dispose de telles résistances : elles pourront être activée par le programme.
10. Broche ES en entrée : utiliser un bouton poussoir : Le montage
Le montage à réaliser pour utiliser un bouton poussoir avec la carte Arduino
est simple si l'on utilise les résistances de rappel au plus internes comme on va
le faire ici.
Il suffit donc de connecter le bouton poussoir (BP) d'une part au 0V et d'autre
part à la broche numérique voulue de la carte Arduino selon :

Noter que la résistance interne est représentée ici en grisé.


A noter : il est déconseillé d'utiliser la broche 13 en entrée en
Il est tout à fait possible de réaliser le même montage en externe mais cela
raison de la présence d'une LED et de sa résistance attachées à
surcharge vite le câblage. cette broche sur la carte Arduino.
11. Notion de rebond et de pause anti-rebond
Pour comprendre Le problème...
Lorsque l'on appuie sur un bouton poussoir, au niveau microscopique, le On comprend aisément ici le problème rencontré : alors que l'on aura appuyé
contact n'est pas immédiat. Tout se passe un peu comme une balle qui qu'une seule fois sur le bouton, et que l'on s'attend à ce qu'il soit considéré
rebondit avant de rester posée au sol : lorsque l'on appuie sur le bouton comme appuyé 1 seule fois, la broche numérique en entrée va changer d'état à
poussoir, le contact « rebondit » à plusieurs reprises avant d'être permanent. plusieurs reprises se comportant comme si le bouton avait été appuyé puis
relâché à plusieurs reprises... c'est l'effet rebond.
En pratique, utiliser une pause anti-rebond
Pour contourner ce problème, on va utiliser ce que l'on appelle une pause anti-
rebond :
• on prendra en compte uniquement le premier changement d'état de la
broche numérique connectée au bouton poussoir
• puis on ne lira pas l'état de la broche pendant un certain
délai (c'est la pause « anti-rebond »), de l'ordre que 100ms par
exemple, de façon à laisser le temps au bouton poussoir de se
stabiliser
D'un point de vue électrique, si on enregistrait ce qui se passe lorsque l'on • puis on lira à nouveau l'état du bouton poussoir...
appuie sur un bouton poussoir, on aurait quelque chose comme çà :
• et ainsi de suite.
De cette façon, les changements ne seront bel et bien pris en compte qu'une
seule fois et le rebond sera ignoré.

La broche connectée au bouton poussoir passerait une première fois à l'état


BAS puis redeviendrait HAUT (rebond) puis à nouveau BAS puis HAUT
(rebond) et ainsi de suite avant de se stabiliser pour rester BAS en
permanence.
12. Broche ES en entrée : Visualiser l'appui sur un bouton poussoir dans le Terminal Série
Nous allons commencer par un programme très simple mais qui va nous
permettre d'apprendre à utiliser un bouton poussoir : nous allons visualiser les
appuis sur un bouton poussoir par un message dans le Terminal Série.
Entete déclarative
On va déclarer à ce niveau :
• 1 constante désignant la broche utilisée, appelée ici BP
• 1 constante int appelée APPUI et initialisée à 0. //---entete déclarative = déclarer ici variables et constantes globales
Fonction setup() const int BP=2; // broche su BP
• On initialise la communication série à 115200 bauds avec l'instruction
[Link](debit) const int APPUI=0; // constante valeur broche à l'appui sur BP

• on configure la broche en entrée avec l'instruction pinMode(broche, //---lafonctionsetup():exécutéeaudébutet1seulefois void setup() {


INPUT)
[Link](115200); // vitesse communication série
• ON ACTIVE LE « RAPPEL AU PLUS » interne de la broche en
écrivant la valeur HIGH sur la broche, bien qu'elle ait été pinMode(BP, INPUT); // broche en entrée
configurée en entrée.
digitalWrite(BP, HIGH); // ACTIVATION DU RAPPEL AU PLUS INTERNE de la broche
Fonction loop() en entrée

• À l'aide d'une condition if() on teste si le bouton poussoir est bien }// fin de la fonction setup()
appuyé en lisant son état avec la fonction digitalRead()
• Si le bouton poussoir est bien appuyé : //---lafonctionloop():exécutéeensuiteenbouclesansfin void loop() {
◦ on envoie un message sur le port Série if(digitalRead(BP)==APPUI) { // si appui [Link]("Appui sur Bouton
◦ on réalise une courte pause anti-rebond Poussoir !"); // message delay(250); // pause anti-rebond
}// fin if
A RETENIR : ON ACTIVE LE « RAPPEL AU PLUS » interne d'une broche
configurée en entrée en écrivant la valeur HIGH sur la broche, bien
qu'elle soit configurée en entrée.
}// fin de la fonction loop()
13. Utiliser un bouton poussoir et une LED : le montage.
Le montage à réaliser pour utiliser un bouton poussoir et une LED avec la
carte Arduino consiste à combiner le montage d'un bouton poussoir et d'une
LED : vous savez faire !
14. Un BP et une LED : La LED reflète l'état du BP
Cette fois, nous allons écrire un programme de façon à ce que la LED soit à
tout moment dans l'état du bouton poussoir. Rien de très compliqué. // --- Déclaration des constantes ---
const int APPUI=0; // constante état du BP - appui sur niveau bas
Entete déclarative
const int BP=2; //declaration constante de broche const int LED=3;
On va déclarer à ce niveau : //declaration constante de broche
• 1 constante désignant la broche utilisée pour la LED, appelée ici LED // --- Déclaration des variables globales ---
• 1 constante désignant la broche utilisée pour le bouton poussoir,
int ETAT_BP=0; // variable état BP
appelée ici BP
• 1 constante int appelée APPUI et initialisée à 0. // La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du
programme
• 1 variable int pour mémoriser l'état du BP
void setup() { // debut de la fonction setup()
Fonction setup()
• on configure la broche de la LED en sortie avec l'instruction // -------Broches en sortie ------- pinMode(LED, OUTPUT); //met
la broche en sortie
pinMode(broche, OUTPUT)
• on configure la broche du bouton poussoir en entrée avec l'instruction // -------Broches en entrée ------- pinMode(BP, INPUT); //met
la broche en entree
pinMode(broche, INPUT)
• ON ACTIVE LE « RAPPEL AU PLUS » interne de la broche en // -------Activation du rappel au + interne des broches en entrée si nécessaire -------
écrivant la valeur HIGH sur la broche, bien qu'elle ait été digitalWrite(BP, HIGH) ; // activation du pullup de la broche en entrée
configurée en entrée. }// fin de la fonction setup()
Fonction loop()
• À l'aide d'une condition if() on teste si le bouton poussoir est bien // la fonction loop() s'exécute sans fin en boucle
appuyé en lisant son état avec la fonction digitalRead()
void loop(){ // debut de la fonction loop()
• Si le bouton poussoir est bien appuyé :
// lire l'état du BP et mémoriser la valeur
◦ on allume la LED ETAT_BP=digitalRead(BP);
◦ sinon, on éteint la LED
// tester l'état du BP mémorisé et allumer la LED si appuyé if
◦ on réalise une courte pause anti-rebond (pas indispensable ici) (ETAT_BP==APPUI){ // si BP appuyé

digitalWrite (LED,1); // allume la LED

}// fin if

//.. sinon éteindre la LED


else { // sinon = BP obligatoirement relâché car seulement 2 états possibles
digitalWrite (LED,0); //éteint la LED
}

}// fin de la fonction loop() - le programme recommence au début de la fonction loop sans
fin
15. Un BP et une LED : le BP en minuteur
Elaborons un petit peu ce programme de façon à ce qu'un appui sur le bouton
// --- Déclaration des constantes ---
poussoir allume la LED un certain temps puis l'éteigne à la façon d'une
const int APPUI=0; // constante état du BP - appui sur niveau bas
minuterie.
Entete déclarative const int BP=2; //declaration constante de broche const int LED=3;
//declaration constante de broche
On va déclarer à ce niveau :
// --- Déclaration des variables globales ---
• 1 constante désignant la broche utilisée pour la LED, appelée ici LED
int etatLED=0; // variable état BP
• 1 constante désignant la broche utilisée pour le bouton poussoir,
appelée ici BP // La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du
• 1 constante int appelée APPUI et initialisée à 0. programme

Fonction setup() void setup() { // debut de la fonction setup()

• on configure la broche de la LED en sortie avec l'instruction // -------Broches en sortie ------- pinMode(LED, OUTPUT); //met
pinMode(broche, OUTPUT) la broche en sortie
• on configure la broche du bouton poussoir en entrée avec l'instruction // -------Broches en entrée ------- pinMode(BP, INPUT); //met
pinMode(broche, INPUT) la broche en entree
• ON ACTIVE LE « RAPPEL AU PLUS » interne de la broche en // -------Activation du rappel au + interne des broches en entrée si nécessaire -------
écrivant la valeur HIGH sur la broche, bien qu'elle ait été digitalWrite(BP, HIGH) ; // activation du pullup de la broche en entrée
configurée en entrée.
}// fin de la fonction setup()
Fonction loop()
• À l'aide d'une condition if() on teste si le bouton poussoir est bien // la fonction loop() s'exécute sans fin en boucle
appuyé en lisant son état avec la fonction digitalRead()
void loop(){ // debut de la fonction loop()
• Si le bouton poussoir est bien appuyé :
◦ on allume la LED avec l'instruction digitalWrite(broche, HIGH) if (digitalRead(BP)==APPUI) { // si le BP est appuyé

◦ puis on réalise une pause de durée voulue à l'aide de l'instruction digitalWrite(LED,HIGH); //allume la LED
delay(duree) delay (5000); // attend 5 secondes- le BP est inactif pendant ce temps digitalWrite
(LED,LOW); // éteint la LED

}// fin si BP appuyé

}// fin de la fonction loop() - le programme recommence au début de la fonction loop sans
fin
16. Un BP et une LED : l'appui sur le BP inverse la LED
A présent, nous allons écrire un programme de façon à ce qu'un appui sur
le bouton poussoir inverse l'état de la LED. // --- Déclaration des constantes ---
const int APPUI=0; // constante état du BP - appui sur niveau bas
Entete déclarative
const int BP=2; //declaration constante de broche const int LED=3;
On va déclarer à ce niveau : //declaration constante de broche
• 1 constante désignant la broche utilisée pour la LED, appelée ici LED // --- Déclaration des variables globales ---
• 1 constante désignant la broche utilisée pour le bouton poussoir,
int etatLED=0; // variable état BP
appelée ici BP
• 1 constante int appelée APPUI et initialisée à 0. // La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du
programme
• 1 variable int pour mémoriser l'état de la LED.
void setup() { // debut de la fonction setup()
Fonction setup()
• on configure la broche de la LED en sortie avec l'instruction // -------Broches en sortie ------- pinMode(LED, OUTPUT); //met
la broche en sortie
pinMode(broche, OUTPUT)
• on configure la broche du bouton poussoir en entrée avec l'instruction // -------Broches en entrée ------- pinMode(BP, INPUT); //met
la broche en entree
pinMode(broche, INPUT)
• ON ACTIVE LE « RAPPEL AU PLUS » interne de la broche en // -------Activation du rappel au + interne des broches en entrée si nécessaire -------
digitalWrite(BP, HIGH) ; // activation du pullup de la broche en entrée
écrivant la valeur HIGH sur la broche, bien qu'elle ait été
configurée en entrée. }// fin de la fonction setup()
Fonction loop()
• À l'aide d'une condition if() on teste si le bouton poussoir est bien // la fonction loop() s'exécute sans fin en boucle
appuyé en lisant son état avec la fonction digitalRead() void loop(){ // debut de la fonction loop()
• Si le bouton poussoir est bien appuyé, on inverse l'état de la LED par
un jeu de condition testant la variable d'état de la LED. if (digitalRead(BP)==APPUI) { // si appui sur le BP

if (etatLED==0) etatLED=1; else etatLED=0; // inverse la variable etatLED


delay(250); // pause anti-rebond
}

//metlaLEDdansl'étatdelavariableetatLED
if (etatLED==1) { // si la variable vaut 1
digitalWrite(LED,HIGH); // la LED est allumée
}
else { // sinon, càd si la variable vaut 0
digitalWrite(LED,LOW); // la LED est éteinte
}

}// fin de la fonction loop() - le programme recommence au début de la fonction loop sans
fin
17. Utiliser 3 boutons poussoir : le montage
Une situation beaucoup plus utile en pratique : utiliser 3 boutons poussoir,
typiquement l'un +, l'autre – et le 3ème OK. Ceci permet de réaliser des
réglages de valeur notamment.

Le montage est une réplication x3 du montage avec un bouton poussoir :


18. BP x 3 : incrémenter/décrémenter une variable avec affichage série
Une des utilisations les plus utiles des boutons poussoirs est le réglage de
valeurs : avec 3 BP, on peut augmenter (ou incrémenter), diminuer (ou //---Déclarationdesconstantesutiles---
const int APPUI=LOW; // constante pour tester état BP
décrémenter) et valider une variable. On pourra de la sorte interagir avec
Arduino pour régler une valeur de déclenchement ou une vitesse de //---DéclarationdesconstantesdesbrochesE/Snumériques--- const int
clignotement.
bpMOINS=2; // Constante pour la broche 2
Ici, on va uniquement voir le principe d'utilisation des 3 BP pour modifier une
const int bpPLUS=3; // Constante pour la broche 3 const int
variable. bpOK=4; // Constante pour la broche 3
Entete déclarative
//---Déclarationdesvariablesglobales--- int valeur=0; //
On va déclarer à ce niveau :
variable à régler
• 3 constante désignant les 3 broches utilisées pour les bouton poussoir, int maxi=20; // valeur maximale
appelée ici bpPLUS, bpMOINS, bpOK. int mini=0; // valeur minimale
• 1 constante int appelée APPUI et initialisée à 0.
• 1 variable représentant une valeur à régler. //Lafonctionsetup()estexécutéeenpremieret1seulefois

Fonction setup() void setup() { // debut de la fonction setup()


• On initialise la communication série à 115200 bauds avec l'instruction //---iciinstructionsàexécuter1seulefoisaudémarrageduprogramme---
[Link](debit)
• on configure les broches des boutons poussoir en entrée avec //-------Initialisationfonctionnalitésutilisées-------
l'instruction pinMode(broche, INPUT) [Link](115200); // initialise connexion série matérielle à 115200 bauds
• ON ACTIVE LE « RAPPEL AU PLUS » interne des broches en //IMPORTANT:réglerleterminalcôtéPCaveclamêmevaleurdetransmission
écrivant la valeur HIGH sur chaque broche.
Fonction loop() //-------Brochesensortiesnumériques-------

• À l'aide d'une condition if() on teste si chaque bouton poussoir est //-------Brochesenentréesnumériques-------
appuyé en lisant son état avec la fonction digitalRead() pinMode (bpMOINS,INPUT); // Broche BP MOINS configurée en entrée pinMode
(bpPLUS,INPUT); // Broche BP PLUS configurée en entrée pinMode (bpOK,INPUT); //
• Si le bouton poussoir PLUS est appuyé, on ajoute 1 à la variable Broche BP OK configurée en entrée
• Si le bouton poussoir MOINS est appuyé, on retranche 1 à la variable
• Si le bouton OK est appuyé, on affiche la variable sur le port Série //-------Activationsibesoindurappelau+
(pullup)desbrochesenentréesnumériques-------
digitalWrite (bpMOINS,HIGH); // Rappel au + activé sur la broche BP MOINS configurée
en entrée
Un des défauts de cette façon de faire est de devoir lire en permanence l 'état digitalWrite (bpPLUS,HIGH); // Rappel au + activé sur la broche BP PLUS
des boutons poussoir pour ne pas rater un appui : si on fait faire autre chose configurée en entrée
à Arduino, on risque de rater des appuis. Pour contourner ce problème, digitalWrite (bpOK,HIGH); // Rappel au + activé sur la broche BP OK
on utilisera une interruption (on verra çà plus tard...) configurée en entrée

}// fin de la fonction setup()


//lafonctionloop()s'exécutesansfin

void loop(){ // debut de la fonction loop()

if (digitalRead(bpPLUS)==APPUI) {

valeur=valeur+1;
if (valeur>maxi) valeur=maxi; // valeur maxi

[Link]("+1");
delay(250); // pause anti-rebond

if (digitalRead(bpMOINS)==APPUI) {

valeur=valeur-1;
if (valeur<mini) valeur=mini; // valeur mini

[Link]("-1");
delay(250); // pause anti-rebond

if (digitalRead(bpOK)==APPUI) {

[Link]("Valeur = ");
[Link](valeur); delay(250); // pause
anti-rebond

}// fin de la fonction loop()


19. BP x 3 : Mini orgue – 3 notes : le montage
Cette fois, on va utiliser simultanément un buzzer piézo-électrique pour
simuler un « mini-orgue » à 3 notes.

Le montage est une réplication x3 du montage avec un bouton poussoir


associé à celui de l'utilisation du buzzer piézo-électrique :
20. BP x 3 : Mini orgue – 3 notes : le programme
Dans ce programme, on va déclencher la génération d'une note lors de l'appui //---Déclarationdesconstantesutiles---
sur un BP donné, et ce pour 3 notes différentes. constint APPUI=LOW; // constante pour tester état BP

Entete déclarative const int bpDO=2; // Constante pour la broche 2 const int
bpRE=3; // Constante pour la broche 3 const int bpMI=4; //
On va déclarer à ce niveau : Constante pour la broche 3
• 3 constante désignant les 3 broches utilisées pour les bouton poussoir,
const int PIEZO=5; // constante pour la broche du piézo
appelée ici bpDO, bpRE, bpMI.
• 1 constante désignant la broche utilisée en sortie avec le buzzer
//---Déclarationdesvariablesglobales---
• 1 constante int appelée APPUI et initialisée à 0.
int DO=262; // variable de la fréquence note int RE=294;
• 3 constantes de notes // variable de la fréquence note int MI=330; // variable de
la fréquence note
Fonction setup()
• on configure la broches du bouton poussoir en sortie avec l'instruction
void setup() { // debut de la fonction setup()
pinMode (broche, OUTPUT)
• on configure les broches des boutons poussoir en entrée avec
l'instruction pinMode(broche, INPUT) //-------Initialisationfonctionnalitésutilisées-------

• ON ACTIVE LE « RAPPEL AU PLUS » interne des broches en


écrivant la valeur HIGH sur chaque broche. //-------Brochesensortiesnumériques-------
pinMode (PIEZO,OUTPUT); // Broche BP MOINS configurée en entrée

//-------Brochesenentréesnumériques-------
pinMode (bpDO,INPUT); // Broche BP MOINS configurée en entrée pinMode
(bpRE,INPUT); // Broche BP PLUS configurée en entrée pinMode (bpMI,INPUT);
// Broche BP OK configurée en entrée

//-------Activationsibesoindurappelau+
(pullup)desbrochesenentréesnumériques-------
digitalWrite (bpDO,HIGH); // Rappel au + activé sur la broche BP MOINS
configurée en entrée
digitalWrite (bpRE,HIGH); // Rappel au + activé sur la broche BP PLUS
configurée en entrée
digitalWrite (bpMI,HIGH); // Rappel au + activé sur la broche BP OK
configurée en entrée

}// fin de la fonction setup()


(suite) Fonction loop() void loop(){ // debut de la fonction loop()
• À l'aide d'une condition if() on teste si chaque bouton poussoir est
appuyé en lisant son état avec la fonction digitalRead()
• Si le bouton poussoir DO est appuyé, on active la note DO avec if (digitalRead(bpDO)==APPUI) {// si appui BP DO
l'instruction tone(broche, note), sinon, on stoppe la note avec
tone(PIEZO,DO); // joue note DO
l'instruction noTone(broche) delay(50); // pause anti-rebond
• Idem pour les 2 autres notes.
}
else if (digitalRead(bpRE)==APPUI) { // sinon si appui BP RE

tone(PIEZO,RE); // joue note RE


delay(50); // pause anti-rebond

}
else if (digitalRead(bpMI)==APPUI) { // sinon, si appui BP MI
tone(PIEZO,MI); // joue note MI
delay(50); // pause anti-rebond
}
else { // sinon
noTone(PIEZO); // sinon stoppe son
}

}// fin de la fonction loop() - le programme recommence au début de la fonction loop sans
fin
Entrées analogiques : faire des mesures et utiliser des capteurs analogiques, utiliser les
nombres à virgules avec la carte Arduino.

Ateliers Arduino
3. Rappel : Notion d'électronique numérique et analogique
L'électronique est une technique qui manipule les « électrons » sous forme de
tension ou d'intensité. On distingue 2 types d'électronique :
• L'électronique analogique qui utilise des variations continues de la
tension qui peut prendre toutes les valeurs intermédiaires (potentiomètre
= variation du minimum au maximum).
• L'électronique numérique qui utilise des variations « abruptes » de
la tension qui va prendre 2 niveaux (interrupteur = allumé ou éteint) :
l'un dit HAUT (5V), l'un dit BAS (0V).
Un microprocesseur, tel que celui de la carte Arduino, est un circuit numérique
qui va permettre de manipuler des niveaux HAUT/BAS.

Pour prendre une image de tuyauterie :


• L'électronique analogique est comparable à un robinet dont
l'écoulementvapouvoirvarierentrel'absenced'eauetledébitmaximum.
• L'électronique numérique est comparable à une vanne « tout ou
rien » qui va soit stopper l'écoulement, soit donner le débit maximum, les
écoulementsintermédiairesn'étantpaspossibles.
L'intérêt majeur d'utiliser 2 niveaux HAUT/BAS est de permettre :
• De compter et calculer en combinant les niveaux HAUT et BAS entre-eux :
c'est le comptage binaire, qui utilise les 0 et les 1,
• De commander / contrôler des dispositifs à partir de plusieurs niveaux
HAUT / BAS combinés entre eux,
• De communiquer des informations entre 2 circuits numériques en envoyant
des niveaux successifs de HAUT/BAS
• De numériser des signaux analogiques (conversion analogique-numérique) !
• De coder des instructions à exécuter par un microprocesseur.
4. Rappel : Une broche numérique ne peut avoir que 2 états : HAUT ou BAS, « y'a ou y'a pas » !
Une broche numérique, dans un circuit numérique est un point du circuit
matérialisé par une broche métallique dans le cas d'un circuit intégré ou d'une
carte électronique.

Une broche numérique va être caractérisée par son état ou niveau de tension : elle
va pouvoir se trouver dans 2 états possibles seulement :
• soit au niveau HAUT (=5V), symbolisé par 1 ou HIGH
• soit au niveau BAS (=0V), symbolisé par 0 ou LOW
• noter qu'à un instant quelconque, la broche se trouve obligatoirement
dans l'un de ces 2 états.

Pour reprendre l'image d'une vanne « tout ou rien » :


• soit il y a de l'eau qui circule
• soit il n'y en n'a pas

Pour reprendre l'image d'un « interrupteur » :


• soit il y a de la lumière,
• soit il n'y en n'a pas...
5. Rappel : Une broche numérique est caractérisée par son SENS : en SORTIE ou en ENTREE !
Une broche numérique est également caractérisée par son sens :
• la broche est dite en sortie d'un circuit numérique lorsque c'est le circuit
numérique qui contrôle l'état Haut/Bas de la broche. On pourra
symboliser le sens de la broche numérique en sortie par une flèche
sortante.
• la broche est dite en entrée d'un circuit numérique lorsque le circuit
numérique « reçoit » (ou « subit ») son état . L'état Haut/Bas de la
broche numérique est contrôlé par « l'extérieur ». On pourra
symboliser le sens de la broche numérique en entrée par une flèche
entrante.
• noter qu'une broche numérique qui est en sortie d'un circuit numérique
est en entrée du circuit extérieur auquel elle est connectée... et
inversement... !
Usage avancé : en interne, dans un microprocesseur, une broche numérique est associée :
• à un bit de donnée (case unitaire mémoire) qui va permettre de fixer/lire son
état
• à un bit de sens qui va définir son mode de fonctionnement
Techniquement, il existe par ailleurs plusieurs technologies de broches numériques (TTL,
CMOS,..) qui ont des définitions différentes des niveaux de tension HAUT et BAS. Seules
des broches compatibles entre-elles pourront être utilisées/connectées ensemble.
Arduino est très souple de ce point de vue et est compatible avec la plupart des
technologies E/S !
6. Le concept de « conversion analogique-numérique » (du monde physique vers le monde numérique !)
Faire une mesure, c'est quoi ? En résumé
On a tous mesuré quelque chose : une hauteur, un poids, un volume de liquide Si on se résume, pour faire une mesure, on a besoin :
dans un verre doseur, une température avec un thermomètre, une tension avec d'un phénomène physique à mesurer

un voltmètre, etc...
• d'une échelle de mesure ou graduation
Quand on mesure, on fait quoi au juste ? Si on y réfléchit bien, faire une
mesure, c'est mettre en correspondance un état physique donné • d'une valeur de référence.
avec une graduation (ou échelle de mesure). Par exemple, lorsque l'on Faisons un rêve...
mesure une température, on associe la « hauteur » de liquide coloré dans le
thermomètre avec la graduation qui est à côté. Revenons à notre Arduino : ce qui serait bien, mais alors très bien, c'est de
pouvoir transformer avec notre Arduino, une tension variable appliquée sur
une broche en un nombre qui serait utilisable comme une variable !
Imaginez une sorte de « règle numérique à tension » :
• on appliquerait une tension entre 0 et 5V par exemple sur une broche
de la carte Arduino...
• et Arduino, à tout moment, pourrait nous dire quand on lui le
demanderait quel est le niveau de tension sur la broche...
Mais faut pas rêver... Un truc pareil, çà doit coûter un max... ?!
La conversion analogique-numérique...
Bon, alors là, j'ai une très bonne nouvelle : Arduino dispose en interne de ce
que l'on appelle un module de « conversion analogique numérique » !
Mais ce n'est pas tout : pour mettre en correspondance l'état physique Autrement dit, une règle numérique à tension de 1024 niveaux : il suffit
que l'on mesure et la graduation, on se base sur une valeur de simplement d'appliquer une tension entre 0 et 5V sur une des
référence : généralement, on fixe précisément l'état physique qui correspond broches dite « analogique » pour obtenir une valeur entre 0 et 1023
à la graduation 0. Par exemple, lorsque l'on mesure la longueur d'un segment, correspondant au niveau de la tension présente sur la broche !
on va commencer par positionner précisément le 0 au niveau du début du
segment. Pour une température, on se basera sur le 0°C pour fixer la mesure,
etc...
7. Principe de fonctionnement d'une broche analogique
8. Les broches analogiques de la carte Arduino
La carte Arduino de base (la UNO, la Duemilanove, etc..) est une carte numérique
qui possède 20 broches d'Entrée/Sortie numérique (notées E/S)
numérotées de 0 à 19 !
Les broches 0 à 19 sont potentiellement utilisables en broches E/S !

Cependant, certaines broches ne doivent pas, dans la mesure du possible être


utilisées en broches E/S :
• les broches 0 et 1 sont utilisées par la communication USB donc, les
utiliser pourrait perturber cette communication. En pratique, ne pas les
utiliser.
• les broches 14 à 19 ont un double rôle : elles peuvent également être
utilisées en tant que broches analogiques pour réaliser des mesures. Donc,
si possible, ne pas les utiliser en broches numériques... mais si on est
obligé, on peut le faire !
A savoir : les broches numériques 14 à 19 sont numérotées de 0 à 5 (ou
désignées par A0, A1, A2, A3 et A5) lorsqu'elles sont utilisées en tant que
broches analogiques.

Remarquer également que la plupart des broches numériques ont des fonctions
particulières potentielles qui seront présentées au fur et à mesure de leur
utilisation. A titre indicatif, les fonctions disponibles sont la génération d'impulsion, la
communication SPI, la communication I2C, les interruptions externes...
D'un point de vue électrique, retenir que :
• chaque broche numérique E/S peut supporter 40 mA d'instensité en
sortie ou en entrée
• L'ensemble des broches numériques E/S ne doit pas dépasser 200mA en
entrée ou en sortie !
Usage avancé : pour des projets nécessitant de nombreuses broches E/S (= mal conçu?),
la carte Arduino Mega dispose de plus d'une 50aine de broches E/S !
9. Pour info : les caractéristiques de la « règle à tension » numérique de l'Arduino
Voici quelques informations concernant la « règle à tension » numérique de la Correspondance entre la graduation et la tension mesurée
carte Arduino :
La « règle à tension » de l'Arduino, dispose de 1024 graduations numérotées
6 broches de mesure ! de 0 à 1023 :
• disponible sur 6 broches dites analogiques : on peut donc utiliser 6 • la graduation 0 correspond au 0V ou 0mV
capteurs en même temps... (et même plus si on utilise un/des • la graduation 1023 correspond au 5V ou 5000mV
« multiplexeur analogique » tel que le CI 4051)
• la graduation 204 correspond au 204x5000/1023 = 997mV soit 1V
Plusieurs centaines de mesures par seconde !
• la graduation nnn correspond à nnn x 5000 / 1023 mV
• une mesure se fait en 100µs environ ce qui permet de réaliser sans
aucune difficulté plusieurs centaines voir milliers de mesure par
seconde (on peut transformer sa carte Arduino en un petit
oscilloscope USB !)
Pleine échelle de mesure de 0 à 5V
• la mesure est réalisée par défaut pour une tension comprise entre 0V
et 5V. La broche ARef permet au besoin d'utiliser une autre tension de référence (2,5V
par exemple), mais en pratique, c'est très peu utilisé.

Une précision de 5mV !


• la « règle à tension » dispose 1024 niveaux (ou graduations) soit une
précision de 5mV environ en 5V !!
Résistance maximale de mesure = 10 KOhms
• pour éviter les erreurs de mesure, on mesurera des tensions sur des
dispositifs ayant une résistance maximale de 10 KOhms . On dit que
l'impédance d'entrée maximale conseillée = 10 KOhms

Dans vos programmes, l'instruction map(valeur, 0,1023,0,5000) vous


permettra de facilement réaliser la conversion.
10. Fiche composant : découvrir la résistance variable.
Description Principe général d'utilisation
Une résistance variable est une résistance... dont on va pouvoir faire varier la Le principe général d'utilisation d'une résistance variable avec une carte
valeur. Vous utilisez déjà ce composant dans la vie de tous les jours : le bouton Arduino va consister :
que l'on tourne pour régler le volume d'un appareil, c'est une résistance
• à connecter la résistance principale entre le 0V et le 5V
variable.
• à connecter la broche variable sur une entrée analogique.
La résistance variable est caractérisée par sa résistance maximale, exprimée en
Ohms. Elle dispose d'un axe de rotation qui permet de faire varier la
résistance. A noter qu'il existe des résistances variables linéaires et
logarithmiques : choisir les linéaires !
La résistance variable présente 3 broches :
• 2 broches correspondant aux broches de la résistance maximale
interne, comme une résistance classique,
• 1 broche qui connectée au « curseur interne» qui permet de faire
varier la résistance entre 0 Ohms et la résistance maximale.

En procédant de cette façon, si on appelle R la valeur actuelle de la résistance variable, Rmax sa


valeur maximale et Vo la tension de sortie, on a la relation suivante : Vo = 5V x R/Rmax (on a
affaire à un diviseur de tension...) .

Principe d'utilisation sur une plaque d'essai


Pour utiliser une résistance variable sur plaque d'essai, on la positionne à
cheval sur le rail principal et on connecte :
• une des broches de la résistance max au +5V et l'autre broche de la
résistance max au 0V,
Schéma théorique • la troisième broche sera connectée à la carte Arduino sur une broche
Le schéma théorique d'une résistance variable est logiquement le suivant : analogique.

La résistance variable permet de simuler simplement un capteur !


Utiliser une valeur entre 1K et 10KOhms avec Arduino.
11. Affichage d'une mesure analogique dans le Terminal Serie : le montage
Principe d'utilisation
Le principe d'utilisation d'une résistance variable avec la carte Arduino est le
suivant :
• on connecte les 2 broches de la résistance maximale interne au + 5V et
au 0V,
• on connecte la broche du « curseur » interne (ou broche de sortie) sur
une broche analogique de la carte Arduino : une des 6 broches A0 à
A5.
De cette façon, en faisant tourner l'axe de la résistance variable, on
obtiendra une tension variant entre 0 et 5V sur la broche du « curseur »
interne .

La carte Arduino, par ailleurs, sera connectée au PC via le câble USB :


on affichera de cette façon les résultats de la mesure côté PC.
12. Affichage d'une mesure analogique brute dans le Terminal Serie
On va commencer par quelque chose de simple : récupérer la valeur brute
(entre 0 et 1023) correspondant à la tension entre 0 et 5V présente sur une // --- constantes des broches ---
broche analogique. const int RVar=0; //declaration constante de broche analogique
Entete déclarative
// --- Déclaration des variables globales ---
On va déclarer à ce niveau : int mesureBrute=0;// Variable pour acquisition résultat brut de conversion analogique
numérique
• une constante de broche pour la voie analogique : ATTENTION, il
faut utiliser le numéro de la broche analogique (entre 0 et 5) //**************** FONCTION SETUP = Code d'initialisation ***** void setup() {
et pas le numéro de la broche numérique (entre 14 et 19..)
// debut de la fonction setup() [Link](115200); // initialise connexion série à 115200
• on déclare une variable globale de type int pour stocker le résultat de
la mesure. bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmi
Fonction setup() ssion
• on initialise la communication série avec l'instruction
[Link](vitesse). On utilisera 115200 bauds. } // fin de la fonction setup()

//***** FONCTION LOOP = Boucle sans fin *****


Fonction loop()
• on réalise une mesure à l'aide de la fonction void loop(){ // debut de la fonction loop()
analogRead(brocheAnalogique) : le résultat est stocké dans une
variable. // acquisition conversion analogique-numerique (CAN) sur la voie analogi que
mesureBrute=analogRead(RVar);
• ensuite, on affiche le résultat dans le Terminal Série à l'aide de la
fonction [Link]() // affiche valeur numerique entière ou à virgule au format décimal
[Link](mesureBrute);
• On réalise ensuite une pause d'une demi-seconde entre 2 mesures
avec l'instruction delay(500). delay(500);
Fonctionnement du programme } // fin de la fonction loop() - le programme recommence au début de la fonction loop sans
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la fin
même valeur que celle utilisée pour l'instruction
[Link](vitesse). Ici, 115200 bauds.
• Toutes les secondes la valeur brute de la mesure s'affiche dans le
Terminal Série : en faisant varier la valeur de la résistance variable, on
observe que la valeur mesurée change entre 0 (à 0V) et 1023 (à 5V).
13. Langage : Le type float pour stocker les valeurs numériques à virgule
Nous allons ici réaliser des opérations sur des nombres décimaux à virgule. Le Le type float
langage Arduino dispose d'un type de variable particulier pour stocker de
telles valeurs : le type float. Le type int et le type long ne permettent de stocker que des valeurs
numériques entières, pas les nombres à virgule.
Quelques rappels au sujet des variables Pour stocker des valeurs décimales à virgule, le langage Arduino dispose d'un
type particlier appelé float.
En programmation, une « boite mémoire » sur laquelle on colle Un float pourra contenir une valeur aussi élevées que 3.4028235E+38 et aussi
une « étiquette » pour y mettre quelque chose : çà s'appelle une basse que -3.4028235E+38.
variable ! Techniquement un float est stocké sur 4 octets également.
Avec Arduino, pour des raisons techniques, la précision d'un float est tout de
même limitée à l'utilisation de 6 à 7 chiffres en tout avant et après la virgule :
En programmation, la « taille » d'une « boite mémoire » (ou au-delà, la précision sera perdue.
variable) s 'appelle le « type ». Pour dire les choses autrement, le
type d'une variable, c'est sa catégorie, son genre .
Déclaration d'une variable de type float
La déclaration d'une variable de type float se fait de la même façon que
Le type int pour n'importe quel autre type de variable :
Vous connaissez déjà le type int (pour integer = entier) qui peut contenir une
valeur entière comprise entre -32536 et + 32535 : le int est un double octet
(16 cases unitaires).

Le type long
L'autre type que vous connaissez est le type long : le type long permet de
stocker une valeur entière comprise entre -2 147 483 648 et +2 147 483
647 : le long est un quadruple octet (32 cases unitaires !) Par exemple :
float maVariable=0.0;
Le type float et les fonctions print() ou println()
Les fonctions print() et println() permettent de fixer le nombre de décimales
affichées :
[Link](1.23456, 0); // affiche "1"
[Link](1.23456, 2); // affiche "1.23"
usage avancé : on fera précéder le type int ou long du mot clé unsigned si on
[Link](1.23456, 4); // affiche "1.2346"
souhaite n'utiliser que des valeurs positives. Ceci a pour effet de doubler la
valeur positive utilisable (de 0 à 65535 pour un int par exemple).
14. Affichage d'une mesure analogique convertie en millivolts dans le Terminal Serie
A présent, on va calculer la valeur en millivolts correspondant à la valeur
brute // --- constantes des broches ---
const int RVar=0; //declaration constante de broche analogique
(entre 0 et 1023) correspondant à la tension entre 0 et 5V présente sur une
broche analogique. // --- Déclaration des variables globales ---
int mesureBrute=0;// Variable pour acquisition résultat brut de conversion analogique
Entete déclarative numérique
On va déclarer à ce niveau : float mesure; // variable à virgule pour calcul valeur en millivolts

• une constante de broche pour la voie analogique : ATTENTION, il //**************** FONCTION SETUP = Code d'initialisation *****
faut utiliser le numéro de la broche analogique (entre 0 et 5) void setup() { // debut de la fonction setup()
et pas le numéro de la broche numérique (entre 14 et 19..)
[Link](115200); // initialise connexion série à 115200 bauds
• on déclare une variable globale de type int pour stocker le résultat de // IMPORTANT : régler le terminal côté PC avec la même valeur de transmi ssion
la mesure.
• on déclare une variable de type float pour stocker la valeur à virgule } // fin de la fonction setup()
en millivolts.
//***** FONCTION LOOP = Boucle sans fin *****
Fonction setup() void loop(){ // debut de la fonction loop()

• on initialise la communication série avec l'instruction // acquisition conversion analogique-numerique (CAN) sur la voie analogi que
[Link](vitesse). On utilisera 115200 bauds. mesureBrute=analogRead(RVar);

Fonction loop() // calcule de la valeur a virgule en millivolts


// = convertit la valeur brute 0 - 1023 en valeur 0 - 5000 mV
• on réalise une mesure à l'aide de la fonction
analogRead(brocheAnalogique) : le résultat est stocké dans une mesure=map(mesureBrute,0,1023,0.0,5000.0);
variable.
//---- calcul équivalent ----
• on convertit la valeur brute en la valeur de la tension correspondante à //mesure=mesureBrute;
l'aide de l'instruction map() qui réalise une règle de 3. //mesure=mesure*5000.0;
• ensuite, on affiche le résultat dans le Terminal Série à l'aide de la // mesure=mesure/1023.0;
fonction [Link]() // affiche valeur numerique entière puis à virgule au format décimal
• On réalise ensuite une pause d'une demi-seconde entre 2 mesures [Link]("Mesure brute =");
avec l'instruction delay(500). [Link](mesureBrute); [Link](" soit
");
Fonctionnement du programme [Link](mesure,2); // affichage avec 2 virgules
[Link](" millivolts.");
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la
même valeur que celle utilisée pour l'instruction delay(500);
[Link](vitesse). Ici, 115200 bauds.
} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans
• Toutes les secondes un message s'affiche dans le Terminal Série : la fin
valeur mesurée change entre 0 (à 0V) et 1023 (à 5V).
15. Fiche technique : Principe d'utilisation d'un capteur analogique
Principe général Capteurs analogiques utilisables avec Arduino
Un capteur analogique est un composant qui va transformer un phénomène Pour être utilisable avec une carte Arduino, il faudra :
physique (température, distance, etc... ) en une tension variable fonction du que la tension de sortie d'un capteur analogique soit comprise entre 0

phénomène physique mesuré. et 5V (c'est la plage de mesure de la « règle à tension» de l'Arduino)
• que la variation de tension soit grande par rapport à la résolution de
5mv/niveau (c'est la graduation minimale de la « règle à tension »)
La bonne nouvelle, c'est qu'il existe pleins de capteurs analogiques
compatibles avec une carte Arduino !

Capteurs analogiques linéaires et non linéaires


Un point important à connaître : il existe 2 grands types de capteurs
analogiques : les capteurs linéaires et les capteurs « non linéaires » :
• Les capteurs linéaires ont une tension de sortie strictement
Brochage et Principe général d'utilisation avec Arduino proportionnelle à la grandeur mesurée (par exemple 10mV par °C) et
Un capteur analogique est un dispositif électronique et assez logiquement, il seront faciles à utiliser.
va disposer de 3 broches (à savoir : un capteur utilise que quelques mA) : • Les capteurs non-linéaires ont une tension de sortie qui est fonction
• 2 broches d'alimentation (typiquement +5V et 0V) de la grandeur mesurée mais évolue selon une loi mathématique non
linéaire (logarithme, exponentielle, etc...). Leur utilisation est plus
• une broche de sortie de la tension analogique, appelée typiquement Vo
compliquée et passe par un tableau d'étalonnage.
ou Vout.
Le principe général d'utilisation d'un capteur analogique est le même que celui
que nous avons vu pour la résistance variable utilisée avec une carte
Arduino : connexion des broches d'alimentation au 0V et au 5V et de la
broche variable sur une entrée analogique.

La courbe de la tension de sortie d'un capteur est fournie dans sa fiche


technique : en pratique, préférer si possible des capteurs linéaires !
16. Exemples de capteurs analogiques utilisables avec une carte Arduino
Les capteurs analogiques utilisables avec une carte Arduino sont nombreux et De quelles informations a-t-on besoin pour utiliser un
variés ! Ils existent soit en composants individuels soit en mini-shields dédiés.
capteur analogique linéaire ?
Capteurs analogiques linéaires Pour utiliser un capteur analogique linéaire, on a besoin de connaître :
Voici quelques exemples : • son brochage (broche +5V, 0V et Vo)
• Capteur de température (LM35) • sa plage de mesure
• Capteur de luminosité ambiante • la correspondance entre la grandeur mesurée et la sortie analogique
• Capteur de débit en Volts
• Capteur d'intensité • une valeur de référence

• Accéléromètre 2 ou 3 axes (mesure inclinaison)


• Capteur de niveau sonore Toutes ces informations sont fournies dans la fiche technique du capteur.

• etc.... Un exemple concret


Par exemple, le capteur LM 35 est un capteur analogique linéaire de
température :
• mesurant la température entre -55 et +150°C
• dont la sortie est à 0V à 0°C
• avec une variation de 10mv par °C
• alimentable en 5V
Capteurs analogiques non-linéaires
Voici quelques exemples :
• Capteur de distance (GP2D12)
• Photorésistance (mesure la lumière)
• Humidistance (mesure humidité)
• etc...

Grâce à ces informations, on pourra utiliser précisément le capteur pour


réaliser un thermomètre avec Arduino !
17. Fiche composant : le capteur analogique linéaire de température LM35
Description Caractéristiques
Le capteur de température LM35 est un capteur de température linéaire • mesurant la température entre -55 et +150°C
fonctionnant en 5V. dont la sortie est à 0V à 0°C

• avec une variation de 10mv par °C
• alimentable en 5V
Grâce à ces informations, on pourra utiliser précisément le capteur pour
réaliser un thermomètre avec Arduino !

Exemple d'utilisation sur plaque d'essai avec Arduino


Brochage On connecte :
3 broches : le 0V (GND), le +5V (+Vs) et la tension de sortie (Vout) • la broche Vs au +5V
• la broche GND au 0V
• la broche Vout à une broche analogique de la carte Arduino.

Schéma fonctionnel
Truc : on peut utiliser un connecteur 3 broches sur fils pour le montage !
18. Réaliser un simple thermomètre numérique avec affichage dans le Terminal Série : le montage
Principe d'utilisation du capteur LM 35
Le principe général d'utilisation d'un capteur analogique est le même que celui
que nous avons vu pour la résistance variable utilisée avec une carte
Arduino : connexion des broches d'alimentation au 0V et au 5V et de la
broche variable sur une entrée analogique.

Schéma théorique du montage


On connecte :
• la broche Vs au +5V
• la broche GND au 0V
• la broche Vout à une broche analogique de la carte Arduino.
La carte Arduino, par ailleurs, sera connectée au PC via le câble USB :
on affichera de cette façon les résultats de la mesure côté PC.
19. Réaliser un simple thermomètre numérique avec affichage dans le Terminal Série : le programme
On peut commencer par réutiliser les programmes déjà vus pour vérifier que
// --- constantes des broches ---
les choses fonctionnent bien et afficher la mesure brute puis la mesure en
millivolts. const int RVar=0; //declaration constante de broche analogique
Une fois fait, on peut convertir la valeur brute ou la tension en °C, ce qui dans
// --- Déclaration des variables globales ---
le cas présent est assez simple : il suffit de prendre la tension en millivolt / 10 ! int mesureBrute=0;// Variable pour acquisition résultat brut de conversion analogique numérique
float mesure; // variable à virgule pour calcul valeur en millivolts
Entete déclarative
On va déclarer à ce niveau : //**************** FONCTION SETUP = Code d'initialisation ***** void setup() {

• une constante de broche pour la voie analogique : ATTENTION, il // debut de la fonction setup() [Link](115200); // initialise connexion série à 115200
faut utiliser le numéro de la broche analogique (entre 0 et 5)
bauds
et pas le numéro de la broche numérique (entre 14 et 19..) // IMPORTANT : régler le terminal côté PC avec la même valeur de transmissio
n
• on déclare une variable globale de type int pour stocker le résultat de
la mesure.
} // fin de la fonction setup()
• on déclare une variable de type float pour stocker la valeur à virgule
en millivolts puis en degrés. //***** FONCTION LOOP = Boucle sans fin *****

Fonction setup()
void loop(){ // debut de la fonction loop()
• on initialise la communication série avec l'instruction
[Link](vitesse). On utilisera 115200 bauds. // acquisition conversion analogique-numerique (CAN) sur la voie analogique
mesureBrute=analogRead(RVar);
Fonction loop()
// calcule de la valeur a virgule en millivolts
• on réalise une mesure à l'aide de la fonction // = convertit la valeur brute 0 - 1023 en valeur 0 - 5000 mV
analogRead(brocheAnalogique) et on stocke dans une variable.
mesure=map(mesureBrute,0,1023,0.0,5000.0);
• on convertit la valeur brute en la valeur de la tension correspondante à
l'aide de l'instruction map() qui réalise une règle de 3. //---- calcul équivalent ----
//mesure=mesureBrute;
• on convertit la valeur en degrés par une simple division par 10 //mesure=mesure*5000.0;
(tension de sortie = 0 +/- 10mv/°C). // mesure=mesure/1023.0;

• ensuite, on affiche le résultat dans le Terminal Série à l'aide de la // affiche valeur numerique entière puis à virgule au format décimal
fonction [Link]() [Link]("Mesure brute =");
[Link](mesureBrute); [Link](" soit
• On réalise ensuite une pause d'une demi-seconde entre 2 mesures ");
avec l'instruction delay(500). [Link](mesure,2); // affichage avec 2 virgules
[Link](" millivolts.");
[Link](" soit ");
Fonctionnement du programme [Link](mesure/10,1); // affichage avec 2 virgules
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la [Link](" degres Celcius");
même valeur que celle utilisée pour delay(500);
l'[Link](vitesse). Ici, 115200 bauds.
} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans
fin
20. Exemple d'affichage de résultat sous forme graphique : un mini-oscillo USB de base !
Présentation de Processing Exemple
Processing est un interface graphique programmable, libre et gratuite, écrite Vous trouverez plusieurs pages proposant les codes Arduino et Processing
en Java (et donc multi-OS) qui permet de facilement réaliser des interfaces pour réaliser facilement un petit oscilloscope USB à l'aide d'une carte Arduino.
graphiques simples , de manipuler des images, de réaliser des graphiques de Voir :
façon interactive à l'aide d'un langage simplifié, comme le langage Arduino.

En effet, l'interface Processing est capable d'interagir facilement avec le
clavier, la souris, mais aussi la communication série USB, le réseau, etc... •
Pour installer et télécharger Processing : [Link]
Vous êtes déjà familiarisé avec Processing sans le savoir : le
logiciel Arduino est basé sur une interface Processing !

Principe de réalisation d'une interface graphique


communiquant avec USB
Une fois que Processing est installé sur l'ordinateur, il devient possible de
communiquer simplement par le port USB avec une carte Arduino elle-même
programmée pour par exemple envoyer des données sur le port Série.
De cette façon, la carte Arduino couplée à l'interface Processing permet de
réaliser simplement des applications de type oscilloscope de base ! Il suffit
pour cela de programmer la carte Arduino pour envoyer le résultat de la
mesure sur le port Série et d'écouter le port Série dans l'interface Processing
pour afficher un point correspondant à la valeur reçue.

L'utilisation d'une interface graphique Processing pour visualiser sous forme


graphique le résultat de la mesure analogique est très utile en pratique
pour tester les capteurs analogiques et préciser : la plage de mesure
utile, la rapidité de réaction du capteur, la cinétique globale de la réponse
(stable ou parasitée...), etc..
A gauche : test d'un capteur de niveau de gris. A droite, test d'un capteur de flamme monté sur servomoteur.
Exemple d'affichage des 6 voies analogiques simultanément.
21. Fiche composant : la photo-résistance
Description Exemple d'utilisation sur plaque d'essai avec Arduino
Une photo-résistance est une résistance qui comme son nom l'indique, va On connecte tout simplement en série la photo-résistance avec une résistance
varier en fonction de la lumière. Grosso modo : entre le 0V et le 5V.
• lorsque la photo-résistance est éclairée, sa valeur chute, de l'ordre de L'entrée analogique sera connectée au point de jonction entre les 2 résistances.
10 K0hms avec une luminosité ambiante,
• lorsque la photo-résistance est dans l'obscurité, sa valeur monte (de
l'ordre de 500 KOhms
Principe d'utilisation
Pour pouvoir utiliser efficacement une photo-résistance, il faut la mettre en
série avec une autre résistance fixe afin de créer un diviseur de tension : de
cette façon, la variation de la luminosité et donc de la résistance de la photo-
résistance se traduira par une variation de tension entre les 2 résistances.

En pratique, utiliser une résistance en série ayant une valeur proche de la


valeur de la photo-résistance éclairée, de l'ordre de 5K à 10K.
22. Un détecteur d'obscurité simple : le montage.

Principe d'utilisation d'une photo-résistance


Pour pouvoir utiliser efficacement une photo-résistance, il faut la mettre en
série avec une autre résistance fixe afin de créer un diviseur de tension : de
cette façon, la variation de la luminosité et donc de la résistance de la photo-
résistance se traduira par une variation de tension entre les 2 résistances.

Schéma théorique du montage


On connecte tout simplement :
• en série la photo-résistance avec une résistance entre le 0V et le 5V.
• L'entrée analogique sera connectée au point de jonction entre les 2
résistances.
La carte Arduino, par ailleurs, sera connectée au PC via le câble USB :
on affichera de cette façon les résultats de la mesure côté PC.

23.
24. Un détecteur d'obscurité simple : le programme.
On reprend la même base programme que ce que l'on a utilisé précédemment
et on va utiliser un seuil pour la détection de l'obscurité. // --- constantes des broches ---

Entete déclarative const int photoR=0; //declaration constante de broche analogique

On va déclarer à ce niveau : // --- Déclaration des variables globales ---


int mesureBrute=0;// Variable pour acquisition résultat brut de conversion analogique
• une constante de broche pour la voie analogique : ATTENTION, il
numérique
faut utiliser le numéro de la broche analogique (entre 0 et 5)
et pas le numéro de la broche numérique (entre 14 et 19..) int seuil=200; // Variable fixant le seuil de détection de l'obscurité - à adapter
• on déclare une variable globale de type int pour stocker le résultat de //**************** FONCTION SETUP = Code d'initialisation ***** void setup() {
la mesure.
// debut de la fonction setup() [Link](115200); // initialise connexion série à 115200
Fonction setup()
bauds
• on initialise la communication série avec l'instruction // IMPORTANT : régler le terminal côté PC avec la même valeur de transmi
[Link](vitesse). On utilisera 115200 bauds. ssion
Fonction loop()
• on réalise une mesure à l'aide de la fonction } // fin de la fonction setup()
analogRead(brocheAnalogique) et on stocke dans une variable.
//***** FONCTION LOOP = Boucle sans fin *****
• ensuite, on affiche le résultat dans le Terminal Série à l'aide de la
fonction [Link]()
void loop(){ // debut de la fonction loop()
• A l'aide d'une condition, on teste la détection de l'obscurité.
// acquisition conversion analogique-numerique (CAN) sur la voie analogi que
• On réalise ensuite une pause d'une demi-seconde entre 2 mesures mesureBrute=analogRead(photoR);
avec l'instruction delay(500).
// affiche valeur numerique entière ou à virgule au format décimal
Fonctionnement du programme [Link](mesureBrute);
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la
même valeur que celle utilisée pour if (mesureBrute<seuil) [Link]("Obscurite detectee"); // message si obscurité détectée
l'[Link](vitesse). Ici, 115200 bauds. delay(500);
• Lorsque l'on passe la main sur la photo-résistance, un message
} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans
indique qu'elle a été détectée. fin
Moteurs : Introduction à l'utilisation des moteurs avec une carte Arduino.

Ateliers Arduino
2. Vue d'ensemble des différents types de moteurs
Introduction Servomoteurs
Un des intérêt majeur d'une carte Arduino est de pouvoir réaliser le contrôle
de motorisations variées selon ses besoins, en interaction avec des capteurs,
des boutons poussoirs, etc... On pourra de la sorte construire assez
simplement un robot motorisé et interactif intelligent !
Vue d'ensemble des différents types de moteurs
Il existe 3 grandes familles de motorisation utilisables avec Arduino, chacune
ayant ses avantages et ses inconvénients comme nous allons le voir :
• les servo-moteurs qui se subdivisent en :
◦ servomoteurs standards (maintien de position entre 0° et 180°)
standard à rotation continue
◦ servomoteurs à rotation continue (rotation continue )
Moteurs et moto-réducteurs à courant continu
• les moteurs à courant continu (dits CC) avec :
◦ les moteurs CC simple (rotation rapide)
◦ les moto-réducteurs (rotation plus lente avec engrenage de force)
• les moteurs dits « pas-à-pas » (rotation à vitesse lente ou moyenne
de précision – la trotteuse ) avec 2 technologies :
◦ les moteurs pas à pas unipolaires
◦ les moteurs pas à pas bipolaires moteur CC avec engrenages moto-réducteur
A quel coût ? Moteurs « pas à pas »
Pour la plupart de ces moteurs, on en trouve neufs à partir de moins de 10€
pièce pour des modèles standards... et chaque gamme propose une grande
variété avec des caractéristiques variées.
Mais le véritable « coût » d'un moteur n'est pas, à mon avis, le prix
du moteur individuel mais le prix de l'ensemble du matériel
« interface + moteur » nécessaire pour l'utiliser. En effet, dans la
plupart des cas, il faudra un circuit électronique d'interface entre le moteur et
la carte Arduino A titre indicatif, une interface moteur polyvalente coûtera
dans les 15-20€.
La bonne nouvelle : il existe un modèle de moteur utilisable en rotation
moteur pas à pas
continue dans les 2 sens et à vitesse variable sans interface à... 12€ pièce !
Suivez le guide !
3. Panorama global des caractéristiques des moteurs utilisables avec Arduino
Servomoteurs Moteurs Courant Continu Moteurs pas à pas
Standard Rotation continue Moteur CC Moto-réducteur Bipolaire Unipolaire

Description Boitier plastique avec Boitier plastique avec Moteur avec axe + 2 fils Moteur avec engrenages + Moteur avec axe + 4 fils Moteur avec axe + 4 fils
pignon + 3 fils pignon + 3 fils 2 fils

Type de mouvement Position angulaire 0-180° Rotation continue vitesse Rotation continue vitesse Rotation continue vitesse > Positionnement angulaire par « crans »
maxi moyenne maxi rapide maxi moyenne
> ou Rotation continue vitesse maxi moyenne

Brochage 3 broches : PWM servo (numérique) / V+ / 0V 2 broches : V+ et 0V, polarité indifférente, fixe le sens 4 broches : 2 par phase x 2 5 broches : 1 commune et
phases 1 par phase x 4 phases

Principe contrôle Largeur impulsion entre Largeur impulsion entre > La polarité fixe le sens de rotation Séquence de polarité V+ successive sur les 4 broches
1ms et 2ms fixe la position 1ms et 2ms fixe sens ET
> impulsion PWM fixe la vitesse
vitesse

Caract. Mécaniques 180° ou 360° 2000 tr/min ou + 200 tr/min voire moins 100 tr/min – Force faible en rotation lente
Force en rotation lente Force en rotation lente

Caract. électriques Tension = 5V voire 6V Tension entre 7 et 12V Tension entre 7 et 12V
I alim = 100mA ou + I alim de 200mA à 2000mA ou + I alim de 200mA à 2000mA ou + par phase
I contrôle = 5mA

Maintien position hors Blocage correct de la position courante en « roue libre » Blocage de la position en « roue libre »
tension courante

Codage Simple avec librairie Arduino Servo (1 broche par servo) Simple via interface soit avec 2 broches PWM, soit 1 Simple avec la librairie Arduino Stepper en mode 2 ou 4
broche sens et 1 PWM vitesse broches

Interface AUCUNE. Circuit de connexion vite utile. Jusqu'à 20 OBLIGATOIRE : 1 « pont en H » par moteur . Réalise OBLIGATOIRE : 2 « ponts en H » par moteur . Réalise
servos avec 1 carte Arduino ! adaptation tension, intensité + contrôle sens, vitesse adaptation tension, intensité
Alim ext 5-6V si + de 3 servomoteurs

Alimentation 5V carte Arduino ou 5V reg ext voire 6V ext Vin / 2A ou+ Alim externe obligatoire 1 à 4A voire + Alim externe obligatoire 1 à 4A voire +

Prix unitaire dès < 10€ dès < 12€ récup – neuf dès 5€ récup – neuf dès < 10€ récup - neuf dès 15€ récup – neuf dès 15€

Coût global unitaire dès <10€ / servo dès < 12€ /servo 5€/mot + interf 7,5€/mot = 10€/mot + interf 7,5€/mot 15€/mot + interf 12,5€/mot 15€/mot + interf 1€/mot
+/- alim si + de 3 +/- alim si + de 3 12,50€/mot (pas réducteur) = 17,50€/mot (25€ mini) = 27,5€/moteur (36€ min) = 16€/mot min
+ alim ext 1 à 4A + alim ext 1 à 4 A + alim ext 1 à 4A + alim ext 1 à 4A

Utilisation type Tourelles, bras, hexapode Robot initiation low cost Hélice Robot mobile 1Kg Découpe numérique, CNC, Robot mobile

Avantages 1 broche, pas interface 1 broche sens ET vitesse Force et blocage ! Silencieux, précis Silencieux, précis

Inconvénients +/- Vibration Peu courant ? Bruit, intensité intensité, bruit réduit Force faible et pas blocage Force faible et pas blocage
4. Servomoteurs : les servomoteurs standards : concrètement

Servomoteur vu de l'intérieur (en pratique, on n'a pas besoin de le démonter... juste pour comprendre) :
5. Servomoteurs : les servomoteurs standards : exemples d'utilisation
Voici quelques exemples d'utilisation de servomoteurs contrôlés avec Arduino et basés sur une mécanique de chez [Link]

Une carte Arduino associée à une simple alimentation adaptée peut permettre de contrôler jusqu'à 20 servomoteurs à la fois !
6. Servomoteurs : les servomoteurs à rotation continue : concrètement

Les servomoteurs à rotation continue « prêts à l'emploi » sont plutôt rares bien que très pratiques : une référence utile, le S04NF de DGServo.

Certains servomoteurs standards peuvent être modifiés en servomoteurs à rotation continue...


7. Servomoteurs : les servomoteurs à rotation continue : exemples d'utilisation

L'utilisation type des servomoteurs à rotation continue = réalisation d'un robot mobile d'initiation.

Le très grand avantage des servomoteurs à rotation continue :


permettre le contrôle de la vitesse ET du sens de rotation avec
une seule broche de la carte Arduino
et sans avoir besoin d'une interface supplémentaire !

On dispose ainsi d'une base ultra-simple et low-cost permettant de contrôler la marche avant / arrière et tourne droite / gauche.
8. Les moteurs et moto-réducteurs à courant continu ou CC : concrètement
Les moteurs CC seuls : pas chers (dès 3-4€), tailles variées, mais peu utilisables « tel que » sauf pour les rotation rapides simples (plusieurs milliers tr/min - hélices)

Les moto-réducteurs (moteurs + engrenages) sont beaucoup plus utiles : vitesse de rotation réduite (centaines tr/min) et force de rotation importante.

Une difficulté souvent rencontrée lors la mise en oeuvre d'un moteur : réaliser une fixation simple...
La gamme de moteur MFA, distribuée notamment par GoTronic, propose plusieurs modèles de moteurs et moto-réducteurs CC avec support intégré.
9. Les moteurs et moto-réducteurs CC : exemples d'utilisation

L'utilisation « type » des moteurs CC est la motorisation d'un robot mobile roulant
10. Les moteurs pas à pas : concrètement

Les moteurs pas à pas existent en différentes tailles et puissance :

Les 2 types de moteurs pas à pas : unipolaires (5 fils de commande) et bipolaire (4 fils de commande)
11. Les moteurs pas à pas : exemples d'utilisation

Châssis de robot mobile Découpe et perçage CNC

Imprimante 3D
voir le projet open source RepRap : [Link]
13. Rappel : Caractéristiques électriques d'une broche Numérique Arduino en sortie
Une broche numérique Arduino individuelle en sortie peut-être considérée
comme une « mini »-alimentation :
• fournissant une tension de 5V régulé au niveau HAUT et 0V au niveau
BAS.
• pouvant fournir au maximum 40mA pour une seule broche en sortie.

Pour l'ensemble des broches numériques :


• l'intensité maximale cumulée ne doit pas dépasser les 200mA.
• Ainsi, pour éviter les soucis, dans l'hypothèse où l'on utilisera au
maximum une 15aine de broches en sortie simultanément, considérer que
l'on peut utiliser sans danger 200mA/15 = 13mA / broche soit en pratique
10 à 15mA par broche.
En pratique : considérer qu'une broche Arduino fournit 5V / 10-15mA

Voici quelques exemples, pour se faire une idée de ce que l'on peut connecter
directement sur une broche numérique d'une carte Arduino en sortie :
• une broche d'un autre CI numérique consommera dans les 1 mA, =>
connexion directe POSSIBLE !
• une LED en série avec sa résistance consommera dans les 10-20mA selon
la résistance utilisée, => connexion directe POSSIBLE !
• la broche de commande d'un servomoteur consommera dans les 5mA, =>
connexion directe POSSIBLE !
• un moteur CC consommera dans les 250mA => connexion directe
IMPOSSIBLE ! (Dans ce cas, on devra utiliser une interface de
puissance comme nous le verrons)
En pratique : TOUJOURS se demander « quelle intensité va être
utilisée ? »
14. Technique : l'alimentation de la carte Arduino
Lorsque l'on utilise un moteur, il est essentiel d'avoir toujours à l'esprit les notions d'intensité et de tension de la carte Arduino. Comme on l'a déjà vu, la carte
Arduino intègre une alimentation interne régulée de 5V rég / 500mA :
• soit en provenance du port USB
• soit à partir de l'alimentation Vin 7-12V / 500mA (ou +)
Il est essentiel de distinguer :
• l'intensité maximale (200mA) que peut fournir le « coeur » de la carte Arduino et limité à 40mA par broche en sortie mais 200mA maximum
pour l'ensemble des broches réunies. Une LED en série avec une résistance utilisera par exemple 15mA fournis par le « coeur » Arduino.
• l'intensité maximale (500mA) que peut fournir l'alimentation +5V régulé/500mA. Cette alimentation de +5V/500mA de la carte Arduino
peut également être mise en parallèle avec une alimentation externe +5V régulée au besoin.
• On dispose donc de 300mA supplémentaires maxi pour alimenter des dispositifs 5V directement à partir de l'alimentation de la carte
Arduino (mais pas à partir des broches !!)
15. Servomoteurs : les servomoteurs standards : schéma électrique type d'utilisation avec Arduino
On connecte :
• le + (fil rouge) et le – (fil noir) respectivement au +5V et au 0V de la carte Arduino
• le fil de commande (fil blanc) à une broche numérique en sortie de la carte Arduino.
16. Les moteurs et moto-réducteurs CC : schéma électrique type d'utilisation avec Arduino
Pour utiliser un moteur ou un moto-réducteur CC avec une carte Arduino, l'utilisation d'une carte d'interface est OBLIGATOIRE !
Bien noter le triple rôle de l'interface : adaptation en tension et en intensité ainsi que le contrôle du sens.
17. Les moteurs pas à pas bipolaires : schéma électrique type d'utilisation avec Arduino
On connecte :
• la phase 1 sur la sortie du 1er « pont en H »
• la phase 2 sur la sortie du 2ème « pont en H »
18. Présentation des circuits d'interface pour moteurs CC ou pas à pas
Les interfaces de moteurs Les cartes et shields d'interface pour moteurs CC
• Encore une fois, vous devez vous dire qu'un circuit comme çà, çà doit • En pratique, il est plus simple d'utiliser des petites cartes
coûter un max... Et bien pas tant que çà... Il existe des circuits intégrés électroniques toutes prêtes qui vont intégrer tous les composants
double « Pont en H » pour quelques euros : notamment le L293D ou externes nécessaires ainsi que les borniers à vis.
encore le L298. On peut utiliser avec Arduino :

• Ces circuits seuls ne sont pas très faciles à utiliser seuls (ils nécessitent ◦ des shields, enfichables broche à broche sur la carte Arduino
des composants externes) et ils sont donc intégrés dans des cartes
d'extension (ou shields) utilisables avec Arduino pour un coût de ◦ des cartes électroniques autonomes
l'ordre de 15-20€. Exemples de cartes d'interfaces à base de L293 x1
Deux exemples de CI double « pont en H » • Ces cartes permettent de contrôler 2 moteurs CC ou 1 moteur pas à
• La plupart des interfaces de contrôle de moteurs utilisées avec pas bipolaire.
Arduino sont basées autour de 2 circuits double « Pont en H » très
utilisés.
• Le L293 est un CI double « pont en H » de puissance modérée :
◦ en boitier DIL, de l'ordre de 3€
◦ permettant de contrôler 2 moteurs CC ou 1 moteur pas à pas
Exemples de cartes d'interface à base de L298 x1
bipolaire (on verra çà plus tard)
• Ces cartes permettent de contrôler 2 moteurs CC ou 1 moteur pas à
◦ capable de fournir 600mA par moteur (1,2A en pic) pas bipolaire.
◦ sous une tension de 5 à 36V
• Le L293 est un CI double « pont en H » de puissance élevée :
◦ en boitier MultiWatt ou SOC, de l'ordre de 6€
◦ permettant de contrôler 2 moteurs CC ou 1 moteur pas à pas
bipolaire Exemples de cartes d'interfaces à base de L293 x2
◦ capable de fournir 2000mA par moteur (3A en pic) • Ces cartes permettent de contrôler 4 moteurs CC ou 1 moteur pas à
pas bipolaire.
◦ sous une tension de 7 à 46V

• Il en existe pleins d'autres qui fonctionnent sur le même principe, Principe d'utilisation avec Arduino
mais ce sont les 2 plus importants à connaître en pratique. • Selon les modèles, ces interfaces disposeront : soit d'une broche de
direction + une broche de vitesse (PWM) par moteur, soit de deux
broches contrôlant chacune un sens et la vitesse (PWM) dans ce sens
par moteur
Apprendre à recevoir des chaînes de caractères en provenance du Terminal Série avec la
carte Arduino, à utiliser les chaînes de caractères avec l'objet String, à utiliser la boucle
conditionnelle while.

Ateliers Arduino
3. Rappel : Principe de communication de l'Arduino vers le PC
Comme vous le savez déjà, la carte Arduino est (re-)programmable à volonté via le Programmation par le port USB
port série USB du PC : c'est ce qui fait toute la simplicité de son utilisation.

Mais la carte Arduino est également capable très simplement de communiquer


avec le PC pendant l'exécution d'un programme :
• pour envoyer des messages vers le PC (chaine texte, valeurs
numériques) afin de les visualiser sur l'écran sous forme texte ou même
sous forme de graphiques (usage avancé) !
• pour recevoir des messages depuis le PC (chaine texte, valeurs
numériques) ce qui permettra de contrôler la carte Arduino à partir du
clavier ou de la souris par exemple (usage avancé) !
Communication par le port USB pendant l'exécution du programme !
Le langage Arduino dispose de toutes les instructions nécessaires pour réaliser et
programmer cette communication au sein d'un programme comme nous allons le
voir ici.
La possibilité offerte par le langage Arduino d'afficher des messages sur le PC est
l'une des grandes forces de ce système : il est ainsi possible de « voir » de
l'intérieur comment un programme fonctionne, ce qui est très puissant pour
comprendre, mais aussi mettre au point ses programmes.

Au final, la carte Arduino programmée pourra fonctionner de 2 façons :


• soit en autonomie, déconnectée du PC une fois programmée,
• soit en communiquant avec le PC pendant l'exécution du programme,
réalisant un véritable périphérique USB programmable et personnalisable
à souhait !
4. Rappel : Notion de « Classe »

Dans les langages de programmation actuels, les concepteurs ont imaginé la


possibilité de pouvoir rassembler des fonctions ensemble lorsqu'elles s'appliquent
à une même fonctionnalité.
Par exemple, toutes les fonctions qui s'occupent des opérations mathématiques
vont pouvoir être regroupées ensemble.
A retenir : On appelle « classe » un regroupement de fonctions.

Tout comme une fonction, une classe aura un nom : pour distinguer une classe
d'une fonction, le nom d'une classe commencera par une MAJUSCULE.

En pratique, lorsquel'onprogrammeenlangageArduino,onn'apasbesoinde
créerdeclasses (ouf !). Mais le langage Arduino ou ses librairies comporte
plusieurs classes et il faut donc comprendre ce concept :
• Ainsi, toutes les fonctions qui gèrent la communication avec le port série
USB sont rassemblées dans une classe appelée Serial : nous allons
utiliser cette classe ici.
• la classe LiquidCrystal pour la gestion d'un afficheur LCD
• la classe Servo pour la gestion d'un servomoteur
• etc...
En pratique, pour utiliser une fonction d'une classe du langage
Arduino, on utilisera le nom de la classe + un point + le nom de la
fonction.

Remarque technique : les instructions de base du langage Arduino, même si elles ne sont
pas précédées par un nom de classe, appartiennent toutes à une même classe (implicite) :
celle du coeur (ou core) du langage Arduino.
5. Rappel : la classe Serial
Ainsi, comme on vient de le dire :
On appelle « classe » un regroupement de fonctions.

La première classe du langage Arduino que nous avons déjà rencontré est celle qui
rassemble toutes les fonctions utilisées pour la communication série USB : cette
classe s'appelle Serial !
Les fonctions en « émission » (rappel) :
Les fonctions de la classe Serial sont au nombre d'une dizaine. Nous avion déjà
présenté les 3 fonctions qui permettent d'écrire un programme pour afficher des
messages vers le PC :
• begin() : fonction d'initialisation de la communication USB
• print() : fonction d'affichage d'un message sans saut de ligne
• println() : fonction d'affichage d'un message avec saut de ligne

Les fonctions en réception


Ici, nous allons découvrir les fonctions de la classe Serial utiles en réception :
• available() : renvoie le nombre d'octets présents en réception sur le port
Série (Sera donc true si caractère présent et false sinon...)
• read() : lit et renvoie le premier octet entrant en réception sur le port série
• flush() : vide la file d'attente en réception du port Série

Rappel : pour utiliser une fonction d'une classe du langage Arduino,


on utilisera le nom de la classe + un point + le nom de la fonction.

Ces fonctions appartiennent à la classe Serial et nous les utiliserons donc sous la
forme : [Link]() ou [Link]() ou [Link]()
A présent, nous avons tous les éléments pour recevoir des messages en provenance
du PC depuis notre carte Arduino !
6. La fonction [Link]()
Description
Donne le nombre d'octets (caractères) disponibles pour lecture dans la file
d'attente (buffer) du port série. (available veut dire disponible en anglais)
Syntaxe
[Link]();
Paramètres
Aucun (laisser les parenthèses vides)
Valeur renvoyée
Renvoie nombre d'octet disponible pour lecture dans la file d'attente (buffer) du
port série, ou 0 si aucun caractère n'est disponible. Si une donnée est arrivée,
[Link]() sera supérieur à 0. La file d'attente du buffer peut recevoir
jusqu'à 128 octets.
Type : int
Exemple
if ([Link]() > 0) { // si des données entrantes sont présentes
// lit le 1er octet arrivé
incomingByte = [Link]();
// ici instructions à exécuter
}
7. La fonction [Link]()
Description
Lit les données entrantes sur le port Série.
Syntaxe
[Link]() ;

Paramètres
Aucun

Valeur renvoyée
Renvoi le premier octet de donnée entrant disponible dans le buffer du port série,
ou -1 si aucune donnée n'est disponible.
Type : int

L'octet lu est « enlevé » de la file d'attente. Le prochain appel de la


fonction read() lira l'octet suivant, etc...

Exemple
if ([Link]() > 0) { // si des données entrantes sont présentes
// lit le 1er octet arrivé
incomingByte = [Link]();
// ici instructions à exécuter
}
8. Rappel : « Hello world ! » : programme Arduino envoyant un message vers le PC via le port USB
Le principe d'utilisation de la communication USB dans un programme Arduino
consiste à :
• initialiser le débit (ou vitesse) de communication une fois pour toute au void setup() {
début du programme (dans la fonction setup() )
[Link](115200); // initialise la communication série
• utiliser les fonctions [Link]() lorsqu'on en a besoin :
◦ soit dans setup() pour afficher des messages une seule fois au début }
du programme,
◦soit dans loop() pour afficher des messages à intervalles réguliers ou void loop() {
en boucle.
Notre premier programme Série va : [Link]("Hello World !"); // affiche le message
• initialiser la communication à 115200 bauds avec [Link]()
delay(1000); // pause de 1 seconde
• afficher un message toutes les secondes
◦ affiche une chaîne : [Link](« mon message »); }
◦ pause d'une seconde : delay(1000); (ne pas oublier ! sinon
saturation du port USB... )
Attention : Une chaine de caractères s'écrit entre « »

Une fois le programme écrit :


• le compiler pour vérifier l'absence d'erreur
• vérifier la carte utilisée (Tools>Board) et le port (Tools>Serial
Port)
• le programmer dans la carte Arduino
Note technique : les chaine de caractères de message sont stockées en mémoire
RAM par défaut, ce qui ne pose pas de problème pour une dizaine de messages.
Dès que l'on va écrire beaucoup de messages, il faudra les écrire en mémoire
FLASH ce qui se fait depuis Arduino 1.0 par [Link](F(« message »));
9. Lancer et paramétrer le Terminal Série pour afficher/recevoir des messages entre le PC et Arduino
Une fois que la carte Arduino est programmée, elle envoie à intervalle régulier des
messages vers le PC. Concrètement, vous ne voyez rien se passer à ce stade : pour
voir les messages envoyés par la carte Arduino au PC, vous allez devoir
utiliser un logiciel de visualisation.
Heureusement pour nous, le logiciel Arduino (qui est vraiment très pratique !)
dispose d'un tel outil de visualisation : c'est le Terminal Série. Pour le lancer
:
• soit Menu Tool > Serial Monitor
• soit clic sur le bouton Terminal Serie
Une fois la fenêtre du Terminal Série ouverte :
• vérifier que la vitesse de communication est la même que celle que vous
avez fixé dans le programme Arduino
• une fois fait vous devriez voir les messages s'afficher dans la fenêtre.
Bien remarquer que le Terminal Série dispose d'un champ de saisie
pour envoyer des caractères vers Arduino : c'est lui que nous utiliser
ici pour envoyer des messages vers Arduino.

• Maintenant que nous avons pu vérifier que le Terminal série fonctionne


normalement en « réception», nous allons pouvoir passer à son utilisation
en « émission».
10. Langage : Type int, type char et code ASCII
Avant d'aborder la réception de données sur le port Série en provenance du Le type char représente un caractère !
PC, il est nécessaire de parler d'un sujet qui prête parfois à confusion... Mais ATTENTION : une variable de type char sera interprétée en
Quelques rappels au sujet des variables tant que code ASCII d'un caractère, pas en tant que valeur
En programmation, une « boite mémoire » sur laquelle on colle numérique !
une « étiquette » pour y mettre quelque chose : çà s'appelle une Par exemple, si un char contient la valeur 65, il sera considéré par le langage
variable ! Arduino comme correspondant au caractère ayant le code ASCII = 65 (c'est à
En programmation, la « taille » d'une « boite mémoire » (ou dire le A) et non pas comme la valeur 65...
variable) s 'appelle le « type ». Pour dire les choses autrement, le Déclaration d'une variable de type char
type d'une variable, c'est sa catégorie, son genre . La déclaration d'une variable de type char se fait de la même façon que
pour n'importe quel autre type de variable :
Le type int
Vous connaissez déjà le type int (pour integer = entier) qui peut contenir une
valeur entière comprise entre -32536 et + 32535 : le int est un double octet
(16 cases unitaires).

Le type char
Le langage Arduino dispose d'un type particulier qui va nous servir par la suite
: le type char
Techniquement, une variable de type char va contenir également une valeur Deux syntaxes sont possibles
entière mais comprise entre -128 et + 127 : un char est donc un octet (8 cases char maVariable=65; // à partir du caractère ASCII – ici lettre A
unitaires). char maVariable='A'; // à partir du caractère lui-même entre ' '
Les types int, char et les fonctions print() ou println()
Soit le char myChar=65 et le int myInt=65 :
[Link](myChar); // affiche la lettre A (code ASCII = 65)
[Link](myInt); // affiche le nombre 65 (valeur numérique)
Convertir un int en char : la fonction char()
[Link](char(myInt)); // affiche la lettre A (code ASCII = 65)
11. Pour info : Le code ASCII (American Standard Code for Information Interchange)
Le code ASCII
Historiquement, pour représenter les caractères sur un système informatique,
on a utilisé un codage simplifié où à 1 nombre correspondait un caractère.
L'intérêt de cette façon de faire, c'est de permettre de coder les caractères sur 1
seul octet (au lieu de coder tous les pixels du caractère...) .

Correspondance entre le code ASCII, le type char et le caractère

Les caractères spéciaux


Pour faire simple, on peut dire qu'une variable de type char contient
un caractère, et c'est ce que vous devez retenir, tout en sachant que la Certains caractères dits « spéciaux » sont à connaître, notamment :
variable char contient en fait le code ASCII du caractère ! • le saut de ligne (New Line) – code ASCII = 10
• le retour de chariot (Carriage Return) – code ASCII = 13

Un truc très utile : pour les caractères 0 à 9, on obtient la valeur numérique correspondante en faisant (code ASCII – 48 )
12. Recevoir un caractère sur le port Série et l'afficher dans le Terminal : le programme
A présent, on va donc écrire notre premier programme qui va recevoir un
//--- entete déclarative = variables et constantes globales int octetReception=0; //
caractère sur le port Série. Prêt ? C'est parti !
Entete déclarative variable de réception octet
char caractereReception=0; // variable de réception caractère
On va déclarer à ce niveau :
//--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
• on déclare une variable int pour stocker l'octet en réception (code
ASCII du caractère). [Link](115200); // initialise la vitesse de la connexion série
//-- utilise la meme vitesse dans le Terminal Série
• on déclare une variable char pour stocker le caractère correspondant.
Fonction setup() } // fin de la fonction setup()

• on initialise la communication série avec l'instruction


[Link](vitesse). On utilisera 115200 bauds. //--- la fonction loop() : exécutée en boucle sans fin void loop() {

Fonction loop() if ([Link]()>0) { // si un caractère en réception octetReception=[Link]();


• A ce niveau, on va « écouter » le port Série en testant l'arrivée d'un
// lit le 1er octet de la file
caractère à l'aide d'une simple condition if pour tester la présence d'attente
d'un octet dans la file d'attente du port série avec la fonction
[Link]() caractereReception=char(octetReception); // récupere le caractere à partir du code Ascii

• Si un octet est reçu, on affiche successivement : [Link]("Arduino a recu valeur :"); [Link](octetReception); // affiche la
valeur de l'octet [Link](" (code ASCII) correspondant au caractere ");
◦ sa valeur numérique (c'est à dire le code ASCII du caractère reçu) [Link](caractereReception); // affiche le caractere
◦ puis le caractère correspondant
} // fin if
Fonctionnement du programme
} // fin de la fonction loop()
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la
même valeur que celle utilisée pour l'instruction
[Link](vitesse). Ici, 115200 bauds.
• Régler également les paramètres de transmission de la chaine de
caractère à l'aide de la 2ème liste défilante. Mettre sur « No Line
Ending » pour aucun ajout après la chaine saisie.
13. Réglage et Utilisation du Terminal Série en « émission » vers Arduino
Lancement et réglage du Terminal Série en Réception
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la
même valeur que celle utilisée pour l'instruction
[Link](vitesse). Ici, 115200 bauds.
• Régler également les paramètres de transmission de la chaine de
caractère à l'aide de la 2ème liste défilante :
◦ sur « No Line Ending » afin qu'aucun caractère de fin de ligne ne
soit émis après la chaine de caractères,
◦ sur « New Line » si on souhaite qu'un saut de ligne soit émis après
la chaine de caractères (envoi le caractère ascii=10 après la
chaîne)
◦ sur « Carriage Return » si on souhaite qu'un retour de chariot soit
émis après la chaine de caractères (envoi le caractère ascii=13
après la chaîne)
◦ sur « Both NL & CR » pour les 2 simultanément.
Envoi d'une chaine sur le port Série
• Ensuite se positionner dans le champ de saisie et saisir 1 ou plusieurs
caractères dans le champ
• Clic sur envoi : la chaîne est émise sur le port Série +/- suivie des
options de fin de ligne.

Visualisation de la réponse d'Arduino


• Si Arduino renvoie une réponse, celle-ci s'affiche dans la fenêtre de
visualisation du Terminal

Amusez-vous à modifier le mode d'émission pour voir les différences...


14. Langage : La classe String : une classe pour gérer facilement les chaînes de caractères !
Une fois que l'on sait utiliser une variable contenant un caractère, on a Déclaration d'un objet de la classe String
logiquement envie de pouvoir manipuler des chaînes de caractères. Un objet de la classe String se déclare tout simplement de la même façon
Utiliser un tableau de variables char ? qu'une variable sous la forme :
La solution qui vient à l'esprit est de vouloir créer un tableau de variables de String chaineReception=""; // déclare un objet String vide
type char, ce qui est effectivement une solution possible, mais qui présente un Usage avancé : noter que l'on ne parle plus ici de variable, mais d'objet car on crée une instance
gros inconvénient : la taille du tableau ne pourra pas varier au cous du (l'objet créé) de la classe String (le moule). Le concept d'objet est plus large que celui de variable et
programme ! Dès lors impossible d'ajouter simplement des caractères à moins associe un espace mémoire ainsi que des fonctions spécifiques. En pratique, on peut considérer
qu'un objet String est une sorte de « super-variable ».
de créer d'emblée un grand tableau...
Opérations de base sur d'un objet String
Une bien meilleure solution : utiliser la classe String !
On peut ajouter très simplement une chaîne de caractère ou des Strings entre
La lourdeur de la gestion des chaînes de caractères à l'aide d'un tableau a eux :
poussé l'équipe du langage Arduino à créer une classe spéciale dédiée à la
gestion des chaînes de caractères : c'est un des domaines où toute la puissance maChaine=maChaine+ «test »; // ajoute une chaine au String
du langage Arduino est évidente ! maChaine=maChaine+ maChaine2; // ajoute une chaine au String
La classe String : un conteneur de chaine de caractères ! Quelques fonctions de la classe String
La classe String c'est tout d'abord un « conteneur » de chaîne de • charAt() : renvoie le caractère à la position voulue
caractères de taille variable : pas besoin d'en préciser la taille initiale et on • compareTo() : compare le String à une chaîne
pourra à tout moment lui ajouter un caractère supplémentaire.
• endsWith() : teste si le String se termine par une sous-chaîne
La classe String : de nombreuses fonction très pratiques !
• indexOf() : recherche la position d'une chaîne
Mais ce n'est pas tout : la classe String va mettre à notre disposition toute une
série de fonctions très très pratiques pour utiliser les chaînes de • length() : renvoie la longueur de la chaîne
caractères : ajouter une chaîne, connaître la taille de la chaîne, se positionner à • setCharAt() : modifie le caractère à la position donnée
un endroit précis de la chaîne, éliminer les espaces, extraire une sous-chaine,
• startsWith() : teste si le String commence par une sous-chaîne
etc...
• substring() : extrait une sous-chaîne à la position donnée
En un mot, souplesse maximale !
• trim() : élimine les espaces
Objet String et les fonctions print() ou println()
Un objet String s'utilise très simplement avec les fonctions print() et println() :
[Link](maChaine); // affiche le String
15. Pour info : toutes les façons valides d'initialiser un String

Pas de panique !

Vous n'avez par besoin de retenir toutes les fonctions de la classe String par coeur : nous les utiliserons au fur et à mesure des besoins !
Retenez simplement que c'est un outil très puissant pour manipuler des chaînes de caractères !
16. Programme : Stocker dans une chaine les caractères reçus sur le port Série et l'afficher dans le Terminal
A ce stade, on va pouvoir stocker tous les caractères reçus sur le port série
dans une chaîne de caractères de taille variable : un objet String. //--- entete déclarative = variables et constantes globales

Entete déclarative int octetReception=0; // variable de réception octet


On va déclarer à ce niveau : char caractereReception=0; // variable de réception caractère
String chaineReception=""; // déclare un objet String vide
• on déclare une variable int pour stocker l'octet en réception (code
ASCII du caractère). //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {

• on déclare une variable char pour stocker le caractère correspondant. [Link](115200); // initialise la vitesse de la connexion série
//-- utilise la meme vitesse dans le Terminal Série
• on déclare un objet String vide pour stocker la chaine de caractère
Fonction setup() } // fin de la fonction setup()

• on initialise la communication série avec l'instruction


[Link](vitesse). On utilisera 115200 bauds. //--- la fonction loop() : exécutée en boucle sans fin void loop() {

Fonction loop() if ([Link]()>0) { // si un caractère en réception octetReception=[Link]();


• A ce niveau, on va « écouter » le port Série en testant l'arrivée d'un
// lit le 1er octet de la file
caractère à l'aide d'une simple condition if pour tester la présence d'attente
d'un octet dans la file d'attente du port série avec la fonction
[Link]() caractereReception=char(octetReception); // récupere le caractere à partir du code Ascii

• Si un octet est reçu : chaineReception=chaineReception+caractereReception; // ajoute la caractère au String


[Link]("Liste des caracteres recus :");
◦ on récupère le caractère correspondant à l'aide de la fonction de [Link](chaineReception);
conversion char()
} // fin if
◦ on ajoute la caractère à l'objet String puis on l'affiche.
Fonctionnement du programme } // fin de la fonction loop()

• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la


même valeur que celle utilisée pour l'instruction
[Link](vitesse). Ici, 115200 bauds.
• Régler également les paramètres de transmission de la chaine de
caractère à l'aide de la 2ème liste défilante. Mettre sur « No Line
Ending » pour aucun ajout après la chaine saisie.
17. Langage : La boucle conditionnelle while( )
Dans certaines situations, il peut être utile d'effectuer une opération tant
qu'une certaine condition est vraie. Par exemple lors de la réception de
caractères sur le port série (tu me vois venir ?... non, sans blague ?!) ou d'un
appui sur un bouton poussoir. La solution passe par ce que l'on pourrait
appeler une boucle conditionnelle qui dit au microprocesseur :
• tant que (=while en anglais) telle condition est vraie, alors faire ceci
• sinon faire cela.
Cette boucle conditionnelle :
• est intéressante car elle permet , à la différence d'un boucle for, de
répéter une tâche un nombre fois non défini à l'avance, répétition qui
dépend d'une condition,
• est à utiliser avec parcimonie, car elle peut bloquer un
programme (si la condition est toujours vraie) mais cet effet est
parfois intéressant pour une exécution pas à pas ou un arrêt à un
endroit précis du code.
L'instruction utilisée pour une boucle conditionnelle « tant que » est
l'instruction while … else... (tant que... sinon...) que l'on écrit de la
façon suivante (presque comme une condition if...else...):
• on commence par le mot clé while suivi de la condition entre ( )
• suivi des { } qui contiennent les instructions à exécuter si la
condition est vraie, chaque instruction devant être suivie d'un ;
• enoption, on peut compléter du mot clé else suivi des { } qui
contiennent les instructions à exécuter si la condition est fausse.
La condition devra être une opération logique :
• qui renverra une valeur de type boolean soit true (vrai) soit false
(faux)
• on utilisera pour cela les opérateurs logiques de comparaison
• pour info, 0 est considéré comme false et toute valeur différente de 0
est considérée comme true (ainsi, if(1) est toujours vrai !)
Truc : while(1); permet de réaliser un point d'arrêt à n'importe quel endroit
d'un programme (la condition est toujours vraie). Parfois utile !
18. Rappel : les opérateurs logiques et leur utilisation (utilisables avec if, while, else, etc..)
La condition de base utilisable est de tester si une variable vaut une certaine valeur :
• on écrira la condition sous la forme variable==valeur (2 signes == )
• Par exemple on écrira if ( variable==2) { instructions ;} ce qui veut dire « si la condition « variable vaut 2 » est vraie alors exécuter les instructions »
Ne pas confondre l'opération logique de test d'égalité == avec le signe = d'affectation :
c'est une erreur fréquente de débutant et même de programmeur expérimenté... !!

Les opérateurs logiques de comparaison


• x == y : VRAI si x est égal à y
• x != y : VRAI si x est différent de y
• x < y : VRAI si x est inférieur à y
• x > y : VRAI si x est supérieur à y
• x <= y : VRAI si x est inférieur ou égal à y
• x >= y : VRAI si x est supérieur ou égal à y
Les opérateurs booléens (permettent d'enchaîner des conditions entre-elles)
• && (ET logique) : VRAI seulement si les deux conditions sont VRAI

• || ( OU logique) : VRAI si l'une des deux conditions est VRAI

• ! (NON logique) : VRAI si l'opérande est FAUX – cas particulier : !x est VRAI chaque fois que x=0 (« tordu » mais pratique !)
19. Pour info : une variante : la boucle conditionnelle do... while
Juste pour votre information, car en pratique çà ne sert pas souvent, il existe
une variante de la boucle while() : la boucle do.. while() (« faire... tant que..
»).
Description
La boucle do / while ("faire tant que" en anglais) fonctionne de la même
façon que la boucle while, à la différence près que la condition est testée à
la fin de la boucle, et par conséquent la boucle do sera toujours
exécutée au moins une fois.
C'est subtil, mais çà peut parfois servir...
Syntaxe

Exemple
20. Programme : Recevoir une chaîne de caractères sur le port Série et l'afficher dans le Terminal
Si vous êtes attentif, vous avez du remarquer que le programme précédent
recevait les caractères 1 à la fois, à chaque passage dans loop(). Il serait plus //--- entete déclarative = variables et constantes globales
pratique de pouvoir recevoir une chaîne de caractère d'un seul coup, « tant
que des caractères sont disponibles »... et on va donc utiliser pour cela une int octetReception=0; // variable de réception octet
char caractereReception=0; // variable de réception caractère
boucle while ! (ben oui, je vous apprends des trucs qui vont servir ! ) String chaineReception=""; // déclare un objet String vide
Entete déclarative
//--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
On va déclarer à ce niveau :
[Link](115200); // initialise la vitesse de la connexion série
• on déclare une variable int pour stocker l'octet en réception (code //-- utilise la meme vitesse dans le Terminal Série
ASCII du caractère).
} // fin de la fonction setup()
• on déclare une variable char pour stocker le caractère correspondant.
• on déclare un objet String vide pour stocker la chaine de caractère
//--- la fonction loop() : exécutée en boucle sans fin void loop() {
Fonction setup()
while ([Link]()>0) { // si un caractère en réception
• on initialise la communication série avec l'instruction
[Link](vitesse). On utilisera 115200 bauds. octetReception=[Link](); // lit le 1er octet de la file
Fonction loop() d'attente

• A ce niveau, on va « écouter » le port Série en testant l'arrivée d'un caractereReception=char(octetReception); // récupere le caractere à partir du code Ascii
caractère à l'aide cette fois d'une boucle while pour tester la présence
chaineReception=chaineReception+caractereReception; // ajoute la caractère au String
d'un octet dans la file d'attente du port série avec la fonction
[Link]() delay(1); // laisse le temps au caractères d'arriver
• Tant qu'un octet est présent : on récupère le caractère correspondant à } // fin while - fin de réception de la chaine
l'aide de la fonction de conversion char(), puis on ajoute la caractère à
l'objet String. On réalise une petite pause entre 2 réceptions. //----- une fois la chaine reçue
if (chaineReception!="") { // la chaine n'est pas vide [Link]("Chaine
• Une fois toute la chaîne reçue,on l'affiche. recue : "); [Link](chaineReception);
Fonctionnement du programme chaineReception=""; // Vide la chaine
} // fin if
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la
même valeur que celle utilisée pour l'instruction
} // fin de la fonction loop()
[Link](vitesse). Ici, 115200 bauds.
• Régler également les paramètres de transmission de la chaine de
caractère à l'aide de la 2ème liste défilante. Mettre sur « No Line
Ending » pour aucun ajout après la chaine saisie.
21. Langage : l'instruction break
L'instruction break permet de sortir d'une boucle même si son déroulement
n'est pas terminé !
Description L'instruction break n'est pas utilisable avec une condition if else !
• L'instruction break est utilisée pour sortir d'une boucle do, for ou
while, en passant outre le déroulement normal de la boucle.
• Pour info, cette instruction est également utilisée pour sortir d'une
instruction switch (mais on n'a pas encore vu çà) .
Syntaxe
• Attention : l'instruction break ne nécessite pas de
parenthèses vides (c'est une exception... ah là là... « pourquoi y
z'aurait pas pu faire simple.... ! »...
• Mettre par contre, le point virgule comme d'hab' !
break;
Exemple
22. Programme : Recevoir une chaîne de caractères suivie d'un saut de ligne sur le port Série et l'afficher
Améliorons encore un peu les choses... Lorsque l'on va envoyer des chaînes de
caractères vers Arduino, c'est pour lui donner des instructions... Imaginons //--- entete déclarative = variables et constantes globales
que l'on en envoie plusieurs à la suite : le port série contiendra
« fairececifairecelapuiscecipuiscela »... Il faudrait que chaque instruction soit int octetReception=0; // variable de réception octet
bien séparée des autres : le truc va consister à intercaler un « saut de ligne » char caractereReception=0; // variable de réception caractère
String chaineReception=""; // déclare un objet String vide
(caractère ascii =10) entre chaque chaine donnant : « fairececi » puis
« fairecela » puis « puisceci » puis « puiscela »... allez action ! //--- la fonction setup() : exécutée au début et 1 seule fois void setup() {
Entete déclarative
[Link](115200); // initialise la vitesse de la connexion série
• on déclare une variable int pour stocker l'octet en réception (code //-- utilise la meme vitesse dans le Terminal Série
ASCII du caractère), une variable char pour stocker le caractère
} // fin de la fonction setup()
correspondant, un objet String vide pour stocker la chaine de
caractère
void loop() { //--- la fonction loop() : exécutée en boucle sans fin
Fonction setup()
• on initialise la communication série avec l'instruction while ([Link]()>0) { // si un caractère en réception
[Link](vitesse). On utilisera 115200 bauds.
octetReception=[Link](); // lit le 1er octet de la file d'attente
Fonction loop()
if (octetReception==10) { // si Octet reçu est le saut de ligne
• A ce niveau, on va « écouter » le port Série en testant l'arrivée d'un [Link] ("Saut de ligne recu : ");
caractère à l'aide d'une boucle while pour tester la présence d'un octet [Link] ("Chaine recue = "+chaineReception); // affiche la chaine recue
dans la file d'attente du port série avec la fonction [Link]() chaineReception=""; //RAZ le String de réception delay(100); //
pause
• Tant qu'un octet différent du saut de ligne est présent on ajoute la break; // sort de la boucle while
caractère à l'objet String. On réalise une petite pause entre 2 } // fin if
réceptions. else { // si le caractère reçu n'est pas un saut de ligne
• Si c'est un saut de ligne que l'on reçoit, on sort de la boucle while. caractereReception=char(octetReception); // récupere le caractere
à partir du code Ascii chaineReception=chaineReception+caractereReception; // ajoute la
• Une fois toute la chaîne reçue,on l'affiche. caractère au String
delay(1); // laisse le temps au caractères d'arriver
Fonctionnement du programme } // fin else
• Ouvrir le Terminal Série (Tools > Serial Monitor) et fixer le débit à la même valeur que
celle utilisée pour l'instruction [Link](vitesse). Ici, 115200 bauds. } // fin while - fin de réception de la chaine

• Régler également les paramètres de transmission de la chaine de


caractère à l'aide de la 2ème liste défilante. Mettre sur « New } // fin de la fonction loop()
Line » pour ajout du « saut de ligne » après la chaine saisie.
Faites la même chose en réutilisant l'option No Line Ending et voyez le résultat :
aucune chaine ne sera prise en compte tant que le saut de ligne n'est pas arrivé !
Rebasculer
sur l'option « NewLine » et cliquer sur « send » : la chaine est prise en compte !

De cette façon, les chaînes peuvent arriver rapidement ou lentement sur le port Série,
tant que le saut de ligne n'est pas reçu, elle n'est pas prise en compte.
Ceci donne de la « robustesse » à la communication série du PC vers Arduino.

Vous aimerez peut-être aussi