Publié le

Votre premier code Arduino

Review et partage :

Introduction

Description

Dans ce cours vous serez présenté à la logique du language Arduino en analysant le plus basique des codes : Blink.

Une fois cette logique acquise nous rédigerons ensemble un code fonctionnel nous permettant de couvrir : fonctions, déclaration de variable, conditions, boucle, communication série….. Des éléments qui vous serviront tout au long de votre vie de Maker !

Comment fonctionne un code Arduino : Blink

Blink est le “Hello World” de l’Arduino, il fait tout simplement clignoter une LED avec des intervalles d’une seconde à chaque fois. Il est utilisé, entre autre, comme code exemple pour notifier du bon fonctionnement  d’un micro-contrôleur et est aussi une parfaite introduction au code Arduino.

Il ressemble à ça :

/*
 Blink
 Turns on an LED on for one second, then off for one second, repeatedly.
 This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;


// the setup routine runs once when you press reset:
void setup() {
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(1000);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(1000);               // wait for a second
}

Réalisez le circuit suivant avec votre micro-contrôleur (avec une resistance de 220 à 1k Ohm par précaution) et téléversez votre code dessus pour le voir à l’œuvre :

Vous pouvez vous servir d’une « breadboard » pour plus de simplicité : en deux mots celle-ci relie tout les pins sur une ligne perpendiculaire à la fente, ainsi le circuit suivant vous permet de brancher ensembles fils, resistance et led en série sans soudure.

PS : La led se branche avec la « grande patte » ou coté bombé vers le +, la pin digitale.

untitled-sketch-2_bb
bz4hdrwjv0hqu

Remarquez dès à présent que dans votre code, tout ce qui est écrit entre « /* » et « */ » ou après deux slash « // » est grisé car ce sont en fait des commentaires : du texte qui ne sera pas lu par votre micro-contrôleur mais qui sert à donner des indications à l’humain derrière son écran. Il est important de commenter son code et d’expliquer ce que l’on a en tête au moment où on l’écrit : « Cette fonction récupère la valeur du senseur » ou  « Cette variable ne doit pas dépasser 356 » par exemple.

Un code doit être écrit dans l’optique qu’il soit lu par quelqu’un d’autre, cela vous rendra même service à vous si vous ne touchez pas à votre code pendant plusieurs jours (Oui c’est du vécu, et c’est assez perturbant de ne pas arriver à se comprendre soi-même).

 

Première partie : La déclaration de variable

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

 

Cette partie de code hors fonction est utilisée pour y déclarer des variables que l’on réutilisera plus tard. Dans notre cas, nous déclarons que l’int, “integer” (nombre entier) led est égale à 13.

Ainsi plus tard, quand nous demanderons à notre code d’allumer la led, il saura que sa position est 13.

Vous pouvez changer le nom de cette variable à volonté tant que vous utilisez le même nom plus tard dans le code (vous pouvez donc le changer pour led1, ou led2 si vous avez plusieurs led par exemple).

Remarquez que la fin d’une ligne de code est toujours accompagnée d’un point virgule qui permet de différencier les commandes les unes des autres.

Vous pouvez déclarer autant de variables que vous voulez et elles seront ensuite modifiables dans le code (que nous ferons dans le chapitre suivant).

Deuxième partie, la fonction setup :

// the setup routine runs once when you press reset:
void setup() {
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);
}

 

Cette partie est une fonction, on les reconnaît car elles se présentent sous la forme

void nomdelafonction() {
    code de la fonction
}

 

La fonction setup est une des deux fonctions incluses dans tout code Arduino (bien que pas forcément remplies). Celle-ci a la particularité de n’être lancée qu’une seule fois lors de la mise en route de l’Arduino (ou pression du bouton reset sur certains micro-contrôleurs qui éteint et rallume l’Arduino).

On va donc y mettre les éléments qui répondent à cet objectif, dans notre cas

pinMode(led, OUTPUT);

 

qui permet d’initialiser la pin en position led (que l’on a déclaré comme étant 13 dans la première partie) en tant qu’Output.

 

Nous aurions pu tout à fait mettre directement la position de la led sur cette ligne et ne pas le faire dans une variable en écrivant :

pinMode(13, OUTPUT);

 

Mais il est bon de prendre pour habitude de déclarer les valeurs soumises aux changements dans des variables en haut de page pour pouvoir les modifier facilement.

 

Imaginez par exemple le cas ou vous auriez une dizaine de led de couleurs différentes et dont vous devez changer la position, il sera alors beaucoup plus simple et agréable de modifier une variable bien nommée du type

int ledRougeGauche = 13;

 

que d’aller fouiller dans les lignes où celles-ci sont déclarées, d’autant plus que dans le cas des leds par exemple il sera nécessaire de redonner cette position pour allumer et éteindre la led et donc effectuer les changements à chaque ligne.

Alors rendez service au vous du futur, utilisez les variables et donnez leurs des noms explicites !

Troisième partie, la fonction loop :

// the loop routine runs over and over again forever:
void loop() {
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(1000);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(1000);               // wait for a second
}

 

C’est dans cette fonction que va réellement se trouver les ordres que nous allons donner à notre micro-ordinateur. Contrairement à la fonction setup(), la fonction loop() a la particularité de se lancer et bien… en boucle. C’est à dire que dès que toutes les actions de la boucle sont réalisées, la boucle est relancée et les actions recommencent.

 

Notre boucle commence avec

digitalWrite(led, HIGH);

 

où l’on donne un Haut voltage (HIGH) à notre sortie digitale en position “led”, notre variable bien-aimée (<3).

 

La deuxième ligne de notre commande est très importante

delay(1000);

 

Il s’agit littéralement d’un retard (d’une pause) que l’on donne à l’Arduino avant qu’il n’effectue la commande suivante. La durée de ce retard est donnée en millisecondes, ici nous avons donc 1000 millisecondes (soit 1 seconde, oui monsieur/madame/mademoiselle) pendant lesquelles l’Arduino va se mettre en pause avant d’exécuter le reste du code et donc laisser la led allumée.

 

La ligne suivante nous est familière

digitalWrite(led, LOW);

 

Même principe que la première ligne sauf que nous appliquons cette fois un bas voltage à la led ce qui aura pour effet de l’éteindre.

Nous concluons le code avec un autre retard d’une seconde pour garder la led éteinte.

delay(1000);

 

En effet la boucle se relançant automatiquement lorsque toutes les lignes sont exécutées, si nous ne mettons pas ce dernier retard, la led se rallumera directement après s’être éteinte.

Nous avons donc ici un code complet pour faire clignoter notre led, vous pouvez d’ores et déjà expérimenter avec ce code, essayez par exemple de changer la sortie de la led, de modifier la durée des retards et pourquoi pas même ajouter une seconde led avant de passer au chapitre suivant.

Photoresistance et communication série

Maintenant que l’on comprend mieux comment un code Arduino fonctionne, nous allons faire le nôtre en partant de 0. Et pour se challenger un peu, nous allons faire un code contenant, des variables, une condition, une fonction, une boucle itérative et qui permettra à la carte de nous renvoyer des informations. Si cette liste vous fait un peu peur, ne vous en faites pas, on va y aller petit à petit. Dites vous que la plupart de ces éléments seront primordiaux dans vos futurs codes.

 

Le projet : Une led qui “respire” dans le noir.

 

Nous allons donc essayer de faire un petit projet composé d’une photorésistance qui est en fait une résistance dont la valeur varie en fonction de la lumière qu’elle reçoit, 2 résistances (une de 10k ohm et une autre d’une valeur comprise entre 220 et 1k ohm) et enfin une LED à deux pattes  (vous pouvez prendre n’importe quelle couleur, évitez juste le vert pour la simple et bonne raison que c’est celle que j’aime le moins ^^).

Commençons par ouvrir un nouveau croquis, vous êtes alors accueilli par les deux fonctions setup() et loop().

 

Nous allons débuter par l’installation de notre photorésistance, cette résistance doit être branchée sur une PIN analog pour que cela nous permette de lire le voltage sortant et d’en déduire la quantité de lumière. La résistance de 10k Ohm aura une patte dans la terre et une autre partageant la PIN analog de la photorésistance.

untitled-sketch-2_bb-3

Déclarons alors la Pin choisie (0) à l’aide d’une variable de nombre entier : int.

int photoResistor = 0;

 

(à mettre au dessus de la boucle setup)

A propos des variables : int est utilisée pour définir un nombre entier, dans notre cas, c’est l’idéal puisque nous ne déclarerons jamais de PIN « 10,7 ». Il existe cependant d’autres type de variables.

Nom de la variableValeurs quelle accueilleUtilisations possibles
intnombre entier de -32,768 à 32,767définition de PIN, comptage…
longnombre entier beaucoup plus grandsGros comptage ?
floatnombre décimaldivision, valeurs de senseurs…
booleantrue or falsevérification de condition
StringChaine de caractèrestockage de phrase ou mot
charcaractère unique ou code ASCIIcomparaisons de caractères

Nous pouvons ensuite lire la valeur de notre photorésistance grâce à la ligne suivante:

analogRead(photoResistor);

Cependant il sera plus pratique pour nous de mettre la valeur lue dans une variable pour que l’on puisse la manipuler plus facilement. Créons alors une nouvelle variable, encore une fois un int, juste en dessous de la précédente.

int light;

 

(par convention, évitons les noms  longs, compliqués et les accents pour prévenir les erreurs).

 

La lecture de la résistance se fera donc grâce à la ligne suivante:

light = analogRead(photoResistor);

 

Nous pourrions mettre cette ligne dans la fonction setup() comme dans loop(), mais rappelez vous, la fonction setup() n’est lancée qu’une seule fois. Notre but est de connaître la luminosité à tout moment, pas seulement quand on lance notre Arduino. C’est donc la boucle loop() tournant indéfiniment qu’il nous faut. A chaque lancement, la variable light sera changée pour contenir la nouvelle valeur lue.

 

Nous en avons désormais fini avec la photorésistance ! Cependant nous n’en faisons rien pour l’instant…

 

La prochaine étape va alors être d’établir une communication série entre le micro-contrôleur et notre ordinateur pour que nous puissions lire les valeurs récupérerées.

La communication série s’ouvre avec la ligne suivante à mettre dans le setup() :

Serial.begin(9600);

 

où 9600 est la fréquence de la communication.

 

Une fois cette communication ouverte, nous pourrons demander à notre micro-contrôleur de nous renvoyer ce que nous voulons dans notre console. Dans notre cas, nous voulons connaître l’état de la variable light.

 

On distingue deux fonctions pour communiquer dans la console :

print() et println(). La différence étant que println() fait un retour à la ligne après avoir “imprimé” le message là ou plusieurs print() seront les uns derrière les autres.

 

Pour envoyer nos valeurs nous allons donc les utiliser comme ceci juste après la lecture de la photorésistance :

Serial.print("Luminosite = ");
Serial.println(light);

 

(Le texte doit être entouré de guillemets sinon Arduino cherchera une variable !)

 

Qui nous renverra des messages du type :

Luminosite = 481
Luminosite = 516
Luminosite = 234
Luminosite = 2

 

Avant de nous lancer et de tester tout ça, il est important que nous rajoutions un petit retard dans notre fonction loop() qui nous enverra la valeur relevée plusieurs CENTAINES de fois par secondes. Limitons ce nombre à 5 avec

delay(200);

 

pour appliquer une pause de 200 millisecondes après l’envoi d’un message.

 

Nous pouvons alors téléverser le code sur la carte. Un message au dessus de la console viendra nous notifier du succès de l’opération. Ouvrons alors le moniteur série grâce au raccourci situé en haut à droite de la fenêtre,  depuis le menu outil ou encore via la combinaison « ctrl+maj+M ».

lugitlzbgc8tq

 

Vous verrez alors défiler les valeurs relevées par le micro-contrôleur. Si ce n’est pas le cas, vérifiez que la bonne fréquence est sélectionnée en bas à droite : 9600.

Amusez vous à faire varier ces valeurs en couvrant la photorésistance avec votre main ou encore en allumant et éteignant la lumière…

Condition d’allumage de la LED

Maintenant que nous avons ces valeurs nous allons nous en servir pour allumer notre led. Commençons par l’installer sur une PIN PWM, c’est à dire autorisant l’analogWrite() qui nous permettra d’allumer notre led avec différentes intensités et une résistance de 220 ohm comme suit (n’hésitez pas à utiliser une platine d’essai) :

untitled-sketch_bb

Note: Les PINs PWM seront indiquées sur votre micro-contrôleur à l’aide d’une tilde « ~ » ou point. N’hésitez pas à vérifier son diagramme en cas de doute.

Puis en la déclarant de la même manière que nous avions fait dans Blink, c’est-à-dire avec une variable en haut du croquis :

int led = 11;

Et enfin en la configurant dans la fonction setup() :

pinMode(led, OUTPUT);

 

Notre led est maintenant utilisable, nous allons donc créer une condition pour que celle-ci ne s’allume que lorsque la luminosité est basse. Avec votre montage et votre moniteur ouvert, trouvez donc une bonne valeur pour la déclencher. Si par exemple votre photorésistance retourne 750 lorsqu’elle est à la lumière et 320 lorsque vous la cachez, prenez une valeur entre les deux du type 500 pour pouvoir facilement l’atteindre quand vous ferez vos tests. A terme vous pourrez augmenter cette valeur si vous trouvez que la led ne s’allume pas assez souvent ou la baisser si au contraire elle s’allume trop souvent.

 

Cette valeur choisie sera notre seuil que nous allons bien entendu mettre dans une variable créée auprès de ses camarades.

int threshold = 500;

 

C’est maintenant que nous allons réellement commencer à coder puisque nous allons créer notre condition pour que notre led s’allume.

 

Mettons à l’écrit ce que nous voulons que notre code fasse.

 

Si la lumière relevée par notre photorésistance est plus basse que notre seuil, alors on allume la lumière.

 

Une condition s’écrit de la manière suivante :

if (condition a vérifier) {
    alors...
}

 

Notez que la condition, comme une fonction, est accompagnée d’accolades, elles sont très importantes car elles préviennent l’Arduino du début et de la fin de votre fonction/condition/boucle.

Le code exécuté sera fait à l’intérieur de ses accolades. Pensez à bien indenter votre code pour ne pas perdre le fil de vos accolades et prévenir les erreurs, vous pouvez laissez Arduino le faire automatiquement via le raccourcis Outils > Formatage Automatique ou Ctrl+ T.

comparaison

Code correctement indenté face à un code non-indenté.

La valeur relevée par la photorésistance, nous l’avons mise dans une variable, c’est “light”. Notre seuil c’est également une variable : “threshold”.

if (light < threshold) {
    digitalWrite(led, HIGH);
}

Cette condition est valable pour allumer la led, mais dans l’état actuel, elle restera allumée une fois que la condition n’est plus vérifiée. Nous pourrions faire une autre condition du type :

if (light >= threshhold) {
    digitalWrite(led, LOW);
}

Mais nous pouvons tout simplement mettre un “sinon” après un “si” qui sera exécuté si la première condition n’est pas remplie :

else {
    digitalWrite(led, LOW);
}

On va pouvoir mettre ces deux conditions juste après nos relevés de valeurs et téléverser ce nouveau code pour le tester directement !

hqglfqoc5jvn6

Oh joie, ça fonctionne !

Il ne nous reste donc plus qu’à animer cette led un petit peu tristoune :’(

Animation de la LED

Pour cela la première étape va être de réorganiser notre code qui va légèrement se compliquer.

Nous allons ranger tout ce qui concerne l’allumage de la led dans une autre fonction que l’on appellera lorsque notre condition créée précédemment sera vérifiée.

En dessous de la fermeture de la fonction loop, nous allons alors créer une fonction ledOn de la manière suivante :

void ledOn() {

}

 

dans laquelle vous pouvez déplacer le :

digitalWrite(led, HIGH);

qu’il y avait dans la condition puisque dans cette condition, nous allons désormais appeler notre fonction ledOn() de la manière suivante :

if (light < threshold) {
 ledOn();
}

 

Vous pouvez alors téléverser ce code et remarquer que….. rien…. rien n’a changé, et pour cause, le code est exactement le même, nous l’avons juste réorganisé pour pouvoir plus facilement nous y retrouver. En soi, rien ne vous empêche de faire la totalité de votre code dans la loop, mais de la même manière que les variables, il est plus simple de s’y retrouver dans des fonctions nommées explicitement qu’une succession de commande désordonnées.

 

Vous saurez alors que tout ce qui se trouve dans cette fonction concerne l’allumage de la led qui n’arrivera uniquement lorsque la condition sera remplie.

 

Concentrons nous donc sur cette fonction dans laquelle nous allons mettre l’animation que nous voulons donner à notre LED. Encore une fois, mettons à l’écrit notre objectif.

Donner une animation de respiration à notre led, c’est à dire que la luminosité diminue jusqu’à ce qu’elle atteigne 0, puis qu’elle augmente jusqu’à ce qu’elle atteigne 255 (la luminosité maximale).

 

Pour cela nous allons utiliser une nouvelle structure for, une boucle munie d’un compteur qui s’arrêtera lorsque son compteur aura atteint une limite définie.

for (int i=0; i<256; i++) {

}

 

Cette boucle a trois paramètres :

 

J’espère que vous allez reconnaître le premier puisque c’est une variable, un nombre entier qui va initialiser notre compteur. Ici, nous l’initialisons à 0.

Remarquez que nous déclarons cette variable directement en paramètre de la boucle et non en haut du croquis avec les autres. C’est parce que contrairement aux autres variables, celle ci est utilisée uniquement dans le cadre de cette boucle, je n’ai pas besoin de l’utiliser autre part.

 

Le deuxième paramètre est la limite de notre compteur, la condition qui si elle n’est pas vérifiée interrompra le fonctionnement de la boucle pour passer à la suite.

Notre condition limite sera i inférieur à 256, je vous explique pourquoi juste après.

 

Le troisième et dernier paramètre est l’incrémentation, c’est l’opération qui va être effectuée à chaque fois qu’une boucle est effectuée. Notre but est d’augmenter le compteur d’un à chaque fois.

Cela peut s’écrire de plusieurs manières :

 

« i = i+1 » , « i += 1 » ou encore « i++ »

Toutes auront le même résultat. La dernière solution étant la plus courte (et comme nous sommes fainéant) c’est celle que nous choisirons.

 

Avec ces trois paramètres nous aurons donc une boucle qui tournera 255 fois avec une variable “i” qui augmentera d’un à chaque fois. C’est cette variable que nous allons utiliser pour définir la luminosité de notre led allant de 0 à 255.

Il nous suffit de mettre à l’intérieur de cette boucle :

analogWrite(led, i);

 

Nous allons également rajouter un retard de 10 millisecondes car le microcontrôleur exécutera la boucle le plus vite possible, ce qui rendra l’animation invisible pour nos petits yeux. Notre boucle ressemblera donc à ça :

for (int i=0; i<256; i++) {
   analogWrite(led, i);
   delay(10);
 }

szdjsq1yoemqa

Téléversez et testez ce nouveau croquis. Vous avez bien une led qui s’allume lentement et de manière assez fluide. Cependant ce n’est pas le cas de son extinction et c’est normal !

Une fois que notre “i” est au dessus de 255, la boucle se termine et la fonction ledOn() également, si notre condition de luminosité est toujours vérifiée, la fonction et donc la boucle sont relancées et la luminosité de la led est remise à 0.

 

Nous allons donc ajouter une deuxième boucle for() très similaire juste après la fermeture de la précédente.

for (int j=255; j>=0; j--) {
  analogWrite(led, j);
  delay(10);
}

 

Cette fois nous initialisons notre compteur à 255, on l’arrête lorsqu’il atteint 0 et au lieu d’augmenter de 1 à chaque fois nous réduisons de 1 avec j–. Sachez que concernant cette dernière incrémentation, vous pouvez tout à fait faire le choix d’augmenter ou de réduire d’une autre valeur que 1 pour que l’animation aille plus vite, mais l’on préférera modifier le retard dans ce cas là pour garder une animation fluide (255 étapes en incrémentant de 1 contre 51 si l’on augmente de 5 par exemple).

 

Réalisons un dernier téléversement et observons alors notre jolie led respirer. Vous remarquerez que lorsque vous remettez de la lumière, la led reste allumée un moment avant de s’éteindre, c’est tout simplement car notre fonction ledOn() doit se terminer avant que la condition dans loop() se revérifie.

ks0yfltgvhkm4

Ce code n’est peut-être pas optimal mais il nous aura permis d’utiliser des variables globales et locales, de vérifier une condition avant de lancer une commande, d’établir une connexion série avec le micro-contrôleur pour qu’il nous envoie des messages et de créer une boucle itérative avec un compteur.

 

Toutes ces nouvelles connaissances bien que basiques vous permettront de réaliser déjà bon nombre de codes Arduino. Je ne peux que vous conseiller de consulter les différents exemples contenus dans Arduino IDE pour essayer de comprendre leurs fonctionnements et explorer le vaste scope des possibilités !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *