XXIII. Déboguer▲
La réalisation de projets avec Arduino comporte une grande part d'essais et d'erreurs. Que ce soit pour la partie électronique ou pour la programmation, il est fréquent pour les débutants, mais aussi pour les plus avancés, de faire des erreurs. Or, alors que celles-ci sont parfois très faciles à détecter, elles sont plus souvent « cachées » et demandent à être découvertes. Voilà pourquoi une bonne pratique de la programmation et de la conception de circuits est de mise (voir chapitres « Précautions d'utilisationPrécautions d'utilisation » et « Bien structurer son code »).
XXIII-A. En programmation▲
Lorsqu'un problème survient ou que les choses ne se déroulent pas comme attendu, il est important d'identifier le problème en utilisant une approche méthodique et logique. Pour les problèmes de programmation, une pratique courante est de valider les différentes parties de code séparément, pour identifier la ou les parties du code qui occasionnent une anomalie. Pour ce faire, il est facile de mettre sous commentaire des sections complètes d'instructions en utilisant /* et */. Ensuite, il est important de prendre connaissance de l'état de nos variables, capteurs et autres. Utiliser la fonction Serial.println () pour faire afficher dans le moniteur sériel nos valeurs est très utile, et peut-être combiné avec des caractères nous indiquant où le Arduino se trouve dans le code. Par exemple le code suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
int
valeurCapteur =
0
;
void
setup()
{
Serial.begin(9600
);
}
void
loop()
{
// afficher qu'on lit le capteur
Serial.print("lire capteur : "
);
// lire capteur et afficher
valeurCapteur =
analogRead(3
);
Serial.println(valeurCapteur);
// vérifier si capteur est égal à 5
if
(valeurCapteur=
5
) {
Serial.println("test réussi!"
);
}
delay(1000
);
}
Ce programme devrait imprimer « test réussi » si la valeur du capteur est à 5.
L'utilisation d'un Serial.print() avec du texte (« lire capteur : ») nous permet de précéder l'affichage de la valeur du capteur par un élément indiquant au niveau de la console à quoi correspond le chiffre qui sera affiché. Remarquez le fait que nous utilisons Serial.print() pour afficher le texte et rester sur la même ligne d'affichage, puis le Serial.println() pour afficher la valeur et ensuite changer de ligne.
Notre programme comporte également un délai d'une seconde. Cela nous donne le temps de voir les informations affichées au moniteur. Autrement, les chiffres défileraient trop rapidement. Attention ! En ajoutant des délais, il est aussi possible de perdre la bonne exécution du programme dans son temps. Par exemple, des capteurs qui fournissent une réponse rapide (l'impact avec un piézo, par exemple) fournissent une information qui se déroule dans un très cours laps de temps. Ainsi, pendant que le programme attend avec delay(), il est possible que l'événement que nous cherchons à observer se soit déjà déroulé !
Lorsque nous copions ce programme, le compilons et l'exécutons, il ne fonctionne pas comme prévu ! Il contient délibérément un erreur. Même si le moniteur affiche une valeur différente de 5 pour le capteur, il affiche « test réussi ». Pourquoi ? Analysons le problème. Nous pouvons être suffisamment certains que la valeur du capteur est bien lue, et qu'elle module en fonction des manipulations physiques que nous ferions sur celui-ci. Si ce n'était pas le cas, le problème résiderait alors dans le capteur lui-même ou la connexion entre la carte Arduino et le capteur, mais comme dans le cadre de cette simulation, la valeur du capteur est représentative du phénomène physique, notre problème se situe ailleurs.
Quelles instructions suivent celui de l'affichage de la valeur du capteur ? L'énoncé conditionnel if
(valeurCapteur=
5
). Nous pouvons être suffisamment certains que la valeur du capteur n'est pas 5 en observant le moniteur sériel, mais tout de même, la condition semble réalisée puisqu'il affiche « test réussi ». Comme aucune autre instruction ne modifie valeurCapteur, il doit forcément y avoir quelque chose qui cloche avec la fonction if
(). Si vous êtes incapable de trouver quoi, une bonne pratique est de se référer à l'aide offerte par le programme (Help > Reference) (ou Ctrl+Maj+F en surlignant le mot-clef recherché) afin de valider la bonne utilisation de la fonction, la syntaxe, etc. En observant la condition valeurCapteur=
5
, nous observons ainsi que nous nous sommes trompés d'opérateur ! Un « = » attribue la valeur à la variable qui se trouve à sa gauche. L'opérateur que nous aurions dû utiliser devrait plutôt être « == », qui retourne un vrai si les deux valeurs comparées sont équivalentes et un faux si elles ne le sont pas. Comme notre condition était une assignation, elle ne retournait pas faux et entraînait l'exécution des instructions comprises dans le if
().
Que doit-on retenir de cet exemple ?
Lorsqu'on débogue un programme, il faut toujours avoir une approche modulaire, c'est-à-dire aborder chaque élément du code ou du circuit indépendamment des autres et s'assurer de son bon fonctionnement. Cette vérification doit également être faite de manière séquentielle, ou en ordre. On part soit de l'élément physique, pour remonter vers le circuit, puis vers l'Arduino, puis vers le programme. Ou l'inverse. Un autre exemple :
un capteur contrôle l'activation d'un moteur. Rien ne marche ! Docteur, que faire ?
- Vérifier que le capteur ne soit pas physiquement endommagé.
- Vérifier que le capteur soit bien connecté à son circuit.
- Vérifier que tous les composants du circuit soit bien connectés.
- Vérifier que la connexion au Arduino est bonne.
- Vérifier que la donnée est bien lue et l'afficher dans le moniteur.
- Vérifier les manipulations qui sont faites sur les variables ou la valeur du capteur.
- Vérifier que ces valeurs sont envoyées correctement au moteur.
- Vérifier que le moteur est bien connecté et non endommagé.
À travers toutes ces étapes, il est possible de tester hors du contexte du programme les éléments. Par exemple, pour tester que le moteur répond bien, il est possible de créer un nouveau petit programme temporaire pour ne tester que le moteur. Souvent, utiliser des exemples fournis dans le menu File ou le menu Help est utile, puisque ces exemples ne contiennent pas d'erreur en théorie.
XXIII-A-1. En électronique▲
Le même principe s'applique en électronique et avec l'électricité. Analyser chaque circuit, ou chaque partie de circuit, ou chaque composant, de manière modulaire nous permettra d'identifier un composant grillé, un circuit mal configuré, etc., tout en prenant soin d'avoir d'abord vérifié que notre source d'alimentation est d'abord sous tension ! L'outil par excellence pour déboguer est bien évidemment le multimètre (voir chapitre « Les bases de l'électroniqueLes bases de l'électronique »).