Académique Documents
Professionnel Documents
Culture Documents
S’initier
à
Arduino
Programmation
et montages électroniques
Inclus
+ de 30 plans
de montage
détaillés
Frédéric SILLON
S’initier
à
Arduino
Programmation
et montages électroniques
Inclus
+ de 30 plans
de montage
détaillés
Direction artistique : Nicolas Wiel
Graphisme de couverture : Pierre-André Gualino
Mise en pages : PCA
© Dunod, 2021
11 rue Paul Bert, 92240 Malakoff
www.dunod.com
ISBN 978-2-10-083007-7
TABLE DES
MATIÈRES
INTRODUCTION 7
/>1 DÉCOUVERTE 9
Présentation 9
La famille des cartes Arduino 11
Un peu d’histoire… 14
Sécurité 16
Les microcontrôleurs 16
Électricité statique et électronique 19
Installation de l’IDE 20
Découverte de l’IDE 25
Schéma et Pinout de la carte Arduino Uno 27
Les connecteurs de l’Arduino Uno 30
Branchement de la carte, précautions 30
/>3 LE LANGAGE 43
La mémoire, les nombres et le reste… 43
Les bases du langage Arduino 49
Le programme Blink 57
CONCLUSION 231
Introduction /7
Listings à télécharger sur www.dunod.com
Tous les listings présents dans cet ouvrage sont disponibles
sur le site www.dunod.com. Si vous pouvez les récupérer tels
quels, nous conseillons cependant de les réécrire à la main,
car il n’y a rien de mieux pour apprendre à programmer que de
saisir soi-même les lignes de code.
// REMERCIEMENTS
Je tiens particulièrement à remercier mon épouse Isabelle ainsi que mes deux
enfants, Manon et Erwan, qui m’ont accompagné tout au long de ce livre et qui
m’accompagnent aussi dans la vie.
/> CHAPITRE
DÉCOUVERTE
1
Dans ce premier chapitre, nous allons faire un peu d’histoire, découvrir notre
carte Arduino et son environnement de programmation.
>> Présentation
>> Les microcontrôleurs dans notre environnement et leur histoire
>> Installation
>> Découverte de l’environnement de programmation et de la carte Arduino Uno
>> Schéma de la carte Arduino Uno
>> Premiers branchements
PRÉSENTATION
Nos appareils quotidiens sont remplis de cartes électroniques qui compor
tent des composants classiques ainsi que des composants programmables.
Les composants programmables sont des composants électroniques qui ont
l’avantage d’être modifiables
comme bon nous semble (ou
presque…). On peut faire
énormément de choses
avec, à conditions d’arriver
à leur expliquer comment
ils doivent le faire. De la
machine à laver à la télévi-
sion en passant par la voi-
ture, la fusée ou la console
de jeux, notre monde en est
rempli. Il suffit de regarder
autour de nous pour nous en
apercevoir rapidement. Figure 1.1 Détail d’une carte électronique
Présentation /9
Parmi ces composants programmables, on va trouver notamment des micro-
contrôleurs, des microprocesseurs, ainsi que d’autres composants plus ou moins
complexes et on va leur expliquer ce qu’ils doivent faire en les programmant.
Au départ réservé à des gens très spécialisés, ce petit monde a beaucoup évo-
lué durant ces dernières années, et des logiciels de programmation très simples
d’utilisation sont apparus.
En partant du principe qu’il faut essayer pour mieux comprendre, les mon-
tages que nous allons étudier ensemble utilisent des microcontrôleurs, ainsi que
des composants plus classiques mais tout aussi indispensables, et nous allons
voir comment faire fonctionner tout ce petit monde pour créer nos propres
montages.
Le cœur de notre carte, ou plutôt son cerveau, est un composant microcontrô-
leur qui s’appelle ATMega328P. De nombreux fabricants proposent des micro-
contrôleurs, comme Microchip, NXP, ST, Renesas ou Intel.
Que ce soient des microcontrôleurs ou des microprocesseurs, ces composants
ont la particularité commune d’être programmables. À eux seuls, ils ne savent rien
faire à part calculer très très vite et avoir une mémoire d’éléphant. On va donc
pouvoir leur apprendre plein de choses qu’ils vont exécuter tout seuls et très vite.
En travaillant progressivement et sans se décourager, à la fois sur les compo-
sants et sur les programmes, on va explorer ces deux mondes très proches l’un
de l’autre : l’électronique et la programmation.
Internet regorge de ressources. Quand on maîtrisera mieux ces deux mondes,
on pourra y trouver beaucoup d’idées pour réaliser les projets les plus fous,
comme sur la page create.arduino.cc/projecthub du site Arduino.
Uno, c’est la carte de base, qui comporte tout de même 14 entrées/sorties digitales
et 6 entrées analogiques. D’un prix très abordable, elle sera la base de nos montages.
Avec ses 32 ko de mémoire flash et ses 2 ko de RAM, on pourra déjà bien s’amuser.
Arduino Mega 2560 est une carte beaucoup plus complète, qui comporte
54 entrées/sorties digitales, 16 entrées analogiques et 4 ports série. La mémoire
est également plus fournie, avec 256 ko de mémoire flash et 8 ko de mémoire RAM.
L’Arduino Mini est une toute petite carte avec 14 entrées/sorties digitales et
8 entrées analogiques. Par contre, elle ne comporte pas de port USB comme la
Uno ou la Mega.
Il existe de très nombreux modèles dont certains sont équipés de liaisons Wifi
ou de ports Ethernet. Nous n’en parlerons pas ici car nous avons déjà assez à faire
avec les fonctions standard… Cependant, ces cartes seront très intéressantes à
utiliser pour des montages communicants.
Il existe aussi des cartes dites compatibles Arduino, qui ne sont pas les origi-
nales mais qui sont programmables et utilisables de la même façon, comme celle
de Velleman.
Certaines ont des fonctions qui sont très sympathiques, comme la carte Flora
d’Adafruit Industrie, que l’on peut coudre sur ses vêtements.
Quoi que vous choisissiez, le principal sera de bien utiliser sa carte et d’explorer
toutes ses fonctions. Cela permettra d’apprendre beaucoup de choses qui per-
mettront plus tard de faire de gros projets.
UN PEU D’HISTOIRE…
On peut dire que l’électronique est née au début du vingtième siècle avec
la naissance des premiers tubes à vide. Il s’agissait alors de gros composants
électroniques qui ressemblaient à des ampoules électriques comme celles qui
nous servent à nous éclairer aujourd’hui. Ils étaient très rudimentaires, mais
pourtant révolutionnaires à leur époque. Cette science s’est développée pour
devenir celle que l’on connaît actuellement, avec une grande évolution appa-
rue dans le milieu du vingtième siècle avec l’invention du transistor, du circuit
intégré et plus tard du microprocesseur. Ces composants ont bouleversé notre
monde technologique, bien qu’il s’agisse tout de même d’une discipline assez
récente dans notre histoire.
L’idée de la programmation est pourtant apparue bien avant les premiers ordi-
nateurs modernes. Par exemple, Lady Ada Lovelace – qui s’appelait en réalité
Augusta Ada King, comtesse de Lovelace –, née en 1815, est considérée comme la
première programmeuse. Les ordinateurs n’existaient pas à cette époque, mais
LES MICROCONTRÔLEURS
// ET UN MICROPROCESSEUR ?
Un microprocesseur est également un circuit intégré plus ou moins complexe,
mais qui n’a qu’une seule fonction principale : celle de calculer. Par contre, il va
calculer très très vite et servira de gros cerveau à une carte électronique. On va
alors lui associer de la mémoire, ainsi que d’autres circuits qui s’occuperont de
gérer son environnement. Au final, on aura un système un peu identique à un µC,
mais qui sera beaucoup plus puissant en termes de calcul. Dans nos ordinateurs
de bureau ou dans nos portables, on va donc retrouver un microprocesseur qui
va calculer, gérer la mémoire, et s’entourer de divers autres circuits pour gérer le
disque dur, le clavier, l’écran et les autres systèmes autour de lui.
On peut citer parmi les noms les plus connus les Core i7, i5, Xenon, MC68000,
MC68020, ou encore MC6809 pour les plus anciens, et on peut également les
classer par famille : 8, 16, 32 ou 64 bits.
On va généralement l’appeler µP (µ pour micro et P pour Processeur).
Par définition, étant donné que le µC comporte déjà des interfaces vers le
monde extérieur, une carte électronique avec un µC sera souvent plus petite
qu’une équipée d’un µP pour effectuer les mêmes fonctions. Celle avec le µC
sera par contre souvent beaucoup plus lente ou beaucoup plus limitée en termes
d’extensions.
Les cartes à microprocesseur sont donc généralement plus complexes que les
cartes à microcontrôleur, car ces premiers n’ont ni mémoire interne, ni circuits
internes pour communiquer avec le monde extérieur.
Pour débuter dans le monde de la programmation, une carte à µC est donc un
très bon choix.
On voit ici que ces prototypes sont plus complexes que notre Arduino Uno…
Il ne va rien corriger à notre place et si ça ne fonctionne pas, c’est que l’on s’est
trompé. Mais rien de grave, il suffira de trouver l’erreur, de la corriger et de lui
renvoyer le nouveau programme. On parle alors de déboggage, pour trouver les
bugs de programme.
Une des explications connues du terme débogguer viendrait d’ailleurs du
monde de l’électronique au temps des premiers ordinateurs qui fonctionnaient
avec des relais, dans les années 1940-1950. À cette époque, un ordinateur moins
puissant que notre Arduino prenait la place d’une pièce entière, et consommait
énormément d’énergie.
En consommant de l’énergie, les armoires où se trouvaient tous ses compo-
sants étaient assez chaudes pour que les insectes du genre punaises, cafards et
autres papillons s’y installent. Un de ces systèmes étant alors tombé en panne, il
a fallu le dépanner. La cause de la panne fut trouvée, et elle était due à un insecte
(bug en anglais), qui s’était coincé dans un des composants. Jolie légende…
Aujourd’hui, nous n’avons plus d’insectes dans nos ordinateurs, mais les bugs
sont toujours bien là et nous apprendrons à les trouver.
INSTALLATION DE L’IDE
Nous allons à présent installer notre IDE. Les installations suivantes ont été
faites sous Windows 10, sous MacOS ElCapitan, Mojave et Catalina mais aussi
sur un Raspberry équipé de Linux Raspbian. Les procédures peuvent légèrement
changer suivant les ordinateurs utilisés, mais on s’y retrouvera facilement.
Le site officiel d’Arduino est www.arduino.cc. Bien que ce site soit en anglais,
il est très facile de comprendre ce qu’il s’y passe. Pour télécharger la version de
l’IDE qui correspond au système d’exploitation de notre ordinateur, on va aller à
la page www.arduino.cc/en/Main/Software.
On clique alors sur le bouton Contribute and Download pour faire un don, ou sur
le bouton Download pour simplement télécharger, au choix.
Il suffira alors de cliquer sur cette icône pour lancer notre nouvel IDE Arduino
qui s’ouvre avec un nouveau programme par défaut. Le premier lancement est
parfois un peu long, mais rien d’affolant.
Une fois l’extraction terminée, aller dans ce nouveau répertoire créé et cliquer
sur Arduino.
Partie 1 : tout en haut, il s’agit du panneau de commande où l’on retrouve les
boutons pour Compiler, Téléverser et Créer, Charger, Sauver un programme.
Partie 2 : au centre, on retrouve l’Éditeur, dans lequel nous allons écrire notre pro-
gramme source (notre code source, ou sketch ou encore croquis en langage Arduino).
Partie 3 : et en bas, il s’agit de la fenêtre de Résultats, dans laquelle notre IDE
nous dira s’il a trouvé un bug, si tout s’est bien passé ou autre.
// LES SAUVEGARDES
Lorsque l’on clique sur le bouton Enregistrer, l’IDE sauvegarde le sketch sur
lequel on travaille sur le disque de l’ordinateur. Par exemple, si ce sketch s’appelle
Prog1, l’IDE va se charger de le renommer Prog1.ino (il met lui-même ino après
chaque nom de fichier afin de s’y retrouver). Il va même créer un répertoire Prog1
dans lequel il va ranger le programme Prog1.ino. Il est super ordonné !
Si on avait déjà un sketch nommé Prog1.ino sur notre disque dur, il sera rem-
placé par le nouveau Prog1.ino, ce qui est normal.
// LE PINOUT
Un document très important est le pinout de notre carte. Le pinout explique
sur quels connecteurs nous allons trouver les informations qui nous intéressent,
et comment elles sont reliées au µC de notre Arduino. Il peut également être
téléchargé sur cette page : store.arduino.cc/arduino-uno-rev3.
// CHOIX DU PORT
Maintenant que nous avons indiqué à notre IDE quel type de carte nous utili-
sons, il va falloir lui indiquer sur quelle prise (sur quel Port) de notre ordinateur
nous allons la brancher.
BLINK
Pour nous faciliter les choses, l’EDI de l’Arduino est livré avec tout un tas
d’exemples que l’on peut étudier et réutiliser. Ils peuvent servir de base à nos
propres créations.
Sur un système à µC ou à µP avec un écran, ou sur un ordinateur, on a pour
habitude d’appeler notre premier programme d’apprentissage « Hello World »,
c’est-à-dire « Bonjour le monde ». Comme nous n’avons pas d’écran sur notre
Arduino, l’autre premier programme d’apprentissage que nous allons pouvoir
écrire s’appelle « Blink » en anglais, ou « Clignoter ».
Généralement sur les petits systèmes à µC, on a l’habitude de mettre une Led
que l’on pourra allumer ou éteindre à volonté, et qui pourra être parfois bien pra-
tique pour nous servir de repère dans notre programme.
Par exemple, si un endroit de notre programme fonctionne mal, on pourra le
découper en parties plus petites, et allumer et éteindre cette Led à différentes
étapes. Si la Led ne s’allume pas alors qu’elle aurait dû le faire à un moment pré-
cis, cela veut sans doute dire que notre programme comporte un bug juste avant
cela et qu’il est bloqué.
Ces exemples vont aussi nous permettre d’explorer toutes les facettes de
notre carte. Cependant, il y a des exemples qui ne fonctionneront pas avec notre
Arduino Uno, comme ceux qui font appel aux liaisons Ethernet.
En effet, notre carte n’a pas de connexion Ethernet et il faudrait alors utiliser
un autre modèle d’Arduino.
Nous allons donc pour l’instant ouvrir le sketch Blink qui se trouve dans les
exemples livrés avec l’IDE, puis le compiler et le téléverser sur la carte.
Ce sketch fait clignoter la Led notée L sur notre carte, et elle clignotait déjà
lorsque l’on a branché la carte toute neuve sur l’ordinateur car ce programme était
déjà embarqué. Ce n’est pas grave, car nous allons tout de même apprendre pas
mal de choses essentielles pour continuer et Blink nous servira de cobaye pour nos
premières expériences.
Allons-y !
// CHARGEMENT
Pour ouvrir le programme Blink et donc le charger dans l’EDI, il suffira d’aller
dans le menu Fichier, puis Exemples et 01.Basics et enfin Blink.
Blink /35
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off
delay(1000); // wait for a second
}
Pour l’instant, nous allons juste le compiler et le téléverser dans notre carte.
// COMPILATION
La compilation d’un sketch se fait simplement en cliquant sur le bouton Vérifier.
Figure 2.3 Compilation
Figure 2.5 Téléversement
Blink /37
Pendant le téléversement, deux
Leds jaunes Rx et Tx de la carte
Arduino se sont mises à clignoter rapi-
dement, au fur et à mesure que l’EDI
dialoguait avec elles. Une fois ces
échanges terminés, la Led orange L se
met à clignoter indéfiniment.
Notre premier programme s’exé-
cute sans souci !
Maintenant que cette première
étape est passée, nous pourrons Figure 2.7 La Led L de la carte Arduino
regarder d’un peu plus près comment
tout cela fonctionne.
UN ORGANIGRAMME
Un organigramme est un dessin avec des cases qui permet de découper chaque
étape du programme et de les mettre les unes après les autres sur le papier. Ainsi,
on pourra réfléchir comme notre µC le fait lui-même, et si on n’arrive pas au résul-
tat voulu en suivant cet organigramme, notre Arduino n’y arrivera pas non plus
(une fois de plus, il ne réfléchit pas à notre place…).
Par exemple, pour Blink, on veut faire clignoter la Led L qui se trouve sur notre
carte Arduino. Cela signifie qu’il faut l’allumer, attendre, l’éteindre, attendre, et
recommencer indéfiniment.
L’organigramme général pourrait être comme ceci.
Blink /39
On voit ici que cet exemple en Scratch ressemble beaucoup à un organi-
gramme…
Pour en revenir à nos moutons, j’avais fait une faute dans le sketch de Blink en
tapant la phrase « N’importe quoi ! ». Maintenant que l’on a vu pourquoi la vérifi-
cation avait échoué, nous allons donc aller à la ligne indiquée en orange par l’EDI
et la corriger.
Lorsque l’erreur est corrigée, ce qui n’est pas toujours facile avouons-le, on
peut recompiler le sketch et le téléverser.
On voit que chaque bit d’un octet mémoire porte un petit nom, de b7 à b0.
b7 b6 b5 b4 b3 b2 b1 b0
Chaque bit peut avoir deux valeurs possibles, soit 0 soit 1. On dit qu’il est posi-
tionné à 1 ou à 0. De plus, il peut aussi ne comporter qu’un seul symbole et on
peut dire que b7 vaut 1 ou 0, mais on ne peut pas dire que b7 vaut 101, car 101 est
constitué de trois symboles.
Pourquoi cela ? Avant d’aller plus loin, on ne panique pas sur ce qui va suivre, et on
prend un papier et un crayon pour réfléchir en même temps qu’on lit les exemples…
REMARQUE
En informatique, on utilise le symbole * au lieu du symbole mathématique × pour
faire une multiplication. Par exemple, 3 fois 2 se note 3 * 2, et non pas 3 × 2.
Donc, en combinant tout ça, et en ne prenant que les bits qui sont positionnés
à 1, on a la valeur décimale de notre octet qui est alors :
1*128 + 1*64 + 0*32 + 1*16 + 1*8 + 0*4 + 0*2 + 1*1
Donc 128 + 64 + 16 + 8 + 1 = 217.
Et voilà !
QUESTION PIÈGE
Si on parle du nombre 101, est-ce que c’est 101 en décimal, ou 101 en binaire ? Et
bien si on écrit simplement 101, on considère qu’il s’agit de 101 en décimal, comme
on compte d’habitude. Si on veut parler de la valeur 101 en binaire, on écrit habi-
tuellement 0b (zéro suivi de la lettre b) devant afin de montrer que l’on parle d’une
valeur binaire. Ainsi, 0b101 est bien un nombre binaire qui équivaut à 5 en décimal
si on refait notre petite conversion comme tout à l’heure.
À quoi ça sert ?
Et bien lorsque l’on a étudié le pinout de notre carte Arduino, on a vu que cer-
taines pins de nos connecteurs s’appellent par exemple D0 ou D7.
Si on se dit que D7 peut correspondre à b7 de notre octet, et si D0 du connec-
teur peut correspondre à b0, alors on comprend mieux à quoi cela peut servir.
On va pourvoir associer chaque pin du connecteur à un bit d’octet, ce qui nous
permettra de mettre cette pin à 1 ou à 0, c’est-à-dire de l’activer ou non.
Si on met des Leds sur chaque sortie des connecteurs de D7 à D0, que l’on met
notre octet à 11011001 comme on vient de le voir, et que l’on transfère cet octet sur
les sorties D7 à D0 du connecteur, alors les Leds branchées sur D7-D6-D4-D3-D0
// LE SYSTÈME HEXADÉCIMAL
En dehors de notre système de comptage décimal et du système binaire que
nous venons de voir, il existe un autre système de comptage que l’on utilise beau-
coup en informatique : le système hexadécimal.
Décimal était sur une base de 10 (on compte de 0 à 9 en utilisant 10 symboles,
puis on recommence). Hexadécimal est quant à lui sur une base de 16 symboles
(d’où son nom de hexa).
En binaire, on a deux symboles : 0‑1.
En décimal, on a 10 symboles : 0‑1-2‑3-4‑5-6‑7-8‑9.
En hexadécimal, on a 16 symboles : 0‑1-2‑3-4‑5-6‑7-8‑9-A-B-C-D-E-F.
C’est un peu déroutant, mais notre nombre 217 décimal qui s’écrivait également
0b11011001 peut maintenant s’écrire D9 en hexadécimal…
Au lieu de trois symboles, on n’en utilise que deux, d’où son utilité.
On a vu que pour compter en décimal, après 8‑9 on reprend 1 et on lui colle 0
pour avoir 10 puis 11‑12‑13‑14, etc.
En hexa, ce sera la même chose. Après D-E-F, on reprend 1 et on lui colle 0 pour
continuer ainsi : D-E-F-10‑11‑12…
Décimal
0‑1-2‑3-4‑5-6‑7-8‑9-10‑11‑12‑13‑14‑15‑16‑17‑18‑19‑20‑21‑22‑23…
Hexadécimal
0‑1-2‑3-4‑5-6‑7-8‑9-A-B-C-D-E-F-10‑11‑12‑13‑14‑15‑16‑17‑18‑19‑1A-1B-1C-1D-
1E-1F-20…
On voit tout de suite que l’on peut compter en utilisant moins de symboles.
Pour faire la conversion, on va regrouper notre octet en deux groupes de quatre
bits.
Ainsi, pour notre valeur 217, on écrira en exagérant :
b7 b6 b5 b4 b3 b2 b1 b0
1 1 0 1 1 0 0 1
Pour le système décimal, on avait fixé l’équivalence suivante.
b7 b6 b5 b4 b3 b2 b1 b0
128 64 32 16 8 4 2 1
Pour notre conversion hexa, comme on considère notre octet de huit bits en
deux groupes de quatre bits (deux quartets), on ne va s’occuper que d’un quartet
// PRINCIPE KISS
Avant tout, un sketch est une suite d’instructions qui seront exécutées les unes
après les autres. On va donc avoir un ensemble de lignes de codes, chaque ligne
(ou presque) étant terminée par un point virgule ; et un retour à la ligne.
Même s’il ne sert à rien pour le compilateur, le retour à la ligne permettra de
faire des programmes plus lisibles.
On peut dire sans beaucoup se tromper que ceci :
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
Les variables
Nous avons vu que les constantes sont simples à utiliser et qu’il n’y a pas besoin
de leur donner de type si on les define car le compilateur s’en charge tout seul, ce
qui n’est pas le cas des const. Les variables sont également simples à utiliser, mais
il y a quelques précautions à prendre tout comme avec les const.
Pour déclarer une variable, il va falloir indiquer au compilateur combien de
cases mémoires on veut qu’il lui réserve. On le fera en indiquant le type de chaque
variable.
byte monAge;
Ici, on peut choisir un type byte qui peut contenir un nombre de 0 à 255, il y a
peu de chances que l’on puisse le dépasser. Un byte suffit donc.
Si on veut mémoriser le nombre de jours de soleil dans les îles, on devra
prendre un nombre plus grand, int ou un unsigned int.
int nombreDeJoursDeSoleil;
Les tableaux
Pour ranger nos données, on pourra utiliser les tableaux. Dans un tableau, on
aura des lignes et des colonnes et toutes les données devront être du même type.
On pourra ainsi créer des tableaux de char ou d’unsigned int par exemple.
À NOTER
La première case de notre tableau de dix cases aura donc l’indice 0, et la dernière
l’indice 9.
// LES FONCTIONS
Pour écrire notre programme, on va utiliser des fonctions qui sont déjà définies
et connues par notre EDI, ainsi que d’autres fonctions qu’il ne connaît pas mais
que l’on va lui apprendre au fur et à mesure de nos besoins.
/ FONCTIONS
digitalWrite()
digitalWrite() permet d’écrire 1 ou 0 sur la pin du connecteur que l’on désire
activer ou désactiver.
pin est le numéro de la pin, value est l’état HIGH ou LOW que l’on désire mettre.
On s’en servira pour allumer ou éteindre une Led par exemple.
Syntaxe :
digitalWrite(pin, value)
Paramètres :
> pin : Numéro de la pin
> value : HIGH ou LOW
Exemple :
digitalWrite(LedRouge, LOW)
digitalRead()
digitalRead() permet de lire l’état de la pin du connecteur que l’on désire
interroger.
On pourra s’en servir pour lire l’état d’un bouton poussoir.
pinMode()
pinMode() permet de mettre la pin du connecteur en entrée ou en sortie.
Le mode peut être en entrée INPUT, en sortie OUTPUT ou encore en entrée avec
une résistance de pull-up activée INPUT_PULLUP (nous reparlerons de ce mode).
On l’utilisera pour indiquer à l’Arduino comment arranger son électronique
interne pour lire un bouton poussoir ou activer une Led par exemple.
Syntaxe :
pinMode(pin, mode);
Paramètres :
>> pin : numéro de la pin
>> mode : INPUT, OUTPUT ou INPUT_PULLUP
Exemples :
pinMode(LedRouge, OUTPUT);
pinMode(leBoutonPoussoir, INPUT);
analogRead()
En plus de ses entrées numériques qui ne peuvent gérer que des valeurs
binaires (marche/arrêt ou on/off par exemple), l’Arduino Uno comporte des
entrées analogiques (des pins A0 à A5), qui peuvent lire toutes les valeurs
comprises entre 0 et 5 V, avec une grande précision.
Dans ses circuits internes, il a un convertisseur analogique/numérique qui
va pouvoir transformer une tension 0‑5 V en une valeur binaire que l’on pourra
ensuite utiliser dans nos programmes.
Nous avons déjà vu les conversions décimales vers binaire, et il s’agit un peu
de la même chose pour les conversions analogiques/numériques. Notre µC va
regarder ce qu’il se passe sur une de ses entrées analogiques avec une grande
précision, regarder si cette valeur est petite, moyenne, grande ou autre et ranger
le résultat de sa conversion sur un mot binaire de 10 bits.
Cela veut dire que pour une tension de 0 V sur une de ces entrées, notre µC va tra-
duire ça en 0b0000000000 et pour une tension maximale de 5V il va traduire cela
en 0b1111111111. Pour 2,5 V ce sera la moitié de cette valeur binaire et ainsi de suite.
Si on refait un rapide calcul sur 10 bits, 0b1111111111 est égal à 1 024 en décimal. Il est
donc capable de mesurer cette tension de 5V en la découpant en 1 024 morceaux.
On en reparlera un peu plus tard en étudiant le potentiomètre. Retenons le
fait que la valeur retournée par cette fonction est sur 10 bits (1 024 en décimal),
analogWrite()
La fonction analogWrite() permet de créer une tension variable sur la pin considé-
rée. Sur la carte Arduino Uno, il s’agira d’un signal PWM qu’il faudra associer à d’autres
composants pour créer un vrai signal analogique que nous étudierons plus tard.
Syntaxe :
analogWrite(pin, value)
Paramètres :
>> pin : numéro de la pin
>> value : valeur entre 0 et 255
Exemple :
int out = 9; // sortie analogique sur pin 9
void setup() {
pinMode(out, OUTPUT); // pin out en sortie
}
void loop() {
analogWrite(out, 125); // met un PWM à 125
}
tone()
Si on connecte un buzzer ou un haut-parleur sur la sortie pin, la fonction tone()
permet de créer un signal qui permettra de produire un son de fréquence fre-
quency. Cette fréquence s’exprime en hertz (Hz).
Par exemple, la note LA a une fréquence de 440 Hz, et chaque note est définie
par sa fréquence.
Pour stopper le son, on utilisera ensuite la fonction noTone().
Une autre syntaxe est disponible pour cette fonction avec laquelle on peut indi-
quer la durée du son par le paramètre duration. Dans ce cas, la fonction noTone()
n’est plus utile.
noTone()
Cette fonction permet de stopper le signal qui a été mis à disposition par la
fonction précédente sur la sortie pin.
Syntaxe :
noTone(pin)
Paramètres :
>> pin : numéro de la pin
Exemple :
noTone(sortieBuzzer)
delay()
La fonction delay() permet de créer un temps d’attente d’une durée de ms,
exprimé en millisecondes (ms : millièmes de secondes).
Syntaxe :
delay(ms)
Paramètres :
>> ms : durée en millisecondes
Exemple :
delay(1000); // Crée un temps d’attente de 1 seconde
delayMicroseconds()
La fonction delayMicroseconds() permet quant à elle de créer un temps
d’attente de us, exprimé en microsecondes (µs : millionièmes de seconde).
La valeur maximale de ce délai est de 16 383 microsecondes (16 383 µs).
Il y a 1 000 µs dans une ms, et 1 000 ms dans 1 seconde.
Syntaxe :
delayMicroseconds(us)
Paramètres :
>> ms : durée en microsecondes
Exemple :
delayMicroseconds(1000); // Crée un temps d’attente de 0,001 seconde
#include
#include indique au compilateur qu’il devra inclure ce qu’il y a dans un fichier
bibliothèque lors de la compilation.
Par exemple, si on veut inclure le code source qu’il y a dans le fichier biblio_
LCD.h que l’on avait écrit pour un autre projet, on indiquera :
#include <biblio_LCD.h>
Ainsi, on pourra utiliser tout ce qu’il y a dans ce fichier bibliothèque, sans avoir
à tout réécrire (d’où l’intérêt d’une bibliothèque…).
Nous essaierons les bibliothèques un peu plus tard.
HIGH
Il s’agit d’une constante qui correspond à l’état haut dans le monde Arduino.
Ainsi, on pourra l’utiliser pour activer une sortie :
digitalWrite(LED_BUILTIN, HIGH);
LOW
À l’opposé de HIGH, il s’agit d’une constante qui va servir à mettre une sortie à
l’état bas.
digitalWrite(LED_BUILTIN, LOW);
INPUT
INPUT est une constante du monde Arduino qui permettra de positionner une
broche du µC en entrée afin de pouvoir lire la valeur du signal qui arrive dessus.
Par exemple, pour paramétrer une pin du microcontrolleur qui devra recevoir
un bouton poussoir pour lire son état, on écrira :
pinMode(BOUTON, INPUT);
OUTPUT
De la même manière, OUTPUT servira à configurer une pin du µC en sortie, pour
activer une Led par exemple :
pinMode(LED_ROUGE, OUTPUT);
LED_BUILTIN
Cette constante représente la Led qui est montée en standard sur notre carte
Arduino, et que nous activons avec le premier programme Blink.
digitalWrite(LED_BUILTIN, HIGH);
true
Cette constante vaut 1 et représente la valeur Vrai pour des tests.
false
Celle-ci représente la valeur Faux et vaut 0.
// OPÉRATEURS
Pour effectuer des opérations comme l’addition ou la multiplication par
exemple, nous aurons besoin d’opérateurs.
Les opérateurs qui suivent sont donc utilisés pour les opérations mathéma-
tiques, mais aussi pour comparer des nombres ou des variables. Il existe égale-
ment des opérateurs logiques qui permettront de faire des opérations sur nos
octets.
Opérateurs composés
Certains des opérateurs vus précédemment peuvent avoir une écriture un peu
particulière, mais très pratique.
Par exemple, on peut très bien écrire :
x = 7;
x = x + 1; // on ajoute 1 à la variable x, donc x = 8
Opérateurs logiques
Un opérateur logique va donc, comme son nom l’indique, faire des opérations
de logique booléenne. On va ainsi pouvoir faire des opérations sur des bits, et des
donc des opérations sur des octets.
Par la suite, on pourra appliquer ces opérateurs à des signaux électriques à
l’aide de portes logiques. On parle alors de logique combinatoire.
Il ne faut PAS les confondre avec les opérateurs de comparaison !
On retrouve bien notre tableau, avec cependant une notation encore différente
pour dire ~(A&B).
Ici, il y a Y = AB, avec une barre au-dessus. On lit cela AB barre.
La notation en algèbre de Boole dit que AB (ou encore A.B) veut dire A & B,
donc A ET B.
OR
Sortie = A + B donc A OU B
Figure 3.6
Figure 3.7
NOT
Sortie = A\ donc NON A
Figure 3.8
NOR
Sortie = (A+B)\ donc NON (A OU B)
Figure 3.9
NAND
Sortie = (AB)\ donc NON (A ET B)
Figure 3.10
Il reste encore un opérateur que nous n’avons pas vu et qui est le XOR, ou bien
OU EXCLUSIF.
Figure 3.11
On utilisera assez peu le XOR par rapport aux autres portes, mais il peut nous
servir à simplifier des équations.
// INSTRUCTIONS
Afin d’indiquer à notre µC ce qu’il doit faire précisément, on va utiliser tout un
jeu d’instructions qui est propre à chaque langage. Par exemple, en C on pourra
dire :
if (valeur == 10) {
montantDuLoyer = 25;
Changer = true;
}
En assembleur, on aura quelque chose qui ressemblera à ceci :
.CursOff MOVE.L D0, (A0)+ ; Display On, Curseur off, not Blink
MOVEQ #$0C, D0
MOVE.B D0, LCD
JSR .WaiLCD
MOVE.L -(A0), D0
RTS
if
L’instruction if, qui veut dire si en anglais, permet de tester la valeur de nos
variables. Par exemple, si on veut savoir si leScore est égal à 10, on utilisera la
forme suivante en pseudocode (du code qui ressemble à du code, et qui n’en est
pas vraiment mais qui permet de réfléchir…)
si (leScore est 10)
alors onLesABattu
onEstContents
onVaFeterCa
Ce que l’on peut facilement traduire par :
if (leScore == 10) {
onLesABattu = true;
onEstContents = true;
onVaFeterCa = true;
}
PRÉSENTATION DU CODE
Contrairement à d’autres langages comme Python, nous n’avons pas besoin de
respecter une mise en forme particulière pour notre code. On pourra tout aussi
bien écrire :
if (leScore == 10) {
onLesABattu = true;
onEstContents = true;
onVaFeterCa = true;
}
Ou encore :
if (leScore == 10) {
onLesABattu = true;
On voit ici que la ligne commence par if, puis on met ce que l’on veut tester
entre parenthèses. On met ensuite une paire d’accolades {} entre lesquelles on
va mettre ce qu’il y a à faire si la condition testée est vraie.
On a donc la syntaxe suivante :
if (condition est vraie) {
on fait ceci
et encore cela
}
Une erreur de frappe courante est d’écrire :
if (leScore = 10) {
bla bla bla…
}
Qui voit l’erreur ?
Eh bien on a utilisé = au lieu de == (un seul signe = au lieu de deux).
On a ainsi dit leScore vaut 10 au lieu de poser la question Est-ce que le score
vaut 10 ? Grave erreur, car le compilateur ne verra pas l’erreur. En effet, il n’y a
pas de faute de syntaxe. Par contre, le programme ne fonctionnera pas comme
attendu.
Nous avons déjà vu les opérateurs de comparaison, comme == ou encore >=.
C’est ici que l’on va principalement les utiliser.
De même, s’il n’y a qu’une seule chose à faire après la comparaison, on peut se
passer de mettre les accolades :
if (leScore > 10)
onEstSuperBons = true;
On peut également utiliser plusieurs termes dans la comparaison.
Par exemple, si on veut tester ceci :
si (leMatch est gagné) et (leTemps est ensoleillé)
alors on va piqueniquer
On pourrait utiliser l’opérateur ET que nous avons vu précédemment :
if ((leMatchEstGagne == true) && (leTemps == SOLEIL)) {
onVaPiqueNiquer();
}
else
Le else est utilisé avec le if. Si on traduit else en français, cela veut dire autre,
dans le sens autrement ou sinon.
On peut donc dire par exemple :
si (leMatch est gagné) et (leTemps est ensoleillé)
alors on pourrait piqueniquer
sinon
on mangera dedans
et on rentrera en bus
Et donc en code :
if ((leMatchEstGagne == true) && (leTemps == SOLEIL))
onVaPiqueNiquer();
else {
onMangeraDedans();
onRentreraEnBus = true;
}
On voit ici que je n’ai pas mis d’accolade après le if. En effet, il n’y a qu’une
seule instruction ensuite. Par contre, j’en ai mis pour le else car il y a plusieurs
lignes à prendre en compte.
On peut donc dire en résumé :
if (condition vraie) {
on fait ceci
et cela
}
else {
on fera ça
et ça
}
On peut même enchaîner les instructions if pour traiter plusieurs cas.
if (condition vraie) {
on fait ceci
et cela
}
else if (autre condition vraie) {
on fera ça
}
else {
on fera ça
et ça
}
while ()
L’instruction while permet d’effectuer une boucle, c’est-à-dire que si la condi-
tion qui se trouve entre parenthèses est vraie, le programme va effectuer ce qu’il
y a entre les parenthèses suivantes indéfiniment.
Il ne sortira de cette boucle que lorsque la condition deviendra fausse, et il
restera dans la boucle tant que la condition ne sera pas remplie.
On peut par exemple dire :
Tant que (leScore < 10)
onMarqueDesButs
etOnContinue
encoreEtEncore
Ce que l’on peut traduire par :
while (leScore < 10) {
onMarqueDesButs();
etOnContinue();
encoreEtEncore();
}
Comment sortir de la boucle ? On en sortira lorsque leScore sera égal à 10, ce
qui veut dire qu’il faut marquer un but à chaque tour de while si on veut s’en sortir
rapidement… Ensuite, le programme reprendra son cours normal.
while (leScore < 10) {
onMarqueDesButs();
etOnContinue();
encoreEtEncore();
leScore ++; // Ici, leScore = leScore +1
}
onAGagne(); // A la sortie de la boucle, on continue
Si la condition est vraie au moment où l’on va rentrer dans la boucle, celle-ci ne
sera pas exécutée. En effet, si on a déjà 10 buts ou plus, pas la peine d’en marquer
d’autres, on a déjà gagné.
do...while ()
L’instruction do while () ressemble à l’instruction while().
La seule différence est que la condition est testée à la fin de la boucle, ce qui
veut dire que celle-ci sera exécutée au moins une fois.
do {
onMarqueDesButs(); // On marque TANT QUE le score est < 10
} while(leScore < 10);
for
Pour faire des boucles où on comptera le nombre de tours effectués, on utili-
sera une boucle for.
Par exemple :
for (int i=0; i<10; i++) {
onRepete(); // On refait ça 10 fois
}
goto
L’instruction goto est très peu utilisée en C, et on évitera son emploi.
On pourra s’en servir pour sortir d’une boucle, et aller à un endroit bien spéci-
fique du programme.
for (int i=0; i<10; i++) {
Serial.println(i);
if (i==4) goto QUATRE;
}
QUATRE:
Serial.println("QUATRE FOIS");
Lorsque i vaudra 4, au lieu de continuer dans la boucle normalement, le pro-
gramme sera interrompu et ira directement à l’étiquette QUATRE. Le résultat sur
le Moniteur Série sera alors 0-1-2-3-4-QUATRE FOIS…
return
L’instruction return permet de retourner un résultat depuis une fonction. Si
une fonction doit retourner la valeur d’une variable x de type int par exemple,
on aura alors :
int leCalcul(void) {
x = x+1;
return(x);
}
On pourra alors récupérer le résultat de ce calcul lors de l’appel de la fonction :
y = leCalcul();
Dans ce cas-là, la variable y prendra la valeur retournée par notre fonction,
c’est-à-dire par ce qui a été calculé dans leCalcul().
break
Le break va permettre de casser une séquence, par exemple pour sortir d’une
boucle for ou d’un while plus tôt que prévu, sans exécuter le reste.
for (i=0, i<10, i++) {
Serial.println(i);
if (i==4) break; // On sort prematurement
}
continue
À l’inverse de break, continue va permettre de retourner au début de la boucle
si on le souhaite, sans effectuer les instructions qui suivent :
for (int i = 0; i < 10; i ++)
{
if (i > 4){ // retour au debut si i > 4
continue;
Serial.println(i); // On ecrit: 0 1 2 3 4 0 1 2 …
}
Avec tout ça, on a déjà de quoi bien s’amuser, et passer de longues heures à coder.
Il ne faudra pas hésiter à faire des petits sketches de quelques lignes, juste
pour essayer et voir comment fonctionnent ces instructions.
Le moniteur Série que nous utiliserons plus tard sera alors d’une grande utilité.
Figure 3.14 MonBlink
Notre EDI va l’enregistrer dans le répertoire Croquis, qui est le répertoire par défaut
de nos sketchs. Ce répertoire par défaut est défini dans les Paramètres d’Arduino.
Figure 3.16 MonBlink
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
On voit que le temps du delay() est 1 000 pour l’allumage et pour l’extinc-
tion de la Led. On pourrait peut-être rajouter deux constantes de temps, une
pour l’allumage, et une pour l’extinction. Ainsi, si on veut modifier un temps ou
un autre, on n’aura pas besoin de chercher partout dans le programme, il suffira
d’aller voir du côté des constantes. C’est nettement plus pratique.
On pourrait faire ainsi, en mettant ON et OFF à deux valeurs différentes :
#define TEMPS_ON 1000 // 1000 milliseconde = 1 seconde
#define TEMPS_OFF 500 // 500 millisecondes = 0,5 secondes
Notre loop( ) deviendrait alors :
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(TEMPS_ON);
digitalWrite(LED_BUILTIN, LOW);
delay(TEMPS_OFF);
}
Comme on a déjà parlé des fonctions dans les chapitres précédents, il est
temps de les essayer. Au lieu d’appeler digitalWrite( ) puis delay( ), on pour-
rait regrouper ces deux fonctions en une seule, en lui passant un paramètre de
temps par exemple.
Déclarons notre fonction d’allumage :
void allumeLed(int duree) {
digitalWrite(LED_BUILTIN, HIGH);
delay(duree);
}
Et notre fonction d’extinction :
void eteindLed(int duree) {
digitalWrite(LED_BUILTIN, LOW);
delay(duree);
}
Ici, dans notre fonction allumeLed( ), on appelle digitalWrite( ), puis delay( )
en lui passant la valeur de la durée. Même chose pour la fonction eteindLed( ).
void loop() {
gereLed(HIGH, TEMPS_ON);
gereLed(LOW, TEMPS_OFF);
}
LES BIBLIOTHÈQUES
En plus d’être un IDE simple à utiliser, notre environnement de programmation
nous donne accès à une fonction qui est intéressante, et qui est la gestion des
Bibliothèques.
Une Bibliothèque (ou une Librairie) regroupe des fonctions qui ont été écrites
par d’autres développeurs par exemple, et que l’on peut utiliser de façon simple.
Par exemple, dans notre sketch MonBlink, on a écrit des fonctions intéressantes
telles que gereLed(), allumeLed() ou eteindLed(). Chaque fois que l’on utilise des
Leds dans nos montages, on pourrait reprendre la source de MonBlink, retrouver
ces fonctions et faire des copier/coller dans notre nouveau sketch. Ce serait une
solution, mais pas très élégante. De plus, si on a écrit d’autres fonctions dans d’autres
sketchs, il faudrait à chaque fois essayer de les retrouver pour les réutiliser ailleurs.
Pas très pratique…
D’où l’idée de regrouper toutes ces petites fonctions dans des fichiers séparés,
de les classer par type, et de les réutiliser plus tard. On aurait ainsi créé une biblio-
thèque, dans laquelle on pourrait venir piocher nos fonctions au besoin, sans tout
réécrire à chaque fois. De même, pour les partager avec d’autres programmeurs,
ce serait super simple. On pourrait par exemple avoir une bibliothèque avec plein
de fonctions pour les Leds, une autre spécialisée dans les boutons poussoirs, une
autre dans la gestion d’un écran, etc.
Allons dans le menu des exemples pour ouvrir le fichier Exemples/Liquid
Crystal/Cursor.
Ce sketch montre l’utilisation d’un écran LCD avec l’Arduino, ce que nous ferons
un peu plus tard.
Pour utiliser un écran, il faudrait donc écrire toutes les fonctions qui per-
mettent de gérer le curseur, d’écrire un caractère, d’effacer l’écran et j’en passe.
Pas mal d’heures de programmation et de déboggage en perspective. Heureu-
sement, il existe une bibliothèque toute prête pour gérer un écran LCD, et nous
pouvons l’utiliser.
Regardons à la ligne 41 de l’exemple que nous venons d’ouvrir :
// include the library code:
#include <LiquidCrystal.h>
Après le commentaire, on y trouve un #include, suivi de < > avec un nom de
fichier qui est ici LiquidCrystal.h.
Ce nom de fichier correspond au fichier entête de cette librairie, c’est-à-dire au
fichier dans lequel on va retrouver les noms de toutes les fonctions, variables et
constantes disponibles.
Pour ajouter une bibliothèque à notre IDE, il suffit d’aller dans le menu Croquis/
Inclure une bibliothèque.
Si on va dans le menu Gérer les bibliothèques, notre IDE va d’abord faire une
mise à jour des bibliothèques dont il peut disposer.
On voit que notre carte comporte des composants bien différents les uns des
autres et nous allons regarder comment les représenter sur un schéma.
// SYMBOLE DE LA RÉSISTANCE
On a déjà vu à quoi ressemble le symbole de la résistance, mais suivant la
convention utilisée (ou le logiciel de schémas utilisé), on peut avoir ces deux
représentations possibles et qui sont strictement identiques :
En général, on lui donne aussi un nom. Ici, elle s’appelle R (comme Résistance),
suivi du chiffre 1 comme c’est la première résistance du schéma, et bien cela
donne le nom de R1.
Si on en rajoute une, elle s’appellera R2 et cela donnera par exemple :
Figure 4.4
On note aussi sa valeur, par exemple 1 KΩ (sur les schémas, on marque parfois
seulement 1 K au lieu de 1 KΩ – on prononce 1 kilo ohm).
La liste de tous les composants utilisés s’appelle alors une nomenclature.
// SYMBOLE DE LA LED
En électronique, on dessine le symbole de la Led de cette façon :
Figure 4.5
On lui donne aussi un nom (LED1), et une valeur (Rouge par exemple).
Les petites flèches sur le symbole de la Led montrent qu’elle fait de la lumière,
et on a un triangle et une barre droite.
Il y a déjà une Led intégrée à la carte Arduino, et nous allons donc en câbler une
seconde sur le connecteur d’extension de l’Arduino.
Nous allons la brancher avec une RÉSISTANCE, mais on va tout d’abord obser-
ver ces composants de très près.
// LA LED
La LED (Light Emitting Diode), ou Diode Electro Luminescente (DEL) en français,
est un composant qui va s’allumer lorsqu’elle est traversée par un courant.
Pourquoi ma LED a-t-elle une patte plus grande que l’autre ? C’est normal ?
Eh bien OUI, c’est normal. En fait, c’est normal et c’est même très pratique.
Une LED a bien deux pattes, et comme beaucoup de composants en élec
tronique, elles ne servent pas toutes les deux à la même chose.
Si on regarde la LED de près, et même de très très près, on va également aper-
cevoir ce qu’il y a à l’intérieur : on va voir son PLUS et son MOINS…
Regardons-la à la loupe :
Figure 4.10
On voit qu’à l’intérieur il y a une plus petite plaque et une autre moins petite.
IMPORTANT
La LED a donc une ANODE et une CATHODE.
L’ANODE est la PLUS grande patte, la CATHODE est la MOINS grande patte.
On branche l’ANODE au PLUS, et la CATHODE au MOINS.
Pour câbler la Led sur l’Arduino, il va également nous falloir une Résistance.
// LA RÉSISTANCE
La Résistance est un composant essentiel en électronique.
renons-en une en main, par exemple une qui est Rouge-Rouge-
P
Figure 4.12
Marron-Or dans la main et observons-la également.
Comme on le voit, elle a un corps avec deux pattes et des
anneaux de couleurs.
Figure 4.13
Avec ce code, si on veut écrire 220 Ω, on va prendre les deux premiers chiffres
de la valeur, et ensuite le nombre de zéros qu’il y a après.
Sur le CODE DES COULEURS, on a donc :
Bague 1 : 2 = Rouge
Bague 2 : 2 = Rouge
Bague 3 : 0 = Marron
Bague Or dans la main droite.
On a donc 220 = Rouge-Rouge-Marron…
Pour 1 KΩ par exemple, soit = 1 000 Ω, on peut dire que 1 000 s’écrit un peu
comme 10 suivi de deux zéros, soit 10 00.
En prenant le code des couleurs, on a :
Bague 1 : 1 = Marron
Bague 2 : 0 = Noir
Bague 3 : 00 = Rouge
Et Bague Or à droite :
Figure 4.15
Figure 4.16
Pour notre montage, on va choisir une résistance de valeur 220 Ω, soit avec des
bagues Rouge-Rouge-Marron-Or.
Nous verrons plus tard comment on peut calculer cette valeur de résistance de
façon plus précise.
L’écriture chimique de cette molécule d’eau est H2O, ce qui veut dire qu’elle est
composée de deux molécules d’hydrogène (H) et d’une molécule d’oxygène (O).
Si on regarde à présent son atome d’hydrogène avec nos super lunettes, on
verra qu’il est lui-même composé d’éléments élémentaires. Il comporte un noyau
avec un électron qui tourne autour de ce noyau. Ce sont des éléments extrême-
ment petits.
On voit aussi que tous les électrons ne tournent pas sur la même orbite, et qu’il
peut y en avoir une très grande quantité qui tourne autour du noyau. Il y en a qui
sont proches du noyau, d’autres qui sont plus loin.
Une matière est généralement constituée d’un assemblage de plusieurs types
d’atomes qui vont donc former des molécules, ces molécules assemblées les unes
aux autres vont former la matière que nous connaissons. Un fil électrique est par
exemple constitué d’un assemblage de cuivre et potentiellement d’autres maté-
riaux. Ce qui veut dire aussi que sous nos yeux, tout ce petit monde bouge en
permanence, et ceci dans tous les matériaux qui nous entourent.
Tous ces éléments primaires sont classés dans le Tableau périodique des élé-
ments ou Tableau de Mendeleïev, imaginé par le chimiste russe Dmitri Ivanovitch
Mendeleïev en 1869. On y trouve différentes informations sur la constitution de
chacun des atomes que nous connaissons.
// LE COURANT
On a vu que ces électrons qui tournent autour du noyau lui sont fortement liés,
et ils ne peuvent en principe pas partir. Ils vont tourner autour du noyau indéfini-
ment. Ce sont donc des électrons liés. Cependant, si des électrons tournent sur
une orbite qui se trouve plus loin du noyau, sur la dernière couche par exemple, ils
peuvent être éjectés et récupérés par un autre atome. Si un autre électron a déjà
été éjecté d’un atome voisin, le nôtre ira prendre sa place et tournera autour de
ce nouveau noyau. Ce sont des électrons libres. Ils se baladent d’atome en atome.
S’ils se baladent ainsi d’atome en atome et tous dans le même sens, ils créent
alors un courant d’électrons : c’est le courant électrique.
Si un élément est constitué uniquement d’électrons fortement liés, il n’y aura
donc pas de courant électrique. Le sens de déplacement de tout ce beau monde
déterminera également les électrodes positives ou négatives. Par convention,
// LA TENSION
Pour que nos électrons aient envie de se déplacer ainsi, et tous dans le même
sens, il faut qu’il y ait quelque chose que les y oblige un peu. En effet, on a vu que
les électrons libres peuvent sauter sur des atomes qui ont déjà perdu un électron
et prendre leur place.
Pour réaliser cela, il faut donc créer un déséquilibre électrique entre les deux
extrémités de notre fil afin de permettre ce déplacement d’électrons. Ce déséqui-
libre est appelé différence de potentiel et se mesure en volts (du nom d ’Alessandro
Volta, physicien italien du xviiie siècle). C’est la tension.
Le courant et la tension se mesurent ainsi, avec un ampèremètre et un volt-
mètre.
// LA PUISSANCE
Maintenant que l’on connaît le courant et la tension, on va pouvoir commencer
à écrire des équations intéressantes.
La première qui lie ces deux valeurs est la puissance, et c’est le produit du
courant et de la tension.
PUISSANCE
P=U×I
Elle s’exprime en watts (W), du nom de l’ingénieur écossais James Watt vivant
au xviiie siècle. Dans cette équation, la tension U s’exprime en volts et le courant I
s’exprime en ampères.
Si on considère des milliampères dans notre montage, il faudra impérativement
les convertir en ampères avant d’utiliser cette équation.
Il est très important de calculer la puissance que reçoit un composant (la puis-
sance absorbée), afin de vérifier qu’il est bien capable de résister aux contraintes
de courant et de tension qu’on lui impose, sans qu’il ne parte en fumée… Si on fait
passer 10 W dans un composant qui ne peut accepter que 1 W, il va très rapidement
brûler.
// LA RÉSISTANCE ÉLECTRIQUE
La résistance électrique d’un matériau est sa capacité à s’opposer au passage
du courant, c’est-à-dire au déplacement des électrons libres qui le constituent.
Cette résistance définit si un corps est électriquement conducteur ou isolant.
Dans un matériau isolant, les électrons libres sont peu nombreux et le courant a
donc du mal à se créer puisque peu d’électrons sont capables de se déplacer. Au
contraire, dans un matériau conducteur, il y a beaucoup d’électrons libres qui ne
demandent qu’à se balader. De plus, le matériau facilite leur déplacement.
// LA LOI D’OHM
Pour calculer la valeur de la résistance à utiliser dans nos montages, on utili-
sera la loi d’Ohm qui fait intervenir la tension en volts, le courant en ampère et
donc la résistance en ohm. Ils sont reliés par la formule suivante :
LOI D’OHM
U=R×I
FORMULES USUELLES
Si on veut calculer la tension : U = R × I (en volts)
U
Si on veut calculer le courant : I = (en ampères)
R
U
Si on veut calculer la résistance : R = (en ohms)
I
U
On voit donc bien le rôle de la résistance sur cette équation I = .
R
Plus la résistance est grande, plus le courant sera faible.
La sortie de notre Arduino sur laquelle est connectée la Led avec sa résistance
donne une tension de 5 V. Sur ce schéma, on voit que la Led et la résistance sup-
portent également cette tension de 5 V à elles deux.
Comme la datasheet de la Led nous indique que la tension à ses bornes est de
2 V lorsqu’elle est correctement alimentée, on peut dire que la résistance voit une
tension de 5 – 2 = 3 V.
Ici, la Led et la résistance sont traversées par le même courant car elles sont
en série, l’une derrière l’autre, et on voit que le courant qui sort de la pile ne peut
pas aller ailleurs que dans la résistance puis dans la Led.
Comme on veut calculer la valeur de la résistance, on va prendre le courant qui la
traverse, ainsi que la tension qu’il y a à ses bornes, soit 3 V comme on vient de le voir.
Donc notre formule R = U / I devient R = 3 / 0,020 = 150 Ω.
Pour les résistances que l’on utilise couramment, toutes les valeurs n’existent
pas en réalité. On n’aura pas par exemple de résistance de 250 ohms ou de
251,3 ohms.
Il n’existe que des valeurs approchées et normalisées et celles que l’on va
utiliser appartiennent à une famille que l’on appelle la série E12 pour laquelle il
n’existe que 12 valeurs qui sont :
1,0 ; 1,2 ; 1,5 ; 1,8 ; 2,2 ; 2,7 ; 3,3 ; 3,9 ; 4,7 ; 5,6 ; 6,8 ; et 8,2 ainsi que leurs mul-
tiples et sous-multiples.
Par exemple, on trouvera des résistances d’une valeur de 1,5 ohm ou de
15 ohms ou encore de 1 500 ohms, tout comme des résistances de 2 700 ohms ou
27 000 000 ohms.
Comme il nous faut une résistance de 150 ohms pour notre montage, ça tombe
bien puisqu’elle existe dans la série E12. Dans le cas où le calcul donnerait une
valeur qui n’est pas dans cette série E12, on pourrait prendre la valeur la plus
proche, ou bien changer de série et prendre des résistances de précision de la
série E48 ou E96 par exemple, mais qui seraient plus chères à l’achat.
ASSOCIATION DE RÉSISTANCES
Les résistances sont des composants simples d’utilisation, mais sont indispen-
sables à tous nos montages, et leur valeur est quelquefois très importante bien
que l’on puisse assez souvent choisir une valeur approximative.
Par exemple, on voudrait utiliser une résistance de 220 ohms pour notre mon-
tage, mais on a récupéré une pleine poignée de 100 ohms et de 470 ohms sur un
ancien appareil électronique. Comment faire ? On ne peut pas les couper en deux
pour n’en prendre que 220 ohms, mais il y a un autre moyen d’y arriver…
Il existe deux façons d’associer les résistances : on peut les monter en série ou
en parallèle.
// MONTAGE EN PARALLÈLE
Le problème est que l’on a aussi récupéré des résistances de 470 Ω sur ce vieil
appareil que l’on a démonté.
Essayons de les monter en parallèle.
Sur notre plaque d’essai, on peut alors avoir l’un de ces trois montages au choix.
Avec tout ce que nous avons déjà appris, nous allons pouvoir commencer à
créer des montages plus sympas et voir comment on pourra :
>> Rajouter des Leds à Arduino
>> Utiliser des boutons poussoirs, un potentiomètre
>> Réaliser des montages très cools
// MISE EN ŒUVRE
Le montage
Prenons la plaque d’expérimentation pour effectuer ce câblage.
Le programme
Comme on l’a fait au chapitre précédent avec le programme Blink qui était dans
les exemples livrés avec Arduino, on va écrire notre programme, et le téléverser
sur la carte.
Reprenons le programme de l’exemple Blink, qui a servi à faire clignoter la Led
orange de la carte Arduino.
Programme Blink
Reprenons le sketch Blink d’origine, et sauvegardons-le en LedExterne.ino.
Voici ce que l’on a :
// the setup function runs once when you press reset or power the board
void setup() { // initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
Pour faire un clignotant comme on l’a fait avec Blink, on pourrait faire exac-
tement comme avec ce bouton poussoir, et cela fonctionnerait. Par contre, il va
falloir aller vite si on veut que ça clignote rapidement… Notre programme Blink
était donc une bonne solution.
etatDuBouton = digitalRead(laPinALire);
Suivant si le bouton est appuyé ou non, etatDuBouton vaudra donc true ou false.
Dans l’initialisation, on a mit etatDuBouton=0, même si on va lui donner un peu
plus tard la valeur du bouton. Dans le fond, ça ne sert à rien, mais c’est une bonne
habitude à prendre d’initialiser les variables, même si on pense qu’elles ne servent
pas tout de suite. En effet, une variable non initialisée peut être une source de bug
importante et difficile à détecter.
Il va donc à présent falloir modifier notre schéma pour brancher le bouton
poussoir sur l’Arduino, ainsi que la Led. Le symbole utilisé pour le bouton poussoir
est ici un peu bizarre par rapport au schéma précédent, mais c’est celui qui est
dans la bibliothèque Fritzing, donc nous allons l’utiliser. La résistance du bouton
poussoir est ici de 10 K, car nous n’avons pas besoin de beaucoup de courant pour
entrer dans l’Arduino. Comme tout à l’heure, nous allons brancher la Led rouge et
sa résistance, sur la sortie 8. Le bouton poussoir sera quant à lui câblé sur la pin 7.
Attention au câblage du bouton poussoir s’il a quatre pattes, car elles sont
souvent reliées deux à deux sur ces modèles.
Notre programme ressemblera donc à ceci.
// (c)Frédéric SILLON 2020
// Bouton poussoir sur pin 7 pour allumer ou eteindre la Led
#define LED_EXTERNE 8 // Explique à l’IDE que la Led est sur la pin 8
#define BOUTON_POUSSOIR 7 // Bouton poussoir connecte sur pin 7
int etatDuBouton = 0; // Sauvegarde de l'état du bouton (on/off)
On voit bien qu’il s’agit d’une résistance, mais avec une patte en plus. Cette
patte supplémentaire est le curseur. C’est lui que l’on va raccorder à notre entrée
analogique, et qui nous donnera une valeur en ohms qui sera variable en fonction
de sa position, ce que l’on comprend bien sur le schéma. Les deux autres pattes
se branchent comme une résistance normale.
Si on place le curseur de notre potentiomètre au milieu de sa course, on
comprend facilement que l’on a partagé cette résistance en deux parties égales,
et que l’on a un peu la même chose que sur le schéma de droite (5 KΩ + 5 KΩ
= 10 KΩ).
Si on branche cet ensemble de deux résistances en 5 V, on voit aussi qu’il n’y
aura que la moitié des 5 V sur le curseur, donc 2,5 V.
Dans cette formule, il est important de bien respecter qui est R1 et qui est R2,
sinon tout sera faux. On peut se dire pour s’en souvenir que R1 est en haut et R2
est en bas par exemple.
On voit aussi que l’on a réussi à convertir la position du curseur qui est en ohms
en une valeur en volts que l’on pourra mesurer avec notre Arduino. C’est plutôt
intéressant.
On pourra raccorder ce fameux potentiomètre à notre carte suivant ce schéma,
mais nous ferons le montage et les essais un peu plus tard.
Avant cela, il faut étudier analogRead() d’un peu plus près, et voir de quelle
manière cette fonction est utilisable.
CONVERSION ANALOGIQUE/NUMÉRIQUE
Si on regarde de nouveau l’aide d’Arduino sur le site de référence à la rubrique
analogRead (www.arduino.cc/reference/en/language/functions/analog-io/
analogread/), on voit que l’Arduino Uno comporte six entrées analogiques notées A0
à A5, et qu’elles ont un operating voltage de 5 volts et une résolution max de 10 bits :
Sur notre montage, le potentiomètre est alimenté en 5 V, avec son curseur sur
l’entrée A0 de l’Arduino. C’est donc OK pour l’operating voltage et aussi pour le
choix de l’entrée A0 (usable pin = pin utilisable).
À quoi correspondent ces 10 bits de résolution ?
La description de analogRead sur le site indique ceci :
Reads the value from the specified analog pin. Arduino boards contain a multi
channel, 10-bit analog to digital converter. This means that it will map input
voltages between 0 and the operating voltage (5V or 3.3V) into integer values
between 0 and 1023. On an Arduino UNO, for example, this yields a resolution
between readings of: 5 volts / 1024 units or, 0.0049 volts (4.9 mV) per unit. See
the table below for the usable pins, operating voltage and maximum resolution
for some Arduino boards.
On pourra utiliser un traducteur en ligne pour traduire ce paragraphe si on
n’est pas trop à l’aise en anglais, et il ne faudra pas hésiter à s’aider de ce type
d’informations car elles seront très utiles. De plus, notre niveau en anglais tech-
nique va s’améliorer petit à petit, ce qui est également une très bonne chose…
Globalement, ça veut donc dire que notre UNO va découper sa tension de
5 volts en 1 024 petites unités, ce qui lui donnera une résolution de 5 volts / 1 024
= 0,0049 volts par unité, soit 4,9 mV.
Il va ensuite lire ce qui est présent sur l’entrée A0 par exemple, et compter
combien de fois il y a d’unités de 4,9 mV.
Comme il part de la valeur zéro pour compter, ces 1 024 unités iront de 0 à
1 023 (ce qui fait bien 1 024 en tout si on compte le 0).
Par exemple, si on lui présente 1,25 V sur l’entrée A0, il va nous retourner un
chiffre correspondant au nombre d’unités 4,9 mV contenues dans 1,25 V. Si on
fait le calcul, on aura 1,25/0,0049 = 255. C’est cette valeur qui sera donnée par
analogRead().
Cela veut dire qu’avec une instruction analogRead(), notre Arduino Uno pourra
lire une tension sur une des pins A0 à A5 avec une précision de 4,9 mV.
C’est plutôt pas mal du tout. Il pourra par exemple faire la différence entre 1,0 V
et 1,0049 V.
La tension qu’il lira sera alors :
Tension = ValeurLue * 0,0049 volt.
Par exemple, s’il lit 236, la tension vaudra 236*0,0049 = 1,1564 V.
// LE CHENILLARD
Avant d’aller plus loin, nous allons réaliser un chenillard avec quatre Leds. Il
nous servira pour notre test de conversion analogique/numérique avec le poten-
tiomètre. Le principe est de les allumer et de les éteindre les unes après les autres
afin de créer un effet de défilement.
Voici le schéma avec les quatre Leds et leurs résistances. Chaque Led sera
pilotée par une sortie de l’Arduino, de D9 à D12. Les valeurs des résistances ont
déjà été calculées dans les chapitres précédents, nous n’y reviendrons donc
pas ici.
Pour chaque sortie, et chacune à leur tour, on fera appel à digitalWrite() pour
les allumer ou les éteindre.
Pour régler la vitesse, on mettra une temporisation avec la fonction delay().
Enfin, en mettant tout ça dans la boucle loop(), le chenillard défilera indéfiniment.
Bien sûr, il faudra tout d’abord définir les pins que nous utiliserons en output
dans la fonction setup() de notre programme.
// (c)Frédéric SILLON 2020
// Chenillard avec Leds sur pins 9, 10, 11, 12
// Arduino UNO
digitalWrite(LED_B, HIGH);
delay(500);
digitalWrite(LED_B, LOW);
digitalWrite(LED_C, HIGH);
delay(500);
digitalWrite(LED_C, LOW);
digitalWrite(LED_D, HIGH);
delay(500);
digitalWrite(LED_D, LOW);
}
On compile et on téléverse le logiciel : on a un super beau chenillard !
Par contre, je trouve que ce programme est un peu trop long, surtout que l’on
répète presque quatre fois la même chose dans le loop().
Profitons-en pour essayer de faire un peu mieux : accrochons-nous…
Si on regarde notre schéma et les #define du programme d’un peu plus près,
on se rend compte que LED_A vaut 9, que LED_B vaut 10, LED_C vaut 11 et que LED_D
vaut 12.
Ça n’a l’air de rien, mais on pourrait aussi dire que LED_B = LED_A + 1 et aussi
que LED_C = LED_B + 1, et ainsi de suite.
Pourquoi ?
// --- Definition des Leds sur les pins 9, 10, 11, 12 du connecteur Arduino
#define LED_A 9
#define LED_B 10
#define LED_C 11
#define LED_D 12
// --- Definition des Leds sur les pins 9, 10, 11, 12 du connecteur Arduino
#define LED_A 9 // On definit LED1, les autres seront calculees
// automatiquement
// --- On met les pins de chaque Led en sortie
void setup() {
int i;
for (i=0; i<4; i++) {
pinMode(LED_A + i, OUTPUT); // En sortie pour chaque Led
digitalWrite(LED_A + i, LOW); // On eteint les Leds
}
}
Il s’agit d’une fenêtre qui nous permet de dialoguer avec notre Arduino par le
biais du cordon USB.
L’Arduino va pouvoir y envoyer des résultats, et on pourra taper des comman
des qui seront envoyées à la carte. À nous programmeurs de développer le pro-
gramme qui lira ces données reçues par l’Arduino.
Pour que l’Arduino envoie une chaîne de caractères vers le Moniteur série, il
suffit de mettre une ligne dans notre programme, par exemple :
Serial.print(“Bonjour”);
Avant cela, il faudra lui indiquer à quelle vitesse on veut que les informations
circulent. Dans le moniteur série, on voit que la vitesse est ici de 19 200 bauds.
Il va alors falloir mettre la même vitesse dans notre programme afin que les
deux se comprennent, et on mettra cette instruction dans le setup():
Serial.begin(19200);
Petite astuce : si on rajoute \n à la fin de la phrase, le moniteur série sautera une
ligne après avoir écrit, ce qui sera beaucoup plus lisible pour la phrase suivante :
Serial.begin(19200);
Serial.print("Initialisation du setup terminée \n");
Serial.print("Tout est prêt !!");
Donc, si on veut que notre Arduino envoie la valeur lue sur la pin A0 (le
POTENTIO), on pourra passer par cette fonction Serial.print().
// (c)Frédéric SILLON 2020
// Chenillard avec Leds sur pins 9, 10, 11, 12
// Reglage de vitesse avec potentiometre et sortie sur le Moniteur Serie
// Arduino UNO
// --- Definition des Leds sur les pins 9, 10, 11, 12 du connecteur Arduino
#define LED_A 9 // On ne definit que LED_A
#define POTENTIO A0 // Et le potentiometre sur A0
ET À L’ENVERS…
Maintenant que l’on sait faire varier la vitesse de notre chenillard avec le poten-
tiomètre, on va essayer de le faire tourner à l’envers.
Si on utilisait le bouton poussoir, on pourrait le faire tourner dans un sens si
le bouton est relâché, et dans l’autre sens s’il est appuyé, tout ceci en gardant le
réglage de vitesse…
Allons-y !
Comme dans l’exemple du bouton poussoir, on va le câbler sur la pin D7, le che-
nillard restera tel qu’il est déjà et on va donc avoir le schéma suivant.
// --- Definition des Leds sur les pins 9, 10, 11, 12 du connecteur Arduino
#define LED_A 9 // On ne definit que LED_A
#define POTENTIO A0 // Et le potentiometre sur A0
#define BOUTON_POUSSOIR 7 // Bouton poussoir connecte sur pin 7
Et à l’envers… /133
// --- Le chenillard se deroule
void loop() {
int i; // Pour compter dans la boucle for
int conversion; // Pour lecture du Potentio
Et à l’envers… /135
Je vous laisse faire l’exercice tout seul, et même s’il ne fonctionne pas du
premier coup, il ne faut pas se décourager. Pour savoir si votre nouvelle version
fonctionne, il faudra juste vérifier qu’elle se compile correctement, et que le résul-
tat est bien celui attendu lorsque le croquis sera téléchargé sur la carte Arduino.
// LE TRANSISTOR NPN
On voit bien sur ce schéma équivalent que le courant qui traverse la Led n’est
pas fourni par la sortie de l’Arduino, mais directement par l’alimentation 5V du
système. On ne risque plus de détruire notre cher ATMega.
Si on met un état Low sur la sortie de l’Arduino qui pilote ce montage, on n’aura
pas de courant qui va arriver sur sa Base, et le transistor sera bloqué.
Il est alors comme un interrupteur ouvert et la Led est éteinte.
On retrouve effectivement ici le symbole que nous avons utilisé pour notre
schéma, et aussi le brochage en boîtier TO92. Il en existe deux versions, avec les
pattes droites ou pliées.
En partant de la gauche, on voit bien où est le Collecteur, la Base et l’Emetteur.
Pour le repérer sur le boîtier lui-même, il suffit de mettre la face plate face à
soi, et la pin 1 se trouvera à gauche.
Passons au schéma et à l’implantation sur l’Arduino.
Avant de brancher tout ça sur l’ordinateur, il faudra bien vérifier le câblage afin
d’être sûr qu’il n’y ait pas de court-circuit, car le montage commence à devenir un
petit peu complexe à câbler.
Dans ce schéma, on utilise l’alimentation 5V de l’Arduino pour alimenter le
montage à transistor.
Un des autres avantages de ce type de montages est que l’on peut utiliser une
autre source d’alimentation. Par exemple, on pourrait alimenter notre Arduino
en 5V, et le transistor pilotant la Led en 12V.
Cela permet de piloter des systèmes différents de celui de commande de façon
très simple.
On aurait également pu utiliser un transistor spécialisé en commutation, mais
notre petit 2N2222 est suffisant pour ce type de montages. Si on n’en a pas, il
suffira de regarder les caractéristiques d’un autre modèle et d’adapter la résis-
tance de base par exemple.
On pourra aussi démonter un vieil appareil qui ne sert plus et récupérer un
transistor dessus. De toutes façons, ces petits transistors ne sont pas très chers
et sont très souvent utilisés, et ce sera une bonne chose d’en avoir une poignée
sous la main pour divers montages.
Au niveau du code, on pourra reprendre le croquis que l’on avait écrit pour
MonBlink. On obtiendra exactement le même résultat, mais avec un montage dif-
férent qui fait intervenir notre transistor.
// (c)Frédéric SILLON 2020
// Clignotant avec la Led Externe sur Pin 8 et la Led interne L
/ TRANSISTOR PNP
On a vu que ce transistor est un modèle NPN. Que se passe-t-il avec un modèle
PNP ? Pour le savoir, on va réaliser le même type de montage, mais avec un tran-
sistor 2N2907, toujours en boîtier TO-92.
En cherchant la datasheet du 2N2907 sur Internet, on la trouvera également
chez le fabricant OnSemi. Son brochage et son symbole sont :
On voit tout de suite que la flèche qui est présente sur son symbole au niveau
de l’émetteur est dans l’autre sens. Il y a fort à parier que son utilisation sera
différente…
Si on refait le même montage que précédemment avec ce 2N2907 (PNP), la
Led et la résistance seront toujours sur le Collecteur, mais avec l’Emetteur à l’ali-
mentation au lieu du zéro volt.
/ LE TRANSISTOR MOSFET
Les transistors précédents sont des modèles dits bipolaires (PNP et NPN).
Il existe cependant d’autres modèles, dont le MOSFET. Si on recherche de nou-
veau une datasheet de mosfet sur Internet, on choisira par exemple le BS170.
On voit tout de suite qu’il s’agit d’un composant bien différent. Il est plus parti-
culièrement adapté au mode commutation et s’utilise très simplement.
On ne parlera plus de Base, Collecteur et Emetteur, mais de Grille (Gate en
anglais), Drain et Source.
Si on regarde les Maximum Ratings du BS170, on verra qu’il ne faut pas dépas-
ser certaines valeurs comme la tension VDSS qui représente la tension maximale
qu’il peut y avoir entre le Drain et la Source (60 V). Dans notre montage, il n’y aura
que 5 volts au maximum, on sera donc correct. Pareil pour la tension VGSS (entre
Gate et Source) qui doit être de 20 V max. Avec notre sortie Arduino qui ne fournit
que 5 V, on sera également très bien.
Le courant circulant dans le Drain ne devra pas dépasser 500 mA. Il faudra
donc bien calculer notre résistance de drain pour ne pas dépasser cette valeur.
On voit ici que le premier mosfet Q1 est piloté par notre sortie D8 Arduino.
Donc lorsque la sortie Arduino amènera un niveau HIGH sur ce premier mosfet,
celui-là deviendra conducteur. Sa jonction Drain-Source sera comme un interrup-
teur fermé, et la cathode de la Led_1 se trouvera à Gnd. Elle va donc s’allumer. Si
ce n’est pas très clair, on pourra revoir les chapitres précédents.
Si l’Arduino applique un niveau LOW sur sa sortie D8, le mosfet Q1 sera alors
bloqué et se comportera comme un interrupteur ouvert. La Led_1 sera alors
éteinte.
Pour le second mosfet Q2, lorsque la sortie Arduino mettra un état HIGH sur
sa sortie D8, on vient de voir que la jonction Drain-Source de Q1 est comme un
court-circuit, et la cathode de Led_1 est à Gnd. Cela veut dire que la Grille de Q2
est également à Gnd. Donc, Q2 va être bloqué et sa jonction Drain-Source sera
ouverte. Dans ce cas, la Led_2 sera éteinte.
Si Arduino met ensuite sa sortie D8 à LOW, on a vu que Q1 est bloqué, donc sa
jonction Drain-Source est ouverte. Dans ce cas, la grille de Q2 ne voit plus Gnd,
mais elle voit la tension qu’il y a sur la cathode de la Led_1. Q2 va fermer sa jonc-
tion Drain-Source. La Led_2 va alors s’allumer.
Si on regarde ces signaux avec un oscilloscope, on pourra voir comment tout
cela se passe en réalité.
Un oscilloscope est un appareil que l’on branche sur le circuit que l’on veut exa-
miner. Il permet de visualiser les signaux électriques comme ils sont en réalité.
Comme il s’agit d’un appareil coûteux et assez complexe à utiliser, nous n’en par-
lerons pas davantage, mais il est bon de savoir qu’il existe. On branche simplement
ses fils sur les signaux que l’on veut visualiser, et on peut les observer en vrai !
La trace du haut est branchée sur la sortie D8 de l’Arduino, et la trace du bas
est branchée sur la grille de Q2. On voit bien ici que pendant que la première est
à HIGH, la seconde est à LOW et inversement.
Comme un petit dessin vaut mieux qu’un grand discours, voici le schéma pour
l’état HIGH et pour l’état LOW de la sortie D8 de notre cher Arduino.
Nous allons voir des fonctions que l’on appelle « avancées » de notre Arduino,
en utilisant des fonctions plus complexes dont il dispose en interne.
Accrochons-nous…
LE PWM
Le PWM est une fonction interne de l’Arduino, qui signifie Pulse Width Modula
tion… En français, il s’agit de modulation en largeur d’impulsion, ou MLI.
Jusqu’à présent, nos sorties digitales de l’Arduino nous donnaient des états
High ou Low lors de l’utilisation de digitalWrite(). Comme on l’a vu sur l’oscil-
logramme du chapitre précédent sur la sortie D8, on avait choisi par programme
que la durée de l’état High était d’une seconde, et que la durée de l’état Low était
d’une seconde également.
On peut donc dire que nos impulsions ont une durée d’une seconde.
Si on voulait faire varier cette largeur de nos impulsions, on pourrait changer
la valeur du delay() à chaque passage dans la boucle.
Ce serait un peu complexe, mais ça fonctionnerait. On pourrait également
garder la même durée de l’état Low, et ne changer que la durée de l’état High à
chaque tour de loop().
En faisant ainsi, on aurait en quelque sorte une modulation en largeur d’im-
pulsion, car on modifierait la largeur de nos impulsions à chaque tour de loop().
Ce n’est pas très pratique, mais c’est un peu le principe du PWM. Non seule-
ment il gère lui-même la largeur de ces impulsions, mais aussi à quel moment a
lieu le changement d’état.
Le PWM /151
Si on regardait un tel programme à l’oscilloscope, on aurait quelque chose comme :
Le rapport qu’il y a entre l’état haut et l’état bas du signal ainsi créé s’appelle
le rapport cyclique. Dans notre sketch Blink, lorsque l’on a mis delay(1000) pour
l’allumage et pour l’extinction des Leds, on avait un rapport cyclique de 50 % car
la durée de l’état haut était égale à la durée de l’état bas.
Un rapport cyclique de 0 % indique que le signal est toujours Low, et un rap-
port cyclique de 100 % indique qu’il est toujours High. Entre ces deux extrêmes,
le rapport cyclique varie.
Il y a un second paramètre à prendre en compte pour un PWM : la fréquence.
La fréquence indique à quelle vitesse le signal se répète. S’il repasse à l’état haut
toutes les secondes, il aura une fréquence de 1 hertz (1 Hz).
Le hertz est l’unité de mesure de fréquence.
À partir d’un top départ, s’il repasse à l’état haut toutes les 0,1 seconde, on aura
une fréquence de 10 Hz.
La formule magique pour déterminer la fréquence F en fonction du temps T est :
1
F=
T
Le temps T est en secondes, et la fréquence F en hertz.
Ainsi, si le signal revient à l’état haut toutes les 0,1 seconde, on aura une fré-
quence de 1/ 0,1 = 10 Hz. Il revient alors à l’état high 10 fois par seconde.
Comme pour les autres unités, on va avoir des Hz, des KHz (1 KHz = 1 kilohertz
= 1 000 Hz), des MHz (1 MHz = 1 mégahertz = 1 000 000 Hz) et bien plus encore.
Sur la carte Arduino UNO, on voit que ces sorties sont D3, D5, D6, D9, D10 et D11.
Nous avons déjà utilisé les sorties D9, D10, D11 et D12 pour notre chenillard par
exemple, et cela veut donc dire que certaines pins de notre Arduino peuvent avoir
plusieurs fonctions.
Pour programmer D9 en état HIGH ou LOW par exemple, on avait utilisé la fonc-
tion digitalWrite(). On aurait également pu mettre un bouton poussoir sur D9 au
lieu de le mettre sur D7 comme nous l’avons fait précédemment avec digitalRead().
À présent, nous allons utiliser une autre fonction que l’on va associer à une pin :
analogWrite(). Nous avions déjà parlé de analogWrite(), car elle permet de géné-
rer un signal variable sur la pin considérée. Si on veut créer un signal qui varie de 0
à 5 volts (un signal analogique), il faudra associer quelques composants simples à
cette sortie. Pour l’instant, on va l’utiliser telle quelle est, en fonction PWM.
Nous avons vu qu’un PWM est défini par la fréquence du signal qu’il produit,
ainsi que par son rapport cyclique. Avec analogWrite(), nous allons simplement
définir la pin à utiliser, ainsi que le rapport cyclique désiré qui peut varier de 0
à 100 %. Pour la fréquence du signal, c’est l’Arduino lui-même qui s’occupe de tout.
La syntaxe est alors la suivante :
analogWrite(pin, valeur);
Pin est le numéro de la sortie.
Valeur est un entier qui varie de 0 à 255 pour définir un rapport cyclique de 0
à 100 % (127 correspondra donc à 50 %).
Pour utiliser une sortie en PWM avec analogWrite(), il n’est pas nécessaire
de la déclarer en sortie avec pinMode() comme nous l’avions fait pour digital
Write(). Arduino se débrouille tout seul…
Avec le petit sketch que voici, nous allons pouvoir créer un PWM, et l’observer
à l’oscilloscope.
Le PWM /153
// (c)Frédéric SILLON 2020
// Signal PWM sur la sortie D9
void setup() {
analogWrite(SIGNAL_PWM, RAPPORT_CYCLIQUE);
}
void loop() {
// Rien à faire, le PWM tourne tout seul ...
}
void setup() {
rapportCyclique = 0;
analogWrite(SIGNAL_PWM, rapportCyclique);
}
void loop() {
rapportCyclique +=10;
analogWrite(SIGNAL_PWM, rapportCyclique);
delay(100);
if (rapportCyclique==255)
rapportCyclique = 0;
}
À présent, on a déclaré une variable rapportCyclique afin de pouvoir la faire
varier dans le loop() en l’incrémentant de 10 toutes les 100 ms de delay().
Ainsi, notre Led va s’allumer progressivement toute seule pendant que le rap-
port cyclique du PWM passe de 0 à 255.
Le PWM /157
Passons maintenant au code.
Nous avons vu qu’il fallait câbler nos trois anodes sur les sorties PWM de
l’Arduino afin de pouvoir utiliser la fonction analogWrite() pour créer un effet
de fader sur chaque couleur. Nous avons donc utilisé D9, D10 et D11 qui sont repé-
rées par le symbole tilde (~) sur le connecteur de notre carte.
Pour gérer les trois couleurs de façon indépendante, nous allons donc créer
trois variables qui vont s’incrémenter à chaque tour de loop() afin de changer la
couleur finale des trois composantes (RGB) mélangées, et qui seront mises dans
les PWM correspondant à chaque couleur.
Premier essai
// (c)Frédéric SILLON 2020
// Signal PWM avec LED RGB multicolore
#define RED 9 // Led RED sur la pin 9
#define GREEN 10 // Led GREEN sur la pin 10
#define BLUE 11 // Led BLUE sur la pin 11
unsigned char redPWM, greenPWM, bluePWM; // Rapport cyclique PWM des trois↵
composantes
void setup() {
redPWM = greenPWM = bluePWM = 0;
analogWrite(RED, redPWM);
analogWrite(GREEN, greenPWM);
analogWrite(BLUE, bluePWM);
}
void loop() {
redPWM +=10;
greenPWM +=10;
bluePWM +=10;
analogWrite(RED, redPWM);
analogWrite(GREEN, greenPWM);
analogWrite(BLUE, bluePWM);
delay(100);
}
Avec ce croquis, on voit que la Led produit une lumière blanc/bleu, mais qu’il
n’y a pas nos 16 millions de couleurs. En effet, quand on mélange les trois couleurs
RGB en quantités égales, on va créer une lumière presque blanche.
Si on veut une lumière qui soit davantage rouge, on va par exemple incrémenter
redPWM beaucoup plus lentement afin de conserver cette couleur plus longtemps
que les deux autres, ou bien la laisser fixe sans l’incrémenter.
Second essai
redPWM = 200; // On initialise redPWM à une valeur fixe
En jouant sur les différentes valeurs des trois PWM, on va pouvoir obtenir des
couleurs vraiment très belles.
Je vous laisse essayer et choisir les valeurs de PWM pour vos plus belles couleurs.
LA LIAISON SÉRIE
Pour que notre Arduino communique avec le monde extérieur, nous avons déjà
utilisé les fonctions telles que digitalRead() et digitalWrite() par exemple.
Avec ce type de fonctions, on peut agir sur le monde extérieur, mais il est plus
difficile de transmettre des ordres par exemple, ou des résultats de calcul.
Pour les résultats, on pourrait très bien les coder en binaire et sortir sur des Leds.
On pourrait imaginer de brancher huit Leds sur l’Arduino et ainsi créer un octet
qui nous servirait à écrire un résultat en binaire. L’inconvénient pour nous humains
est qu’il faudrait faire la conversion de tête à chaque fois qu’un résultat se présente.
De même, on serait limités à des nombres de 8 bits, donc compris entre 0 et 255.
Pour écrire sur l’Arduino, on pourrait également imaginer huit boutons pous-
soirs ou interrupteurs branchés sur les entrées de notre Arduino.
Ainsi, suivant le code binaire que l’on appliquerait sur ces entrées avec nos
interrupteurs, notre µC pourrait interpréter ça comme tel ou tel ordre.
En fait, ce principe était utilisé au tout début des ordinateurs, certains n’avaient
ni clavier ni écran, et on communiquait avec eux de cette façon.
Par chance, notre Arduino dispose d’une interface que nous avons déjà utilisée,
et qui est l’interface série.
// LA SÉRIALISATION
Le principe de la sérialisation est simple : plutôt que de coder nos dialogues sur
huit bits, il suffit de prendre chacun des bits à tour de rôle, et de recopier leur état
sur une seule sortie, un peu comme des billes dans une sarbacane.
On va commencer par le bit b0 par exemple, et suivant s’il est à 1 ou à 0, on va passer
la sortie série à High ou à Low. Ensuite, on regarde l’état du bit b1 et suivant son état,
on passera la même sortie de communication série à High ou à Low. Et ainsi de suite.
De cette façon, on peut passer une très grande quantité d’informations sur un
seul fil, à la queue leu leu.
Pour sécuriser cette transmission, on pourra intercaler des bits de contrôle dans
ce flux de données. Par exemple, à la fin de la transmission, on pourra envoyer un
octet (avec tous ses bits à la queue leu leu) qui donnera le nombre de bits envoyés.
// FORMAT
Dans notre transmission série, il va donc y avoir un émetteur (notre Arduino
par exemple), et un récepteur (notre ordinateur avec l’IDE et son Moniteur Série).
Du côté récepteur, les bits reçus sont poussés les uns après les autres en
mémoire afin de reconstituer notre octet. C’est plutôt bien fait…
De cette façon, on peut donc faire passer nos 8 bits les uns après les autres,
mais on pourrait en transmettre 16 ou 64 ou plus, toujours avec notre fil unique.
Si on reprend la datasheet de notre ATMega328P, on aura les informations
suivantes sur la trame transmise (frame en anglais).
On retrouve bien notre schéma précédent, avec les bits à transmettre, chacun
d’eux ayant ici un petit nom particulier (notés en anglais sous la trame).
Idle : représente l’état de repos du fil de transmission qui pourrait être High ou
Low. Dans une transmission série comme celle-ci, l’état de repos correspond à High.
St : il s’agit du bit de Start, qui passe à l’état Low pour signaler que la transmis-
sion commence. C’est le coup de sifflet du chef de gare.
0 à 8 : voici les bits d’information à transmettre, de b0 à b8 (ce qui fait 9 bits
au total). Si on veut transmettre seulement 8 bits (de b0 à b7), on l’indiquera à
notre ATMega lors de la configuration de son USART. Si on veut en transmettre
davantage, il suffira de les envoyer les uns après les autres dans d’autres octets
en suivant, c’est simple.
P : il s’agit de l’un de ses fameux bits de contrôle dont nous avions parlé un peu
plus tôt. Celui-là est le bit de Parité. Lorsqu’il transmet, l’USART calcule tout seul
la valeur High ou Low de ce bit, en fonction du nombre de bits à High ou Low qu’il
y a dans notre octet b0-b8 à transmettre. On ne va pas s’y attarder, cette infor-
mation intéressera surtout l’USART qu’il y a du côté du récepteur, car il contrôlera
alors la valeur de ce bit comme l’a fait l’émetteur. Si un bit s’est perdu en cour de
route à cause de parasites par exemple, il pourra alors le détecter.
Pour l’instant, ce ne sont que des histoires d’USARTs…
SP : Stop Bit. À la fin de la transmission, on peut demander à l’USART de rajou-
ter un ou deux bits supplémentaires pour indiquer que la transmission est termi-
née. De cette façon, le récepteur saura que c’est la fin du message.
Lorsque tout est transmis, la ligne série repasse à l’état idle en attendant la
prochaine frame à transmettre.
// VITESSE DE TRANSMISSION
Pour transmettre notre frame, l’USART du circuit émetteur et l’USART du cir-
cuit récepteur doivent dialoguer à la même vitesse pour se comprendre. En effet,
quand on va transmettre notre frame de bits sur notre fil série, il faudra bien que
l’on ait une information sur la vitesse de cette transmission (nos fameux bauds…).
// INITIALISATION
Nous avions déjà utilisé le Moniteur Série lors de notre sketch avec le poten-
tiomètre afin de lui envoyer les valeurs lues sur l’entrée analogique POTENTIO.
Dans le setup(), on avait initialisé notre liaison série à 19 200 bauds, puis nous
avions utilisé Serial.print() pour ressortir les résultats sur le moniteur série.
void setup() {
Serial.begin(19200);
Serial.print("Initialisation du setup terminée \n");
}
void loop() {
strcpy(maFutureVariable, "Arduino");
Serial.println(maFutureVariable);
}
Si on reprend notre principe KISS, on voit que l’on répète un peu la même chose
pour chaque Led au niveau de son allumage et de l’extinction des autres. On pour-
rait écrire une fonction changeCouleur() par exemple, qui se chargerait de regar-
der quelles Leds éteindre et quelle Led allumer en fonction de la lettre reçue. Sa
déclaration pourrait être par exemple :
void changeCouleur(char laLettre);
Je vous laisse essayer de l’écrire de la façon la plus simple possible.
Pour savoir si elle fonctionne, il suffira de la compiler, de la téléverser et de voir
si tout fonctionne correctement.
En faisant ainsi, on n’a que les trois couleurs de base de notre Led, car on allume
une seule partie et on éteint les deux autres. L’intérêt de cette Led RGB étant de
pouvoir nous donner ses seize millions de couleurs, il faudra également essayer
de créer une fonction qui fasse par exemple du jaune ou du marron si on rentre
les lettre J ou M. Je vous laisse faire également…
Pour aller plus loin, on peut également écrire les couleurs en entier, comme
rouge ou vert…
Par contre, R est un caractère, alors que rouge est une chaîne de caractères.
En langage Arduino, une chaîne de caractères est un type String.
Il va donc falloir déclarer une variable String pour mémoriser la chaîne reçue
depuis le Moniteur Série, et ensuite demander à Serial de lire une String au lieu
d’un simple caractère.
La lecture de la String se fera par Serial.readString().
Notre sketch sera donc :
// (c)Frédéric SILLON 2020
// LED RGB multicolore pilotée par ordi
// Lecture des couleurs par mots
void loop() {
lectureCouleur = Serial.readString(); // On lit la liaison Serial
void loop() {
if (Serial.available() > 0) {
lectureReponse = Serial.readString(); // On lit la liaison Serial
if (lectureReponse == "oui") { // Si on a reçu oui
analogWrite(RED, 0); // Extinction Red
analogWrite(GREEN, PWM); // Allumage Green
analogWrite(BLUE, 0); // Extinction Blue
}
else { // Sinon,
analogWrite(RED, PWM); // Allumage Red
analogWrite(GREEN, 0); // Extinction Vert
analogWrite(BLUE, 0); // Extinction Blue
}
}
}
On voit ici une nouvelle fonction qui est Serial.available(). Elle va nous indi-
quer combien de caractères sont reçus par l’Arduino depuis sa liaison série. Dans
notre cas, on veut effectuer les tests dès qu’au moins un caractère est reçu, donc
on teste le résultat renvoyé par Serial.available() et on regarde s’il est simple-
ment supérieur à zéro.
Je vous laisse améliorer ces exemples : on dispose à présent d’une porte
ouverte sur le monde extérieur, avec un vrai dialogue utilisateur.
void setup() {
analogWrite(RED, 0); // On eteint Rouge
analogWrite(GREEN, 0); // On eteint Vert
analogWrite(BLUE, 0); // On eteint Bleu
Serial.begin(19200); // Init liaison serie 19200 Bds
}
void loop() {
if (Serial.available() > 0) {
// LE BUS I2C
La liaison I2C (ou bus I2C ou I²C) a été développée par la société Philips dans
les années 80 pour établir des communications entre circuits intégrés sur une
même carte. Au lieu de tirer plein de pistes de cuivre sur un circuit imprimé pour
faire dialoguer des circuits intégrés, ils ont eu l’idée de créer un bus spécifique,
le Inter Integrated Circuits (d’où I2C). On peut ainsi enchaîner les circuits I2C les
uns derrière les autres, avec un minimum de fils de connexion.
Pour transmettre les informations d’un circuit à l’autre, le bus I2C dispose d’un
fil nommé SDA (Serial Data) et d’un fil SCL (Serial Clock). À cela, on ajoute la
masse Gnd, et le tour est joué.
Pour faciliter les choses, notre IDE met la bibliothèque Wire à notre disposition afin
de gérer tous ces échanges. Regardons sur un exemple comment cela fonctionne.
Exemple I2C
Une carte qui est sympa à tester en I2C est par exemple le capteur de mouve-
ments 3D de chez dfrobot.com, que l’on peut trouver chez gotronic.fr ou mouser.fr
pour moins de 20 €. Le capteur détecte nos mouvements juste en passant au-
dessus de ses électrodes, sans contact. On peut par exemple créer un code secret
avec un geste au-dessus du capteur…
Comment ça marche ?
Pour en savoir davantage, on peut aller faire un tour sur le site arduino.cc, à la
page des librairies : www.arduino.cc/reference/en/libraries/. On verra alors un
lien vers la librairie Wire qui se charge de la gestion du bus I2C, et qui pourra nous
donner plus d’informations.
Écriture I2C
Pour écrire sur un périphérique I2C, on procèdera ainsi :
#include <Wire.h>
void setup()
{
Wire.begin(); // Initialisation du Bus I2C
}
void loop()
{
Wire.beginTransmission(0x25); // On adresse le circuit d’adresse 0x25
Wire.write(123); // On lui envoie la valeur 123
Wire.endTransmission(); // On libère le bus
}
Lecture I2C
Pour effectuer la lecture sur un circuit I2C, le site arduino.cc nous donne la
solution, avec un exemple d’utilisation de la fonction Wire.read().
Voici cet exemple.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop()
{
Wire.requestFrom(2, 6); // request 6 bytes from slave device #2
while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
Les commentaires, bien qu’en anglais, sont très bien écrits, et donc facilement
compréhensibles.
Adresse I2C
Comme nous l’avons dit, chaque circuit I2C est défini par une adresse sur ce bus.
Pour les composants ou les modules que l’on peut trouver avec leurs biblio-
thèques, on n’aura pas à s’en occuper la plupart du temps car leur auteur aura
pris soin de gérer cette partie.
Par contre, si c’est un composant sans bibliothèque, il faudra la gérer nous-mêmes.
Pour la trouver et la calculer, il suffira une fois de plus de trouver la datasheet
du composant.
On peut donc le câbler ainsi, et garder le montage que nous avion déjà pour la
Led RGB.
Si vous l’aviez décâblé, profitez-en pour mettre des résistances de 470 ohms si
ce n’est pas déjà fait, ce sera plus doux pour les yeux…
#include <Wire.h>
#include "Adafruit_TCS34725.h"
#define RED 9 // Led RED sur la pin 9
#define GREEN 10 // Led GREEN sur la pin 10
#define BLUE 11 // Led BLUE sur la pin 11
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS,↵
TCS34725_GAIN_4X); // Déclaration variable Capteur de couleur
float red, green, blue; // Couleurs à capturer et reproduire
void loop() {
tcs.getRGB(&red, &green, &blue); // Lecture de la couleur
if ((red>blue) && (blue>green)) { // dominante Red, on allume RED
analogWrite(RED, red);
analogWrite(BLUE, 0);
analogWrite(GREEN, 0);
}
if ((blue>red) && (red>green)) { // dominante Blue, on allume BLUE
analogWrite(BLUE, blue);
analogWrite(RED, 0);
analogWrite(GREEN, 0);
}
if ((green>blue) && (blue>red)) { // dominante Green, on allume GREEN
analogWrite(GREEN, green);
analogWrite(BLUE, 0);
analogWrite(RED, 0);
}
}
Au début de ce sketch, il y a une ligne un peu nouvelle dans sa construction et
qui mérite un peu d’attention.
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS,↵
TCS34725_GAIN_4X); // Déclaration variable Capteur de couleur
En fait, il s’agit de déclarer une variable nommée tcs de type Adafruit_
TCS34725, et de l’initialiser en même temps comme le demande la librairie du
capteur écrite par son auteur.
Si on avait eu plusieurs capteurs de couleur sur la carte par exemple, on aurait pu
déclarer plusieurs variables de type Adafruit_TCS34725, comme tcs_1, tcs_2, tcs_3.
Dans ce cas, chaque capteur associé à sa propre variable saurait être géré par
la bibliothèque. C’est une partie très puissante de notre langage de programma-
tion que nous aborderons plus tard.
Dans le setup(), on éteint la Led RGB et on lance la communication I2C avec le
capteur par tcs.begin().
Dans le loop(), il ne reste plus qu’à interroger le capteur avec tcs.getRGB()
et récupérer les couleurs pour rechercher la dominante afin d’allumer la bonne
couleur de Led.
Il y a une particularité dans l’appel à la fonction tcs.getRGB(). En effet, on
passe l’adresse des variables par &nomVariable afin que la fonction y range les
bonnes valeurs.
Comme exemple d’utilisation du bus SPI, nous allons regarder l’exemple qui
se trouve sur le site officiel Arduino, à l’adresse www.arduino.cc/en/Tutorial/
LibraryExamples/DigitalPotControl. Cela va nous permettre d’étudier un projet
développé par un autre programmeur.
Dans les chapitres précédents, nous avions utilisé un potentiomètre pour
nos expériences. Avec un petit tournevis, on pouvait changer la position de son
On voit ici qu’il est question des deux extrémités du potentiomètre numéro 6
(A et B), ainsi que de son curseur (W).
La ligne numéro 2 est intéressante car il est noté que addr = 1012.
On peut donc en déduire que l’adresse du wiper du potentiomètre numéro 6 se
trouve à l’adresse 101 en binaire (base 2, d’où le petit 2 noté en indice). Si on fait
une rapide conversion, 101 vaut 5 en décimal.
L’adresse du potentiomètre numéro 6 est donc 5 sur le bus SPI lorsque la
ligne CS du circuit est LOW. En continuant de lire cette datasheet, on verra que
le potentiomètre 5 est à l’adresse 4, le potentiomètre 4 à l’adresse 3, et ainsi de
suite jusqu’au potentiomètre 1 qui est à l’adresse 0.
Donc, pour écrire la valeur 123 sur le potentiomètre 6, il faudra écrire :
SPI.transfer(5);
SPI.transfer(123);
C’est assez simple d’utilisation, et le AD5206 est un super composant. De plus,
il est en plus possible de l’alimenter en 5V, ce qui correspond tout à fait à notre
Arduino. La seule chose à laquelle il faudra faire attention est son boîtier. En effet,
il devient plus difficile de le trouver en boîtier DIL (Dual In Line = gros boîtier
comme notre ATMega328 sur l’Arduino Uno).
La tendance étant à la miniaturisation, on le trouvera plus facile en boîtier CMS
(comme le second µC de notre Arduino Uno).
Dans ce cas, il sera très délicat de le câbler sans outillages spécialisés.
LES INTERRUPTIONS
Actuellement, toutes les instructions à exécuter en dehors du setup() se
trouvent dans le loop().
Dans ce loop(), toutes les tâches sont exécutées les unes après les autres,
ce qui fait que dans notre montage avec le bouton poussoir et le chenillard par
exemple, il y a un certain temps d’attente entre le moment où on appuie sur le
bouton et le moment où notre programme réagit. Est-ce que notre µC est trop
lent ? Non, pas du tout. Il exécute les instructions les unes après les autres, et il
void loop() {
etatDuBouton = digitalRead(BOUTON); // Lit etat du bouton
if (etatDuBouton == true) // Si relache,
digitalWrite(LED_BUILTIN, LOW); // Led OFF
else // Sinon
digitalWrite(LED_BUILTIN, HIGH); // Led ON
delay(5000);
}
Si on exécute ce sketch, il faudra attendre la fin de la tempo de 5 secondes
avant que la Led ne change d’état.
Regardons maintenant ce qu’il se passe si on attache notre bouton poussoir au
système d’interruptions de notre µC (je vous laisse faire le câblage avec le bouton
sur la pin D2).
// (c)Frédéric SILLON 2020
// Bouton poussoir Led AVEC interruption
#define BOUTON 2 // Bouton poussoir sur pin 2
int etatDuBouton = 0; // Sauvegarde de l'état du bouton (on/off)
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Initialise Led en sortie
pinMode(BOUTON, INPUT); // Bouton, donc Input
attachInterrupt(digitalPinToInterrupt(BOUTON), changeLed, CHANGE);
}
void changeLed() {
etatDuBouton = digitalRead(BOUTON_POUSSOIR); // Lit etat du bouton
if (etatDuBouton == true) // Si relache,
Nous allons maintenant pouvoir regarder des montages plus évolués, qui pour-
ront être le début de grandes aventures…
Maintenant que tout est câblé, il va falloir le faire tourner. Comme on l’a vu, la
commande d’un servo se fait en PWM.
Pour cela, on a deux solutions. La première est de créer par nous-même ces
signaux en PWM, en respectant les bons timings pour tourner dans un sens ou
dans un autre.
On pourrait par exemple passer la commande à HIGH pendant 2 ms, puis à LOW
pendant 18 ms pour respecter les timings, ce qui pourrait donner :
digitalWrite(SERVO, HIGH);
delay(2);
digitalWrite(SERVO, LOW);
delay(18);
Ce n’est ni élégant, ni très pratique. On pourrait utiliser le PWM de notre
Arduino pour faire la même chose. Il pourrait même exister une bibliothèque toute
faite pour gérer les servos…
En tapant « arduino servo » sur Internet, on arrive facilement sur le site Arduino
qui nous propose la bibliothèque servo.h…
Si on regarde l’exemple Sweep, on va y voir plus clair, et on voit les différentes
étapes pour faire tourner le servo dans un sens et dans l’autre.
En commençant par quelque chose de très simple, on pourrait :
> déclarer la pin PWM sur laquelle est connecté le servo ;
> déclarer une variable monServo pour utiliser la bibliothèque ;
> initialiser monServo sur la pin où on est connecté ;
> écrire le sens de rotation (et la vitesse).
void loop() {
myServo.write(90); // Arrêt du servo
delay(500);
myServo.write(100); // Tourne dans un sens lentement
delay(500);
myServo.write(0); // Tourne dans l'autre sens vite
delay(500);
}
On voit bien le sens de rotation et la vitesse suivant les valeurs prises.
Le servo est un moyen très simple, assez bon marché et peu encombrant pour
motoriser un petit robot mobile. Le choix se fera ensuite sur un servo standard ou
un modèle à rotation continue suivant ce que l’on veut en faire.
Selon que nous lui mettons une roue ou autre chose, on pourra l’utiliser pour
se déplacer, pour faire tourner une tourelle avec un radar par exemple, ou encore
pour tirer ou baisser un levier, un pont-levis, une barrière, la porte d’une fusée,
bref il y a plein d’applications possibles.
Le modèle choisi est un SV12-5 qui va émettre un son continu lorsqu’on l’ali-
mente, et en regardant sa datasheet, on verra que son alimentation doit être
comprise entre 3V et 6V au maximum, ce qui correspond bien à notre Arduino
qui va générer des signaux de 5V et un son d’une fréquence de 3,2 KHz. Pour
ce modèle, on peut tout de même émettre différents sons en modulant le signal
qu’on lui envoie, et il va donc falloir générer ce signal avec une fréquence qui
correspond à la note que l’on veut jouer. Cela ne fonctionnera pas correctement
pour toutes les fréquences, mais suffisamment bien si on reste aux alentours des
3,2 KHz (3 200 hertz) qu’il est capable d’émettre seul.
Pour en revenir aux notes, le La correspond à un signal de fréquence 440 hertz
(Hz). C’est celui que l’on entend en décrochant un téléphone, et qui sert aussi à
accorder les instruments de musique.
Plus le son est aigu, plus sa fréquence est haute, et un DO grave aura une
fréquence de 261 hertz environ alors qu’un DO aigu aura une fréquence de
2 093 hertz.
En effet, chaque son correspond à une fréquence, que notre cerveau analyse
comme une note, agréable ou non. Les notes générées par le buzzer ne sont pas
très agréables, mais elles ont le mérite d’exister.
Si on voulait jouer Au clair de la lune, qui est un peu le Hello World de la musique,
on ferait la séquence de notes : do-do-do-ré-mi-ré-do-mi-ré-ré-do.
Dans les sons assez aigus proches des 3 200 Hz de notre buzzer, on trouvera
le DO à 2 093 Hz, le RÉ à 2 349 Hz et le MI à 2 637 Hz environ.
Pour jouer des notes, notre Arduino a bien évidemment la fonction qui va bien :
tone(). Pour jouer un LA 440 Hz sur un buzzer qui sera branché sur la sortie 8
par exemple, on écrirait :
tone(8, 440);
Pour stopper la musique, on fera aussi simplement :
noTone(8);
On peut aussi indiquer pendant combien de temps la note doit être jouée.
tone(8, 440, 500); //jouée pendant500 ms
On voit que c’est assez simple de créer des sons et de jouer des notes.
Essayons de brancher notre buzzer sur l’Arduino.
void setup() {
pinMode(PIN_BUZZER, OUTPUT); // Pin du buzzer en sortie
troisBips(); // Appel de TroisBips au demarrage
}
void loop() {
tone(PIN_BUZZER, DO, 200); // Note
delay(400); // Silence
tone(PIN_BUZZER, DO, 200); // Note
delay(400); // Silence
tone(PIN_BUZZER, DO, 200); // ...
delay(400);
tone(PIN_BUZZER, RE, 200);
delay(400);
tone(PIN_BUZZER, MI, 200);
delay(800);
tone(PIN_BUZZER, RE, 200);
delay(800);
tone(PIN_BUZZER, DO, 200);
delay(400);
tone(PIN_BUZZER, MI, 200);
delay(400);
tone(PIN_BUZZER, RE, 200);
delay(400);
tone(PIN_BUZZER, RE, 200);
delay(400);
tone(PIN_BUZZER, DO, 200);
delay(1500);
}
void joueNote(unsigned int laNote, unsigned int laDuree, unsigned int leSilence) {
tone(PIN_BUZZER, laNote, laDuree);
delay(leSilence);
}
void setup() {
pinMode(PIN_BUZZER, OUTPUT);
}
void loop() {
for (int i=0; i<11; i++)
joueNote(melodie[i][0], melodie[i][1], melodie[i][2]);
}
Si on veut jouer autre chose, il suffit de modifier le tableau et le nombre d’ité-
rations de la boucle for().
Mis à part la déclaration du tableau, on joue maintenant la mélodie avec deux
lignes de code. C’est tout de même plus élégant !
Cependant ça fonctionne, mais ce n’est tout de même pas très friendly à l’heure
actuelle…
On pourrait également utiliser un écran comme sur les PC connectés en HDMI,
mais un peu trop compliqué pour l’instant. Le bon compromis est l’écran LCD
alphanumérique, comme on en trouve un peu partout.
On voit tout de suite que cette configuration avec bus parallèle D4-D7 est
beaucoup moins simple à câbler qu’une liaison série de type SPI par exemple.
Par contre, le fait de pouvoir travailler en mode 4 bits au lieu de 8 bits offre un
bon compromis pour simplifier un peu ce câblage.
void loop() {
LE CAPTEUR DE LUMIÈRE,
POUR JOUER AVEC LE JOUR ET LA NUIT
Dans la série des composants sympas à utiliser, on va trouver la LDR. Qu’est-ce
que c’est ? C’est une Light Dependant Resistor, ce qui veut dire résistance dépen-
dant de la lumière. En bref, il s’agit donc d’une résistance dont la valeur ohmique
dépend de l’éclairage qu’elle reçoit. Cela paraît intéressant car si on pouvait
mesurer la valeur de cette résistance avec notre Arduino, on pourrait savoir s’il
fait jour ou nuit, sombre ou clair. Avec notre super buzzer, on pourrait faire un
réveil qui nous réveille quand le jour se lève… ou autre chose.
En étudiant le potentiomètre, on a parlé des associations de résistances et du
pont diviseur avec la formule :
R2
Vout = Valim ×
R 1 + R2
Cela veut dire que si on fait un pont diviseur avec une résistance et notre LDR,
on devrait pouvoir obtenir une tension qui varie en fonction de la lumière.
Il ne restera plus qu’à l’injecter sur une entrée analogique de notre Arduino, et
le tour est joué !
La LDR choisie est une LDR720, et si on regarde ses caractéristiques, elle a
une résistance supérieure à 5 mégaohms (5 MΩ) dans l’obscurité et inférieure à
300 Ω en pleine lumière.
On devrait donc bien voir la différence entre lumière/nuit sur un pont diviseur.
En choisissant une résistance de 1 KΩ, la différence entre lumière et obscurité est
assez sensible.
Il faudra sans doute adapter cette valeur en fonction de la LDR choisie, mais
aussi en fonction de la lumière ambiante. Pour ma part, 1 KΩ fonctionne bien.
void setup() {
myLCD.begin(16, 2); // Afficheur 2x16
myLCD.setCursor(4, 1); // Curseur en col 5 ligne 2
myLCD.print("Hello"); // Affichage Hello
}
void loop() {
lumiere = analogRead(LDR)*0.0049; // Lecture et conversion
myLCD.setCursor(0, 0); // Curseur en 0,0
myLCD.print(lumiere); // Ecriture valeur tension
myLCD.setCursor(0,1); // Curseur en col 1, ligne 2
if (lumiere > 3.0) // Si lumiere faible
myLCD.print("Obscurite"); // Obscurite
else // Sinon
myLCD.print("Lumiere "); // Lumiere forte
}
Dans l’affichage des mots Obscurité et Lumière, il y a une petite astuce qui
évite d’effacer l’écran pour chaque affichage : les deux mots n’ont pas la même
longueur et Lumière est complété avec des espaces. Sans cela, l’affichage serait
Obscurité puis Lumièreité. En effet, Lumière est écrit en position 0.1, tout comme
Obscurité, mais comme il est plus court et que l’écran n’est pas effacé, les der-
niers caractères ne seraient pas effacés et resteraient sur l’afficheur. En faisant
ainsi, on les efface tout de même. Essayez de supprimer les espaces qu’il y a après
le mot Lumière dans le sketch afin de voir la différence.
On pourrait également effacer l’écran avec un myLCD.clear(), mais l’écran se
mettrait à clignoter. Essayez de le faire également pour voir la différence, en posi-
tionnant un myLCD.clear() avant d’écrire chacun des deux mots.
Nous voilà prêts à faire pas mal de choses avec tout ça.
Son boîtier ressemble à un transistor, a trois pattes et son brochage est le suivant.
Sur ce brochage, on voit que le TMP36 est alimenté entre Vs et Gnd (de 2,7 à 5V
d’après la datasheet), et que la sortie de mesure est Vout.
Comment connaître la température en fonction de la tension présente sur
Vout ? Eh bien une fois de plus, petit tour sur la datasheet.
Une rapide traduction nous indique donc que le TMP36 fonctionne de –40
à 125 °C, qu’il donne une tension de 750 mV à 25 °C, et également qu’il a une
échelle en sortie de 10 mV/°C.
C’est plus clair maintenant. À chaque degré, on aura 10 mV de plus et le 0 °C
amène une tension de 500 mV.
Comme sa sortie Vout nous donne une tension analogique, on va donc le
connecter sur une entrée analogique de notre Arduino, par exemple sur A1.
Voyons maintenant comment coder tout ça. Si on reprend ce que l’on a vu pré-
cédemment, on a 10 mV par °C et 500 mV à 0 °C.
Comme on part de 0 °C à 500 mV, on peut donc dire que 1 °C donnera
500 + 10 mV, que 2 °C donnera 500 + 20 mV, etc.
Il faudra alors retirer ces 500 mV des mesures de tension qui seront faites. On
aura ainsi la valeur de tension à partir de 0 °C.
Comme on a nos 10 mV pour 1 °C, une simple règle de trois nous amènera à :
V – 500
T=
10
Si on lit 750 mV, on aura donc :
750 – 500
T= = 25
10
Comme annoncé par la datasheet, on retrouve bien nos 25 °C pour 750 mV.
On pourra donc coder la valeur de température ainsi :
temperature = (analogRead(A1)*0.0049*1000 - 500) / 10;
D’où viennent ce 0.0049 et ce 1000 ? Et bien si on se rappelle du chapitre de la
conversion avec analogRead(), on avait vu que :
Tension = valeurLue * 0.0049, car 0.0049 correspond à une unité du conver-
tisseur de notre Arduino, c’est-à-dire à 49 mV par bit.
LiquidCrystal myLCD(RS, EN, DB4, DB5, DB6, DB7); // On declare et Init myLCD
float lumiere = 0; // Memo lecture lumiere
float temperature = 0; // Memo temperature
void setup() {
myLCD.begin(16, 2); // Afficheur 2x16
myLCD.setCursor(0, 0); // Curseur en col 5 ligne 2
myLCD.print("Soleil Chaleur"); // Affichage titre
}
void loop() {
lumiere = analogRead(LDR)*0.0049; // Lecture et conversion
temperature = (analogRead(TEMPERATURE)*0.0049*1000 -500) / 10;
myLCD.setCursor(0, 1); // Curseur en 0,1
if (lumiere > 3.0) // Si lumiere faible
myLCD.print("Obscurite: "); // Obscurite
else // Sinon
myLCD.print("Lumiere : "); // Lumiere forte
myLCD.print(temperature);
}
On voit que la mesure bouge beaucoup dans la valeur affichée après la virgule.
Si on veut afficher seulement les degrés sans s’occuper de la partie décimale,
on va transtyper la valeur float en int.
myLCD.print((int) temperature);
myLCD.print(" C");
Au passage, on rajoute le symbole C pour marquer la température.
Sur certains écrans LCD, il n’est pas possible d’afficher les caractères accen-
tués ni les symboles spéciaux comme le ° pour écrire °C. C’est le cas du mien, il
peut afficher des caractères japonais, mais pas d’accents.
Si on voulait le faire, il faudrait redéfinir certains caractères dans la mémoire
de l’écran.
Nous allons aborder des notions plus complexes, mais qui vont permettre de
créer des bibliothèques de codes déjà existants et d’utiliser différents modules
du commerce, ce qui évite de tout réinventer à chaque fois.
LA PROGRAMMATION OBJET
Si on reprend notre sketch MonBlink, on a pu allumer et éteindre notre Led
très simplement. Une fonction qui allume la Led, et une autre qui l’éteint. Ça fonc-
tionne plutôt bien. Par contre, si on avait 8 Leds à gérer, il y a fort à parier que l’on
aurait beaucoup de lignes de code qui se répètent et on allongerait notre code
pour rien. En plus, si on voulait changer le comportement des Leds, par exemple
les faire clignoter deux fois au lieu d’une à chaque fois, il faudrait réécrire le code
de chaque Led. On pourrait également s’en sortir en utilisant des fonctions qui
regroupent plusieurs actions.
Autre remarque. Quand on a utilisé l’écran LCD, on a commencé par déclarer
une variable myLCD car c’est ce qui était demandé pour pouvoir utiliser la biblio-
thèque qui gère l’écran. Ensuite, on a pu avoir accès aux fonctions le LCD comme
myLCD.print() par exemple.
Si on avait eu un second écran, on aurait ainsi pu déclarer une seconde variable
mySecondLCD et ensuite disposer des mêmes fonctions que précédemment et
écrire mySecondLCD.print(). Et encore un troisième, et un quatrième de la même
façon, sans réécrire toutes les fonctions à chaque fois, juste en déclarant une
variable du type LiquidCrystal.
En fait, c’est un peu comme si notre écran savait faire plein de choses tout seul,
comme un objet qui peut s’allumer, s’éteindre, écrire ou faire plein d’autres choses
si on les lui demande.
Et bien c’est le cas, et ceci nous amène à la programmation Objet et à la créa-
tion de nos propres bibliothèques.
En programmation objet, au lieu d’écrire des fonctions pour chaque chose, on
va plutôt construire des objets qui auront leurs propres variables, leurs propres
void Led::allumer(void) {
digitalWrite(_pin, HIGH); // Allumage Led memorisee
}
void Led::eteindre(void) {
digitalWrite(_pin, LOW); // Extinction Led memorisee
}
void Led::clignoter(void) {
allumer(); // allumage
delay(1000); // Temporisation
eteindre(); // Extinction
delay(1000); // Temporisation
}
On va écrire nos fonctions ainsi :
void Led::allumer(void) {
… // Le code des choses à faire
}
Cette écriture est spécifique à la programmation objet et toutes nos fonctions
commenceront ainsi Led::
La première fonction est un peu spéciale, il s’agit du Constructeur. Le Construc
teur permet d’initialiser l’objet et de le créer en mémoire. Ainsi, le constructeur
de notre Led sera Led::Led().
Maintenant que le code de notre objet Led semble correct, il va falloir zipper les
fichiers cpp et h ensemble afin d’obtenir un fichier Led.zip.
On pourra alors l’inclure dans les bibliothèques de notre IDE. Pour cela, on ira
dans le menu Croquis/Inclure une bibliothèque/Ajouter la bibliothèque ZIP.
void setup() {
}
void loop() {
myLed.clignoter();
ledRouge.clignoter();
}
C’est un peu bizarre au début, mais c’est super puissant, et on retrouve bien
ici l’esprit des bibliothèques que l’on a déjà utilisées pour l’écran et le GPS par
exemple.
La seule chose à faire est de bien documenter les fonctions de la bibliothèque
afin que d’autres programmeurs puissent l’utiliser facilement.
// L’ÉCRAN TFT…
Utiliser l’écran LCD nous permet d’afficher de petits messages, par exemple la
température des chapitres précédents.
Avec un écran graphique, on pourrait dessiner, faire des menus, des boutons
pour cliquer et plein d’autres choses. On pourrait faire une belle IHM pour nos
montages. Une IHM est une Interface Homme Machine, c’est-à-dire un système
de boutons et de menus qui va permettre à l’utilisateur de dialoguer avec notre
montage. Si on rajoute une dalle tactile, on pourrait tout commander avec un
seul doigt !
Par contre, un écran graphique est assez difficile à piloter, de même que la
dalle tactile. Comme d’habitude, le bon réflexe sera de regarder s’il existe une
bibliothèque pour nous aider à démarrer, et apprendre comment cela fonc-
tionne.
La société Adafruit qui est basée à New York propose une multitude de cartes
et composants pour l’Arduino, ainsi qu’un grand nombre de bibliothèques.
Pour s’essayer à l’utilisation de l’écran tactile, on pourra essayer le modèle 2.8"
TFT Touch Shield for Arduino with Resistive Touch Screen par exemple.
Quelles sont donc ses caractéristiques ? 2.8’’ est la taille de sa diagonale, soit
environ 7 cm (1 pouce = 2,54 cm).
Il est TFT, ce qui veut dire qu’il est constitué de « Thin Film Transistors ». Chaque
pixel est commandé par transistors et on parle aussi de matrice active. Ces écrans
sont réactifs et bien contrastés.
Il a aussi un Resistive Touch Screen, c’est-à-dire une dalle tactile résistive. Le
circuit intégré qui contrôle cette dalle résistive est capable de calculer les coor-
données de l’emplacement où l’on a appuyé avec le doigt. Cette technologie est
meilleure marché que celle donnant une dalle tactile capacitive.
Pour installer la bibliothèque, on va aller dans le menu suivant.
void setup(void) {
tft.begin(); // Init Ecran
tft.fillScreen(ILI9341_BLACK); // Efface Ecran
void loop()
{
tft.println("J'aime Arduino !!"); // Ecrit a chaque tour de loop
}
Dans cet exemple, on a tout d’abord créé une variable tft de type Adafruit_
ILI9341. On retrouve ici ce que l’on a vu avec les bibliothèques et les objets.
Ensuite, le setup() démarre la gestion de l’écran et l’efface en le remplissant
d’un grand fond noir. On positionne ensuite le curseur au point d’origine (0,0) et
on choisi d’écrire en blanc avec une fonte de caractères de taille 2.
On écrit notre message et après le delay, on efface de nouveau l’écran avant de
choisir une police de caractères jaune en taille 1.
Dans le loop(), on va écrire notre message en continu, en allant à la ligne à
chaque fois.
Avec ce petit exemple, on voit comment écrire facilement sur l’écran, et en
explorant la bibliothèque Adafruit on pourra apprendre à utiliser les fonctions de
dessin pour faire des lignes, des ronds et des carrés très simplement.
De quoi faire une belle IHM.
Le µC ATMega328P est embarqué sur la carte (sous l’afficheur LCD), et les trois
boutons poussoirs permettent de naviguer dans le système de menus.
Quatre Leds et deux Leds RGB permettent d’améliorer le dialogue utilisateur,
un capteur de température et une LDR permettent de voir le temps qu’il fait.
Par exemple, les deux Leds RGB peuvent être vertes s’il fait beau, bleues s’il
fait froid et s’allumer plus faiblement la nuit. Le buzzer peut faire sonner une
alarme s’il fait trop froid ou trop chaud.
Avec les trois boutons poussoirs, on peut également faire un jeu sur l’écran en
répondant à des questions préprogrammées, puis compter les points et allumer
les Leds.
On peut aussi faire un jeu de mémorisation des couleurs qui défilent avec les
Leds jaune, verte, rouge et bleue.
Le tout est alimenté par le connecteur USB qui sert aussi à communiquer avec
le Moniteur Série de l’IDE. On peut ainsi dialoguer avec la carte par l’intermédiaire
du port RS232.
En résumé, nous avons là une bonne petite plateforme pour apprendre à pro-
grammer, compatible au niveau logiciel avec l’Arduino Uno et son IDE.
On retrouve ainsi l’application de certains exemples sur lesquels nous avons
travaillé ensemble dans les chapitres précédents.
Avec ses capteurs infrarouges (IR) avant et arrière, Gemini peut voir les obsta-
cles qui se présentent devant lui, ou derrière lui s’il doit reculer.
Les capteurs IR se trouvant dessous lui permettent de détecter le sol et évitent
qu’il ne tombe de la table, mais lui permettent aussi de suivre une ligne tracée par
terre.
Pour avancer, il a deux moteurs à courant continu, mais on pourrait tout aussi
bien utiliser deux mini servos comme celui que l’on a utilisé dans les chapitres
précédents.
Les deux LDR à droite et à gauche lui permettent de suivre une lumière ou de
lui échapper. On peut ainsi le diriger avec une lampe de poche dans le noir…
Les Leds multicolores peuvent donner une indication de son état lorsqu’il ne
sait plus où aller par exemple, tandis que les Leds bicolores rouge/vert qui sont
placées à l’avant et à l’arrière s’allument en vert lorsque la voie est libre, et en
rouge lorsqu’un obstacle est détecté.
Le but de ce petit robot est de prendre rapidement la main afin de réaliser très
rapidement de petits programmes, qui deviendront de plus en plus complexes.
De même, on peut s’en servir pour jouer à plusieurs, créer des algorithmes
entre copains et voir lequel est le plus performant.
Qu’est-ce qu’un algorithme ? C’est simplement la façon de résoudre un pro-
blème avec des étapes bien définies, qui s’enchaînent les unes après les autres.
On va faire ceci, puis cela et ensuite encore autre chose, d’une façon bien struc-
turée un peu comme mettre un pied devant l’autre. Pour y arriver, on enchaîne
toute une série de mouvements précis et ordonnés sans même s’en rendre
compte. Si on mélange ces opérations, on tombe…
Pour aborder facilement cette notion d’algorithmes avec les enfants et les
débutants, j’ai développé un langage graphique basé sur un système de cartes
qui ressemblent à des cartes à jouer. Chaque carte comporte des dessins repré-
sentant les diverses instructions, actions ou choix possibles pour le robot, et cer-
taines d’entre elles ont même l’équivalent en code Arduino inscrit dessus.
On les met alors par terre ou sur la table les unes derrière les autres pour créer
l’algorithme que l’on veut faire.