2578_chap03

March 29, 2018 | Author: Ismail Haker | Category: Computer Program, C (Programming Language), Compiler, Computer Programming, Source Code


Comments



Description

3Éléments du langage C Le langage de programmation qui permet de programmer une carte Arduino se nomme le langage C. Ce chapitre vous propose d'en découvrir ou d'en revoir les éléments fonda- mentaux. Ce que vous allez apprendre au cours de ce chapitre vous servira dans tous les programmes que vous allez concevoir pour Arduino. Pour bien tirer proft d'Arduino, il faut avoir compris ces éléments fondamentaux. Programmer Il n'est pas rare de nos jours que les gens parlent plus d'une langue. D'ailleurs, plus vous en apprenez, plus il devient simple d'en apprendre d'autres, parce que vous commencez à repérer des invariants de grammaire et de vocabulaire qui sont partagés entre plusieurs langues. Il en va de même avec les langages de programmation. Autrement dit, si vous avez déjà pratiqué un autre langage, vous serez vite à niveau en langage C. La bonne nouvelle avec les langages de programmation informatique est que leur vocabulaire est bien plus restreint que celui d'une langue humaine. De plus, c'est un langage écrit et non parlé, ce qui vous permet de toujours pouvoir recourir au diction- naire en cas de doute. La grammaire et la syntaxe d'un langage informatique sont très strictes. Une fois que vous avez assimilé une poignée de concepts simples, la progression devient quasiment naturelle. ARDUI__Monk.indb 25 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk 26 Arduino : les bases de la programmation Vous pouvez comparer un programme informatique (les programmes source Arduino s'appellent des croquis ou sketch), comme une liste d'instructions que le processeur doit exécuter dans l'ordre dans lequel elles apparaissent. Prenons comme exemple les trois lignes suivantes : digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); Chacune de ces trois lignes fait réaliser une action. La première ligne force le passage à l'état haut (HIGH) de la broche 13 du circuit. C'est sur cette broche qu'est installée une LED sur la carte Arduino. Cet ordre oblige donc à faire allumer la LED. La deuxième ligne se contente de suspendre l'exécution pendant 500 millisecondes (une demi- seconde). La troisième ligne est ensuite exécutée pour éteindre la LED. L'exécution de ces trois lignes permet donc de faire clignoter une fois la LED. Vous aurez remarqué la présence de plusieurs signes de ponctuation et l'apparent oubli d'espaces entre les mots (et de lettres accentuées). Bien des débutants en programmation savent ce qu'ils veulent faire, mais ils ne savent comment le formuler par écrit. Ne vous inquiétez pas, nous allons tout expliquer. Voyons d'abord ce problème de ponctuation et d'absence d'espaces entre les mots. Ces manières d'écrire sont conformes à la syntaxe du langage et la plupart des langages de programmation vous demandent d'être très précis à ce niveau. Une des règles de syntaxe majeure est que les noms donnés aux choses doivent être constitués d'un seul mot sans espaces. Autrement dit, digitalWrite() est le nom de quelque chose, plus précisément le nom d'une fonction préprogrammée (nous reparlerons des fonctions plus tard). Cette fonction va réaliser une action de changement de l'état d'une broche de sortie sur la carte Arduino. Non seulement il faut éviter les espaces dans les noms, mais il faut tenir compte de la différence entre majuscules et minuscules, c'est-à-dire la casse des lettres. Pour le programme, digitalWrite() n'est pas la même chose que DigitalWrite() ou Digitalwrite(). Notre fonction digitalWrite() a besoin que vous lui indiquiez quelle broche elle doit modifer et s'il faut forcer l'état électrique de la broche à l'état haut (HIGH) ou bas (LOW). Ces deux informations s'appellent des arguments, et ces arguments sont transmis à la fonction lorsqu'elle est appelée. Les arguments d'une fonction doivent être entourés par un couple de parenthèses et séparés les uns des autres par une virgule. Par convention, la parenthèse ouvrante suit immédiatement la dernière lettre du nom de la fonction. Une autre convention qui facilite la lecture par les humains consiste à ajouter un espace après chaque virgule séparant deux arguments. Vous pouvez cependant ajouter plus d'espaces entre les parenthèses si cela vous aide à la lecture. Notez que lorsqu'une fonction n'a qu'un seul argument, il n'y a aucune virgule. ARDUI__Monk.indb 26 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk Chapitre 3 Éléments du langage C 27 Vous remarquez que chacune des trois lignes se termine par un signe point-virgule. Vous pourriez trouver plus logique d'utiliser des points, puisque cela signife la fn d'une commande, un peu comme en fn de phrase. Nous allons découvrir maintenant ce qui se passe lorsque vous transférez le programme grâce au bouton TÉLÉVERSER (Upload) de l'ordinateur de développement vers la carte Arduino, à partir de l'atelier. Nous allons ensuite pouvoir faire quelques essais pratiques de programmation. Qu'est-ce qu'un langage de programmation ? Certains lecteurs seront peut-être surpris de constater que nous avons attendu d'en être au Chapitre 3 pour défnir exactement ce qu'est un langage de programmation, alors que c'est le sujet de ce livre. Au point où nous en sommes, vous savez déjà reconnaître un croquis Arduino et avez certainement une idée générale de ce à quoi servent ces programmes. Nous devons maintenant aller voir plus précisément comment le code source du langage, c'est-à-dire un ensemble de mots dans un programme d'édition, fnit par se transformer en quelque chose qui agit sur le monde réel, comme allumer ou éteindre une LED. La Figure 3.1 montre les grandes étapes de cette chaîne de production qui va de la saisie du code source dans l'atelier IDE Arduino jusqu'à l'exécution du programme sur la carte. Figure 3.1 Du code source à la carte. Compilateur Ordinateur hôte Carte Arduino Chargeur (bootloader) Mémoire Flash du programme CPU Ports LED Lorsque vous utilisez le bouton de téléversement de votre atelier Arduino, vous déclenchez une série d'événements dont les deux dernières étapes correspondent à l'installation du programme exécutable sur la carte Arduino et à son démarrage. Notez qu'il ne s'agit pas de simplement transférer les instructions de code source que vous avez saisies vers la carte Arduino. La première étape de cette chaîne se nomme la compilation. Elle consiste à analyser les instructions de code source que vous avez écrites pour les convertir en séquences de code ARDUI__Monk.indb 27 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk 28 Arduino : les bases de la programmation machine, c'est-à-dire le langage binaire que peut comprendre le processeur de la carte Arduino. Si vous utilisez le bouton triangulaire de vérifcation dans l'atelier Arduino, vous demandez de faire une compilation du programme C sans faire suivre cette action du transfert du code résultant vers la carte. La compilation du code permet en effet de vérifer que la totalité du contenu est conforme aux règles de syntaxe du langage C. Si vous saisissez les deux mots Ciao Bella alors que la zone d'édition de l'atelier est vide, puis utilisez le bouton VÉRIFIER, vous obtiendrez les résultats de la Figure 3.2. Observez notamment le bandeau inférieur de la fenêtre. Figure 3.2 La preuve qu'Arduino ne comprend pas l'italien. L'atelier Arduino a essayé de compiler les deux mots "Ciao Bella". Malgré ses origines italiennes, il n'a rien compris à ce que vous avez tenté de lui dire. Ce texte n'est en effet pas du langage C. Voilà pourquoi vous voyez apparaître dans le bas de l'écran un message un peu obscur : "'Ciao' does not name a type." Cela signife que ce que vous avez écrit ne convient pas du tout. ARDUI__Monk.indb 28 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk Chapitre 3 Éléments du langage C 29 Prenons un autre exemple. Voyons si nous pouvons compiler un croquis totalement vide (voir Figure 3.3). Figure 3.3 Un programme sans setup() ni loop(). Cette fois-ci, le compilateur vous informe dans le bandeau inférieur que votre croquis ne contient aucune fonction nommée setup() ou loop(). Si vous vous souvenez de l'exemple Blink du Chapitre 2, vous savez qu'il fallait insérer un minimum de code standard (boilerplate) avant de pouvoir ajouter vos instructions spécifques dans le programme. Dans la programmation pour Arduino, le code générique prend la forme de deux fonctions qui doivent toujours être présentes dans un croquis et porter exactement les noms setup() et loop(). Nous décrirons en détail les fonctions dans le chapitre suivant du livre. Pour l'instant, contentez-vous d'accepter le fait qu'il est nécessaire de toujours insérer ce code minimal pour que le compilateur accepte de compiler votre croquis (voir Figure 3.4). ARDUI__Monk.indb 29 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk 30 Arduino : les bases de la programmation Figure 3.4 Exemple de croquis pouvant être compilé, bien qu'il soit vide. L'atelier Arduino reconnaît vos efforts de rédaction et accepte la compilation. Il vous le confrme par le message "COMPILATION TERMINÉE." suivi d'un rapport sur la taille du croquis : 466 octets, par exemple. Le message vous indique également que la taille maximale du programme est de 32 256 octets, ce qui vous laisse de la marge pour faire grossir votre croquis. Examinons de plus près ces six lignes de code initiales qui doivent être présentes dans tous vos croquis. Nous y trouvons de nouveaux éléments, et notamment le mot void ainsi que des paires d'accolades. Voyons d'abord à quoi sert le mot void. La première ligne, void setup(), signife que vous défnissez une fonction portant le nom setup(). Dans Arduino, certaines fonctions sont préprogrammées, et c'est le cas de digitalWrite() et de delay(), mais vous pouvez défnir vos propres fonctions. Les deux fonctions setup() et loop() sont particulières : leur nom est immuable, mais c'est à vous de défnir leur contenu dans chacun de vos croquis. Sachez que vous n'allez pas appeler ces deux fonctions spéciales setup() et loop() comme vous le feriez pour digitalWrite(). Vous devez défnir les deux fonctions, mais ARDUI__Monk.indb 30 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk Chapitre 3 Éléments du langage C 31 c'est le système Arduino qui va les appeler. Ce n'est pas un concept facile à comprendre, mais vous pouvez le comparer à une défnition de termes dans un document juridique. Souvent, les documents juridiques contiennent une section de défnition des termes dans laquelle vous pourriez trouver quelque chose dans le style suivant : Définitions : Auteur : Par auteur est désigné la ou les personnes qui sont responsables de la création du livre. Une fois qu'un terme est ainsi défni, les avocats peuvent citer le mot "auteur" comme un raccourci de l'expression "la ou les personnes responsables de la création d'un livre", ce qui permet de rendre les documents plus courts et plus lisibles. Une fonction équivaut un peu à une telle défnition. Vous défnissez la fonction que vous allez ensuite utiliser ailleurs dans votre croquis ou que le système va appeler. Revenons au mot void (vide) qui est utilisé en préfxe des deux fonctions. Il signife qu'elles ne renvoient aucune valeur, alors que c'est le cas de nombreuses autres fonctions. Pour dire qu'il n'y aura pas de valeur renvoyée, nous utilisons ce mot réservé void. Imaginez une fonction qui s'appelle sinus() pour calculer le sinus d'une valeur. Cette fonction devrait par défnition renvoyer une valeur (le résultat de son calcul). Cette valeur serait le sinus de l'angle qui aura été transmis en argument dans l'appel à la fonction. De même que l'on utilise des mots pour défnir un terme dans un document juridique, nous utilisons le langage C pour défnir des fonctions qui sont ensuite appelées à d'autres endroits du programme en langage C. Le mot-clé void est suivi d'un espace, puis du nom de la fonction, puis d'un couple de parenthèses délimitant la liste des paramètres. Dans les deux cas de notre exemple, il n'y a aucun paramètre, mais les parenthèses doivent cependant être présentes. INFO N.d.T. : Vous rencontrerez les deux termes "paramètre" et "argument". Un paramètre est la variable théorique défnie dans la défnition de la fonction. Un argument est une valeur réelle transmise à la place du paramètre lors d'un appel à la fonction. Vous remarquez en revanche qu'il n'y a pas de signe point-virgule après la parenthèse fermante. En effet, il ne s'agit ici que de la première ligne du bloc de défnition d'une fonction. Ce n'est pas un appel à la fonction. C'est entre les accolades que viendront se placer les instructions à exécuter lorsque la fonction sera appelée. Toutes les actions que va réaliser la fonction doivent être placées entre ces accolades. Les accolades et les instructions constituent le corps de la fonction ou son bloc de code. Nous reviendrons sur ce concept plus tard. ARDUI__Monk.indb 31 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk 32 Arduino : les bases de la programmation Vous remarquez que bien qu'il faille défnir les deux fonctions setup() et loop(), il n'est pas obligatoire d'insérer des instructions dans leur corps. Cela dit, si les deux fonctions sont vides, votre croquis n'a aucun effet. Le retour de Blink ! La raison pour laquelle tout programme Arduino rend obligatoire la présence des deux fonctions nommées setup() et loop() est que cela permet de séparer les actions qui ne doivent être réalisées qu'une fois au démarrage du croquis de celles qui doivent pouvoir se dérouler plusieurs fois. La fonction nommée setup() n'est exécutée qu'une fois au début du démarrage du croquis. Nous allons ajouter quelques instructions dans son corps pour faire clignoter la LED de la carte. Ajoutez les deux lignes d'instruction suivantes dans le corps de la fonction setup() du croquis précédent, puis demandez le transfert du programme vers la carte par téléversement : void setup() { pinMode(13, OUTPUT); digitalWrite(13, HIGH); } void loop() { } Les deux instructions ajoutées dans setup() correspondent à deux appels de fonctions prédéfnies qui sont pinMode() et digitalWrite(). Nous connaissons déjà digitalWrite() mais pas pinMode(). Cette fonction permet de confgurer une broche pour qu'elle soit une broche d'entrée ou de sortie. Pour allumer la LED, nous avons donc deux étapes à parcourir. D'abord, nous défnissons la broche 13 comme devant être utilisée comme sortie, puis nous forçons cette sortie à l'état haut (HIGH). Si vous lancez l'exécution de ce croquis, vous verrez la LED s'allumer sur la carte et rester allumée. Ce n'est pas très intéressant. Essayons de la faire clignoter en provoquant un allumage suivi d'une extinction dans la boucle loop() et non dans la fonction de démarrage setup(). Vous pouvez laisser l'appel à pinMode() dans la fonction setup() parce qu'il n'est néces- saire qu'une fois. Cela fonctionnerait toujours si nous déplacions l'appel dans la boucle, mais il serait inutile de répéter cette action de préparation. Prenez la bonne habitude de ne faire les choses qu'une fois si cela sufft. Modifez le croquis pour qu'il ressemble à celui-ci : void setup() { pinMode(13, OUTPUT); ARDUI__Monk.indb 32 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk Chapitre 3 Éléments du langage C 33 } void loop() { digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); } Essayez le croquis. Le résultat va peut-être vous étonner. La LED semble rester allumée en permanence. Comment est-ce possible ? Déroulons mentalement la logique du croquis ligne par ligne : 1. Nous exécutons setup() pour forcer la broche 13 à être une sortie. 2. Nous entrons dans loop() et forçons la broche 13 au niveau haut (LED allumée). 3. Nous provoquons une pause d'une demi-seconde. 4. Nous forçons la broche 13 à l'état bas (LED éteinte). 5. Nous revenons en début de boucle, c'est-à-dire à l'étape 2, et nous redonnons à la broche 13 l'état haut (LED allumée). Le problème se situe entre les étapes 4 et 5. La LED est effectivement éteinte, mais elle est rallumée immédiatement après. L'intervalle entre les deux actions est si réduit que la LED semble rester allumée en permanence. Le microcontrôleur qui équipe la carte Arduino peut réaliser 16 millions d'instructions machine par seconde. Cela ne revient pas à 16 millions d'instructions en langage C, mais cela reste très rapide. Voilà pourquoi notre LED s'éteint bien, mais seulement pendant quelques millionièmes de seconde. Pour résoudre ce problème, il nous sufft d'ajouter une autre pause après avoir éteint la LED. Voici comment modifer votre code source : // sketch_03_01 void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); delay(500); } Si vous faites un nouvel essai, vous devriez voir votre LED clignoter joyeusement une fois par seconde. ARDUI__Monk.indb 33 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk 34 Arduino : les bases de la programmation Vous aurez remarqué un commentaire en début de listing qui indique "// sketch_03_01". Pour vous éviter de devoir tout ressaisir, nous mettons à disposition sur le site compagnon du livre tous les croquis comportant un tel commentaire en en-tête. Vous pouvez les télécharger en version anglaise à l'adresse http://www.arduinobook.com. (N.d.T. : Certains sont fournis en version française sur le site www.pearson.fr.) Variables Dans notre exemple, nous nous servons de la broche 13 et nous y faisons référence en trois endroits différents du programme. Pour travailler avec une autre broche, il faudrait donc modifer le numéro de broche à trois endroits. De même, pour modifer la vitesse de clignotement (utilisée comme argument de la fonction delay()), il faudrait modifer la valeur 500 à deux endroits différents. Une variable est une sorte de symbole pour un nom ou pour une valeur numérique. Elle permet bien plus de choses, mais servons-nous en déjà en tant que symbole d'une valeur. Lorsque vous défnissez une variable en langage C, vous devez d'abord indiquer le type de données que la variable va contenir. Ici, nous avons besoin de variables correspondant à des valeurs numériques entières qui s'appellent en C des valeurs de type int (integer). Pour défnir une variable que nous choisissons de nommer brocheLED et possédant la valeur 13, nous écririons la déclaration suivante : int brocheLED 13; La variable brocheLED est un nom et les règles données plus haut pour les noms des fonctions s'appliquent. Vous ne pouvez donc pas utiliser d'espaces dans le nom, ni de lettres accentuées. Par convention, les programmeurs font débuter leurs noms de variables par une lettre minuscule et commencent chaque nouveau mot par une majuscule en collant les mots les uns aux autres. Cette écriture est souvent désignée sous le terme d'écriture en creux et bosses, ou CamelCase. Ajoutons donc nos déclarations de variables dans le croquis Blink : // sketch_03_02 int brocheLED = 13; int dureePause = 500; void setup() { pinMode(brocheLED, OUTPUT); } void loop() { digitalWrite(brocheLED, HIGH); delay(dureePause); digitalWrite(brocheLED, LOW); delay(dureePause); } ARDUI__Monk.indb 34 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk Chapitre 3 Éléments du langage C 35 Vous remarquez que nous avons déclaré une seconde variable nommée dureePause. À tous les endroits dans le croquis où nous utilisions la valeur 13, nous indiquons dorénavant le nom brocheLED. De même, là où nous utilisions la valeur 500 (une valeur littérale) nous indiquons dorénavant le nom de la variable dureePause. Dorénavant, pour faire clignoter la LED plus rapidement, il sufft de changer à un endroit la valeur affectée à la variable dureePause. Essayez par exemple de réduire cette valeur à 100 et relancez le croquis sur la carte Arduino. Nous avons dit que vous pouviez faire bien d'autres choses avec des variables. Voyons comment modifer le croquis de sorte que le clignotement commence à fréquence élevée, puis ralentisse de plus en plus, comme si la carte Arduino commençait à se lasser. Pour y parvenir, il nous sufft d'ajouter une petite valeur à la valeur actuelle de dureePause à chaque tour de la boucle. Modifez donc le croquis en ajoutant une ligne tout à la fn du corps de la fonction loop(), comme présenté dans l'extrait suivant. Transférez le programme modifé sur la carte Arduino. Appuyez sur le bouton poussoir RESET de la carte et observez l'effet de ralentissement du clignotement. // sketch_03_03 int brocheLED = 13; int dureePause = 100; void setup() { pinMode(brocheLED, OUTPUT); } void loop() { digitalWrite(brocheLED, HIGH); delay(dureePause); digitalWrite(brocheLED, LOW); delay(dureePause); dureePause = dureePause + 100; } Voici que votre carte Arduino fait de l'arithmétique. À chaque appel à la fonction loop(), nous provoquons un clignotement de la LED puis nous ajoutons 100 à la valeur de la variable dureePause. Nous reviendrons un peu plus loin sur les opérations arithmé- tiques. Voyons d'abord comment mieux observer ce que fait la carte Arduino qu'avec un simple clignotement de LED. ARDUI__Monk.indb 35 21/03/13 18:05 © 2013 Pearson France – Arduino – Simon Monk
Copyright © 2024 DOKUMEN.SITE Inc.