• Aucun résultat trouvé

Pr´esentation de l’environnement A

N/A
N/A
Protected

Academic year: 2022

Partager "Pr´esentation de l’environnement A"

Copied!
56
0
0

Texte intégral

(1)

Pr´esentation de l’environnement A RDUINO F. Auger

1

27 avril 2020

Table des Mati`eres

Introduction 2

1 Pr´esentation de l’environnement ARDUINO 2

2 Pr´esentation de l’environnement de d´eveloppement 5

3 Pr´esentation du langage de programmation 7

3.1 Structure g´en´erale d’un programme . . . 9

3.2 Variables, constantes et expressions arithm´etiques . . . 10

3.3 Transmission et affichage de variables . . . 12

3.4 Stockage de donn´ees suppl´ementaires . . . 14

3.5 Op´erateurs et fonctions pr´ed´efinies . . . 15

3.6 Structures conditionnelles et de r´ep´etition . . . 15

3.7 Modules, fonctions et proc´edures . . . 19

3.8 Gestion des broches d’entr´ees-sorties logiques . . . 21

3.9 Gestion des broches d’entr´ees-sorties analogiques . . . 23

3.10 Communications par liaison s´erie. . . 23

3.11 La gestion du temps . . . 25

3.11.1 Les proc´edures de temporisation . . . 25

3.11.2 Les fonctions de consultation du temps ´ecoul´e. . . 25

3.12 Les interruptions . . . 26

3.12.1 Interruptions d´eclench´ees par des ´ev`enements externes . . . 27

3.12.2 Interruptions d´eclench´ees en interne . . . 27

3.12.3 Implantation d’un chien de garde . . . 28

3.13 Librairies et programmation objet . . . 29

3.13.1 La notion d’espace de nom . . . 29

3.13.2 La programmation objet . . . 30

4 Conclusion 33

5 Exercices 33

6 Bibliographie 50

A Notion de variable 51

B D´eveloppement d’applications sur microcontrˆoleur 51

(2)

Avant de pr´esenter l’environnement ARDUINO, on peut d’abord pr´esenter (ou rappeler) ce qu’est un micro- contrˆoleur, le circuit int´egr´e qui est au centre des cartes ARDUINO. Un microcontrˆoleur regroupe dans un unique circuit int´egr´e peu coˆuteux les principaux ´el´ements d’un syst`eme informatique :

• des circuits permettant le traitement de donn´ees (processor core) par l’ex´ecution s´equentielle d’un pro- gramme constitu´e d’op´erations logiques et arithm´etiques ´el´ementaires et d’op´erations de transfert de donn´ees ;

• des circuits de stockage du programme ex´ecut´e par le microcontrˆoleur et des donn´ees manipul´ees par ce programme. Ces circuits sont appel´es des m´emoires, qui peuvent ˆetre soit r´emanentes (ROM) soit volatiles (RAM) ;

• des moyens de communication bidirectionnelle, qui permettent un ´echange d’informations entre le micro- contrˆoleur et son environnement ext´erieur ;

• des moyens de mesure du temps ´ecoul´e (timers) ;

• dans certains cas, des p´eriph´eriques suppl´ementaires sp´ecifiques, tels que des convertisseurs analogique- num´erique ou num´erique-analogique, des horloges temps-r´eel, des contrˆoleurs d’´ecran LCD, des codeurs/d´e- codeurs audio (MP3 . . . ) ou vid´eo (MPEG2 . . . ).

La principale caract´eristique d’un microcontrˆoleur est le nombre de bits des informations ´el´ementaires qu’il peut manipuler. On trouve actuellement des microcontrˆoleurs 4 bits, 8 bits, 16 bits, 32 bits et 64 bits. Les micro- contrˆoleurs sont aujourd’hui utilis´es dans de tr`es nombreux appareils ´electroniques, par exemple

• dans les sites industriels, pour la production (robots), la mesure, le contrˆole-commande et la s´ecurisation ;

• dans les habitations et les ´equipements individuels et m´enagers (machines `a laver, chaudi`eres, t´el´eviseurs, fours micro-ondes, machines `a pain, jeux ´electroniques, calculatrices, lecteurs MP3, t´el´ephones portables, cl´es USB, r´ecepteurs GPS, routeurs internet, imprimantes . . . ) ;

• dans la plupart des moyens de transport, notamment les automobiles (injection, freinage ABS, direction assist´ee . . . ).

Ces composants sont aujourd’huit propos´es par de nombreuses soci´et´es : outre Texas Instruments, qui a commer- cialis´e en 1974 (sous le nom de TMS1000) le premier microcontrˆoleur, les principaux fabricants sont actuellement MicroChip (issu de General Electric), Atmel, ST MicroElectronics, Frescale (issu de Motorola), NXP (issu de Philips), Infineon (issu de Siemens) et Renesas (issu de Hitachi). La fabrication et l’utilisation de ces composants est donc g´en´eratrice d’un tr`es grand nombre d’emplois dans le monde. Ils ont connu depuis leur conception (et connaˆıtront certainement encore `a l’avenir) des ´evolutions importantes sur de nombreux facteurs : la minia- turisation, la consommation ´electrique, le nombre de bits des informations ´el´ementaires manipul´ees (qui tend aujourd’hui vers 32 bits), la vitesse de traitement, la capacit´e des m´emoires, la complexit´e des traitements, le parall´elisme, l’association avec des circuits logiques programmables . . . Leur langage de programmation (princi- palement le langage C et le basic) et surtout leur environnement de programmation constituent ´egalement des axes d’´evolution importants.

La diversit´e des microcontrˆoleurs est si importante que les g´en´eralit´es qu’il est possible de faire sur leurs points communs sont peu nombreuses. Pour se familiariser avec ce type de composants, il paraˆıt donc plus judicieux d’´etudier l’un d’entre eux de fac¸on approfondie.

Ce chapitre pr´esente une famille de cartes `a microcontrˆoleur faciles `a comprendre et `a mettre en œuvre, appel´ee ARDUINO. Les aspects ´electroniques (composants, connections, . . . ) et informatiques (programmation) seront pr´esent´es avec suffisamment de d´etails pour qu’il soit possible d’envisager la r´ealisation d’une application compl`ete apr`es la lecture de ce chapitre.

Pour montrer que la d´emarche de conception d’une application au moyen des cartes `a microcontrˆoleur AR-

DUINOsuit les principes g´en´eraux du d´eveloppement de logiciels pour microcontrˆoleurs, ceux-ci sont pr´esent´es `a la fin de ce chapitre, dans une annexe qui introduit ´egalement une partie du vocabulaire sp´ecifique de ce domaine.

1 Pr´esentation de l’environnement A

RDUINO

L’environnement de d´eveloppement ARDUINO1permet de r´ealiser facilement, grˆace `a des microcontrˆoleurs, des appareils ´electroniques capables d’interagir avec leur environnement de mani`ere autonome. Il associe des cir- cuits ´electroniques et des logiciels qui ont ´et´e r´ealis´es par une ´equipe2 internationale de concepteurs de circuits

(3)

Figure 1: Quatre cartes ARDUINOdisponibles en 2010 : l’ARDUINOUno (produit stan- dard), l’ARDUINO Nano (de la taille d’un circuit int´egr´e `a 30 broches), l’ARDUINO

Mega 2560 (offrant un plus grand nombre de possibilit´es) et l’ARDUINOLilypad (des- tin´e aux applications embarqu´ees).

20050 2006 2007 2008 2009 2010 2011

20 40 60 80 100 120

année

milliers d’unités

produits Arduino vendus

Figure 2: `A gauche : nombre total de produits ARDUINOvendus chaque ann´ee. De septembre 2005 `a aoˆut 2011, 314 461microcontrˆoleurs ARDUINOont ´et´e vendus. `A droite : nombre de pages consult´ees par mois sur le site internethttp://www.arduino.cc(source : Arduino Confidential, OSHW summit, septembre 2011).

(4)

l’ARDUINOpr´esente plusieurs avantages :

• Son prix est tr`es r´eduit : il existe plusieurs cartes ´electroniques, dont la premier ne coˆute que20euros env- iron. Les sch´emas de ces cartes ´electroniques sont librement disponibles, ce qui permet de les comprendre facilement et ´eventuellement de les am´eliorer ou de les adapter `a des besoins sp´ecifiques.

• Le microcontrˆoleur de ces cartes se programme tr`es facilement, en utilisant un environnement de d´evelop- pement gratuit, libre, simple et efficace, disponible pour plusieurs syst`emes d’exploitation (Windows, Mac Os X et Linux). Le langage de programmation utilis´e est une version du langage C adapt´ee aux micro- contrˆoleurs. Cet environnement de d´eveloppement permet ´egalement d’envoyer le programme ´ecrit par l’utilisateur sur son ordinateur vers le microcontrˆoleur d’une carte ARDUINO3.

• Il est utilis´e par de nombreux utilisateurs (voir figure2) qui forment une communaut´e tr`es active4, ce qui permet de disposer d’un grand nombre de programmes d´eja ´ecrits et test´es, `a partir desquels il est possible de concevoir sa propre application.

Ces trois caract´eristiques rendent cet environnement int´eressant pour l’apprentissage des microcontrˆoleurs et pour la r´ealisation de petites applications industrielles (instrumentation, contrˆole/commande, diagnostic, . . . ), individu- elles (domotique, robotique, . . . ) ou artistiques. De ce fait, ce microcontrˆoleur est assez r´epandu : dans un article paru dans la revue IEEE Spectrum, l’´equipe de d´eveloppement du projet ARDUINOa annonc´e avoir vendu 250000 cartes ARDUINO5. En outre, les caract´eristiques mat´erielles et logicielles sont devenues un standard repris par de nombreuses cartes telles que lesfreeduino6, les cartesMC-NOVE,MC-MEGAetMC-NANOdistribu´ees par Farnell7, les tr`es int´eressantsLeaf Maple8,Papilio9,Amani GT10,Nanode11etchipKIT Uno3212, et dans une bien moindre mesure les cartes TEENSYDUINO13et NETDUINO14.

Figure 3: Vues de dessus et de dessous de l’ARDUINONano (dans sa version 2.2), qui permettent de voir la disposition de ses ´el´ements, et brochage de l’ARDUINONano v3.0.

Pour donner une id´ee des possibilit´es offertes par cette famille de microcontrˆoleurs, on peut d´ecrire en d´etail l’un de ses membres, par exemple l’ARDUINO Nano. Cette carte, de la taille d’un circuit int´egr´e `a 30 broches (voir figure3), contient15:

• Un microcontrˆoleurAT Mega 328de la soci´et´e ATMEL, cadenc´e `a16MHz (ce qui lui permet d’ex´ecuter 16millions d’instructions ´el´ementaires par seconde) grˆace `a un quartz bien visible au centre de l’ARDUINO

Nano. Ce microcontrˆoleur contient

– une m´emoire flash de 32 ko, o`u sont stock´es le programme de l’utilisateur (apr`es sa traduction en instructions ´el´ementaires du microcontrˆoleur par un “compilateur” contenu dans l’environnement de d´eveloppement) et les constantes utilis´ees par ce programme ;

– une m´emoire EEPROM de1ko, o`u l’utilisateur peut stocker des donn´ees qui seront conserv´ees mˆeme si le microcontrˆoleur n’est plus aliment´e, constituant ainsi une sorte de petit disque dur16;

– une m´emoire RAM statique de2ko, o`u sont conserv´ees la variables du programme.

(5)

• 14 broches d’entr´ees-sorties logiques bidirectionnelles, d´enomm´eesD0,D1, . . .D13 (broches 1, 2et 5 `a 16). Ces broches sont compatibles avec les familles des circuits int´egr´es TTL et CMOS aliment´es sous5V.

Lorsqu’elles sont configur´ees en sortie, chaque broche peut d´elivrer jusqu’`a40mA. La broche13est reli´ee `a une diode ´electroluminescente, ce qui permet notamment de valider facilement la chaˆıne de d´eveloppement.

Les broches0et1sont reli´ees au port USB, et ne doivent donc pas ˆetre utilis´ees lorsque le microcontrˆoleur est reli´e `a un ordinateur.

• 8 broches d’entr´ees analogiques, qui permettent de recevoir jusqu’`a8 tensions comprises entre0 et5 V, provenant par exemple de capteurs. Ces 8 broches peuvent ´egalement ˆetre utilis´ees comme des entr´ees- sorties logiques suppl´ementaires, portant ainsi le nombre de ces broches `a14 + 8 = 22;

• Un connecteurUSB, qui permet d’´etablir une communication bidirectionnelle avec un ordinateur. Ce moyen de communication est utilis´e notamment pour charger le programme d’application dans le microcontrˆoleur.

Un autre connecteur, au format ICSP, peut ´egalement ˆetre utilis´e pour cela, `a condition de disposer d’un programmateur suppl´ementaire.

• Un r´egulateur de tension, qui produit, `a partir d’une tension continue comprise entre6et20V appliqu´ee entre la broche30(VIN) et la broche29(VSS, correspondant `a la masse), la tension de5V n´ecessaire aux diff´erents circuits de l’ARDUINONano, disponible sur la broche27(VDD). Il est donc possible d’alimenter l’ARDUINONano soit en utilisant une tension continue non r´egul´ee comprise entre6et20V (par exemple un pile 9 V), soit en utilisant une tension continue r´egul´ee de5 V, soit en le connectant `a un ordinateur avec un cˆableUSB. Le circuit int´egr´eFTDI FT 232 RL, qui assure la conversion de la liaison s´erie du microcontrˆoleur ATMega328au format USB, fournit ´egalement une tension r´egul´ee de 3.3V, disponible sur la broche17.

• un bouton-poussoir, reli´e `a la broche28et `a la broche (RESET) de red´emarrage du microcontrˆoleurATMega328.

Ce bouton-poussoir permet de faire red´emarrer le programme d’application.

Pour compl´eter cette description d’un ´el´ement particulier, le tableau de la figure4pr´esente une comparaison de l’ensemble des ´el´ements de la famille ARDUINO.

2 Pr´esentation de l’environnement de d´eveloppement

La simplicit´e du mat´eriel n´ecessaire pour r´ealiser des applications est ´egalement un des points forts de ces cartes.

Pour programmer un ARDUINO, il suffit de disposer d’un ordinateur (un PC peu puissant relativement ancien conviendra parfaitement, ou bien un Apple sous MacOs X) et d’un cˆable USB qui reliera cet ordinateur au mi- crocontrˆoleur. L’environnement de d´eveloppement actuel17(voir figure5) est disponible pour les trois environ- nements de travail Windows, Linux et Mac OsX. Lorsqu’on lance ce logiciel, il apparaˆıt une fenˆetre qui comprend une barre de menus, une barre de boutons, un ´editeur de texte (qui effectue une reconnaissance et une coloration automatique des mots cl´es du langage de programmation utilis´es dans le programme) et une zone de messages.

Les quatre principaux menus de cet environnement de d´eveloppement sont les menus Fichier [File], Edition´ [Edit], Programme [Sketch]et Outils[Tools]. Les principaux sous-menus du menu “Fichier” (voir figure 6) sont :

• Nouveau[New], qui fait apparaˆıtre une nouvelle fenˆetre d’´edition de programmes ;

• Ouvrir[Open], qui permet d’ouvrir un fichier contenant un programme d’application du microcontrˆoleur ;

• Exemples[Examples], qui permet d’ouvrir et d’´etudier de nombreux programmes d’exemples disponibles (un exemple est souvent pr´ef´erable `a de longues explications).

• Enregistrer[Save]etEnregistrer Sous[Save As], qui permettent de sauvegarder un programme dans un fichier. Pour sauvegarder un nouveau programme, il suffit de taper son nom sans extension. L’environnement cr´ee alors un r´epertoire qui contiendra un fichier portant le nom choisi par l’utilisateur termin´e par une ex- tension “.ino” ;

• T´el´everser [Upload to board], qui permet de compiler et de transf´erer un programme vers le micro- contrˆoleur. Ce sous-menu dispose d’un racourci clavierCtrl-Utr`es pratique ;

• Imprimer[Print], qui permet d’imprimer un programme d’application ;

• Quitter[Exit], qui permet de quitter l’environnement de d´eveloppement ;

• Pr´ef´erences[Preferences]qui permet de modifier les param`etres de l’environnement de d´eveloppement.

Les principaux sous-menus du menu “ ´Edition” (voir figure6) sont :

• Couper[Cut],Copier[Copy]etColler[Paste], qui permettent de d´eplacer ou de copier un ensemble de

(6)

Uno/Nano Leonardo Mega Due Zero ItsyBitsy M4 ESP32 DevkitC

processeur ATMEGA328P ATMEGA32U4 ATMEGA2560 SAM3X8E ATSAMD21G18 ATSAMD51 Xtensa LX6

type de processeur AVR AVR AVR ARM Cortex-M3 ARM Cortex-M0 ARM Cortex-M4 Tensilica

taille des registres 8 bits 8 bits 8 bits 32 bits 32 bits 32 bits 32 bits

nombre de broches 28 44 100 144 48

Vcc 5V 5V 5V 3.3V 3.3V 3.3V 3.3V

fr´equence (MHz) 16 16 16 84 48 120 160

m´emoire vive 2ko 2.5ko 8ko 96ko 32ko 192ko 512ko

m´emoire flash 32ko 32ko 265ko 512ko 256ko 512ko 448ko

m´emoire eeprom 1ko 1ko 4ko 0ko 0ko 2Mo 16ko

entr´ees-sorties logiques 14 20 75 75 14 23 36

entr´ees analogiques 6 12 16 16 6 6 18

r´esolution CAN 10 bits 10 bits 10 bits 12 bits 12 bits 12 bits 12 bits

sorties analogiques 0 0 0 2(12 bits) 1(10 bits) 2(12 bits) 2(12 bits)

sorties MLI 6 7 15 12 12 18 16

SparkFun nRF52840 HiFive1 Teensy 4.0 Nano Every Portenta H7 Maixduino

processeur MDBT50Q Freedom E310 NXP iMXRT1062 ATMega4809 STM32H747XI Kendryte+Xtensa

type de processeur ARM Cortex-M4 RISC-V ARM Cortex-M7 AVR dual core Cortex M7+M4 RISC-V+Tensilica

taille des registres 32 bits 32 bits 32 bits 8 bits 32 bits 64 bits

nombre de broches 61 48 33 48

Vcc 3.3V 3.3V 5V 5V 3.3V 5V

fr´equence (MHz) 64 320 600 20 480 et 240 400 MHz

m´emoire vive 256ko 16ko 1024ko 6ko 1 Mo 8 Mo

m´emoire flash 1Mo 16Mo 2048ko 48ko 2Mo

m´emoire eeprom 0 0 0 256o

entr´ees-sorties logiques 48 19 40 14 168 14

entr´ees analogiques 8 0 14 8 36 6

r´esolution CAN 12 bits 12 bits 10 bits 16 bits 12 bits

sorties analogiques 0 0 0 0 2

sorties MLI 16 9 16 5

Figure 4: Caract´eristiques des cartes ARDUINOactuellement propos´ees.

(7)

caract`eres d’un endroit vers un autre ;

• Augmenter l’indentation [Increase Indent] etR´eduire l’indentation[Decrease Indent], qui permettent de d´ecaler le texte s´electionn´e `a la souris vers la gauche ou vers la droite. Ces menus permettent d’am´eliorer tr`es facilement la pr´esentation d’un programme ;

• Chercher[Find]qui permet de rechercher une chaˆıne de caract`eres dans un texte et ´eventuellement de la remplacer par une autre ;

Les principaux sous-menus du menu “Croquis”[Sketch](voir figure6) sont :

• V´erifier/Compiler[Verify/Compile], qui permet de compiler un programme sans l’envoyer vers le micro- contrˆoleur, pour rechercher d’´eventuelles erreurs de syntaxe ;

• Afficher le dossier du croquis [Show Sketch Folder], qui permet d’explorer le r´epertoire contenant le programme.

Les principaux sous-menus du menu “Outils”[Tools](voir figure6) sont :

• Formatage Automatique [Auto Format], qui permet de redisposer automatiquement les instructions du programme pour qu’il soit plus lisible. Ce sous-menu dispose d’un racourci clavierCtrl-Ttr`es pratique ;

• Terminal de mise au point [Serial Monitor], qui permet de faire apparaˆıtre un terminal assez rudimen- taire, afin d’afficher sur l’´ecran de l’ordinateur la valeur d’une variable du programme en cours d’ex´ecution par le microcontrˆoleur, et ´eventuellement de saisir au clavier des donn´ees qui seront transmises au micro- contrˆoleur. Ce terminal facilite beaucoup la mise au point des programmes et constitue un ´el´ement essentiel pour les tester, les corriger et les am´eliorer ;

• Carte[Board], qui permet de pr´eciser le circuit ARDUINOutilis´e ;

• Port USB[Serial Port], qui permet de pr´eciser sur quel port USB est connect´e le microcontrˆoleur.

Il existe ´egalement une aide en ligne tr`es compl`ete, disponible par le sous-menuAide[Help]et qu’il ne faut pas h´esiter `a consulter.

Grˆace `a cet environnement de d´eveloppement, il est facile de g´erer les diff´erentes ´etapes ducycle de d´evelop- pementusuel d’un programme, g´en´eralement constitu´e des ´etapes suivantes :

• cr´eer un nouveau programme (soit par le menuFichier/Nouveau [File/New]soit avec l’icˆone ) ou ouvrir un programme existant (soit par le menuFichier/Ouvrir [File/Open]soit avec l’icˆone

) ;

• le sauvegarder (Fichier/Enregistrer ouFichier/Enregistrer [File/Save]ouCtrl Sou icˆone ) puis le compiler (Croquis/Compiler [Sketch/Compile]ouCtrl Rou icˆone ) pour v´erifier l’absence d’erreurs de syntaxe ;

• pr´eciser la cible mat´erielle choisie (Outils/Type de carte [Tools/Board]) et le port USB auquel il est reli´e (Outils/Port s´erie [Tools/Serial Port]) ;

• charger le programme dans le microcontrˆoleur utilis´e (Fichier/T´el´everser [File/Upload],Ctrl Uou icˆone ).

3 Pr´esentation du langage de programmation

Le langage de programmation utilis´e dans l’environnement ARDUINO est un d´eriv´e du langage C adapt´e aux microcontrˆoleurs. Il a ´et´e concu `a partir de 2001 par une ´equipe internationale d’informaticiens et d’enseignants en informatique, qui ont de nombreuses ann´ees d’exp´erience dans l’enseignement du langage C (ou d’une ver- sion am´elior´ee du langage C int´egrant les concepts d’objets et de classe apel´ee le C++) et dans son utilisation pour la programmation de microcontrˆoleurs. Il a ´et´e conc¸u pour faciliter l’apprentissage et l’utilisation des mi- crocontrˆoleurs par des personnes qui ne sont pas des informaticiens confirm´es (et qui n’ont pas n´ecessairement l’intention de le devenir), grˆace notamment `a des outils qui facilitent beaucoup la mise au point et la correc- tion d’erreurs. Les paragraphes suivants pr´esentent succintement ces caract´eristiques, en les regroupant par th`emes. Le document de r´ef´erence pour ce langage est actuellement le manuel de r´ef´erence disponible `a l’adresse http://arduino.cc/en/Reference/HomePage. L’aide de l’environnement de d´eveloppement con- stitue ´egalement une source d’information tr`es compl`ete et facilement accessible.

(8)

Figure 5: L’environnement de d´eveloppement de programmes pour les microcontrˆoleurs ARDUINO. L’environnement pr´esent´e sur cette figure correspond `a la version 1.0.4, diffus´ee en mars 2013.

Figure 6: Menus “Fichier”, “ ´Edition”, “Croquis” et “Outils” de l’environnement de d´eveloppement AR-

DUINO.

(9)

3.1 Structure g´en´erale d’un programme

Rappelons qu’un programme est une suite d’instructions ex´ecut´ees dans l’ordre o`u elles sont ´ecrites. Chaque instruction se termine par un point-virgule (;), que l’on appelle les´eparateur d’instructions. Il permet d’´ecrire plus d’une instruction sur une mˆeme ligne, en indiquant clairement la fin d’une instruction et le d´ebut de la suivante. Lesaccolades ouvrantes {et fermantes } permettent de d´efinir un bloc d’instructions, qui regroupe plusieurs instructions contigu¨es.

Il est fortement recommand´e d’inclure ´egalement dans un programme quelques commentaires pour faciliter sa compr´ehension et sa gestion. Dans un programme ARDUINO, une mani`ere d’ins´erer un commentaire est d’utiliser la s´equence//, qui indique que les caract`eres qui suivent sur la mˆeme ligne sont descommentaires, et non des instructions du programme.

La structure g´en´erale d’un programme pour ARDUINO est de la forme suivante :

// entete indiquant le but du programme, son auteur et sa date de creation // zone declaration des constantes, des variables globales et des fonctions // setup ***************************************************

// mettre ici tout ce qui sera execute une seule fois au demarrage du programme void setup()

{ }

// loop ****************************************************

// boucle principale contenant les instructions repetees en permanence void loop()

{ }

Cette structure comporte trois parties :

• La premi`ere partie, pr´ec´ed´ee de quelques commentaires de pr´esentation, correspond aux d´eclarations des constantes, des variables et des fonctions particuli`eres utilis´ees dans le programme. Les variables d´eclar´ees en d´ebut de programme seront connues et pourront ˆetre utilis´ees n’importe o`u dans le programme (et dans les fonctions d´efinies par l’utilisateur), raison pour laquelle on les appelle desvariables globales.

• La seconde partie correspond `a lafonction d’initialisation(setup) du microcontrˆoleur. `A la mise sous tension, apr`es un appui sur le boutonresetou apr`es le chargement du programme dans le microcontrˆoleur, cette fonction est ex´ecut´ee d`es le d´ebut, une seule fois.

• La troisi`eme partie est laboucle principale(loop) du programme. Apr`es avoir ex´ecut´e la fonctionsetup, le microcontrˆoleur r´ep`ete inlassablement la fonctionloop.

Les fonctionssetup()etloop(), mˆeme vides, doivent ˆetre pr´esentes dans tout programme ARDUINO. Elles offrent l’avantage de faire une distinction claire entre les op´erations r´ealis´ees au d´emarrage et les op´erations effectu´ees `a chaque it´eration.

Cette structure est l´eg`erement diff´erente de celle des programmes classiques ´ecrits en C pour des ordinateurs.

Les microcontrˆoleurs, contrairement aux ordinateurs, sont destin´es `a r´ep´eter toujours la mˆeme fonction. Il est donc normal que le langage utilis´e pour les programmer soit adapt´e `a cette particularit´e. Les programmes ´ecrits en C et destin´es `a ˆetre ex´ecut´es par des ordinateurs comportent une fonctionmain, qui correspond au programme principal ex´ecut´e une seule fois. Une fois ce programme principal termin´e, le syst`eme d’exploitation reprend la maˆıtrise de l’ordinateur. Dans l’environnement ARDUINO, les programmes destin´es `a ˆetre ex´ecut´es par des microcontrˆoleurs comportent donc uneboucle principale, qui contient les op´erations qui vont ˆetre r´ep´et´ees inlass- ablement. Les lecteurs habitu´es au langage C appr´ecieront d’apprendre que l’environnement ARDUINOutilise un compilateur C tr`es performant (avrgcc) qui compile le programme ´ecrit par l’utilisateur apr`es qu’il ait ´et´e compl´et´e syst´ematiquement par la fonctionmainsuivante :

int main(void) {

targetSpecificInit();

setup();

for (;;)

(10)

return 0;

}

L’instruction tr`es curieuse for (;;) montre assez clairement que le langage C n’est pas bien adapt´e pour d´ecrire des programmes destin´es `a des microcontrˆoleurs. Enfin, cette d´efinition de la fonction main montre que n’importe quel microcontrˆoleur pour lequel un compilateur C a ´et´e d´evelopp´e18 peut ˆetre programm´e dans l’esprit de l’environnement de d´eveloppement ARDUINO: il suffit pour cela de d´efinir des fonctionssetup()et loop()et de les appeler dans unmainr´eduit aux quelques lignes ci-dessus. Les connaissances acquises lors de l’apprentissage de la programmation d’un microcontrˆoleur ARDUINOpeuvent donc facilement ˆetre appliqu´ees `a d’autres environnements mat´eriels programmables en langage C.

3.2 Variables, constantes et expressions arithm´etiques

L’ARDUINO Nano poss`ede 2 kilo octets de m´emoire vive, o`u vont ˆetre stock´ees les variables du programme d’application. Cela peut paraˆıtre peu, mais c’est malgr´e tout suffisant pour de tr`es nombreux programmes d’instrumentation ou de contˆole de processus. Le nom de ces variables doit commencer par une lettre, et con- tenir soit des lettres soit des chiffres. Les majuscules et les minuscules sont diff´erenci´ees : xetXcorrespondent donc `a deux variables diff´erentes. Il est vivement conseill´e, pour augmenter la facilit´e de compr´ehension des programmes, d’utiliser des noms de variables clairs, et en rapport avec ce qu’ils repr´esentent :temperature, niveauetlampesont des noms de variables beaucoup plus faciles `a comprendre quex1,x2etb0!

La notion de variable, fondamentale en informatique, est suppos´ee connue. Si n´ecessaire, on en trouvera cependant une pr´esentation succinte page51. Comme dans de nombreux langages (notamment le langage C ou le

“Visual Basic pour applications” de Microsoft) le nom et le type de chaque variable doivent ˆetre pr´ecis´es au d´ebut du programme. Pour fournir `a l’utilisateur un “r´ecipient” adapt´e `a chaque type d’information manipulable par un microcontrˆoleur ARDUINO, il existe huit types de variables :

• boolean, qui correspond `a une variable logique19, qui peut valoir soit0soit1;

• char, qui correspond `a un nombre entierrelatif cod´e en notation en compl´ement `a2sur8bits, donc compris entre−128et+127;

• byte (ou son ´equivalentunsigned char), qui correspond `a un nombre entiernaturelcod´e sur 8 bits, donc compris entre0et+255;

• int, qui correspond `a un nombre entierrelatif cod´e en notation en compl´ement `a2sur16bits, donc compris entre−32768et+32767;

• word, (ou son ´equivalentunsigned int), qui correspond `a un nombre entiernaturelcod´e sur16bits, donc compris entre0et65535;

• long, qui correspond `a un nombre entier relatif cod´e en notation en compl´ement `a 2 sur 32 bits, donc compris entre−2 147 483 648et+2 147 483 647;

• unsigned long, qui correspond `a un nombre entier naturel cod´e sur 32 bits, donc compris entre 0 et +4 294 967 295;

• float, qui correspond `a un nombre r´eel (ou nombre “`a virgule”) au format IEEE 754 simple pr´ecision sur 32 bits. Des variables de typefloatpeuvent ˆetre d´eclar´ees, affect´ees et utilis´ees dans des op´erations de calcul arithm´etique. Il est cependant important de retenir que le microcontrˆoleur met beaucoup plus de temps pour r´ealiser des calculs math´ematiques avec des variables de type float qu’avec des variables enti`eres. Ceci est dˆu au fait que les op´erations arithm´etiques entre nombres r´eels sont effectu´ees par du logiciel (c’est-`a-dire `a l’aide de programmes informatiques) et non par du mat´eriel (c’est-`a-dire `a l’aide de circuits ´electroniques int´egr´es dans le microcontrˆoleur).

Pour l’instant, l’environnement ARDUINOne g`ere pas les nombres r´eels au format IEEE 754 double pr´ecision sur64bits, et le typedoubleest d´efini comme un synonyme du typefloat.

Par exemple, pour pouvoir utiliser dans un programme une variable logique appel´eetest, un nombre entier appel´eindice, et un nombre r´eel appel´etension, il suffit d’´ecrire au d´ebut du programme :

boolean test ; int indice ; float tension ;

Lorsque l’application le justifie, il est aussi possible de d´eclarer une variable qui ne correspond pas seulement

`aune seuleinformation, mais `aplusieursinformations de mˆeme type. C’est ce que l’on appelle untableau. C’est

(11)

une “grosse” variable contenant une suite d’informations de mˆeme type (char,int, float. . . ) rang´ees les unes apr`es les autres dans la m´emoire vive du microcontrˆoleur. Le nombre total d’informations contenues dans le tableau doit ˆetre indiqu´e au moment de la d´eclaration, entre deux crochets, comme dans l’exemple ci-dessous :

int DixDernieresMesures[10] ; float VecteurAcceleration[ 3] ;

Outre les variables, il est ´egalement possible de d´efinir desconstantes20, pour donner un nom `a des valeurs fixes utilis´ees dans un programme. Ceci facilite la lecture et la modification des programmes. Dans l’environnement ARDUINO, il existe deux mani`eres de d´efinir des constantes :

• la premi`ere consiste `a utiliser une directive#define, qui sera utilis´ee au moment de la compilation du programme. Par exemple, apr`es la directive

#define Gain 1600.0

le compilateur remplacera Gain par 1600.0 `a chaque fois qu’il trouvera ce nom dans le programme (comme la fonction chercher/remplacer de l’´editeur). Cette directive n’est pas une instruction du langage C, mais plutˆot un service rendu par l’environnement de d´eveloppement, et ne se termine donc pas par un point-virgule.

• la seconde mani`ere consiste `a ´ecrire le qualificatifconst devant les instructions de d´eclaration d’une va- riable. La d´eclaration ´equivalente `a la pr´ec´edente sera donc :

const float Gain=1.6e3;

Il est important de se rappeler que les quantit´es ainsi d´efinies sont des constantes et non des variables : apr`es leur d´eclaration, il n’est pas possible de changer leur valeur. Elles peuvent ˆetre vues comme des variables en lecture seule(read only), dans lesquelles il n’est pas possible de stocker de nouvelles valeurs.

La deuxi`eme m´ethode semble pr´ef´erable `a la premi`ere, notamment parce qu’elle permet de d´efinir facilement un tableau de constantes :

const float Coefficients[5]= {1.6, 2.4, 3.2, 2.8, 1.7};

Mais la premi`ere est pratiqu´ee depuis de nombreuses ann´ees par des informaticiens chevronn´es, ce qui explique qu’elle est encore tr`es utilis´ee.

Une fois d´efinies ces variables et ces constantes, il est possible de les utiliser pour recevoir et manipuler des informations. On utilisera pour cela l’op´erateur d’affectation, qui permet de stocker une donn´ee dans une variable.

Dans le langage de programmation de l’environnement ARDUINO, le symbole de l’op´erateur d’affectationest le signe ´egal (=), comme dans le langage C. Il faut faire attention `a bien mettre la donn´ee et la variable dans laquelle on veut stocker cette donn´ee respectivement `a droite et `a gauche du signe ´egal. `A gauche du signe ´egal, il ne peut y avoir rien d’autre qu’un nom de variable. `A droite, on peut trouver un nombre ou une expression plus ou moins complexe. Les valeurs num´eriques peuvent ˆetre ´ecrites dans la repr´esentation d´ecimale habituelle, en binaire (il suffit d’´ecrire unBau d´ebut de la repr´esentation) ou en hexad´ecimal (en utilisant dans ce cas la s´equence un0x).

Ainsix=17;,x=B10001; etx=0x11;sont trois mani`eres diff´erentes de mettre la mˆeme valeur, 17, dans la variablex.

Pour acc´eder `a une information contenue dans un tableau, il suffit d’´ecrire le nom du tableau suivi de l’indice de l’information d´esir´ee, ´ecrit entre crochets. La premi`ere information porte le num´ero0.

int Tableau[3];

Tableau[0]=20; Tableau[1]=1019; Tableau[2]=3*Tableau[0]+7;

Pour illustrer les notions expos´ees dans ce paragraphe, le programme ci-dessous21calcule les valeurs succes- sives de la suitexn+1 =a xn+b, o`ua(la pente) etb(le d´ecalage) sont d´efinis comme des constantes etxnest un nombre entier naturel cod´e sur8bits (byte), initialis´e `a z´ero lors de l’initialisation (setup).

// exemple de declaration et d’affectation d’une variable // F. Auger, aout 2010

const byte pente=3, decalage=17;

byte xn;

// setup ***************************************************

void setup()

(12)

// loop ****************************************************

void loop()

{xn=pente*xn+decalage;}

Les valeurs successives de la variablexncontenue dans la m´emoire du microcontrˆoleur sont donc0,17,68,221, 168(car3 × 221 + 17 = 680 = 2 × 256 + 168),9,44, . . . Il serait utile de pouvoir v´erifier cela en envoyant les valeurs dexn`a l’ordinateur pour qu’il les affiche sur son ´ecran, ce qui est l’objet du prochain paragraphe.

Enfin, quelques possibilit´es suppl´ementaires peuvent ˆetre mentionn´ees, principalement `a titre d’information :

• Les affectations multiples sont possibles : x1=x2=x3=10;met la valeur10dans les trois variablesx1, x2etx3;

• Des op´erateurs d’affectation compos´es peuvent ˆetre utilis´es pour ´ecrire de mani`ere abr´eg´ee des instructions du type “x=x+1;” sous la forme “x+=1;”. Les op´erateurs compos´es utilisables sont+=,-=,*=,/=,%=,

&=,|=,ˆ=,<<=et>>=, Ils permettent d’´eviter d’avoir `a ´ecrire le nom d’une variable de chaque cot´e du signe ´egal, ce qui se justifie principalement lorsque ce nom de variable est compliqu´e ;

• Il existe un op´erateur d’affectation conditionnelle : par exemple, l’instruction “max=(a>b)?a:b;” met dans la variablemaxla valeur deasia>b, et la valeur debdans le cas contraire.

Ces possibilit´es ne favorisent pas la lisibilit´e des programmes et ne diminuent pas significativement la place qu’ils occupent en m´emoire. Il n’est pas indispensable de les connaˆıtre pour pouvoir commencer `a ´ecrire des programmes. Elles sont donc pr´esent´ees ici pour permettre la compr´ehension de programmes existants, mais pas n´ecessairement pour inciter `a les utiliser, car elles sont tr`es diversement appr´eci´ees par les informaticiens.

3.3 Transmission et affichage de variables

instruction r´esultat `a l’´ecran

affichage de nombres entiers

Serial.print(78); 78

Serial.print(78, DEC); 78 Serial.print(78, BIN); 1001110 Serial.print(78, OCT); 116 Serial.print(78, HEX); 4E

affichage de nombres r´eels Serial.print(1.23456); 1.23 Serial.print(1.23456, 0); 1 Serial.print(1.23456, 2); 1.23 Serial.print(1.23456, 4); 1.2346

affichage de caract`eres et de chaˆınes

Serial.print(78); N

Serial.print(’N’); N

Serial.print("Hello world.") Hello world

Figure 7: Tableau des diff´erentes possibilit´es de la fonction Serial.print(val) ou Serial.print(val, format), avec le r´esultat obtenu `a l’´ecran.

Bien souvent, une carte `a microcontrˆoleur comme l’ARDUINO Nano effectue la surveillance ou le contrˆole d’un ph´enom`ene physique, et effectue assez peu d’´echanges d’informations avec un op´erateur humain au moyen d’un clavier et d’un ´ecran. C’est pour cette raison que les fonctionsscanfetprintfne sont pas pr´ed´efinies dans son langage de programmation. Par contre, lors de la phase de mise au point d’un programme, il peut ˆetre utile d’afficher sur l’´ecran de l’ordinateur la valeur d’une variable pendant l’ex´ecution du programme de l’ARDUINO. Cela facilite beaucoup la recherche d’erreurs de programmation.

(13)

Figure 8: Copie d’´ecran de l’´emulateur de terminal de l’environnement de d´eveloppement ARDUINO.

Pour cela, le langage de programmation des microcontrˆoleurs ARDUINOcomprend des instructions qui per- mettent de transmettre des informations vers l’ordinateur, en utilisant la liaison de communication s´erie ´etablie par le cˆable USB. De plus, l’environnement de d´eveloppement comprend un ´emulateur de terminal rudimen- taire appel´e “moniteur s´erie”[Serial Monitor], obtenu par le menu Outils/Moniteur s´erie[Tools/Serial Monitor]

de l’environnement de d´eveloppement ou avec l’icˆone ), qui va permettre d’afficher `a l’´ecran les informations rec¸ues (voir figure8). L’association de ces deux caract´eristiques permet, lors de la phase de mise au point d’un programme, d’afficher facilement la valeur d’une variable, d’indiquer quelle est la portion de programme en cours d’ex´ecution, ou de voir l’effet d’une op´eration appliqu´ee sur des donn´ees.

Les instructions de transmission d’information entre le microcontrˆoleur et l’ordinateur sont regroup´ees dans une biblioth`eque[library] appel´eeSerial. Parmi les instructions contenues dans cette biblioth`eque, trois sont particuli`erement utiles :

• la fonctionSerial.begin, qui permet d’´etablir la communication et de pr´eciser la vitesse de transmission des informations, exprim´ee en bauds, qui correspond plus ou moins `a des bits par seconde. En g´en´eral, cette vitesse est choisie parmi un ensemble de valeurs couramment utilis´ees : 300, 1200, 2400, 4800, 9600,14400,19200, 28800, 38400,57600et115200. Cette fonction est souvent utilis´ee lors de la phase d’initialisation (setup) du programme ;

• la fonctionSerial.print, qui envoie des caract`eres d’imprimerie (lettres, chiffres, signes de ponctuation . . . ) vers l’ordinateur, afin d’afficher un message ou la valeur d’une variable, ´ecrite en d´ecimal, en binaire ou en hexad´ecimal. La figure7montre les diff´erentes possibilit´es de cette fonction et le r´esultat obtenu sur l’´ecran dans chaque cas ;

• la fonctionSerial.println, presque identique `a la pr´ec´edente, mais qui envoie `a la fin du message un code suppl´ementaire deretour en d´ebut de ligne22suivi d’un code depassage `a la ligne suivante23.

Cette biblioth`eque comprend ´egalement d’autres fonctions int´eressantes, dont on trouvera la description dans le manuel de r´ef´erence de l’environnement ARDUINO.

A titre d’illustration, le programme ci-dessous est une version modifi´ee du programme pr´ec´edent, dans lequel` des instructions ont ´et´e rajout´ees pour ´etablir la communication avec l’ordinateur `a9600bauds et pour afficher la variablexn`a chaque it´eration. La boucle principale de ce programme utilise la fonction pr´ed´efiniedelay(ms), qui oblige le microcontrˆoleur `a attendremsmillisecondes avant de commencer une nouvelle it´eration :

// exemple de declaration, d’affectation et d’affichage d’une variable // F. Auger, aout 2010

const byte pente=3, decalage=17;

byte xn, yn;

(14)

// setup ***************************************************

void setup() {

Serial.begin(9600); // initialisation de la liaison serie avec le pc Serial.println("Demarrage du programme");

xn=0; yn=xn*xn;

}

// loop ****************************************************

void loop() {

Serial.print( " xn = " ); Serial.print(xn, DEC);

Serial.print( " yn = " ); Serial.println(yn, DEC);

xn=pente*xn+decalage;

delay(1000);

}

La figure8montre que les r´esultats obtenus sont bien conformes `a ceux qui ´etaient attendus.

3.4 Stockage de donn´ees suppl´ementaires

La m´emoireEEPROMdu microcontrˆoleur peut ˆetre utilis´e pour conserver des donn´ees. Dans certains cas, cela peut permettre de stocker davantage de donn´ees que ce que peut contenir la m´emoireRAM. De plus, c’est une m´emoire r´emanente, ce qui signifie que les donn´ees ne seront donc pas perdues si le microcontrˆoleur n’est plus aliment´e. Cet avantage ne doit cependant pas faire oublier les inconv´enients des m´emoiresEEPROM: des temps d’acc`es en ´ecriture ´elev´es (3.3ms), et un nombre limit´e de cycles d’´ecriture (100 000par octet).

La m´emoire EEPROMde l’ARDUINO Nano permet de stocker1024octets, chaque octet ´etant stock´e `a une adresse comprise entre0et1023. Les deux instructions de lecture et d’´ecriture dans l’EEPROMsont regroup´ees dans la biblioth`eque appel´eeEEPROM. Pour utiliser cette biblioth`eque, il est n´ecessaire d’´ecrire une directive

#include <EEPROM.h>au d´ebut du programme. Ces deux fonctions sont :

• la fonctionEEPROM.read(address), qui renvoie la donn´ee contenue `a l’adresse fournie en param`etre ;

• l’instruction EEPROM.write(address,data), qui ´ecrit `a l’adresse indiqu´ee la donn´ee (de type byte) fournie en second param`etre.

A titre d’illustration, le programme ci-dessous,`

// lecture et ecriture dans l’EEPROM du micro-controleur

// F. Auger, IUT de Saint-Nazaire (Universite de Nantes, France), aout 2010

#include <EEPROM.h> // utilisation de la bibliotheque EEPROM unsigned int annee;

// setup ***************************************************

void setup()

{// initialisation de la liaison serie avec le pc

Serial.begin(9600); Serial.println("Demarrage du programme");

// ecriture dans 4 octets de la memoire EEPROM

EEPROM.write(0,14); EEPROM.write(1,7); EEPROM.write(2,6); EEPROM.write(3,253);

}

// loop ****************************************************

void loop() {

Serial.print( EEPROM.read(0), DEC); Serial.print("/"); // affichage des 2 premiers octets Serial.print( EEPROM.read(1), DEC); Serial.print("/");

Serial.println( EEPROM.read(2)*256+EEPROM.read(3), DEC); // affichage d’un entier 16 bits

delay(2000); // attend 2 s avant la reprise

}

(15)

affichera le r´esultat ci-dessous dans la fenˆetreSerial Monitor:

Demarrage du programme 14/7/1789

3.5 Op´erateurs et fonctions pr´ed´efinies

Il est possible d’appliquer sur les variables et les constantes des fonctions pr´ed´efinies ainsi que des op´erateurs logiques ou arithm´etiques, dont les principaux sont pr´esent´es sur les figures 9 et 10. Toutes les expressions arithm´etiques sont ´evalu´ees en respectant l’ordre de pr´ec´edence classique : les multiplications et divisions sont prioritaires par rapport aux additions et aux soustractions. Par exemple, l’instruction “x=10-2*3;” mettra4dans la variablex, car la multiplication (2*3) sera faite avant la soustraction :10−2∗3est ´equivalent `a10−(2∗3) et non pas `a(10−2)∗3.

op´erateurs logiques

˜ n´egation de chaque bit (compl´ement `a un)

˜B10011010renvoieB01100101

& et logique B10011010 & B10100011renvoieB10000010

| ou logique B10011010 | B10100011renvoieB10111011

ˆ ou exclusif B10011010 ˆ B10100011renvoieB00111001

<< d´ecalage `a gauche B10011010 << 1renvoieB00110100

>> d´ecalage `a droite B10011010 >> 1renvoieB01001101 Figure 9: op´erateurs logiques disponibles.

3.6 Structures conditionnelles et de r´ep´etition

Dans les programmes, il est souvent n´ecessaire d’appliquer le mˆeme traitement sur des donn´ees diff´erentes, ou de n’effectuer certains traitements que dans certaines situations. Dans le langage de programmation de l’environnement ARDUINO, ces probl`emes sont r´esolus en utilisant les mˆemes structures algorithmiques que celles du langage C :

• La structure conditionnelle (ou alternative) s’´ecrit

if (condition)

{instructions executees si condition est vraie}

else

{instructions executees si condition est fausse}

Cette structure ´evalue condition, qui doit renvoyer une variable bool´eenne. Si celle-ci est vraie, les instructions pr´esentes apr`es la condition seront ex´ecut´ees. Si conditionest fausse, ce sont les instruc- tions situ´ees apr`es leelsequi seront ex´ecut´ees. La partie alternative (else ...) est facultative. Il est

´egalement possible d’imbriquer plusieurs structures conditionnelles en utilisant unelse if, comme dans l’exemple ci-dessous :

if (condition1)

{instructions executees si condition1 est vraie}

else if (condition2)

{instructions executees si condition1 est fausse et si condition2 est vraie}

else

{instructions executees si condition1 et condition2 sont fausses}

Les conditions utilis´ees dans les structures conditionnelles peuvent ˆetre ´elabor´ees `a l’aide des op´erateurs de comparaison de la figure11, et modifi´ees ou associ´ees `a l’aide des op´erateurs logiques de la figure12. Par exemple, le morceau de programme suivant,

(16)

fonctions et op´erateurs applicables aux nombres de tout type - n´egation (compl´ement `a deux)

abs valeur absolue (d’un nombre sign´e16bits)

+ addition

- soustraction

* multiplication

/ division exacte ou euclidienne (ou euclidienne), suivant le types des variables max calcule le maximum de2nombres :y=max(x,100)sera ´egal `axsi celui-ci est

sup´erieur `a100, et ´egal `a100sinon.

min calcule le minimum de2nombres :y=min(x,100)sera ´egal `axsi celui-ci est inf´erieur `a100, et ´egal `a100sinon.

constrain constrain(x, a, b)contraintx`a rester entreaetb.

fonctions applicables seulement aux nombres entiers

% reste de la division euclidienne de deux nombres entiers :17 % 5renvoie 2 map map(x, x1, x2, y1, y2)calcule une transformation lin´eairey=a x+b,

o`uaetbsont tels quey1 =a x1+bety2 =a x2+b.

bitRead bitRead(x, n)renvoie le niveau logique du bitnde la variablex.

bitWrite bitWrite(x, n, level) met le bit n de la variable x au niveau logique level.

fonctions qui renvoient un r´esultat de typedouble sqrt racine carr´ee

square carr´e

log fonction logarithme n´ep´erien log10 fonction logarithme d´ecimal

exp fonction exponentielle

pow pow(x,n)´el`evex`a la puissancen.

sin sinus

cos cosinus

tan tangente

atan arctangente

atan2 atan2(y,x)arctangente dey/xentre0et2π.

Figure 10: op´erateurs arithm´etiques et fonctions disponibles.

(17)

if (temperature>=80) {alarme_chaud=1;}

else {

alarme_chaud=0;

if (temperature<=6) {alarme_froid=1;}

else

{alarme_froid=0;}

}

examine si la variable temperature est sup´erieure ou ´egale `a 80. La variable alarme_chaud est mise `a 1 si c’est le cas, et mise `a 0 dans le cas contraire. Si, en plus d’ˆetre inf´erieure `a 80, la variable temperatureest inf´erieure `a6, la variablealarme_froidest mise `a1. Elle est mise `a0dans le cas contraire.

op´erateurs de comparaison

== ´egal

!= diff´erent

< inf´erieur

<= inf´erieur ou ´egal

> sup´erieur

>= sup´erieur ou ´egal

Figure 11: op´erateurs de comparaison.

association de comparaisons

! n´egation

&& et logique

|| ou logique

Figure 12: op´erateurs d’association de comparaisons.

Rappelons ´egalement qu’une condition ne peut ˆetre que la comparaison entre2nombres, ou une association de comparaisons entre 2 nombres : pour tester par exemple si un nombre x est compris entre0 et2, on

´ecrira surtout pasif (0<x<2)mais

if ((0<x)&&(x<2)) {y=log(x*(2-x));}

• Il existe plusieurs structures de r´ep´etition (ou boucles). La premi`ere est la structure de r´ep´etition avec pr´e- condition, qui est utilis´ee pour r´ep´eter un ensemble d’instructions tant qu’une condition (appel´eecondition de poursuite) est vraie. La syntaxe est :

while (condition)

{instructions repetees}

• La deuxi`eme est la structure de r´ep´etition avec post-condition, utilis´ee lorsque la condition de poursuite doit ˆetre plac´ee apr`es le groupe d’instructions r´ep´et´ees. La syntaxe est :

do

{instructions repetees}

while (condition);

On notera qu’avec une telle structure, le groupe d’instructions est ex´ecut´e au moins une fois, puisque la condition de poursuite est ´evalu´ee apr`es ce groupe d’instructions.

(18)

compteurou tout simplementboucle for, utilis´ee principalement lorsque l’on sait d’avance combien de fois on doit r´ep´eter un ensemble d’instructions. La syntaxe est :

for (Initialisation;ConditionPoursuite;Progression) {instructions repetees}

Cette structure est ´equivalente `a

Initialisation;

while (ConditionPoursuite) {

instructions repetees;

Progression;

}

Par exemple, l’instruction

for (i=0;i<5;i=i+1) {Serial.println(i,DEC);}

est ´equivalente `a

i=0;

while (i<5) {

Serial.println(i,DEC);

i=i+1;

}

et affiche les cinq valeurs deicomprises entre0et4.

Pour illustrer ces structures, on peut prendre comme exemple le programme ci-dessous, qui extrait (d’une mani`ere assez peu efficace) les chiffres d´ecimaux d’un nombre entier naturel :

// Extraction des chiffres de la representation decimale d’un nombre

// F. Auger, IUT de Saint-Nazaire (Universite de Nantes, France), aout 2010 int i;

unsigned int Nombre, CopieNombre, Seuil, Chiffre[4];

// setup ***************************************************

void setup()

{ // initialisation de la liaison serie avec le pc

Serial.begin(9600); Serial.println("Demarrage du programme");

Nombre=63451; // initialisation du nombre }

// loop ****************************************************

void loop() {

CopieNombre=Nombre; Seuil=10000; // initialisation de l’algorithme

for (i=4;i>=0;i=i-1) // on commence par les dizaines de milliers {

Chiffre[i]=0; // initialisation de chiffre a zero

while (CopieNombre>=Seuil) // on augmente le chiffre et diminue la copie {Chiffre[i]=Chiffre[i]+1; CopieNombre=CopieNombre-Seuil;}

Serial.print( Chiffre[i], DEC);

Seuil=Seuil/10; // on passa a la puissance de 10 en dessous }

Serial.println(); delay(2000); // attend 2 s avant la reprise }

(19)

3.7 Modules, fonctions et proc´edures

Les programmes pr´esent´es dans les paragraphes pr´ec´edents utilisent des fonctions pr´ed´efinies (delay,sin,cos, Serial.print,EEPROM.read, . . . ) fournies par l’environnement de d´eveloppement ARDUINO. Il pourrait ˆetre int´eressant pour l’utilisateur de d´efinir lui-mˆeme de nouvelles instructions, qui effectueraient chacune une tˆache bien pr´ecise. Ces instructions offriraient de nombreux avantages car elles permettraient :

• de structurer les programmes, de faciliter leur conception et leur lecture ;

• d’´ecrire une fois et une seule les instructions r´ealisant une action donn´ee, effectu´ee plusieurs fois dans un programme, afin de diminuer la taille des programmes, de limiter les erreurs dues `a des oublis de modifica- tion lorsque le code est chang´e et de faciliter la validation et l’´evolution des programmes ;

• de r´eutiliser ult´erieurement les instructions d´efinies dans de nouvelles applications, ou d’utiliser des instruc- tions d´efinies par d’autres utilisateurs dans ses propres programmes. Cela contribuerait donc `a la r´eduction du temps de conception d’une application, `a la division du travail lors de la conception d’une application complexe et au partage des savoir-faire.

Le d´efinition de nouvelles fonctions, qui permet donc la d´ecomposition d’un programme enmodules, s’obtient dans l’environnement ARDUINO en utilisant la mˆeme syntaxe que celle du langage C. Le point de d´epart est la notion defonctionqui, `a partir d’informations qui lui sont fournies, en d´elivre de nouvelles. La syntaxe de d´eclaration d’une fonction est

typeSortie NouvelleFonction(type1 Entree1, type2 Entree2, typeN EntreeN) {

instructions

return expression; // expression doit renvoyer une donnee de type typeSortie }

o`uNouvelleFonctionest le nom donn´e `a la fonction,Entree1,Entree2. . .EntreeNsont les param`etres d’entr´ee (ou arguments) de la fonction,instructionsles traitements appliqu´es aux arguments pour obtenir l’information renvoy´ee (retourn´ee) par la fonction, qui est obtenue parexpression. Il n’y a pas de contrainte sur la localisation de cette d´eclaration : elle peut ˆetre situ´ee avant ou apr`es les instructionssetupetloop, au choix de l’utilisateur. Par exemple, la fonction suivante calcule l’aire d’un rectangle :

float aireRectangle(float largeur, float longueur) {

return largeur * longueur;

}

Une fois d´efinie, une fonction peut ˆetre appel´ee en ´ecrivantNouvelleFonction(arg1, arg2, argn), exactement comme on utilise par exemple la fonctionsin. Voici quelques exemples d’utilisation de la fonction aireRectangle:

x=aireRectangle(4.3, 9.8);

Serial.print("L’aire d’un rectangle de largeur "); Serial.print(LargeurMesuree , 3);

Serial.print("et de longueur "); Serial.print(LongueurMesuree, 3);

Serial.print("est egale a ");

Serial.println(aireRectangle(LargeurMesuree,LongueurMesuree), 3);

Comme second exemple, la fonction ci-dessous calcule la partie enti`ere de la racine carr´ee d’un nombre entier naturelN, c’est-`a-dire le plus grand nombre entier naturelrdont le carr´e est inf´erieur ou ´egal `aN. Il est bas´e sur le fait que la diff´erence de deux carr´es successifs est un nombre impair :

(n+ 1)2−n2= 2n+ 1, donc n2 =

n−1

X

k=0

(2k+ 1)

unsigned int IntegerSqrt(unsigned int Nombre) {

long CopieNombre, Racine; // variables internes a la fonction CopieNombre=Nombre; Racine=0; // initialisation de Racine a zero while (CopieNombre >0) // tant que CopieNombre est positif

{

Racine=Racine+1; // on augmente Racine

CopieNombre=CopieNombre-(2*Racine+1); // et on diminue CopieNombre

(20)

return Racine;

}

Si cette fonction est utilis´ee dans la boucle principale suivante,

void loop() {

Serial.print("sqrt("); Serial.print(N1, DEC); Serial.print(")= ");

Serial.print(IntegerSqrt(N1), DEC);

N1=N1+1; if (N1%7==0) Serial.println(); else Serial.print(", ");

delay(400); // 400 ms = 0.4 s

}

on obtiendra le r´esultat d’ex´ecution suivant :

Demarrage du programme

sqrt(0)= 0, sqrt(1)= 1, sqrt(2)= 1, sqrt(3)= 1, sqrt(4)= 2, sqrt(5)= 2, sqrt(6)= 2 sqrt(7)= 2, sqrt(8)= 2, sqrt(9)= 3, sqrt(10)= 3, sqrt(11)= 3, sqrt(12)= 3, sqrt(13)= 3 sqrt(14)= 3, sqrt(15)= 3, sqrt(16)= 4, sqrt(17)= 4, sqrt(18)= 4, sqrt(19)= 4, sqrt(20)= 4 sqrt(21)= 4, sqrt(22)= 4, sqrt(23)= 4, sqrt(24)= 4, sqrt(25)= 5, sqrt(26)= 5, sqrt(27)= 5 sqrt(28)= 5, sqrt(29)= 5, sqrt(30)= 5, sqrt(31)= 5, sqrt(32)= 5, sqrt(33)= 5, sqrt(34)= 5 sqrt(35)= 5, sqrt(36)= 6, sqrt(37)= 6, sqrt(38)= 6, sqrt(39)= 6, sqrt(40)= 6, sqrt(41)= 6 sqrt(42)= 6, sqrt(43)= 6, sqrt(44)= 6, sqrt(45)= 6, sqrt(46)= 6, sqrt(47)= 6, sqrt(48)= 6 sqrt(49)= 7, sqrt(50)= 7, sqrt(51)= 7, sqrt(52)= 7, sqrt(53)= 7, sqrt(54)= 7, sqrt(55)= 7

Le mˆeme principe peut ˆetre utilis´e pour calculer la partie enti`ere de la racine cubique d’un nombre, en s’appuyant sur le fait que(n+ 1)3= 2n3−(n−1)3+ 6n.

Dans certains cas, l’utilisateur peut souhaiter d´efinir une fonction qui ne renvoie pas de r´esultat. C’est ce qu’on appelle uneproc´edure. Le type du r´esultat renvoy´e par la fonction sera alors d´eclar´e commevoid(vide), et la fonction ne comportera alors pas d’instructionreturn. Si l’utilisateur souhaite d´efinir une fonction sans arguments, la liste des param`etres d’entr´ee sera d´eclar´ee comme(void), ou plus simplement comme(). C’est ce qui est utilis´e dans l’exemple ci-dessous :

void PunitionQuotidienne() {

int j;

for (j = 0 ; j < nombreDeLignes ; j=j+1)

{Serial.println("Je ne dois pas copier sur mon voisin");}

}

Les proc´edures sont ensuite appel´ees en ´ecrivant leur nom suivi de leur liste de param`etres, comme dans l’exemple ci-dessous :

void loop() {

PunitionQuotidienne();

delay(86400000); // 86400000 ms = 24*60*60*1000 ms = 1 jour }

Les deux ´el´ements essentiels d’un programme ARDUINO,setupetloop, sont elles aussi des proc´edures.

Dans d’autres cas, l’utilisateur peut souhaiter d´efinir une fonction qui renvoie plusieurs r´esultats. Cela ne va pas ˆetre possible simplement, puisque la syntaxe de d´eclaration des fonctions, pr´esent´ee pr´ec´edemment, n’autorise qu’un seul param`etre de sortie. Pour r´esoudre ce probl`eme, les param`etres de sortie pourraient ˆetre contenus dans la liste des arguments de la fonction, qui serait appel´ee par une instruction de la forme

AutreFonction(entree1, entree2, sortie1, sortie2); // attention, erreur !

Mais cela ne va pas ˆetre possible aussi simplement, car la transmission d’informations entre le programme ap- pelant et la fonction appel´ee est r´ealis´ee par un passage de valeurs, ce qui veut dire que les fonctions ne disposent que d’une copie du contenu des variables utilis´ees par le programme appelant. Pour qu’une fonction modifie le contenu d’une variable utilis´ee par le programme appelant, il faut que ce dernier lui communique l’adresse de cette variable, ce que l’on appelle en informatique unpointeursur cette variable. Une fonction `a deux entr´ees et deux sorties sera par exemple d´efinie par

void AutreFonction(int e1, int e2, int *a_s1, int *a_s2)

(21)

o`ua_s1 est l’adresse d’une variable de type int, dont le contenu est24 *a_s1. Cette fonction peut alors ˆetre appel´ee en ´ecrivant

AutreFonction(entree1, entree2, &sortie1, &sortie2); // syntaxe correcte

o`u sortie1est une variable de type int, dont l’adresse25 est &sortie1. `A titre d’exemple, la fonction ci- dessous calcule leplus grand commun diviseur(PGCD) et leplus petit commun multiple(PPCM) de deux nombres entiers :

void PgcdEtPpcm(unsigned int a, unsigned int b, unsigned int *a_pgcd, unsigned long *a_ppcm) {

unsigned long ma, copie_ma, mb; // variables internes a la fonction

ma=a ; mb=b; // premiere partie : calcul du pgcd

do {

if (ma<mb)

{copie_ma=ma ; ma=mb ; mb=copie_ma ;} // interversion de a et b

ma = ma % mb; // on remplace a par le reste de

} // la division euclidienne de a par b

while (ma>0); // tant que ma n’est pas nul

*a_pgcd=mb; // le resultat est stocke a l’adresse a_pgcd

ma=a ; mb=b; // deuxieme partie : calcul du ppcm

while (ma != mb) // tant que ma et mb ne sont pas egaux {

if (ma < mb) // on augmente le plus petit des deux {ma=ma+a;}

else

{mb=mb+b;}

}

*a_ppcm=ma; // le resultat est stocke a l’adresse a_ppcm

}

Si cette fonction est utilis´ee dans la boucle principale suivante,

void loop() {

N1=14; N2 = 30; PgcdEtPpcm(N1,N2,&Pgcd_N1etN2,&Ppcm_N1etN2);

Serial.print("N1= "); Serial.print(N1, DEC);

Serial.print(", N2= "); Serial.print(N2, DEC);

Serial.print(", pgcd(N1,N2)= "); Serial.print(Pgcd_N1etN2, DEC);

Serial.print(", ppcm(N1,N2)= "); Serial.print(Ppcm_N1etN2, DEC);

Serial.println(); delay(1000); // 1000 ms = 1 s }

on obtiendra le r´esultat d’ex´ecution suivant :

N1= 14, N2= 30, pgcd(N1,N2)= 2, ppcm(N1,N2)= 210

Le langage de programmation de l’environnement ARDUINO permet donc de d´ecouper le programme de l’utilisateur en modules. Il est recommand´e d’´ecrire des modules qui ne d´epassent pas environ60 lignes, pour qu’ils puissent ˆetre imprim´es sur une page et donc ˆetre facilement pr´esent´es en entier sous les yeux. Il est

´egalement recommand´e d’´eviter au maximum l’usage des variables globales, afin de diminuer les erreurs de programmation et de cr´eer des petits morceaux de code faciles `a comprendre, mˆeme sans connaˆıtre leur contexte d’utilisation.

3.8 Gestion des broches d’entr´ees-sorties logiques

En plus de la plupart des fonctions “standard” du langage C, le langage de programmation de l’environnement ARDUINOfournit plusieurs fonctions d´edi´ees aux entr´ees-sorties logiques. L’ARDUINONano poss`ede14entr´ees- sorties logiques bidirectionnelles, num´erot´ees de0`a13. Ces entr´ees-sorties logiques sont l’une des caract´eristiques principales de ce microcontrˆoleur, car elles lui permettent d’´echanger des informations avec l’ext´erieur, ce qui est la finalit´e de cet appareil. Les trois fonctions de gestion des entr´ees-sorties logiques les plus couramment utilis´ees sont :

Références

Documents relatifs

Lorsque le signal que l’on cherche `a ´etudier s’y prˆete (par exemple, un signal p´eriodique ayant lui mˆeme des composantes purement sinuso¨ıdales), cette transformation

Toute rature ou utilisation de tipex entraˆıne une note nulle... Les fractions doivent

Consigne : Pose et effectue

technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire

technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire de l'addition … technique opératoire

technique opératoire de la multiplication … technique opératoire de la multiplication … technique opératoire de la multiplication … technique opératoire de la multiplication

Consigne : Pose et effectue

technique opératoire de la division … technique opératoire de la division … technique opératoire de la division … technique opératoire de la division … technique opératoire de