Infoforall

1 - ARDUINO / Prise en main de la carte et du logiciel

arduino

Bien. Je pars du principe que vous avez installé le logiciel Arduino et que vous avez bien connecté l'USB de l'Arduino sur l'ordinateur.

1 - Le port USB

Commençons par expliquer ce qu'est un port USB.

USB veut dire Universal Serial Bus. Il s'agit donc d'un moyen d'envoyer des informations sur la technique de la communication série : on utilise une seule voie sur laquelle les informations sont envoyées les unes à la suite des autres. Comme notre port USB est à la base un ensemble de fils de cuivre, le signal porteur de l'information est un signal électrique.

L'un des intérêts de l'USB est qu'il permet le branchement à chaud (c'est à dire qu'on peut le brancher alors que l'ordinateur est déjà allumé) et qu'il permet le Plug-and-Play (c'est à dire qu'il peut reconnaitre automatiquement le type de périphérique et le faire fonctionner correctement).

Un autre avantage, et non des moindres, est qu'un port USB intègre également une borne 5V et une borne de masse : on peut donc alimenter un appareil ne nécesitant pas trop de courant à l'aide de son port USB !

bornes usb

On obtient la description suivante :

  • Borne 1 : borne 5V de l'alimentation
  • Borne 4 : borne de masse de l'alimentation
  • Bornes 2 et 3 : bornes transmettant les informations.

Il existe plusieurs types de connecteurs USB :

types usb

De gauche à droite : micro-B mâle ; UC-E6 propriétaire (non USB) ; mini-B mâle ; A femelle ; A mâle ; B mâle.

Pour connecter votre UNO et votre PC, vous avez certainement besoin d'un USB type A et d'un USB type B.

01° Connecter la carte UNO et l'ordinateur. Vous devriez voir les DEL s'allumer. C'est bien le signe que le PC parvient à alimenter en tension. Mais la communication peut-elle se faire ?

2 - Reconnaissance de la carte et driver

Si vous avez correctement installé votre programme IDE Arduino, la carte devrait être reconnue.

02° Ouvrir le panneau de configuration et aller dans le menu gestionnaire de périphérique (si vous êtes sous Windows bien entendu).

De deux choses l'une : soit vous trouvez votre carte et son numéro de port associé, soit vous ne le trouvez pas. Dans ce cas, il faudrait mettre à jour votre driver

Windows 10 : j'ai remarqué que Windows 10 avait encore caché un peu plus l'interface périphérique. Celle que vous obtenez en cliquant directement dans le menu Paramètres n'est qu'une version simplifiée. On peut toujours accéder à l'ancienne via : Démarrer - Système Window - Panneau de configuration. Et là, vous pourrez sélectionner la carte et mettre à jour les pilotes en la sélectionnant avec un clic droit.

Sinon, même en restant dans l'interface de base, vous avez encore accès au gestionnaire de périphérique, mais il faut aller en bas de la page.

03° Chercher l'accès à votre périphérique et à son driver : cela vous sera toujours utile un jour. Noter le numéro du port au passage. Et si tout fonctionne pour l'instant, ne modifiez rien !

gestionnaire

3 - IDE Arduino

Il est temps de lancer l'interface, l'IDE Arduino :

icone IDE

04° Lancez l'IDE et regardez son interface :

Vous devriez avoir un écran qui ressemble à ceci :

Ecran IDE

05° Utilisez le menu OUTILS pour aller sélectionner le bon type de carte et le bon port USB de communication :

Choix de la carte Choix du port

Commençons par regarder le programme de base : c'est un programme vide qui ne fait rien. Premier constat : l'Arduino se programme en C.

Ecran IDE

void setup() {

    // put your setup code here, to run once:

}


void loop() {

    // put your main code here, to run repeatedly:

}

Les deux entités setup() et loop() sont ce qu'on nomme des fonctions : des lignes de code qui sont exécutées lorsqu'on les appele. On reconnait les fonctions au fait qu'elles sont toujours suivies de parenthèses ().

De quelles lignes de code parle-t-on d'ailleurs ? De celles qui seront tapées entre les accolodes { et }.

Ici, on voit qu'il n'y a aucune ligne de code : les fonctions ne font donc rien !

Les deux fonctions sont néanmoins particulières : elles sont executées de façon autonome par le microprocesseur :

06° Ouvrir le programme BLINK en utilisant le menu FICHIER - Exemples - ... comme indiqué ci-dessous :

Blink

07° Avant d'expliquer ce programme, commençons par l'envoyer dans l'Arduino UNO : utilisez le bouton TELEVERSER de l'interface :

Televerser

Si vous n'avez pas eu d'erreur, vous avez dû voir que le logiciel compile votre programme (c'est à dire qu'il transforme vos lignes de code en suite de bits compréhensibles par le microprocesseur) puis qu'il l'envoie dans le microprocesseur.

La DEL orange devrait se mettre à clignoter.

DEL integrée

08° Modifier le programme en changer les valeurs :

// the loop function runs over and over again forever

void loop() {

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(100); // wait for a second

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    delay(100); // wait for a second

}

La DEL orange devrait se mettre à clignoter plus vite.

Bon, ça fonctionne comment alors ? Voici ce programme de base :

/*

Blink

    Turns on an LED on for one second, then off for one second, repeatedly.


    Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO

    it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to

    the correct LED pin independent of which board is used.

    If you want to know what pin the on-board LED is connected to on your Arduino model, check

        the Technical Specs of your board at https://www.arduino.cc/en/Main/Products


    This example code is in the public domain.


    modified 8 May 2014

    by Scott Fitzgerald


    modified 2 Sep 2016

    by Arturo Guadalupi


    modified 8 Sep 2016

    by Colby Newman

*/


// 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);

}


// the loop function runs over and over again forever

void loop() {

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(1000); // wait for a second

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    delay(1000); // wait for a second

}

La première partie comporte des commentaires, c'est à dire des lignes qui sont destinées à être lues par un humain et pas à être interprétées comme des lignes de code :

/*

Blink

    Turns on an LED on for one second, then off for one second, repeatedly.


    Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO

    it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to

    the correct LED pin independent of which board is used.

    If you want to know what pin the on-board LED is connected to on your Arduino model, check

        the Technical Specs of your board at https://www.arduino.cc/en/Main/Products


    This example code is in the public domain.


    modified 8 May 2014

    by Scott Fitzgerald


    modified 2 Sep 2016

    by Arturo Guadalupi


    modified 8 Sep 2016

    by Colby Newman

*/

09° Quels sont les caractères qui semblent indiquer le début d'un commentaire multiligne ? Quels sont les caractères qui semblent indiquer la fin d'un commentaire multipligne ?

...CORRECTION...

Le début du commentaire se précise avec /*, dans le sens d'apparition sur le clavier numérique.

La fin du commentaire se précise avec l'inverse : */.

En gros, le commentaire signale que :

La DEL (Diode électroluminescente en français, LED en anglais) va alterner entre lumineuse et éteinte toutes les secondes.

La plupart des cartes Arduino possèdent une DEL controlable via la programmation et integrée directement sur la carte. Selon les modèles de carte, il peut s'agir des bornes 13 (c'est le cas de la UNO) ou 6.

Dans tous les cas, la variable constante LED_BUILTIN contient la bonne valeur de la borne DEL.

On signale que le code est dans le domaine public et on donne ensuite les différentes mises à jour effectuées.

10° Tentons de voir si pour le UNO la borne est bien la 13 : utiliser le programme suivant dans le microprocesseur. Il utilise directement le numéro de la borne et pas uniquement la variable CONSTANTE LED_BUILTIN.

// the setup function runs once when you press reset or power the board

void setup() {

    // initialize digital pin LED_BUILTIN as an output.

    pinMode(13, OUTPUT);

}


// the loop function runs over and over again forever

void loop() {

    digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(2000); // wait for a second

    digitalWrite(13, LOW); // turn the LED off by making the voltage LOW

    delay(2000); // wait for a second

}

Et sinon, il fonctionne comment ce programme ? Pour l'instant, nous n'avons fait que lire les commentaires.

void setup() {

    // initialize digital pin LED_BUILTIN as an output.

    pinMode(LED_BUILTIN, OUTPUT);

}


La fonction setup() s'exécute lors de la mise en marche du programme.

Ici, elle ne contient qu'une ligne unique qui signale comment utiliser l'une des bornes d'entrée/sortie de l'Arduino :

On utilise la fonction pinMode(...) qui permet de définir la nature des bornes. On notera qu'on trouve des choses à l'intérieur des parenthèses. Ce sont les arguments de la fonction, des valeurs qu'on transmet de façon à ce qu'elle fasse ce qu'on veut. La borne LED_BUILTIN (variable constante qui contient 13 si vous avez suivi) devra être utilisée en tant que borne de SORTIE (OUTPUT). Cela se code par :

pinMode(LED_BUILTIN, OUTPUT);

TRADUCTION en humain : utilise la borne 13 (LED_BUILTIN) comme une borne de sortie (OUTPUT).

J'ai signalé en le surlignant que les lignes de code doivent finir un point-virgule en C. Cela signale la fin de l'instruction de façon à ce que l'interpréteur puisse savoir qu'on passe désormais à la suite.

Les tabulations (touche TAB de votre clavier, celle à côté de A) permettent de rendre le code plus lisible.

On notera enfin qu'il n'y a pas de point-virgule après la déclaration de la fonction (void setup()) car ce n'est pas une instruction mais une déclaration. Le début et la fin des instructions de la fonction sont encodés avec les accolades { }.

// the loop function runs over and over again forever

void loop() {

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(1000); // wait for a second

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    delay(1000); // wait for a second

}

Cette fois, on voit 4 lignes finissant par un point-virgule. On a donc 4 instructions.

Il y a une nouveauté néanmoins : les //. Ceux-ci signalent comme /* et */ qu'on a un commentaire jusqu'à la fin de la ligne. Mais contrairement à /* et */, l'utilisation de // ne permet qu'un commentaire sur cette unique ligne. Si on veut en faire d'autres, il faut rajouter d'autres //. On les utilise pour donner des explications sur une ligne de code précise.

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(1000); // wait for a second

Cette fois, on utilse une nouvelle fonction : digitalWrite(...) qui permet de modifier la valeur d'une borne déclarée en sortie / OUTPUT. Nous verrons bientôt ce que veut dire le digital. Ainsi digitalWrite(LED_BUILTIN, HIGH); veut dire :

TRADUCTION en humain : Fixe la borne de sortie 13 à la valeur haute (1 ou état haut ou 5 V, HIGH). Ainsi, la DEL va recevoir du courant et va briller.

Ensuite, on rencontre une autre fonction : la fonction delay(...) va mettre le système en pause pendant quelques millisecondes. Pour ceux qui ne connaissent pas, cela fonctionne comme les millimètres par rapport au mètre. 1s = 1000 ms. delay(1000); veut dire :

TRADUCTION en humain : Attends pendant 1000 ms, soit 1s, avant d'exécuter la ligne du dessous.

Les deux dernières lignes sont donc plus ou moins limpides, j'espère :

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    delay(1000); // wait for a second

On utilise la fonction digitalWrite(...) pour placer la sortie 13 à la valeur basse (0 ou état bas ou 0V, LOW). La DEL s'éteint puisqu'elle n'est plus alimentée.

Avec delay(1000);, on attend 1 s avant de passer à la suite.

La suite ? Quelle suite : la fonction est finie ! On rencontre même l'accolade finale }...

Oui, c'est vrai. Mais nous sommes dans la fonction particulière loop() : elle s'exécute en boucle. On repart donc sur la première ligne, celle où on place la borne de sortie 13 à l'état HAUT.

4 - Moniteur série

Une dernière chose pour la fin : comment demander à la carte de nous renvoyer des informations pour vérifier que tout se passe bien. Et oui, il est possible qu'une DEL soit HS et qu'elle ne puisse plus briller alors qu'elle le devrait. Comment savoir alors si c'est une panne matériel ou un bug informatique ? C'est simple, il faut utiliser le moniteur série.

On peut l'ouvrir en cliquant sur l'icone en haut à droite qui ressemble à une petite loupe :

Icone moniteur

Pour demander à l'Arduino d'afficher des choses à l'intérieur du moniteur, nous allons devoir utiliser de nouvelles fonction.

11° Modifier le code de la fonction setup() comme indiqué ci-dessous, ouvrir le moniteur, téléverser le nouveau code et observer le résultat.

void setup() {

    // initialize digital pin LED_BUILTIN as an output.

    pinMode(LED_BUILTIN, OUTPUT);

    Serial.begin(9600);

    Serial.println("Nous sommes dans la fonction setup().");

}


Vous devriez constater que le message Nous sommes dans la fonction setup(). apparait UNE FOIS dans le moniteur.

Nous venons d'utiliser une nouvelle entité informatique : une Classe. Elle se nomme Serial, pour série en anglais. Le nom de cette classe Serial commence par une majuscule. C'est une façon de codifier les choses en informatique. Pour séparer les classes du reste (les fonctions ...), on commence toujours les noms des classes par des Majuscules.

Qu'est-ce qu'une Classe ? Nous verrons ça plus tard dans le détail mais disons pour l'instant que c'est une boîte qui contient tout ce qu'il faut pour gérer la Classe à l'intérieur. Ainsi, la classe Serial va nous permettre de gérer le moniteur Série et elle contient toutes les fonctions pour le faire. D'ailleurs, lorsqu'on parle d'une fonction propre à une classe (une fonction codée à l'intérieur de la classe elle-même), on ne parle pas de fonction mais de méthodes. Voilà pour le vocabulaire.

Quelques explications sur ces lignes de code :

    Serial.begin(9600);

On utilise la méthode qui se nomme begin(...) et qui se trouve dans la classe nommée Serial. La codification est très rigoureuse : on note la classe puis un point puis le nom de la méthode voulue.

Le 9600 donné en argument est la vitesse de communication. Ici 9600 bits par seconde. Pensez à vérifier que le moniteur est bien réglé sur cette valeur.

La méthode begin(...) de la classe Serial sert à ouvrir le canal de communication entre l'Arduino et le moniteur.

    Serial.println("Nous sommes dans la fonction setup().");

Encore une fois, nous allons utiliser une méthode de la classe Serial. On note donc Serial.. Cette fois, la méthode se nomme println(...).

Elle permet d'afficher des choses sur le moniteur ET de passer à la ligne. Ici, l'argument est une chaîne de caractére et on ne notera qu'on le transmet entre deux guillemets " et ". Ce qui va s'afficher et donc ce qui est compris entre les deux.

    Serial.println("Nous sommes dans la fonction setup().");

12° Modifier le code de la fonction loop() comme indiqué ci-dessous, ouvrir le moniteur. Demandez vous ce que devrez faire le code puis téléversez et observee le résultat.

// the loop function runs over and over again forever

void loop() {

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    delay(1000); // wait for a second

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    delay(1000); // wait for a second

    Serial.println("Nous sommes dans la fonction loop().");

}

Et oui, cette fois, il affiche la chaîne de caractères plusieurs fois car il s'agit de la fonction loop(), celle qui tourne en boucle.

Et si on veut comprendre ce que contiennent les variables, il suffit de lui demander.

Nous allons donc utiliser une nouvelle fonction : la fonction digitalRead(numero_borne) permet de lire l'état (HAUT HIGH 1 ou BAS LOW 0) d'une borne numérique dont on lui transmet le numéro. Nous pourrons bien entendu utiliser également la constante LED_BUILTIN qui contient 13.

13° Rajouter des éléments dans la fonction loop() de façon à afficher dans le moniteur l'état de la borne LED_BUILTIN et donc de savoir si elle devrait briller ou non.

Correction possible :

// the loop function runs over and over again forever

void loop() {

    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

    Serial.println(digitalRead(LED_BUILTIN));

    delay(1000); // wait for a second

    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

    Serial.println(digitalRead(LED_BUILTIN));

    delay(1000); // wait for a second

    Serial.println("Nous sommes dans la fonction loop().");

}

Bilan

Nous avons donc vu pour l'instant uniquement comment controler et lire l'état d'une borne numérique.

Nous avons vu qu'on peut utiliser des constantes, stockées dans un nom en MAJUSCULES séparées par des underscores _ si le nom est un nom composé. Ainsi, LED_BUILTIN est une constante qui contient 13. HIGH contient 1 et LOW contient 0.

Nous avons vu que chaque instruction doit finir par un point-virgule pour signaler qu'on passe à l'instruction suivante.

Les fonctions sont des lignes de code qui vont s'exécuter lorsqu'on fait appel à la fonction. Leurs noms commencent par une minuscule et chaque premier mot ensuite commence par une majuscule. Exemple : pinMode(). Elles comportent nécessairement des parenthèses qui servent à leur transmettre des arguments. Si on ne transmet rien, on place au moins ceci : (). Une fonction peut comporter plusieurs isntructions : le début et la fin des instructions sont signalés avec des accolades { et }.

Le programme de base de l'Arduino comporte deux fonctions particulières :

  • La fonction setup() qui est lancée automatiquement et une unique fois.
  • La fonction loop() qui tourne en boucle tant que le programme fonctionne.

Les fonctions permettant de gérer les bornes sont :

  • Pour définir la nature ENTREE(INPUT) ou SORTIE (OUTPUT) d'une borne : pinMode(LED_BUILTIN, OUTPUT); par exemple.
  • Pour forcer l'état d'une borne numérique de SORTIE à HIGH ou LOW : digitalWrite(LED_BUILTIN, HIGH); par exemple.
  • Pour obtenir l'état HIGH ou LOW d'une borne numérique : digitalRead(LED_BUILTIN; par exemple.

Pour créer un délais d'attente : delay(temps) avec le temps en ms.

Il existe également des classes, dont le nom commencent toujours par une majuscule : ce sont des entités informatiques qui contiennent les fonctions qui permettent de les gérer. On nomme d'ailleurs ces fonctions des méthodes. Pour accéder à une méthode, on tape le nom de la classe, un point et le nom de la méthode voulue.

Exemple avec la classe Serial :

  • Pour lancer la communication avec le moniteur Serial : Serial.begin(9600);
  • Pour afficher quelque chose dans le moniteur Serial : Serial.println(Le truc à afficher);

Attention : si vous voulez afficher du texte, il ne faut pas oublier les guillemets " ".

Nous irons un peu plus loin dans le chapitre suivant. Nous verrons les différents ports disponibles, ainsi que la façon dont le microcontrolleur stocke les données.