Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
ProgrammeravecArduinoens’amusant
OlivierEngler
ProgrammeravecArduinoens’amusantpourlesNuls
PourlesNulsestunemarquedéposéedeWileyPublishing,Inc
ForDummiesestunemarquedéposéedeWileyPublishing,IncCollectiondirigéeparJean-PierreCanoMaquette:PierreBrandeisEditionfrançaisepubliéeenaccordavecWileyPublishing,Inc.©ÉditionsFirst,undépartementd’Édi8,201712avenued’Italie75013ParisTél.:0144160900Fax:0144160901e-mail:[email protected]:www.editionsfirst.frISBN:978-2-412-02387-7ISBnnumérique:9782412028001Dépôtlégal:mai2017ImpriméenFranceTousdroitsréservés.Toute reproduction,mêmepartielle, du contenu, de lacouverture ou des icônes, par quelque procédé que ce soit (électronique,photocopie,bandemagnétiqueouautre)estinterditesansautorisationparécritdeWileyPublishing,Inc.
Cetteœuvreestprotégéeparledroitd’auteuretstrictementréservéeàl’usageprivéduclient.Toutereproductionoudiffusionauprofitdetiers,àtitregratuitou onéreux, de tout ou partie de cette œuvre est strictement interdite etconstitueunecontrefaçonprévueparlesarticlesL335-2etsuivantsduCodedelapropriété intellectuelle.L’éditeurseréserveledroitdepoursuivretouteatteinteàsesdroitsdepropriétéintellectuelledevantlesjuridictionscivilesoupénales.
CelivrenumériqueaétéconvertiinitialementauformatEPUBparIsakowww.isako.comàpartirdel'éditionpapierdumêmeouvrage.
IntroductionBienvenue dans le monde de l’invisible, de l’intouchable, de lamatièremolle,dusoft-ware!
Nous allons vraiment nous amuser à prendre puis à garder lecontrôle de quelque chose de trop étrange : ta propre capacité àinsufflerduraisonnementdansunbébé-cerveaufaitavecdusable.
Quand tu écris d’habitude, c’est pour te relire (fonction demémoire)oubienpourquequelqu’und’autreterelise(fonctiondecommunication).
Dansce livre, tuvasapprendreàécriredeshistoiresquivontêtrevécuesparuncircuitélectroniquecommesavraieetuniqueréalité.
Sansprogramme,unordinateurest l’objet leplus inutileque l’onpuissefabriquer.
Avecunprogramme,c’estl’outilleplusutile,lepluspolyvalentetlepluscomplicedel’hommequipuisses’imaginer.
L’étatd’espritdulivrePresquetousleslivresconsacrésauphénomèneArduinoseveulentpratiques.Le lecteura trèsenviedesavoirconstruire toutessortesdemontages,et son impatienceest supposée.Onestguidédans lemontage, dans le soudage, on va piocher par téléchargement unexempledéjàécrit et testé,on le transfère sur lacarte, ethop !çamarche.Gratificationimmédiate.
Etaprès?Àquelmomentauras-tuapprisàexpérimenter,àdevenirautonome, à avoir de nouvelles idées si tu n’as pas fait trèslentementlespremierspas?
Jeteproposeicidet’émerveillerdevantdepremiersmontagestrèssimplesauniveaumatériel,maisdeplusenplusévoluésauniveauprogrammation. Ce livre privilégie le code. La matière obéit, lecodedirige!
Aprèscettemiseenroute,tupourrasenvisagerdepoursuivreavecun environnement de programmation comme ceux desprofessionnels : langage C, C++, Java, JavaScript, Python, atelierEclipse…Maisd’abordlesbases.
Sécurité!Undéfique jemesuisdonnéconcerne le feràsouder.Dansdeuxprojets,savoirmaniercetoutilouavoirdanslesparagesquelqu’unqui sait est plus confortable, mais on peut faire sans. Aucunbranchementàunepriseélectrique220Vnonplus.Châtaigne,gohome!
Résumédel’histoire(plandulivre)
Ce livre propose quatre parties qui peuvent se faire en quatresemaines(ouquatremois,maisquatrejours,ceseraitstressant).
Semaine1:MiseenrouteDans leChapitre1, «Quel est cet animal ? » , nous découvronsl’objet à dompter en apprenant un langage. Cet objet est unmicrocontrôleur installé sur une carte électronique. C’est le seulchapitrequetupeuxparcourirunepremièrefois, t’arrêter lorsquecela devient corsé, puis y revenir (sans faute, hein ?) après avoirdérouléplusieursautreschapitres.
LeChapitre2,«L’atelierducyberartisan»,teguidedanslamiseenplacesurtonordinateurd’unlogicielpourcréeretmodifiertesprogrammespuislesenvoyerverslacarte.
Enfin, leChapitre 3, « Le tour de chauffe » , explique commentrécupéreretimplanterlesexemplesdulivre,découvrirleMoniteursérieetchargerunpremierprogramme.
Semaine2:ParleretécouterlemondeC’estdansleChapitre4,«Àl’écoutedumondeennoiretblanc»,que nous faisons nos premiers pas dans l’art d’écrire un textesourceensurveillantl’étatd’uneentréenumérique.
NousenchaînonsdansleChapitre5,«Àl’écoutedumonderéel»,avec les entrées analogiques, les types de données, ta premièrefonction()etlesconditions.Nousnesommesplusenvacances,maisc’estunfeud’artificedenouveautés!
Poursereposerlesneurones,nousutilisonsnospetitsdoigtspourconstruiredeseffetslumineuxinéditsavecdesdiodesLEDdansleChapitre6, «Parler, c’est agir » .Cene sera pas par hasard quenousferonsgénérerdesvaleursaléatoires.
Notre mikon va se montrer sociable comme jamais dans leChapitre7,«Donnerune impulsion» ,enproduisantdesvaleursanalogiques. Pour clore la semaine, nous allons créer un jeu (desociété)dedevinettenumérique.
Semaine3:SonsetlumièresPlace aux modules. De l’intelligence concentrée. LeChapitre 8,« Ta baguette magique » , explore la lumière invisible et oseaborderuntoutpetitpeulaprogrammationorientéeobjets.Danslatroussedebaseduprogrammeur,nousversonslastructureswitchcaseetlestableauxdevaleurs.Rienquecela!
AvecleChapitre9,«Quepersonnenebouge!»,cesera«susauxintrus»etnousferonsdubruit…etdel’algorithmique.
Enfin,leChapitre10,«Levoleurdecouleurs»,repeintlemondeavecseulementdurouge,duvertetdubleu.Maiséteinslalumière,c’estmieux.
Semaine4:LetempsdeslettresDans leChapitre11, « Le temps liquide » , nous affichons notrecaractèreetnousprenonsnotretempspourlefaire.
NousrepartonsducôtéobscurdesondesdansleChapitre12,«Unpeud’échologie».Lemikonentendracequenousn’entendonspas.Et pour nous rassurer, nous terminons avec un instrument sonoretrèsmalléable.
L’AnnexeréunitunmémentodulangageArduinoetquelquespistespourt’inviteràpoursuivrel’aventure.
PourréaliserlesprojetsBiensûr,iltefautd’abordtacarteArduinoUnoouunecompatible.Lavraie,celledecouleur«bleuArduino»,vautenviron20euros.Les clones sont normalement d’une autre couleur (blanc, rouge,bleu ciel, vert) et moins chers. Si tu choisis un clone, fais-toigarantirparlevendeurqu’ilestvraimentcompatible.
Si tu trouves une carte nommée Genuino, c’est aussi la carteofficielle, mais il y a eu une époque où les créateurs italiens del’Arduino n’avaient plus le droit d’utiliser le nom en dehors desUSA.Leschosessontrevenuesdansl’ordre.
Le tableau suivant présente les besoins en composantsmajeurs detous lesprojetsdu livre.J’yajouteun lotdepièces indispensablesdans la réserve de toute personne qui a envie de réaliser desmontagesenélectroniquenumérique.
Voici d’abord ces composants que tu vas pouvoir réutiliser d’unprojetàl’autre:
» aumoinsuneplaqued’essaioudeprototypage,une
detaillenormale(800trousenviron;situlepeux,
prendsaussiunededemi-longueur(400trous)etune
miniature(170trous)(voirlafinduChapitre2);
» aumoins5résistancesde100ohms,5autres
de220ohms,5de470ohmsetaumoinsune
de1kohm;
» unedizainedefilsdeconnexionmulticoloresavec
brochesterminalemâle-mâle(descourtsetdesplus
longs);
» unedizainedefilsdeconnexionmulticoloresavec
brochesterminalemâle-femelle;
» quelquesfilsdeconnexionmulticoloresavecbroches
terminalefemelle-femelle;
» (enoption)unporte-pile9V.
Lebudgetpourcesincontournablesestd’environ10euros.
Jenevaispascitercescomposantschaquefoisdanslesmontages.Jevaissupposerquetuenastoujoursassezd’avancedanstonpetitstock.Enrevanche,pourchaqueprojet,jecitelecomposantmajeur,celuiengénéralleplusonéreux.
Chapitre Projet Qté Composantmajeur Budget
04 Digit 1 Boutdestrap 0€
05 Analo 1 Boutdestrap 0€
05 Tempera 1 Capteurde
températureLM35ou
LM335(+rés.1kohm)
3€
06 Luciole 1 DiodeLEDrouge,
verteoubleue(+rés.
220ohms)
0,50€
07 Binar - idemLuciole 0€
07 Binar2 1 =Binar1+seconde
diodeLED(+rés.de
220ohms)
0,50€
07 Binar4 2 =Binar2+deuxautres
LED(+2rés.de220
ohms)
1€
07 Devinum - idemBinar4 0€
08 BagMagik 1 Capteurinfrarougede
typeTSOP38238
3€
09 Gardien 1 CapteurPIRVelleman
VMA314ou
compatible
6€
09 Sonner 1 Haut-parleur8ohms
ou32ohms
3€
09 TestOreilles - idemSonner 0€
10 Tricolore 1 DiodeLEDRGBanode
commune(de
préférence)ou
cathodecommune(+
3rés.270ohms)
2€
10 Arkenciel - idemTricolore 0€
10 VolKool 1 Capteurdecouleur
AdafruitTCS34725
10€
11 KristaLiq 1 ModuleafficheurLCD
deDFRobotDFR0009
11€
11 KristAlpha - idemKristaliq 0€
11 KristaProverbe - idemKristaliq 0€
11 Tokante 1 10€
ModulehorlogeRTC
TinyRTCàbasede
DS1307
12 Telemaster 1 Moduleàultrasons
HC-SR05(Velleman
VMA306ou
compatible)
5€
12 TelemasterLCD - idemTelemaster+
afficheurdeKristaLiq
0€
12 Taprochpa - idemTelemaster+
haut-parleurde
Sonner
0€
TOTAL 55€
Sicebudgetesttropélevé,s’ilfautenleverundescomposantslespluschers, tuchoisirasselon tespréférences.Tupourras tepasserdel’horlogeDS1307ouducapteurdecouleurTCS34725.Tupeuxréaliser tous les projets jusqu’au Chapitre 9 inclus pour moinsde20euros.
Une boîte de rangement translucide multicasier est très pratiquepouryrangertouteslespetitespièces.
Jedonnedesconseilsconcernantlessitesderevendeursàlafindulivre.
LacommunautéArduinoQuand tu entres dans le monde Arduino, tu viens rejoindre unecommunauté de millions de pratiquants qui se retrouvent sur lessites Web bien sûr, mais pas seulement : de nombreux locauxassociatifs t’ouvrent leursportesenmétropoleetenfrancophonie.Tupeuxyobtenirde l’aideet, surtout,partager tesdécouvertesettrouverdespartenairespourréaliserquelquechoseàplusieurs.
Unebonneadresseàfréquenterenpremierestleforumenfrançaisdusiteofficiel:
http://forum.arduino.cc/index.php?board=33.0
Figure1:Paged'accueilduforumArduinofrancophone.
Lavaleur33estlepréfixetéléphoniquedelaFrance.
Etmaintenant,enavanttoute!
ISemaine1:Miseenroute
Aumenudecettesemaine:
Chapitre1:Quelestcetanimal?
Chapitre2:Lesoutilsqu’iltefaut
Chapitre3:Letourdechauffe
E
Chapitre1Quelestcetanimal?
AUMENUDUCHAPITRE:
» Ilétaitunecarte
» Ilétaitunmikon
» Deslangagespourraisonner
n général, on dit qu’un être humain est constitué d’un corps etd’uneâme,doncd’unepensée.Si tun’avaispasdecorps, tunepourraissansdoutepasterendrecomptequetupenses,donctu
nepourraissansdoutepaspenser.
Il envademêmeavecunordinateur : il se composed’unepartiematérielle (sa quincaillerie ou hardware) et d’une partieimmatérielle (son programme ou software). Cela n’a riend’étonnant:l’ordinateuraétéinventéparleshumains.
Ce livre se consacre à la carte Arduino Uno, et j’ai déjà indiquédans l’introduction qu’il s’agissait d’une carte d’expérimentationconstruite autour d’unmicrocontrôleur (MCU,Micro ControllerUnit).Est-cedifférentd’unordinateur?
Dans un ordinateur habituel, il faut réunir sur une grande cartenommée carte mère de nombreux composants. Voici les plusimportants:
» unprocesseur;
» desbarrettesdemémoire;
» descircuitsd’entrée-sortie(pourcontrôlerledisque
dur,lacartegraphique,laliaisonInternet,lesports
USB);
» unealimentation.
Un microcontrôleur réunit la plupart de ces composants sur uneseule puce. Il est généralement bien moins puissant qu’unprocesseurd’ordinateurdebureau,maisilregroupedanslamêmepucelestroisélémentsfondamentauxd’unordinateur:
» unprocesseurpourtraiterlesdonnéesetfaireles
calculs(laCPU)–ici,c’estnotremikon;
» unespacedestockagemémoirepourlesinstructions
àexécuteretlesdonnéesqu’ilmanipule;
» desmoyenspourcommuniqueravecl’extérieur,qui
sontsesportsd’entréeetsesportsdesortie.
AulieudecommencerparunevisiteguidéedelacarteArduino,jeteproposedeplongerd’aborddanslapucedumikon, leroidelacarte.Nous verrons sa « cour » , les composants qui l’entourent,dansunsecondtemps.
Dans toute la suite du livre, pour éviter d’écrire sans cesse«microcontrôleur»,jevaisbaptisernotrenouvelami«mikon».
TonmikonestunATmega328UncomposantsedistinguedetouslesautressurtacarteArduino:c’estlemicrocontrôleur,pardon,lemikon.Ilcontientaumoinsunmilliondefoisplusdecomposantsquetousceuxquetuvoisautourdeluisurlacarte!
Cecomposantestutilisédansdesmillionsdeproduits,desappareilsménagers aux gadgets électroniques, des alarmes aux machines-outilsdel’industrie.Ilseprésentesouslaformed’unrectangledeplastiquenoiravecdespattesmétalliques.
Figure1.1:ApparenceexternedumikonATmega328.
Protégée dans son boîtier noir se trouve une fine lamelle desiliciumgravéd’environ3mmdecôté:c’estelle,lapuce.Touteslespattesdesdeuxcôtésduboîtier(ilyena14dechaquecôté)sontreliéesàcettepetiteplaquedesilicium.
La plaque contient des centaines de milliers de circuitsélectroniquesélémentaires.LaFigure1.2montreàquoi ressemblecette petite puce énormément agrandie. Je te rappelle que la tailleréelleestde3mmsur3!
Figure1.2:VuemicroscopiqueducircuitATmega328.
Et voici sur la Figure 1.3 les ensembles de composants qui sontréunis dans le mikon. Je rappelle que dans les ordinateurs debureau,laplupartdecesboîtessontdescomposantsséparés.
Il n’existe aucun objet dans l’univers connu qui possède une telledensité d’intelligence, pour un prix de 3 euros environ pièce. Tupeux par exemple acheter des poussins à 2 euros pièce pour telancer dans l’élevage de poules pondeuses, mais les poussins nesontpasdesobjets.Cesontdesorganismesvivantstrèscomplexes.Bien sûr, ils exécutent aussi un programme, mais c’est leurprogrammegénétiquecodédansleurADN.
Lemikonn’estpasuncerveauvidequiattendquetuytransfèrestonpremierprogramme.Dèssasortiedel’usine,ilsaitfaireuncertainnombred’opérationsélémentaires (son jeud’instructions),et ilnepourrajamaisenfaired’autres.
La mission d’un programmeur consiste à décomposersuffisammentdesopérationscomplexespourqu’ellespuissentêtreréaliséesaveccesinstructionsélémentaires.
Figure1.3:SynoptiquedumicrocontrôleurATmega328.
Voici les principales catégories d’opérations que sait faire tonmikon(ainsiquetouslesmicroprocesseursactuels):
1. Opérationsarithmétiques.Addition,soustraction,
multiplication,etc.
Quandtufaisuneadditiondetête,tudoissouvent
mémoriserunrésultatintermédiairequelquepart(«et
jeretiens3»).Tuutilisespourcelatamémoireàcourt
terme.Lapucefaitdemême:elleabesoindepetits
espacesdestockagedanslesquellesellepeutécrirele
résultatintermédiairedesesopérations.
Cespetitsespacess’appellentdesregistres.Lapuce
ATmega328possède32registres.Chaqueregistre
contienthuitpetitsinterrupteursélectriques(pourhuit
bits).
Enfait,cesregistressontutilisésparpairessousforme
de16registresde16bits.Nousverronsplusloinàquoi
ilsserventetcequesontlesbits.
2. Opérationsdedéplacement.Avantdecommencer
uneopération,lemikondoitallerchercherlesvaleurs
danssamémoire.Unefoisl’opérationterminée,ildoit
yrangerlerésultat.Pourtoutcela,ilfautunespace
mémoireendehorsdesregistres.C’estpourquoile
mikonpossèdetouteuneséried’instructionspour
chargerunevaleuretstockerunevaleurdansla
mémoirededonnées(SRAM).
3. Opérationsdebranchement.Latroisièmecatégorie
d’instructionsestlaplusimportante:elleréunittoutes
lesopérationsquifontd’unprocesseurautrechose
qu’unsimpleautomate.Eneffet,grâceauxinstructions
debranchementcombinéesàdesinstructionsdetest,
lecomportementexactduprogrammepeutvarier
d’unefoisàlasuivante.Jem’explique.
Lorsquetuveuxréaliserunerecettedecuisine,tusuis
dansl’ordrelesétapesnumérotées.Iln’yauraitaucun
intérêtàsauterdel’étape1àl’étape4puisàremonter
verslesétapes2puis3.Lefonctionnementestlinéaire:
tuvasdudébutàlafin.
Danscertainesrecettes,tulaissesreposerunepartie
decequetupréparespourconfectionner,parexemple,
unesaucequiseraajoutéeauplat.C’estunesous-
recette.Quandlasauceestprête,tureprendslasuite
delarecetteprincipale.
Unprogrammedansunprocesseurestluiaussi
constituéd’instructionsquisesuivent.Leprocesseur
lesexécutel’uneaprèsl’autreaurythmed’unehorloge
(quidonneletempopourpasseràl’instruction
suivante).Cependant,tupeuxdécideravecune
instructiondebranchementdesautercertaines
instructionspourcontinuerl’exécutionunpeuplusloin
puisrevenir,cequidonneunesouplesseinfinie.
4. Opérationsdetest.C’estcettedernièrecatégorie
d’instructionsquetucombinesaveclaprécédentepour
déciderdechangerlecomportementduprogramme
enfonctiond’unevaleurquipeutêtrecomparéeà0,ou
àuneautrevaleurpoursavoirsielleestégale,
inférieureousupérieure,etc.
Ilexisteunedernièrecatégoried’instructions:cellesquiserventàmanipulerlessignauxélectriquesbitparbit.Nousavonsdéjàassezdechosesàdécouvrirpourleslaisserdecôtépourl’instant.
Autotal,lemicrocontrôleurATmega328possèdeunpeuplusd’unecentained’instructionsmachine.
Unprocesseurestdoncunemachinequiutilisedutemps,aurythmedestopsdesonhorloge,etdel’espace(samémoire),pourmodifieret créer des données. Les instructions de son programme sontstockées dans sa mémoire Flash et les données, dans une autremémoiredetravail(marquéeSRAMsurleschémasuivant).
Voicileniveaudedétailultimepourlesprincipauxconstituantsdeton mikon. La figure suivante montre uniquement les détails durectangleAVRCPUetdesdeuxboîtesdemémoire(FlashetSRAM)delafigureprécédente.Petit,maiscostaud!
Figure1.4:Composantsdel’unitécentraledumikon.
Lamémoireduprogramme(mémoireFlash)Lorsqueleprogrammedémarre,ilvachercherlavaleursetrouvanttout au début de cette zone mémoire. Cette valeur numériquereprésentelapremièreinstructionqu’ildoitexécuter.
Une fois celle-ci exécutée (mêmependant qu’elle s’exécute), il vachercher l’instruction suivante et ainsi de suite jusqu’à la fin duprogramme,avecéventuellementdesbranchementsetdessauts,deschargements et déchargements de données et des opérationsarithmétiques.Chaqueactionderecherchedel’instructionsuivantesefaitaurythmedestopsd’horloge.Poursavoiroùilenestdansl’avancement parmi les instructions, lemikon possède un registremémoirespécial:lepointeurd’instruction.
C’estquoisontravail?Lecœurd’unmikonestunensembledecircuitscapablesderéagirà des valeurs numériques (binaires) pour en créer d’autres. Cetravailestfaitparl’unitéarithmétiqueetlogiqueALU(Arithmetic
and Logic Unit). Elle sait réaliser environ une centained’opérationsdifférentes.Cesont les instructionsmachinedont j’aiparléplushaut.
Lesrésultatsdecestraitementspeuventêtrerendusdisponiblessurdesbrochesde sortiede lapuceATmegaqui sontdisponibles surlesconnexionsmarquéesDIGITALdetacarteArduino.Surchacunedesbrochesdesortie,ilpeutyavoirsoitunetensionde5volts,soitpasdetension(0volt).Lacombinaisonexactede0etde1surlesbroches de sortie dépend entièrement du programme en coursd’exécutiondanslemikon.
D’unecertainefaçon,lemikonfabriquedeladentelledetensionàpartir de la tension continue 5 V qui lui sert d’alimentationélectrique. C’est une dentelle très fine car les tensions sur lesbrochesdesortiepeuventchangerjusqu’àplusieursmillionsdefoisparsecondesurunArduinoUno.
Letopdel’horloge
Le processeur fonctionne en progressant d’une étape à chaque
coupd’unehorloge,c’est-à-direàchaquechangementdetension
entre0Vet5Vdusignald’horlogequieststabiliséparuncristal
de quartz. Tu peux voir le composant cristal sur la carte : il se
trouveducôtégaucheaumilieu,dansunboîtierrectangulaireà
coinsarrondis.Situleregardesdeprès,tudevraispouvoirlirela
valeur 16 suivie d’autres chiffres. Cela signifie que ce cristal
résonne à 16 MHz, c’est-à-dire qu’il oscille et change
d’état16millionsdefoisparseconde.
FréquenceetgourmandiseLafréquenced’horlogedetonmikonestbieninférieureàcelledesprocesseurs équipant les ordinateurs de bureau actuels. Ces CPUIntel ou AMD ont une horloge tournant entre 1 et 3 GHz (troismilliardsdehertz),soitenviron100foisplusvitequecelledetonmikon(16MHzoumoins).
Mais les processeurs sont comme les cerveaux humains : plus turéfléchisintensément,plustoncerveauconsommedesucre,etplussouvent tu dois te recharger en énergie. Ton Arduino Unoconsomme beaucoup moins que le processeur d’un ordinateurclassiqueetchauffedoncbeaucoupmoins.
Lorsqu’ilexécutedesinstructions,leprocesseurAtmelATmega328consommeenviron10mA,soit0,05wattsalorsqu’unprocesseur
de milieu de gamme actuel consomme environ 1 000 fois plus(50watts).
Mieux encore, lorsque le processeur ATmega bascule en veille,c’est-à-dire au repos (mais prêt à se réveiller s’il arrive quelquechosesurunebroched’entrée),laconsommationdescendà0,1µA(micro-ampère,encore100000foismoins).
C’estcequipermetd’utiliserdescartesArduinopourtoutessortesdemontagessurpilesendomotique,enélectroniquedeloisirs,danslesvoitures,l’électroménager,lesjouets,etc.
Tacarte,c’estuneUnoReculonsmaintenantpourvoirsinotremikonestbienentourésurlacarte.D’abord,jerappellequ’ilexistetouteunefamilledecartesArduino,delaminusculeNanoàlagrandesœurMega2560.Notrepréférée est la Uno. La marque officielle est Arduino ou bienGenuino.
L’électricitéstatiquetuelesmikon!
Unemiseengarde :en fonctiondeshabitsquetuportes, ilest
possiblequetuaccumulessanslesavoirdel’électricitéstatique.
Tuaspeut-êtredéjàreçuunedéchargeenenlevantunpullouun
T-shirt.Pouréviterdedétruire tacarteavantmêmed’avoir joué
avec,toucheparexempleunradiateurouunepoignéedeporte,
puissors-ladesonemballage.
Danstous lescas,netouchepas inutilement lescontactssur le
dessousducircuit.
Tupeuxprendrelacarteenmainenlatenantparlesconnecteursenplastique enhaut et en bas et en l’orientant dans le bon sens pour
pouvoirlirelestextes.Quevois-tu?
Figure1.5:VuegénéraledelacarteArduinoUno.
» Enhautàgauche,ilyaungroscarréenmétal.C’est,
tul’avaisdéjàdeviné,lapriseUSB.
» Enbasàgaucheilyaunautreconnecteur,arrondi
celui-ci.Ilserviraplustardàinsérerunjackpour
alimentertacartesansavoirbesoindegarderlecâble
USB.Engénéral,tubrancherasdanscejackun
adaptateurdepile9V.
» Entrecesdeuxprises,tudoispouvoirdétecteruntout
petitcircuitnoiràgauchedurectangleovalisédu
cristaldequartz.C’estlerégulateurdetension,qui
permetd’alimenterproprementlemicrocontrôleur
avecunetensiontoujoursbienégaleà
5Vetsansparasites.
Figure1.6:GrosplansurleconnecteurUSBetlejackd’alimentation.
» Turemarqueségalementdeuxcylindresgrisclairen
bas,àdroitedelaprisejackd’alimentation.Cesont
descondensateursquifiltrentlatensiond’entrée.
Avectoutescesprécautions,tonmicrocontrôleurseraalimentéavecdel’énergiedehautequalité,etilt’enremerciera.
En longeant le bord inférieur vers la droite, nous trouvons leconnecteur noir des broches d’alimentation. Seules trois nousserontutiles,etdanstouslesprojets,d’ailleurs.
Enlesparcourantdegaucheàdroite(seulescellesquenousallonsutilisersontengras):
» Lapremièrebrochen’apasdelégendeetn’estpas
utilisée.
» LabrocheIOREFsertàdistribueràdescartes
d’extensionlamêmetensionquecelleutiliséeparla
carteArduino.Ellefournitsoitdu5V,soitdu3,3V.
» LabrocheRESETsertàreportersurunecarte
d’extensionleboutonRESETducoinsupérieurgauche
quifaitredémarrerleprogramme.
» Labroche3,3Vsertàalimenterdescomposants
fonctionnantaveccettetensionréduiteaulieude5V
(maximum50mA).
» Labroche5Vestlaseulesurlaquelletupeuxobtenir
le+5Vpouralimenterlescomposants.Elleestparfois
marquéeVcc.
» LesdeuxbrochesGNDcorrespondentaupôle
négatifd’alimentation,c’est-à-direàlamasse,en
anglaisground,abrégéenGNDetparfoisenVss.
» Enfin,labrocheVINdonnelamêmetensionquecelle
quiestfournieenentréelorsquetualimenteslacarte
avecunepileouunadaptateursecteur.
Figure1.7:Sortiesd’alimentationetentréesanalogiques.
Nelebrusquepas!
TacarteArduinoettonmikonsontdesobjetsdélicats.Ilfautfaireattention à ne pas trop demander au mikon. Ce qui pourraitfacilement le détruire, c’est de lui demander de fournir trop decourant.Voyonscequ’estuncourantélectrique.
Le courant, c’est de l’énergie qui se déplace.Quand tu vois l’eaucoulerdansune rivière, tudevinesqu’ellevad’unpointhautversunpointplusbasparcequ’elleestattiréeparlecentredelaterreetva finirdans lamer.Si tu installesunmoulin sur la rivière, l’eauqui se déplace fera tourner le moulin. L’eau produira un travailparce que son déplacement représente de l’énergie. Il en va demême avec le courant électrique qui coule entre les deux bornesd’unepileouentrelesdeuxfilsd’unepriseélectrique.
Situasdesradiateursélectriquescheztoi,tusaisqu’enréglantunradiateur aumaximum, tu vas générer plus de chaleur. C’est toutsimplement parce que tu fais passer plus de courant dans leradiateur. Ce courant est freiné par des résistances et c’est cefreinage qui crée la chaleur. Si tu règles le radiateur à moitié, ilconsommeradeuxfoismoinsdecourant.Lecourantsemesureenampères (A). Pour un radiateur de 2 000 W en 220 V, laconsommationestd’environ10A(2000diviséspar220).
Tonmikonestbeaucoup,beaucoup,moinsgourmand:chacunedesbroches de sortie ne peut fournir aumaximum que 0,04 ampère,soit 40 milliampères (mA). L’ensemble des broches ne doit pasdépasser les 200 milliampères. Il faudra prendre les mêmesprécautionsenutilisantlesbrochesenentrée:nejamaisfairepasserplusde40mAparunebrochedetacarteArduino.
SuitedelavisiteLe dernier connecteur en bas rassemble les six broches d’entréesanalogiquesàdroite,repéréesparlamentionANALOGIN(voirlaFigure1.7).
En remontant vers le bord supérieur de la carte, nous saluons lemikonaupassage.
Lemikonetsonembase
En général, car cela varie d’un fabricant à l’autre, le mikon se
présente sous la forme d’un rectangle noir avec 14 pattes de
chaque côté. Si tu regardes bien, tu dois voir que ce circuit est
insérédansuneembaseenplastique.C’estcetteembasequiest
soudée sur la carte. C’est une très sage précaution, car cela
permet de changer uniquement le microcontrôleur au lieu de
jeterlacarte.Siparmalheurtuledétruisunjour,ilsuffiradetirer
doucement aux deux extrémités pour extraire la puce, puis en
inséreruneneuve.Celaépargnededevoirdessoudertoutesces
petitesbrochesoudejeterlacarte.
Nousarrivonsenfinauxbrochesdesortiesurlebordsupérieur,àcôtédelamentionDIGITAL.C’estsurcesbrochesqu’ilyauraoupasune tensionde5Ven fonctiondesopérations réaliséespar lemikon(Figure1.8).
Figure1.8:Grosplansurlesentrées/sortiesnumériques.
Le but du mikon n’est pas de travailler dans son coin, maisd’écoutercequi sepasseautourde luipuisde réagir enparlantàsontour.Voyonsdonclesentrées-sortiesplusendétails.
Écouteretparler:lesentréesetsorties
Tu saismaintenant que cetteminuscule puce de 3mmde côté estcapable de réaliser, par exemple, 1 million d’instructions parseconde. Mais à quoi sert tout ce travail si tu ne peux pas enprofiter?
Il faut que les résultats puissent être renvoyés vers l’extérieur, etc’estàcelaqueserventlesbrochesdesortienumérique.
DébranchesinécessairelecâbleUSBpourpouvoirtournerlacarteArduino dans tous les sens. Prends-la et observe bien le bordsupérieurdelacarte, làoùsetrouventlesdeuxconnecteursnoirs,au-dessusdelamentionDIGITALPWM.
Regarde les chiffresmarqués juste sous les connecteurs : ils vontde0à13,cequifait14brochesdesortie.LamentionDIGITALterappelle que sur ces broches, il ne pourra y avoir que soit 0 V,soit5V.Cesontdesbrochestout-ou-rien.Danstesprogrammes,tupourrasécriredes instructionspour forcerparexemple labrochenumérotée7(donclahuitième)àl’étathaut,c’est-à-diredemanièrequ’ilyaitunetensionde5Vsurcecontact.
Enfrançais,onparlede«sortienumérique»,maisletermeanglaisdigitalesttellementrépanduquetuleverrassouventutilisé.Ilfautsavoirqu’enanglais,unchiffreseditdigit.Enfrançais,cemotn’estutilisé que pour les empreintes digitales. Tu peux utiliser le mot« digital » , mais n’oublie pas que tu rencontreras le mot«numérique»situpoursuisdanslavoiedel’électronique.
RetournelacarteArduinopourvoirlecôtépile.Orientelaplaqueparrapportàtasourcedelumièrepourpouvoirdevinercequiestgravésurlasurface.Tudoisvoirdestraitsquivontdesbrochesduconnecteurduhautjusqu’auxbrochesdumikonenbas.Celamontrequelesconnecteursde lacarteArduinodonnentdirectementaccèsauxpattes du circuit intégré, de façonbienplus confortable parcequetupeuxdirectementinsérerunfildanschacundesconnecteursnoirs.
Revenons aux légendes des sorties numériques (voir Figure 1.8).Quelques-unesneserésumentpasaunumérodelabroche.
RxetTxsontenbateauLesbroches0et1sontsuiviesrespectivementdelamentionRXetTX.Cesdeuxbrochesserventàfairecommuniquerlacarteavectonordinateur,commeellelefaitparlapriseUSB.Danstesprojets,dèsquetuaurasbesoind’affichersurl’ordinateurdesvaleursenvoyéespar le mikon, il ne faudra jamais utiliser ces deuxbroches0et1danslemontage,carcelagénéreraitunconflitetunrésultatbizarre.
Cesdeuxbroches sontdirectement reliées (tudoismecroire)auxdeux petites LEDmarquées TX et RX du côté gauche, un peu endessousdelabroche13.Ellesvonts’allumeraurythmedel’envoi(TX, Transmit) ou de la réception (RX, Receive) de bits dedonnéessurlapriseUSB.
Desbrochesespañoles?Plusieursbrochesprésententunpetitsymbole~(untilde)avantleurnuméro. Il s’agitdesbroches3,5,6,9,10et11.Ces sixbrochespeuvent être utilisées d’unemanière un peu spéciale.À côté de lamention DIGITAL, tu vois la mention PWM. C’est une techniquepourutiliserunesortienumériquedemanièreàsimulerunesortieanalogique.NousverronsceladanslaSemaine2.
Analogiqueounumérique?Quandtuallumesouéteinslalumièredetachambre,tuutilisesunmécanisme numérique, car la lumière est soit totalement allumée,soittotalementéteinte.Enrevanche,aulongd’unejournée,lesoleildiffuseune lumièrequi variegraduellement : c’est unphénomèneanalogique.Ilnedisparaîtpasenunéclairà18heurespile.
Quand tu règles le volume de ta chaîne stéréo, la variation estcontinue.C’estunphénomèneanalogiqueégalement.En revanche,tongrille-painestsoitentraindedorerunetartine,soitill’éjecte.Ilne reste pas àmi-hauteur (sauf bien sûr si une tartine se coince).C’estunphénomènenumérique,discontinuplusprécisément.
Unordinateurneconnaîtàl’intérieurquedeschosesdiscontinues,numériques:iln’yaquedes0etdes1.Soitilyaducourant,soitiln’y en a pas. Pourtant, dans le monde physique (IRL), il y a descomposants qui doivent être contrôlés de façon analogique, parexemplelevolumesonorequel’onenvoieàunhaut-parleur.C’estpour pouvoir contrôler graduellement de tels composants que tonmikonpossèdecertainesbrochesdesortienumériquespouvantêtreutilisées selon le principe PWM dont j’expliquerai les détails entempsutile.
Ton mikon peut donc parler en changeant l’état des brochesnumériques de sortie. C’est un langage vraiment élémentairepuisqu’il n’est constitué que de 0 et de 1,mais n’oublie pas qu’ilpeutchangerl’étatdechacunedesbrochesplusieursmilliersdefoisparseconde.SitupouvaisenvoyerducodeMorseàcettevitesse,unlivre entier pourrait être envoyé en quelques secondes. Ce n’estdoncpassiridiculequecela.
Renvoyerdesrésultatsvers lemondeextérieurpourcontrôlerdescomposants est une chose, mais il serait formidable de pouvoirécoutercequisepassedanslemonde.C’estàcelaqueserventlesentréesnumériques.
LesentréesnumériquesInutiled’allerchercherbienloin:lesentréesnumériquessefontsurles mêmes broches que les sorties numériques. En effet, dans tesprogrammes, tu peux à toutmoment choisir d’utiliser une brocheparmilesquatorzecommeentréeoucommesortie.
Lorsqu’elles sont utilisées en entrées numériques, les six brochesPWM sont strictement identiques aux autres. En revanche, maremarque concernant les deux broches 0 et 1 reste valable. Si tuutilises leMoniteur sériedans l’ateliercommeonva ledécouvrir
dans le prochain chapitre, n’utilise pas ces broches dans tesmontages.
Je viens de dire qu’il s’agissait de broches d’entrées numériques.Autrement dit, elles peuvent seulement détecter qu’il y a 0 Vou5V;maisquesepasse-t-ilavec4Vsuruneentrée?
Le fabricant de tonmikon, le fondeur, qui est la sociétéAtmel, achoisidecréerunezonedesécuritéentrelesdeuxétatslogiquesbas(0V)ethaut(5V):
» Entre0Vet0,8V,c’estunétatbas,doncun0.
» Entre2,8Vet5V,c’estunétathaut,doncun1.
» Entre0,8Vet2,8V,l’étatestindéterminé,etledernier
étatrestevalable.
Ces broches d’entrées numériques vont te servir à détecter toutessortes de changements, par exemple le fait d’appuyer sur un petitbouton-poussoir peut faire basculer une entrée de 0 V à 5 V oude5Và0V.Cela tepermetdedétecterquequelqu’unapressé lebouton.Dansunsystèmed’alarme,lefaitqu’unefenêtres’ouvrevachanger l’état d’un contacteur et tu pourras le détecter sur unebroched’entréenumérique.
Maiscommentfairepourrécupérerunevaleuranalogiquecommeunetempératureouuneintensitédelumièrenaturelle?Cesontdesvaleurs analogiques, pas numériques. Dans ce cas, il faudraitdisposerd’entréesanalogiques.Justement,lacarteArduinoenoffresix.
LesentréesanalogiquesRevenonsmaintenantauxentréesanalogiquesenpartiebassedelacarte(Figure1.7).LeconnecteurdedroiteportelalégendeANALOGIN.Bingo!C’estcequinousintéressemaintenant.
Pour ces six entrées analogiques, la légende va de A0 à A5 (iciaussi,oncommenceàcompterà0).
C’est surcesbrochesque tuvaspouvoir fairevenirunsignalquivarieentre0et5Vdefaçonprogressive.Parexemple,si tuveuxgérerunboutonderéglagedevolume,etqueceboutonenvoi5Vlorsqu’il est à fond, le fait demettre le bouton àmi-chemin doitprésenter2,5Vsurl’entréeanalogiquesurlaquelletul’asbranché.Maisilyaquelquechosed’étrange,non?
J’aiditque tonmikonnesavaitcomprendrequedesbits (des0etdes1).Commentpourrait-ildistinguerentreunetensionde2,5Vetunetensionde2,6V?Enplus,cesdeuxtensionssontdanslaplagegrise.Cen’estniun0,niun1.Ildoityavoiruneastuce.
La question est celle-ci : peut-on lire une valeur analogique avecunemachinepurementnumériquetellequ’unmicrocontrôleur?Maréponseestsimple:YesyouCAN.Eneffet,c’estuncircuitappeléCAN, Convertisseur Analogique-Numérique (en anglais DAC,DigitalAnalogConverter)quifait le traducteur.Nousutiliseronsuntelconvertisseurdanslaprochainepartie.
Uncerveauvideàlanaissance?QuandtudéballestacarteArduinoUno,elleestneuve,personnen’aencore travaillé avec (enfin, sauf si tu l’as achetée d’occasion).Puisqu’elle est neuve, elle ne devrait encore rien savoir fairepuisquetun’yasencoreinstalléaucunprogramme…
Enfait,lefabricantdelacarteaeulabonneidée,unefoislacarteconstruite et testée, d’y installer un petit programmeminimal quipermetdès lamise sous tensiondevérifierqu’elle fonctionne.Ceprogrammeest l’undesplus simplesprogrammes fournisdans laséried’exemplesquetuvasrécupérerenmêmetempsquel’atelierdedéveloppementIDEArduino.
Puisquecepetitprogrammeestdéjàenplace,nousallonsvérifierquelacartefonctionnebien.
Séquencepratique:testonsnotre
bébéPourcepremiertest,iltefautréunir:
» tacarteArduinoUno;
» soncâbleUSB.
Etc’esttout!
1. Commenceparorganisertonenvironnementpour
quetupuissesposerlacarteArduinosurtonplande
travailsansqu’ilyaitunrisquedecourt-circuitavecles
contactsdudessousdelacarte.
Eneffet,ilfautquetupuissesvoirlecôtédelacarteoù
setrouventlesconnecteursetlescomposants.Dece
fait,lescontactsdudessouspourraienttoucherun
objetmétalliquequitraîneraitparlà.
2. Branched’abordunboutducâbleUSBdansuneprise
USBdel’ordinateur.
3. TiensfermementlacarteArduinoavectamain
principale(ladroitepourlaplupartdesgens),puis
insèreleconnecteurUSBdanslapriseducôtégauche
delacarteArduino.
Tonmikonseréveille!Continueàmaintenirlacartesi
nécessairecarlesbouclesducâblepeuventemporter
lacarteetlafairetomber,carelleestlégère.
Pourensavoirplussurlescircuitsélectroniques,jete
conseille,danslamêmecollection,Découvrir
l’électroniqueens’amusant.
4. Maintenant,observebienlespetiteslumières(des
LED)quisetrouventsurlacarte.Repèrecelleportantla
légendeLEDouL.Elledoits’allumerets’éteindreà
rythmerégulier.
UneautreLEDmarquéeONrestealluméeen
permanence,c’estcellequiconfirmequetacarteest
soustension.Maisrevenonsàcellequiclignote.
Pourquoiclignote-telle?Ilyadeuxpossibilités:
» Soitelleclignoteparcequ’ilyasurlacarteun
circuitquel’onappelleoscillateur(àbasede
condensateursetderésistances).Cen’estpasle
cas,carcelanedonneraitpasexactementle
mêmerésultat.OnverraitlaLEDdevenirdeplus
enplus,puisdemoinsenmoinsbrillanteaufur
etàmesurequelecondensateursechargeetse
décharge.Commecelivren’estpasconsacréà
l’électronique,jen’enparlepasplusici.
» L’autrecauseduclignotementdelaLEDest
cellequinousintéresse:cesontdes
instructionsexécutéesparlemikonqui
modifientpériodiquementl’étatd’unebrochede
sortiedumicrocontrôleur,soit5voltspour
allumerlaLED,soit0voltpourl’éteindre.
Figure1.9:PremieressaidelacarteArduino.
C’estexactementcequisepasse.C’estunvéritableprogrammequiest en train de fonctionner quand tu vois clignoter la LED ! Sansmême avoir vu comment était écrit ce programme, essayons dedevineràquoiildevraitressembler:
1. Oncommenceavecuneinstructionpourforcerà5V
lasortiedumicrocontrôleursurlaquelleestbranchée
cettepetiteLED.
2. Avecuneinstruction,onmaintientlasortiedansle
mêmeétatpendantuncertaintemps,àvuedenez,une
demi-seconde.
3. Onpasseàunetroisièmeinstructionpourramener
l’étatdelabrochedesortiedelaLEDà0volt.
4. Onenchaîneavecunequatrièmeinstructionpour
resterenpausedanslemêmeétatélectrique.
5. Avecunedernièreinstruction,onforcelemikonà
revenirexécuterlapremièredesquatreinstructions
(c’estunsaut,JUMP!)
C’est exactement ce que fait le programme que nous allonsdécouvrir bientôt, quand nous aurons installé le logiciel sur tonordinateur pour afficher et modifier le code source desprogrammes.
Mais comment se fait-il qu’il y ait un programme dans la carteArduinoalorsqu’elleétaithorstensiondanssonemballage?C’esttout simplement parce que les programmes sont écrits dans unemémoireFlash,quines’effacepasquandoncoupel’alimentation.C’estlemêmegenredecircuitmémoirequeceluidetesclésUSB.
Tupeuxmaintenant débrancher la carte pour qu’elle se reposeunpeu.
Langagesdehautetdebasniveau
Quand tuvasprogrammer tonArduino, tuvasutiliserun langagede programmation (un infolangage). Celui le plus utilisé sur unArduinoestlelangageC,trèsrépandudanslemonde.
Chaquelignequetuvasécriredanscelangagepeutreprésenterdesdizaines ou des centaines d’instructions machine du mikon. VoiciquelqueslignesenlangageC:
if(heure==7){
sHabiller();
sortir();
}
C’est loin d’être incompréhensible, non ? S’il est 7 heures, ons’habilleetonsort.
Un programme spécial (le compilateur) analyse une à une leslignesdetontextesourcepourproduireunautrefichiercontenantuneséried’instructionsmachine.
Voiciquelques lignesen langagemachine (Figure1.10) telles quevisualisées dans un programme d’édition hexadécimale. Chaquecoupledechiffresreprésenteunesériedehuitbitsà0ouà1,cequirendlalectureun(tout)petitpeuplusfacile.
C’est ce fichier qui sera envoyédans lamémoireFlashdumikonparl’opérationdetéléversement.Dèsquecetransfertestterminé,leprogrammedémarre.
Il est possible d’écrire dans un langage quasiment identique auxinstructions machine et c’est le langage de bas niveau appeléassembleur. Laissons-le de côté dans ce livre ; nous avons biend’autreschosesàdécouvriretàexpérimenterd’abord.
Quand tuauras terminéce livre, tupourras,avecprécaution,allervoir làoùse tapissent lesfichiersproduitspar lecompilateur.Parexemple, sous Windows :C:\Users\ton_nom\AppData\Local\Tem
p\arduino_build_999999
Figure1.10:Aspectdecequiesttéléverséverslemikon.
RécapitulonsNous allons maintenant découvrir les outils avec lesquels tu vaspouvoir écrire le texte source de tes programmes, puis le fairetraduireetletransférerverslemikonsurlacarte.
Je te rappelle que j’ai listé dans l’introduction du livre lescomposantsàseprocurerpourréaliserlesprojets.
À
Chapitre2L’atelierducyberartisan
AUMENUDUCHAPITRE:
» Unatelier,c’estmieuxpourtravaillerets’amuser
» C’estquandcompile?
la différence d’un ordinateur de bureau, tu ne peux mettre enplace qu’un seul programme à la fois sur le mikon. Pourl’instant, il contient le programme qui a été installé en usine,
celui qui fait clignoter une fois par seconde lamini-LED soudée,reliéeàlabroche13.
Pour pouvoir y installer un autre programme, il faut utiliser unoutilquiva téléverserun fichierbinairequiaurad’abordétécrééparunautreoutil,lecompilateur.Maisavantcela,ilfautavoirécritle textesource,avecunoutilquiressembleunpeuàun traitementdetexteouauBloc-notesdeWindows.
Voyons donc d’abord comment récupérer l’excellent logicielgratuitpourcréertesprogrammes.Ilréunitplusieursoutils:
» unéditeurdetextepourrédigeretmodifierlecode
source;
» uncompilateurquivatraduirecetexteenlangage
binaire;
» untéléverseurquivaenvoyerlefichierbinaireversla
mémoireFlashdumikon.
Installationdel’atelierArduinoIDE
L’outil unique avec lequel tu vas faire tes premiers pas (et lessuivants)estunatelierdedéveloppementlogiciel.OnditégalementIDE, qui vient de l’anglais Integrated Developement
Environment. Nous allons d’abord récupérer ce programme,l’installerpuisleparamétrerpourqu’ilfonctionneavectacarte.
1. Danstonnavigateurpréféré,recherchelesdeuxmots
suivants:
ArduinoIDE
Pourquoinepasenprofiterpourdécouvrirlemoteur
européenQwant(www.qwant.com)?
Danslesréponsesfourniesparlemoteurde
recherche,choisiscellequicorrespondàl’adresse
suivante:
https://www.arduino.cc/en/Main/Software
Tudevraisvoirapparaîtreunepagedanslestylede
celleillustréeenFigure2.1.
Figure2.1:Lapagedetéléchargementdel’atelierIDE.
CetoutilexistedorénavantenversionWeb(Accessthe
OnlineIDE),maiscen’estpascellequinousintéresse.
Descendsunpeudanslapagejusqu’àvoirapparaîtrela
zoneintituléeDownloadtheArduinoIDE.
Figure2.2:SectiondetéléchargementdanslapageArduino.
Danslapartiedroite,tuasaccèsauxliensdes
différentesversionsdel’atelier,selonlesystème
d’exploitationquetuutilises.
AtelierpourWindows1. DanslasectionDownloadprésentéedansla
Figure2.2,cliqueWindowsInstallerouMacOSX.
2. Lapagequiapparaîtteproposedecontribuerau
financementdumouvementArduino.Pourl’instant,tu
vasdécouvrirquelestcemouvement.
3. ÀgaucheduboutonContributeandDownload,
cliquelelienJustDownload,moinsvisible(Figure2.3).
Figure2.3:Leboutondetéléchargementsimple.
Enfonctiondesréglagesdetonnavigateur,soitle
téléchargementdémarredirectementpourcopierle
fichierdansledossierTéléchargements,soitilte
demandesituveuxenregistrerlefichieretàquel
endroit(Figure2.4).
Figure2.4:Choixd’enregistrementdufichier.
Danscedeuxièmecas,choisisl’endroitoùtuvas
téléchargerlefichier,parexempledans
Téléchargements.Turemarquesquelefichier
commenceparlenomArduino,suividunumérode
version.Àl’heureoùj’écrisceslignes,nousensommes
àlaversion1.8.
Figure2.5:Choixdudossierdestockage.
4. OuvresinécessairetonExplorateur,Finderou
Navigateurdefichiersetrends-toidansledossierdans
lequeltuasdemandédedéposerlefichiertéléchargé.
Tudoisvoirapparaîtreunfichierportantlenom
«Arduino-numérodeversion».
5. Double-cliquelenomdufichierpourdémarrer
l’installation.
SousLinuxSous Linux, le plus simple consiste à utiliser ton gestionnaire depaquetages en cherchant Arduino. Toute la suite va s’enchaîner
automatiquement.
Installationdel’atelierPourgarantirquel’installationseferaavectouslesdroitsd’accès,cliqueduboutondroitdanslenomoudansl’icônedel’installateuret choisis Exécuter en tant qu’administrateur (cetteprécautionn'estpastoujoursnécessaire).
Figure2.6:Démarragedel’installateursousWindows.
1. Siuneboîtemessagestandardtedemandede
confirmerquetuautorisesl’applicationàmodifierton
ordinateur,cliqueOui.
Lapremièreboîtededialoguedel’installateurapparaît.
2. IlsuffitdecliquerenbasàdroiteleboutonIAgree.
Celaconfirmequetuacceptesd’utiliserlelogicieldans
lesconditionsdelaFreeSoftwareFoundation.C’estla
fondationauniveaumondialquigèrelesdroitsdes
auteursdelogicielsopensource.
Figure2.7:Démarragedel’installateursousWindows.
3. Danslesoptionssuivantes,iln’yarienàchanger.Tu
vasinstallerlelogicielArduino,lepiloteUSB,un
raccourcidanslemenuDémarreroudans
Applications,unraccourcisurleBureau,ettuvascréer
touslesfichierssourcesavecl’extension.inoqui
dénoteleformatdesfichierssourcesArduino.Tupeux
àprésentdirectementcliquerleboutonNextpour
passeràl’étapesuivante.
Figure2.8:Choixdescomposantsàinstaller.
Àlatroisièmeétape,tupeuxchangerledossierdans
lequelvaêtreinstallél’atelier.Nechangerienàce
niveausaufsitusaiscequetuveuxfaire.Cliquele
boutonInstallpourlancerletravail.
Figure2.9:Choixdudossierd’installationdel’atelier.
Iln’yaplusqu’àadmirerletravaild’installationencours
(Figure2.10).Tupeuxmêmeafficherlesdétailssicela
t’intéresse.
Figure2.10:Installationencours.
Tuconstatesqu’ilyaplusde3000fichiersàinstaller.
Tousneseserontpasutiles,carl’installationcouvre
touslesmodèlesdecartesArduino,etpasseulement
laUno.
Unefoisl’installationterminée,ilestpossiblequ’une
boîtedesécuritésurgissepourtedemandersitu
autorisesl’installationd’unpilotedepériphérique
(driver).Cepiloteestindispensable:ilpermetde
communiqueraveclacartevialeportUSB.
9. CliqueleboutonInstall(Figure2.11).
Figure2.11:Installationdupilotepériphérique.
Ilestpossiblequ’unedeuxièmeetunetroisièmeboîte
dedemanded’autorisationapparaissentensuite.Il
suffitderépondreInstall.
SilelogicielPare-feudusystèmetedemande
d’autoriserl’installationdeJava,répondsAutoriser
l’accès.
Figure2.12:Installationdupilotepériphérique.
10.Tureviensàlaboîteprincipaled’installation.Letitre
indiqueCompleted.CliqueleboutonClose:
l’installationestterminée.
Voyonsmaintenantcommentconfigurerl’atelier.
Premierdémarragedel’atelier
IDEMaintenant que tu as installé le logiciel atelier, tu as sans douteenviedel’essayerauplusvite.Alorsallons-y:
Procédurepratique1. Silacarten’estpasbranchéesurl’ordinateur,
rebranche-la,enfaisantattentionàlaposersurune
surfacenonmétallique.
2. Cherchesurlebureauoudanslesmenuslenom
Arduinoetdouble-cliquepourlancerleprogramme.
3. Tuvoisapparaîtrelafenêtreprincipaledetonatelier
(Figure2.13).Nousenouvrironsuneautredetempsen
temps,maisengénéral,cen’estquedanscettefenêtre
quenousallonstravailler.Qu’est-cequetudécouvres?
Figure2.13:Vuegénéraledel’atelierArduino.
Toutenhaut,labarredetitreavecunementionétrangejusteavantlenomduprogrammeetlenumérodeversion:
sketch_apr02a
Le mot sketch se traduit par « croquis » . C’est ainsi que lesinventeurs de l’Arduino ont décidé d’appeler les programmes,c’est-à-direlecodesourcequetuécris.Dèsquel’atelierdémarre,ilouvre un croquis pour pouvoir démarrer immédiatement. Cecroquis n’est pas entièrement vide, comme tu peux le constater.Nousyreviendronsplustard.
La mention apr02a signifie qu’il s’agit du premier nouveauprojetdu2avril.
On retrouve ensuite classiquement une barre de menus, avecFichier, Édition, Croquis, Outils et Aide. Nous endécouvrironslesdétailsaufuretàmesuredesbesoins.
Sous la barre de menus, il y a une barre de boutons que nousapprendronsàutiliseraufuretàmesure.
Vientensuitelagrandezoneblanchedanslaquelletuécrislecodesourcedetesprogrammes,commedansuntraitementdetexte.Elleestpresquevidepour l’instant.Nous reviendronsplus loin surcetembryondeprogramme.
L’ongletenhautrappellelenomduprogrammeencours.
Dans la partie inférieure, sous un bandeau vert, nous trouvons ungrandpanneaunoir.C’est ici que s’afficheront lesmessagesde lapartdel’atelier,notammentlorsqu’ilvadétecteruneerreurdanstonprogramme.
Enfin,toutenbas,labarred’étatrappellelemodèledecartedétectéetleportdecommunication.
Justement,ilnousfautpasserparunepetiteétapedepréparationquineseraréaliséequ’unefois.
ConfigurationdelacartePourétablirledialogueentrelacarteetl’atelier,ilfautdéfinirdeuxparamètres : le typede carte et le nomduport de communicationUSB.
1. OuvrelemenuOutilspuislesous-menuTypede
carte.
2. Tudécouvresuntrèsgrandnombredecartes:ilest
possiblequelemodèleArduino/GenuinoUnosoit
déjàsélectionné.Sicen’estpaslecas,sélectionnece
modèledecarte(Figure2.14).
Figure2.14:Choixdumodèledecarte.
3. OuvreànouveaulemenuOutilsetchoisislesous-
menuPort(Figure2.15).Cemenuestgrisésitun’aspas
branchélacarteousiellen’estpasdutoutdétectée.
Figure2.15:Choixduportdecommunication.
Si lacarten’estpasdétectéealorsqu’elleestbienbranchéepar lecâbleUSBetque le témoindemisesous tensionestallumésur lacarte,c’estqu’ilyaunproblèmeauniveaudupilote.Danscecas,rare,jenepeuxquet’inviteràterenseignersurleforumArduinofrançais.
4. Pourvérifierquetoutestbienconfiguré,ouvreune
foisdepluslemenuOutilsetchoisislacommande
GetBoardInfo(Interrogerlacarte).
Figure2.16:Messageconfirmantquelacarteestdétectée.
Tudoisvoirapparaîtreunepetiteboîtededialogue
indiquantquatreparamètres,etnotammentlenuméro
desérie,SN.Sache-le:chaquecarteestidentifiable
parmitoutescellesquisontutilisées,deValparaisoà
Séoul.
5. CliqueOKpourrefermerlaboîte.
Tu es maintenant prêt à lancer ta première vérification et tapremièrecompilation.
Compilationdetest...Jet’expliquaisdanslepremierchapitrequelesprogrammesquetuécrisdoiventêtretraduitsencodeexécutableavantd’êtretransférésverslacarte.
Cette opération se nomme la compilation. Dans l’atelier, celacorrespondauboutonVérifier,lepremierdelabarredeboutons.
Clique le boutonVérifier et observe bien le contenu du panneauinférieur.
Figure2.17:Messagesd’unecompilationréussie.
Deuxlignesapparaissentdanslepanneauinférieur:
» Lapremièreligneditquelecroquisutilisequelques
centainesd’octetsdel’espacedestockagede
programmes,c’est-à-direlamémoireFlash.Le
messagerappelled’ailleursquetupeuxaumaximum
installer32256octetsdecodebinaire,soitunpeu
moinsde32ko.C’estbienlavaleurindiquéeparle
constructeurpourlamémoireFlash.
» Lasecondeligneparledevariablesglobales.C’estun
peuétrange,puisqueceprogrammeminimaln’utilise
aucunevariable.Pourtant,nousoccupons9octetsde
lamémoiredesdonnées,c’est-à-direlamémoire
appeléeSRAM.Celacorrespondbienàcequele
constructeurprétend:ilvendlemikon
avec2048octetsdemémoirepourlesvariables:
2048moinsles9octetsquenousoccuponsfont
bien2039,commeaffiché.
Ces messages ne sont pas anodins. En effet, un mikon n’a pasbeaucoupdemémoireetilfaudratoujourssurveillercesmessagescaronremplitvitel’espacedisponible.
Ceprogrammenefaitrien,maisilseraacceptéparlemikonparcequ’il contient les deux éléments obligatoires dans tout croquisArduino : lesdeuxfonctionsquiportentobligatoirement lesnomssetup()etloop().Nousverronscelaplustard.Pourl’instant,essayons de transférer le programme vers la carte Arduinopuisqu’ilpeutêtrecompilé.
…ettéléversementdetest1. Cliqueledeuxièmeboutondelabarredeboutons,
Téléverser.Riennesepasse,saufqu’iln’yapasde
messaged’erreur.Pasdenouvelles,bonnesnouvelles.
Provoquons-leunpeu,notremikon!
2. Dansl’éditeur,placelecurseurautoutdébutdela
lignedelafonctionsetup():
voidsetup(){
3. AveclatoucheSuppr,supprimelalettrevdudébut
dumotvoid(Figure2.18).
Figure2.18:Uneerreurvolontaire.
Dèsquetumodifieslefichiervideproposéau
démarrage,ilfautenregistrercetteversionmodifiée
dansunfichierpourpouvoircompilerleprogramme.
4. DanslemenuFichier,choisisEnregistrersous.
Tuvoisapparaîtreuneboîtestandard(Enregistrerle
dossierdescroquis...).Apriori,lefichierseraimplanté
dansunsous-dossierdeMesdocuments.Tupeux
conservercetemplacementpouryréunirtousles
projetsoudéfinirunnouveaudossierailleurssitusais
lefaire.
5. Choisisavecsoinlenomdetondossier,carcela
seraégalementlenomdufichierduprojet.Par
exemple:
VideEtBogue
6. Tupeuxmaintenanttenterunecompilationavecle
boutonVérifierouleraccourciclavierCtrl-R.
Tuvoisapparaîtretrèsvitedeuxlignesaffichéesenorangedanslepanneau des messages, ce qui signifie que c’est un problème(Figure2.19).
Figure2.19:Lecompilateurn’estpascontent.
Lemessage est en anglais,mais la deuxième ligne signifie que lemotoidnedésignepasuntypeconnu.Qu’est-cequecelaveutdire?
C’esttoutsimplementquelecompilateurdoitnormalementtrouveràcetendroitundesmotsréservéspourindiqueruntypededonnées,c’est-à-direlanatured’unedonnée.Ici,ils’agitd’untypespécial,letypevoidquisignifie«vide».
Tuaspeut-êtredéjàfeuilletéunlivredansunelangueétrangère,parexempleenchinois,enhindiouenarménien?Regardeparexemplecetextrait:
Figure2.20:Unephraseenbengali.
Situneconnaispaslalangue,tunesaurasmêmepasprononcerlessons.Iltefautuneindication.
Le compilateur du langage est beaucoup plus bête qu’un êtrehumain. Il faut tout luidire. Il fautdoncnotamment luidirequandon indique un chiffre ou quandon indique une lettre.C’est à celaque sert le type de données. Ici, le type void signifie toutsimplementqu’iln’yapasde type.Nousy reviendrons.Contente-toidesavoirqu’ilfautécriresansfôte(sic)poursefaireobéirparlemikon.
Maintenantquetuasvutonpremiermessaged’erreur,remettonsleschosesenordre:
1. Ajouteànouveaulalettrevenminusculeaudébutdu
motoidtoutaudébutduprogramme.
2. Relancelacompilationquidoitsedéroulersans
problème.
Tuasmaintenant terminédemettreenplace tonprincipaloutildetravail,maiscen’estpasleseul.
Terminons avec quelques outils qui vont te permettre de mieuxt’amuser.
AutresoutilsTrèspeud’outilsvontêtrenécessairespuisquecelivreestdédiéàlaprogrammation.
SoudureDans ce livre, j’ai choisi de ne pas utiliser de fer à souder.Toutefois,ilenfaudraitunlorsquelemodulet’estlivrésansquelesbrochesdeconnexionsoientsoudées.
Danscecas,deuxsolutions:
» Tudemandesautourdetoisiquelqu’unpeutfaireles
soudures.
» Situsaissouderàl’étain,tulefaistoi-même,mais
prendstesprécautions.
Au pire, les rares exemples pour lesquels certains fournisseursvendent le module non soudé resteront de côté le temps que tupuisses trouver la solution. Cela n’empêche pas de réaliser lesautresprojets.
OutilsmanuelsLesoutilsdonttupeuxavoirbesoinsont:
» Multimètre.Pourmesurerdesvolts,desampèreset
desohms.
» Pinces.Unepetitepinceàbecsplatsetunepince
coupante.
» Tournevis.(option)Unmini-tournevispourréglerle
potentiomètredel’afficheur.
» Connexions.Unebonneréservedefilsdeconnexion
quej’appellestraps(onditaussijarretières).Desmâle-
mâlecourtsetlongs,desmâle-femelleetquelques
femelle-femelle.
» Plaques.Aumoinsuneplaqued’essaioude
prototypage.Lestroistailleslesplusutiliséessont:
» lanormaleavec800trousenviron,avecdeux
railsdanslesensverticalpourlenégatifetle
positifdel’alimentation;
» lademi-longueuravec400trousenvironetles
deuxrailsaussisurlescôtés;
» laminiatureavec170trous,quin’apasderails
d’alimentation.
Avoir plusieurs plaques t’épargne de tout démonter pour passer àunautreprojet.
Figure2.21:Quelquesplaquesd’essai.
C’estgrâceàcesplaquesquetun’aspasbesoindeferàsouder.Lesbrochesetpattesdescomposantss’enfichentdanslestrousquisontinterconnectés 5 par 5 dans chaque demi-rangée. Dans laFigure2.22,destraitsjaunesmontrentcommentsefontlescontactspar-dessous.
Figure2.22:Visualisationdesliaisonsderangées.
RécapitulonsDanscechapitre,nousavonsdécouvert:
» l’installationetlapréparationdel’atelierArduino;
» lafenêtred’éditiondutextesource;
» lapremièrecompilationetlepremierbogue;
» quelquesoutilsàseprocurer.
P
Chapitre3Letourdechauffe
AUMENUDECECHAPITRE:
» Commentrécupéreretimplanterlesexemplesdulivre
» DécouvrirleMoniteursérie
» Chargerunprogrammedéjàtoutprêt
» Homéostasie?
uisquecelivreestconsacréàlaprogrammationinformatique,ilest normal que tu y trouves de nombreux exemples de codesource.Pourvérifiersicequetusaisisestcorrect,oulorsquetu
estroppressé,tuaurastoujourslapossibilitédechargerlaversioncomplètedechaqueprojet.
Maispour enprofiter, il faut récupérerun fichier compressé, quel’on appelle une archive, au format ZIP sur le site de l’éditeur.Voyonscelasur-le-champ.
Accéderausitedulivre1. OuvretonnavigateurWebetvaàl’adressesuivante:
pourlesnuls.fr/livres/programmer-en-s-
amusant-arduino-megapoche-pour-les-nuls-
9782412023877
ouplussimple:
goo.gl/7xIEph
2. Tuarrivessurlapagedulivre.Tuytrouvesunezone
permettantdetéléchargerlesfichiers.
3. Cliquele(s)lien(s)detéléchargement.
Figure3.1:LapageWebd’unautrelivredelacollection«Programmerens’amusant»avecsonliendetéléchargement.
Sil’adresseindiquéeci-dessusnefonctionnepas,
rends-toisurlapagepourlesnuls.frpuiscliquel’icônedeloupeetsaisislestermes«programmer
arduino»danslazonederechercheafindetrouverla
fichedulivre(voirFigure3.2).
4. Unefenêtrevolanteestapparue.Ouvrelalistepour
sélectionnerleoulesfichiersarchivesdisponibles.
Situn’asrienchangéauxréglagesdetonnavigateur,le
fichiervaêtrestockédanstondossierdes
téléchargements.Situconnaisbientonnavigateur,tu
aspeut-êtremodifiéuneoptionpourquele
programmetedemandeàquelendroitildoitdéposer
cequ’iltélécharge.
Jesupposedanslasuitequelefichieraétéstockédans
Téléchargements.
Figure3.2:Recherchedelapagedulivre.
5. Unefoisqueletéléchargementestterminé,ouvreton
Explorateurdefichiers(appeléFindersousMacOS).
AffichelesdétailsdudossierTéléchargements.Tu
doispouvoirrepérerlefichierquetuviensde
télécharger.Trieéventuellementl’affichagepardates
décroissantespourqu’ilapparaisseenpremier.
6. Cliqueduboutondroitdanslenomoudansl’icônede
l’archivepourchoisirlacommandeCouper.Nous
allonsreplacerl’archivedansledossierdestinataire.
ToujoursdanstonnavigateurouExplorateurde
fichiers,ouvreledossierDocuments.Tudoisvoir
apparaîtreunsous-dossierportantlenomArduino,
quiaétécréélorsdel’installationdel’atelier
(Figure3.3).
Figure3.3:DéplacementdesexemplesdansledossierdetravailMesdocuments/Arduino.
7. CliquecenomArduinopourfaireapparaîtreson
contenudanslevoletdesdétails,puisamènele
pointeurdesourisdansunezonelibreàdroiteetclique
duboutondroitpourchoisirlacommandeColler.Tu
peuxégalementcliquerduboutondroitdanslenomdu
dossierArduinoetchoisirColler.
Le fichier archive estmaintenant à l’endroit où il doit se trouverpourendéballerlecontenu.
Décompressiondel’archivedesexemples
Clique du bouton droit le nom du fichier d’archive et choisis lacommandeExtrairetout...
Ilneresteplusqu’àpatienterjusqu’àcequetouslessous-dossierssoientcréésetremplisaveclesdifférentsfichiers.
Dès que c’est fini, tu peux constater qu’il y a un sous-dossier parpartiedulivre.Parfois,tuteretrouvesavecunsous-niveauentrop.Danscecas,redescendsle«sous-sous-dossier»d’unniveau.
C’estquoi,cedossierlibraries?Tu as certainement remarqué qu’il y avait déjà un dossier dansArduino. Ce dossier est vide pour l’instant. C’est ici que tupourrasdéposerdes fichiers archivede librairies, c’est-à-diredescollectionsdesous-programmesquivonttefairegagnerdutemps.Nousverronscelaentempsutile.
PournepastomberchaosAufuretàmesuredetaprogressiondanscelivre,tuvascréerdeplus en plus de programmes. Dans le monde Arduino, à chaqueprojet correspond un dossier. Tu vas donc rapidement avoir desdizaines de dossiers les uns à la suite des autres, ce qui est peuconfortable.
Voilà pourquoi je te conseille de créer immédiatement dans tondossierDocuments/Arduinounpremiersous-dossierauqueltudonneras le nom que tu veux, mais en évitant les espaces et leslettresaccentuées.Parexemple:ArduiTonyouGeekBosssontok,maispasMesprojetsd’été.
Puisque tu envisages sérieusement de devenir un maître desmachines, prends dès le départ l’excellente habitude de ne pasutiliser d’espace dans les noms de tes dossiers et de tes fichiers.C’est peut-être un peu gênant au début si tu n’en avais pas prisl’habitude, mais tu me remercieras lorsque tu auras besoin detravaillerenmode textedansun terminal,ceque je te souhaiteun
jour.
Pour simuler l’espace, il suffit d’utiliser le caractère desoulignement ouunderscore (le fameux « tiret_du_huit » sur leclavier) en remplacement de chaque espace. Le résultat visuelressembleàcequeceladonneraitavecdesespaces,commedanscetexemple:
Montrèslongnomdedossier
Voicilemêmesansespaces,niaccents:
mon_tres_long_nom_de_dossier
Nousenavonsfiniaveclespréparatifs.Enavantpournotrepremierprogramme.
Découvronslemoniteurdel’atelier
Certainsprétendentquelaprogrammationinformatiquen’estpasuntravail, mais un art. Il est vrai que la création d’un programmecommence en général par une inspiration, et se poursuit avecbeaucoupde transpirationmentale. Il faut avancer étapepar étape,parfois un peu rebrousser chemin, et tout cela en observantcommentsecomporteleprogramme.
Maispour savoir cequi sepassedans lapetitepucedumikon (lemicrocontrôleur, je le rappelle), il fautdisposerd’unmoyenpourque cemikon renvoie des informations vers l’atelier.C’est à celaquesertleMoniteursérie.
LeMoniteursérieestunesecondefenêtrequiapparaîtàcôtédelafenêtreprincipaledel’atelier.Découvrons-la.
1. Pourdémarrerl’atelierArduino,cliquesonicônequise
trouvesurtonbureau,dansledossierdesapplications
oudanslemenugénéral(selonlesystèmedonttu
disposes).
2. Lorsqu’ildémarre,l’atelierrechargetoujourstousles
fichiersquiétaientouvertsaumomentoùtul’asquitté
ladernièrefois.Siplusieursfenêtressontapparues,
referme-lestoutessaufune.(Quandturefermesla
dernièrefenêtre,celafaitquitterl’atelier.)
3. PourouvrirlafenêtreduMoniteursérie,tupeux
cliquerl’icôneduborddroitenhaut,cellequi
représenteunesortedeloupeavecunpointaucentre,
oubienutiliserlacommandeOutils/Moniteursérie
(Figure3.4).L’endroitesttoutàfaitlogique,puisquece
moniteurvadevenirundetesoutilsdetravailpourla
miseaupointdetesprojets.
Figure3.4:CommandeeticônepourouvrirlafenêtreduMoniteursérie.
4. Normalement,tun’aspasencoreconnectélacarte
ArduinovialecâbleUSB.Autrementdit,sitouts’est
bienpassé,celas’estmalpassé.Eneffet,lorsquetu
demandesl’ouverturedelafenêtreduMoniteursérie
etqu’iln’yaaucunecarteArduinodétectée,un
messaged’erreurapparaîtdanslepanneauinférieur,
commequoi«LacartesurCOMxn’estpasdisponible»
(Figure3.5).
Figure3.5:LeMoniteursérieabesoindedétecterlacarteArduino!
Autrementdit,ilneresteplusqu’àbrancherlacarte
avantd’essayerànouveaud’ouvrirlafenêtredu
moniteur.
5. VérifiequetacarteArduinon’estpasposéesur
quelquechosedemétallique,puismets-lasoustension
enbranchantlecâbleUSB.
6. Essaieànouveaud’ouvrirlafenêtredumoniteurparle
menuouparl’icône.Cettefois-ci,elledevrait
apparaître.
7. Repositionnelesdeuxfenêtresdel’atelierpourqu’elles
soientbienvisiblestoutesdeuxenpermanence.
Figure3.6:FenêtreduMoniteursérieàdroitedelafenêtreprincipaledel’atelier.
Tuesmaintenantprêtàutilisercetoutil.
Chargementd’unprogrammeUnpointtrèsimportantconcernantleMoniteursérie:dansl’angleinférieur droit de la fenêtre du moniteur, tu vois deux listes desélection.Celle de droite contient une valeur numérique expriméedansl’unitéBaud.Cettevaleuresttrèsimportante(Figure3.7).
Si,danstonprogramme,tuinsèresuneinstructionpourconfigurerlemoniteuravecuneautrevaleurquecelle indiquée ici,cequivas’afficher n’aura aucun sens. Prends donc toujours l’habitude devérifiercequisélectionnédanscetteliste.
Figure3.7:Listedesélectiondelavitessedecommunication.
Chargementducodesourced’unprogramme1. Danslafenêtreprincipaledel’atelier,ouvrelemenu
FichieretchoisisOuvrir.
2. Uneboîtestandarddesélectiondefichiersapparaît.
Utiliselespossibilitésdetonsystèmepournaviguer
parmilesdossiersafind’atteindreceluidanslequel
nousavonsimplantétouslesfichiersd’exemples,
normalementunsous-dossierde
Documents/Arduino.
3. Cherchelesous-dossiernomméP1(Figure3.8).Dans
cesous-dossier,tudoistrouverunautredossier
portantlenomP11_MaTempera.Ouvre-le.
Figure3.8:Ledossierdupremierexemple.
4. Tuvoisalorsunseulfichierportantlemêmenomque
ledossierquilecontient.Ilenvatoujoursainsiavec
l’atelierArduino.Chaqueprojetestrangédecette
manière.
Lefichierestletextesourceduprojet.Ilseprésenteau
formatINO(extensiondenomdefichier.ino).Ilest
possiblequelesextensionsnesoientpasvisiblesdans
leparamétragedetamachine.Jeteconseillefortement
delesrendrevisibles.
Pourafficherlesextensions,ilfautaccéderauxoptions
del’Explorateurdefichiers.Parexemple,sous
Windows10,ilfautouvrirlemenuAffichageetcliquer
Optionssurleborddroit.Danslaboîtededialoguedes
optionsdesdossiers,choisisladeuxièmepage,
Affichage.Danslalistedesoptions,descendsunpeu
grâceàl’ascenseuràdroitejusqu’àtrouverl’option
intituléeainsi:
Masquerlesextensionsdesfichiersdontletype
estconnu.
Activecetteoptionencliquantlacase.Refermeensuite
laboîte.
5 Ilsuffitdesélectionnerl’uniquefichierpuisdecliquer
leboutonOuvrirenbasàdroite.Tupeuxaussi
directementdouble-cliquerdanslenomdefichierou
sonicône.
PassageenrevueducodesourceTudoismaintenantavoirdeuxfenêtresd’éditionouvertes:cellequiestapparuequandtuasdémarréleprogramme(l’embryon)etcellequicontientlenouveaufichierquenousvenonsdecharger.
Situcompareslescontenusdesfenêtres,tudoispouvoirdistinguerdeuxlignesidentiques:
voidsetup()
{
voidloop();
{
Ne prends pas peur en découvrant le contenu du programmed’exemple.Nousn’allonsparledécortiquer,nimaintenant,niplustard.Contente-toiderepérerlesdeuxlignesdontjeviensdeparler.Tuvas les trouververs ledébutducontenu.Cesont lesnomsdesdeux fonctions qui doivent toujours être présentes dans un projetArduino,danstouslescas.Nousverronsdanslechapitresuivantàquoiserventceslignes.
Je t’accorde volontiers que nous démarrons sur les chapeaux deroue.Eneffet,cepremierprogrammecontientdestechniquesquelaplupart des passionnés de l’Arduino ne découvrent que bien plustard,etcertainsjamais.
Mais ici, il s’agit d’un livre consacré à la programmation et nonsimplementaubranchementd’uncapteuroud’unmoteursuividelarécupération d’un programme déjà écrit par quelqu’un d’autre.Donc,onbombeletorse,etenavant!
VérificationetcompilationPour faire bonnemesure, nous allons lancer une vérification, quidoitnormalementsedéroulersanserreur.Nous lançonsensuite leprogrammeenletransférantverslemikondelacarteArduino.
1. Tuvoislafenêtred’éditionetlafenêtredumoniteur?
Bien.Dansl’atelier,utiliselacommandeVérifier,soit
encliquantl’icônelaplusàgaucheenhaut,soiten
ouvrantlemenuCroquispuisenchoisissant
Vérifier/Compiler(Figure3.9).
Figure3.9:CommandesdumenuCroquispourvérifierettéléverserleprojet.
2. Observelapartieinférieure.Tuvoislacompilationen
cours.Unefoiscelle-ciréussie,deuxlignes
apparaissent(Figure3.10).
Lapremièreligneindiquel’occupationmémoiredu
codemachinequicorrespondàceprogrammesource.
Normalement,lavaleurestégaleà3536.J’indiquaisdanslepremierchapitrequelemikondel’ArduinoUno
possédaitunespacemémoireFlashpourles
programmes.CettemémoireFlashoffre32ko,
soit32768octets.Nousenavonsconsommé
presque10%.
Figure3.10:Messagesdecompilationréussie.
Utilisesinécessaireletranslateur(ascenseur
horizontal)souslepanneauinférieurpourvoirlafindu
message.
Ladeuxièmeligneparledevariablesglobales.Tiens,
nousn’avonspasencorevucequ’étaitunevariable
globale(nipasglobaled’ailleurs).Cesontles
emplacementsmémoiredontleprogrammeabesoin
pourstockerlesvaleursqu’ilmanipule.Ici,nousen
consommons214octets.
3. Silacompilationréussit,l’imageexécutabledu
programmeestcopiéeverslamémoiredumikonsurla
carte,puisleprogrammedémarreimmédiatement.
DanslafenêtreduMoniteursérie,latempérature
indiquéedoitsesituerversles21oC(Figure3.11).Situ
viensdedémarrerlacarteArduino,c’estàpeuprèsla
températuredelapièce.Notecependantquelemikon
n’estpasunthermomètre.Nousinterrogeonsun
capteurinternequipermetd’éviteraumikond’être
détruitparunetropfortechaleur.Ilnepeutpasservir
dethermomètre.
Figure3.11:AffichagedelatempératuredumikondansleMoniteursérie.
4. NotequeleMoniteursériecontinueàaffichertoujours
lamêmetempératureavecparfoisquelquespetits
sauts.
Voyonssinouspouvonsinfluencerphysiquementla
températuredumikon.
5. Sanshésiter,poseundoigt(nonmouillé!)outon
poucesurleboîtiernoirdumicronetappuie
légèrementpourtransmettreunpeudechaleurdeton
corps.ObservebienleMoniteursérie.Tudevraisvoir
monterlatempérature.Changeéventuellementde
doigtpourtransmettreencoreplusdechaleur.
Enappuyantsuffisamment,maissansforcer,tudois
pouvoirfairemonterlatempératured’unoudedeux
degrésenviron(Figure3.12).Observel’affichagedu
Moniteursérie.
Figure3.12:Faisonschaufferlabête!
6. RetienssinécessairelacarteparsoncâbleUSBet
soufflesurlemikonpourlerefroidir(sanspostillonner
dessus,sipossible).Normalement,tudoispouvoirfaire
redescendrelatempératuredumikon.Ilréagitdonc
bienàtaprésence.
Aveccepetitexemplepratique,tuesentréencontactphysiqueavecton mikon. Partons maintenant à la découverte du langage aveclequeltuvascréerlapenséed‘Arduino.
RécapitulonsDanscechapitre,nousavonsapprisà:
» téléchargerlesfichiersd’exemples;
» ouvrirlafenêtreduMoniteursérie;
» chargerunprogramme;
» vérifierettéléverserunprogramme;
» lireetmodifierlatempératureinternedumikon.
IISemaine2:Parleretécouterlemonde
Aumenudecettesemaine:
Chapitre4:Àl'écoutedumondeennoiretblanc?
Chapitre5:Àl’écoutedumonderéel
Chapitre6:Parler,c’estagir
Chapitre7:Donneruneimpulsion
L
Chapitre4Àl’écoutedumondeennoiretblanc
AUMENUDECECHAPITRE:
» L’artd’écrireuntextesource
» Détecterl’étatd’uneentréenumérique
» AfficherunevaleurdansleMoniteursérie
» ÉviterlesflottementsavecPULLUP
eWebadémarrédefaçonexpérimentaleen1994pourcequiestdes pays francophones. Comme sur toute terre inconnue, il afalluapprendresurletas.Lasurpriseaétéaurendez-vous.
Nous atteignons ici un grandmoment dans le cours de ce livre :nous allons apprendre en détail à écrire un texte pour animer unmicrocontrôleur.
Partird’unefeuilleblanche(oupresque)
Pour l’instant, nous n’aurons pas besoin de la carte Arduino.Débranche-lasinécessaire.
1. Démarrel’ateliercommetuasapprisàlefaireau
coursduchapitreprécédent,enutilisantl’icôneoule
nomdel’applicationdanslemenu.
Lorsquelafenêtred’éditiondel’atelierapparaît,ilest
possiblequ’elleprésenteledernierprojetsurlequeltu
astravaillé.Cen’estqu’aupremierdémarragequetu
voisapparaîtredirectementlefichierquasividequisert
depointdedépart.
2. OuvrelemenuFichierpourchoisirlacommande
Nouveau.
Tuvoisapparaîtreunesecondefenêtred’édition.C’est
cellequinousintéresse.
3. Refermelapremièrefenêtrequiestapparueau
démarrage(saufsic’esttonpremierdémarrage).
UtiliselacommandeFichier/Fermerdelafenêtreà
fermeroulacasedefermeturehabituelle(enhautà
droiteouàgauche).
Figure4.1:Étatinitialdel’éditeuraudémarraged’unnouveauprojet.
Si tucompares lerésultatàcequel’ona l’habitudedevoirquandon commence avec un nouveau fichier, par exemple dans untraitementdetexte,tupeuxt’étonnerdevoirquelafenêtren’estpasvide.Pourquoi?
La réponsedemandedepasser auxprésentations.Le langagedanslequel tu écris tes projets Arduino est une variante d’un deslangageslesplusrépandusdanslemondeentier,lelangageC.
LelangageC?
LelangageCestunesortedepatriarchedanslesinfo-langages.Il
a eu une nombreuse descendance, et notamment les langages
C++,JavaetC#.Créédanslesannées1970,lelangageCatrouvé
unbeléquilibreentredeuxbesoinsopposés : celuide travailler
vite enne seperdantpasdans lesdétails, et celui de contrôler
précisément lapartiematérielleenentrant justementdanstous
lesdétails.
Ce que tu vois dans la fenêtre de l’éditeur est un embryon deprogramme, en anglais un stub. Il contient deux définitions defonctions,cesdeuxfonctionsdevantêtreprésentesdanstoutprojetArduino.Voyonsceladansunlisting.
Listing4.1:L’embryondeprogrammeArduino.
voidsetup(){
//Iciviennentlesinstructionsde
préparation
}
voidloop(){
//Icicellesqu'ilfautrépéter
}
Quevoit-onaujuste?
» Ilyadeuxlignesquicommencentparunmotanglais,
void,quisignifie«vide»,etsepoursuiventavecun
nomsuivid’unepairedeparenthèsesetd’une
accoladeouvrante.
» Ilyadeuxlignesquicommencentparundoublesigne
/.Ceslignessonttotalementignoréesparla
vérificationetlacompilation.Ellesneserventqu’à
l’auteurduprogrammeetàsescollègues.
» Et,enfin,deuxlignesquinecontiennentqu’une
accoladefermante.
Tu devines déjà que les signes de ponctuation vont avoir uneénorme importance. Par exemple, les accolades doivent toujoursallerpardeux.S’ilyenauneouvrante,ilfautquelquepartquel’ontrouvelafermantequiluicorrespond.
SavoirfaireblocEnlangageC,lesaccoladesserventàmarquerledébutetlafind’unbloc autonome.Toutes les lignes d’instructions qui seront placéesentre les deux accolades seront exécutées de la première à ladernière, mais l’exécution ne se poursuivra pas toujours après lafermante.
La lecture normale d’un programme ressemble à celle d’un textehumain:oncommenceparledébutetondescenddeligneenlignejusqu’à la fin.Avecun jeud’accolades,cette lectureest limitéeaudébutetàlafindubloc.Pourl’instant,lesdeuxblocsdel’embryonsontvides.Leslignesdecommentaires(enanglaisdansl’original)n’existentpaspourlemikon.Vérifionscela.
Miseenpratique:premièrevérificationLa commande Vérifier est utilisable même lorsque la carteArduino n’est pas connectée (mais pas la suivante, Téléverser).Nousallonsprofiterdecettepossibilité.
1. UtiliseleboutonVérifieretobservelepanneau
inférieurdel’éditeur.
Auboutdequelquesinstants,tudoisvoirapparaître
lesdeuxmessagesdefindevérificationquirappellent
l’espaceoccupéparlesinstructionsduprogrammeet
celuioccupéparlesvariablesglobales.
Enfait,danscetétat,leprojetnefaitabsolumentrien,
maisilestvalableetacceptéparlevérificateur.Nous
pourrionsdoncmêmelecompileretletéléverserdans
lacarteArduino,quines’enplaindraitpas.Simplement,
leprogrammetourneraitenbouclesansrienfaire.
Le fait que les deux fonctions soient totalement vides n’a aucunrapport avec la présencedumotqui signifie «vide» endébut deligne(void).
Àquoisertunefonction?Une fonction, c’est quelque chose qui fonctionne, qui réalise uncertain travail. En informatique, ce travail est appliqué à desdonnées. Le nom « fonction » provient au départ du monde desmathématiques.Enmathématiques,unefonctionpeuts’écrirede lafaçonsuivante:
F(x)=x+2
Dans cet exemple, la fonction qui porte le nom F effectue untraitementquiconsisteàmultiplierlavaleurpardeux.Sionutilisecette fonction avec la valeur 4 pour la variable x, la fonctionvaudra6.
D’ailleurs,lecoupledeparenthèsesquisuitimmédiatementlesdeuxmotssetupetlooptémoignedecethéritage. Ici,cecoupleestvide,maisdanstesprojets,tuindiquerasentrelesdeuxparenthèsesle nom d’une ou de plusieurs variables qui vont contenir desvaleurs;lafonctionvatravaillersurcesvaleurs.
En informatique, la notion de fonction est plus vaste qu’enmathématiques. Tu pourras créer des fonctions qui n’auront pasbesoin de renvoyer le résultat de leur travail. Pour les deuxfonctionsobligatoires,c’estlecas,etcelaexpliquelemotvoid.
Par exemple, imaginons une fonction que nous décidons denommercontrolerMoteur() (tunotesque jen’utilisepasdelettres accentuées dans les noms des fonctions,même en français,carc’estinterdit).
Cettefonctionpourra,parexemple,démarreretarrêterunmoteurélectrique. Pour te servir de la fonction, tu vas indiquer son nomailleursdansleprogramme,c’est-à-direappelerlafonction.
Appelerunefonction,c’estdemandersonexécutionimmédiate.
Tucomprendsdoncquetoutprogrammedoitconteniraumoinsunefonction. Dans le langage C normalisé, cette fonction obligatoireporte le nom anglais qui signifie « principal », c’est-à-diremain().DanslavarianteArduino,ilaétéchoisideprévoirdèsledépart non pas une, mais deux fonctions. En quoi se distinguent-elles?
Lesdeuxfonctionssetup()etloop()Toutprojetdemandenormalementquelquespréparatifs,commelechoixdumoded’utilisationd’unebroche,enentréeouensortie,leréglaged’unevitessededialogueavecunordinateur,lapréparationd’une variable, etc. Cette étape de configuration ne doit pardéfinition être réalisée qu’une seule fois au démarrage duprogramme. Et le mot anglais pour configurer est setup. Voilàpourlapremièredesdeuxfonctions.
Une fois les préparatifs terminés, il reste plus qu’à se mettre autravail!C’estàceniveauqu’ilyauneénormedifférenceentredes
projetspourunmicrocontrôleur,telqueceluidelacarteArduino,etlesapplicationspourlesplusgrandsordinateurs.
Le mikon de ta carte ne peut par définition exécuter qu’un seulprogrammeàlafoisetill’exécutesansjamaiss’arrêter.Iln’yapasdecommandeQuitterdansunprojetArduino.C’estcequiexpliquele nomchoisi pour la deuxième fonction obligatoire : en anglais,loopsignifie«boucle».Touteslesinstructionsquetuvasajouterentrelesdeuxaccoladesdublocdecettefonctionserontexécutéesde la première à la dernière, puis à nouveau de la première à ladernière, et ainsi de suite jusqu’à ce que tu coupes l’alimentationélectriquedelacarteouquetuutilisesleboutonderéinitialisationReset.
Àl’intérieurdelafonctionloop(),tupeuxnonseulementinsérerdesinstructions,parexemplepouradditionnerdeuxnombres,maistuvas surtoutpouvoiryplacerdesappelsversd’autres fonctions.C’estàpartirdecettepossibilitéquesedéploietoutelapuissancedelaprogrammationinformatique.
Jet’accordequelesprécédentsparagraphesontétéasseztouffus,etjeteproposeunpeudemiseenpratiqueenguisederécréation.
Miseenpratique:allègementducodesource1. Pourl’instant,leprojetporteunnomautomatique,
peusuggestif:lemotsketch,unsigne_etledébutdu
nomdujouretsonnuméro.
Choisisunjolinompourceprojet,parexemple
CH04_Digit1.
2. Cliquedanslalignedecommentairesquiconstituele
corpsdublocdelapremièrefonctionetsupprime
toutecetteligne.
Unepremièresolutionconsisteàtriple-cliquerdansla
lignepuisutiliserlatoucheSuppr.Tupeuxégalement
teplacercontrelamargegaucheetsélectionnerpar
glissement.
3. Faislamêmechosepoursupprimerlalignede
commentairesdanslafonctionprincipaleloop().
Figure4.2:L’embryondeprogrammeallégé.
4. Lanceunevérificationcommetusaislefaire
maintenant.Ilnedevraityavoiraucunedifférencedans
lerésultat.
5. Essayonsmaintenantdejoueravecundélimiteurde
bloc.Place-toijusteàdroitedelapremièreaccoladeet
supprime-laaveclatoucheRetourarrière(ouutilise
uneautretechniquepoursupprimercecaractère).
Dèsquetumodifiesl’embryon,tuesobligédestocker
letextesourcedansunfichiersurdisque.
6. Lanceunenouvellevérificationqui,sitoutvabien,
devraitmalsepasser.
Situobserveslepanneauinférieur,tudoisvoirdes
messagesenorange.Lecompilateurseplaintparce
qu’ilestperdu.Lasimpleabsenced’uneaccolade
dérègletoutelastructureduprogramme.
7. Replacel’accoladelàoùelleétait,cequitepermetde
prendretesrepèressurleclavier.
Maisoùsontlesaccolades?C’estsimple:
» SousWindows,ilfautcombinerlatoucheAltGravec
lestouchesdudessus’4ou=+,commesousLinux.
» SousMacOS,ilfaututiliserlestroistouchesAlt,Maj
etlabonneparenthèse.
Nous en savons assezpour nous lancer dansnotre premier projetpratique.
Projet1:détectionsuruneentréenumérique
Commeunanimal,unprocesseurs’inscritdanssonenvironnement.Iladesorganesdessenspoursavoircequisepasseautourdelui;il a des nerfs moteurs pour agir sur son environnement.Intéressons-nousd’abordàsesorganesdessens,sesnerfssensitifs.Enlangageinformatique,celacorrespondàsesentrées(inputs).
Nous allons commencer en douceur en observant ce qui se passesurunebroched’entréenumériquedumikon.Tuasapprisdansleschapitres antérieurs que le processeur de la carte Arduino Unopossède14brochesnumériquesquipeuventservirenentréecommeensortie.Nousallonsbranchersurunedecesbrochesunsimplefilmuni de broches mâles, ce que l’on appelle un strap. Il servirad’antennepourquelavaleurluevariedefaçonimprévisible.
Onnepeutpasfaireplussimplequecepremierprojet,maiscelanenousempêchepasdeprendredès ledépartdebonneshabitudes. Ilfaut commencer par une analyse théorique, pour définir lescontoursdecequ’onappelleunalgorithme.Tuvasvoirquec’esttrèsfacile.
AnalysethéoriquedelasolutionLe problème à résoudre est très simple : nous devons pouvoirdétecter le passage de l’entrée numérique de l’état 0 ou à l’état 1.Nous allons donc demander aumikon de lire de façon répétée lavaleur qu’il trouve sur la broche d’entrée numérique que nousallonsluiindiquer.
Mais comme les broches numériques peuvent servir en entréecomme en sortie, il faut d’abord lui dire que nous avons décidéd’utiliserlabrochechoisiecommeentrée,etnoncommesortie.
LaFigure4.3montre la logiquedenotreprojet dans sapremièreversion.
Figure4.3:Solutionduproblèmedelectured’uneentréenumérique.
L’innéetl’acquisLe mikon possède dès le départ un certain nombre de fonctionsinternes,dontunefonctionpourlirel’étatd’unebrochenumériquevers un registre, et une autre pour copier la valeur depuis ceregistreversunemplacementdanslamémoire.Cesfonctionssontdites natives : ce sont des instructions machine, gravées à toutjamais dans lamatière de la puce. Elles sont très élémentaires, etcelanousprendraitbeaucoupdetempsd’écriretouslesdétailsdesopérationsrequisesuniquementavecelles.
Eneffet,avantdeprocéderàlalecture,ilfautpréparerleportpuisle mikon lui-même et réaliser différentes opérations dans lesmémoiresinternesdumikonpouraboutiraurésultat.
Le jeu d’instructions d’unmicrocontrôleur correspond à la partieinnée, la même qui permet à un bébé animal de se lever dès lanaissance, sans avoir encore acquis aucun savoir du mondeextérieur.
Chacun des projets que tu vas créer correspondra à l’acquis dumikon,cequetuvasluiapprendreàfaire.Entrecesdeuxextrêmes(l’innéetl’acquis),ilyatoutunmondeintermédiairequiestceluides fonctions prédéfinies. Elles ont été conçues par d’autrespersonnes. Tu peux en profiter directement. Pas besoin de lesécrire;celateferagagnerénormémentdetemps.
Nousallonsutiliserdanstoutcelivredenombreusesfonctionsditesprédéfinies. Ces fonctions sont regroupées par thèmes dans desconteneurs que l’on appelle des librairies (anciennementbibliothèques).Ilyaainsiunelibrairiepourémettredessons,uneautrepourpiloteruncircuitGPS,etc.
Pourêtreencoreplusprécis,ilyaunnoyaud’environ60fonctionsqui sont installées dès le départ en même temps que l’atelierArduino. Les autres devront être téléchargées et installées enfonctiondetesbesoins.
Passons à la pratique en utilisant deux premières fonctionsprédéfinies : lapremièrevapréparer lemikonàutiliser labrochechoisiecommeentréenumérique,etlasecondevalirelavaleurquisetrouveàcemomentsurlabroche.
Les noms des fonctions prédéfinies sont quasiment toujours enanglais.Cellesdontnousallonsavoirbesoinsontlessuivantes:
pinMode()
digitalRead()
LafonctionpinMode()
La fonction standard qui permet de choisir le mode d’utilisationd’une broche (pin en anglais), pinMode(), a besoin, pourtravailler correctement, qu’on lui transmette deux valeurs audémarrage,c’est-à-diredeuxparamètresd’entrée:
» lenumérodelabrocheconcernée,icilabroche
numéro7;
» unmotréservéindiquantlemoded’utilisation,soit
INPUT,soitOUTPUT(avecdesvariantesquenous
verronsplustard).Ici,ceseraINPUT.
Puisque le réglagedumoden’abesoind’être réaliséqu’uneseulefoisaudébut,nousallonsajoutercettepremièreinstructiondanslebloc (le corps) de la première des deux fonctions obligatoires,c’est-à-diresetup().
1. Dansl’éditeurArduino,cliqueentrelesdeux
accolades,etinsères’illefautunelignevideavecla
toucheEntrée.Tuesdanslecorpsdelapremière
fonction.
2. Saisislasuitedecaractèressuivante,sansenomettre
unseul.Turemarqueslesdeuxespacesaudébut,sans
douteinséréesd’officeparl’éditeur:
pinMode(7,INPUT);
3. Procèdedelamêmefaçondanslecorpsvidede
l’autrefonctionobligatoire,loop(),ensaisissant
exactementl’instructionsuivante.Entreparenthèses,
c’estlenumérodelabroched’entréequelafonction
doitlire:
digitalRead(7);
4. Prendsmaintenantquelquesinstantspourrelirele
contenudetontextesource.Ildoitcorrespondre
exactementaulistingsuivant.
Tupeuxstockerlanouvelleversionsousunnouveau
nom.Ellecorrespondàl’exempleCH04_Digit2.
Listing4.2:DeuxièmeversionduprojetDigit(CH04_Digit2)
voidsetup(){
pinMode(7,INPUT);
}
voidloop(){
digitalRead(7);
}
PréparationdumontagephysiqueNotre programme est prêt à être testé, mais la carte Arduino pasencore.
1. ObservebientacarteArduino.Repèreleconnecteur
noirduhaut,celuimarquéDIGITAL(PWM).Ilesten
deuxparties:numéros0à7puisnuméros8à13(ainsi
quequelquesbrochessansintérêtpourl’instant,sauf
GND).
2. Sansencorebrancherlacarteàl’ordinateur,insèreun
strapdequelquescentimètresdelongdanslabroche
numériquenuméro7.Aide-toidelaphotoenFigure4.4.
Figure4.4:Branchementd’unstrapsurlabrochenumérique.
3. Vérifiequelabrocheestbienenfoncéeetquelebout
librenetoucheriendemétallique,nisurlacarte,nilà
oùtul’asposée(Figure4.5).Nousauronsbesoinde
repositionnerceboutlibrepourfairevarierlavaleur
lue.
Figure4.5:Leboutlibredustrapdoitpendredanslevide.
4. BranchelecâbleUSBsurl’ordinateur.
TestduprojetNouspouvonsmaintenant téléverser leprojetdans lamémoireduprogrammedumikonsurlacarte.
1. Commenceparunderniercontrôleaumoyendela
commandeVérifier.Leprogrammedoitsecompiler
correctement.
S’ilyaunproblème,relisletextesourceenle
comparantaucontenudulistingprécédent.
2. UtilisemaintenantlacommandeTéléverserpour
transférerlecodebinairerésultantdecetextesource
danslemikonetenlancerl’exécution.
Quesepasse-t-il?Ilnesepasseriendutout.Pourtant,
jet’assurequeleprogrammefonctionneetquele
processeurn’arrêtepasdelirelavaleurqu’iltrouvesur
labrocheàlaquellenousavonsreliélestrap.Quefaut-
ilfaire?
Ilnousfautrécupérerlavaleurlueendonnantunnom
àunecasedanslamémoire,casedanslaquellenous
allonsentreposercettevaleur.Enfait,nousallonscréer
notrepremièrevariable.
Maisauparavant,unpetitretoursurlesfonctions.
ÀproposdesnomsdesfonctionsNous venons de saisir deux noms de fonctions, pinMode() etdigitalRead().Quelquesremarques:
» Toutd’abord,iln’yajamaisd’espacedansunnom(on
parleaussisouventd’identifiantaulieudenom).
» Deuxièmement,tuconstatesquel’onutiliseune
manièred’écrireassezoriginaledanslesnoms,c’est
l’écritureendosdechameau(oudroMaDaire).Lenom
commencetoujoursparuneminuscule,maislesmots
accoléscommencentchacunparunecapitalepouren
faciliterlalecture:pinMode()estlaréuniondesdeux
motsanglaisinput(entrée)etmode.Demême,
digitalRead()estl’uniondumotdigital(envrai
français,ondevraitd’ailleursdire«numérique»)et
readquiestleverbe«lire».
En écrivant un tel mot suivi entre parenthèses des noms desvariablesd’entrée,tudemandesd’exécuterlesinstructionsducorpsde la fonction. Tu ne vois pas ces instructions. La fonction peutcontenir des dizaines ou des centaines d’instructions. Cela te faitgagner un temps énorme, en profitant du travail des autresprogrammeurs.
NotrepremièrevariableUne variable est un nom, mais à la différence de celui d’unefonction, qui provoque une action, le nom d’une variable sert àrangeretàretrouverunevaleur,unedonnée,danslamémoiredesdonnéesdumikon.Nousavonsvudansunchapitreantérieurquelescartes telles que Arduino possèdent une très petite quantité demémoire pour les données. Par exemple, il n’y a que2048octetsdisponiblesdanslemikonATmega328quiéquipelaArduinoUno.Autrementdit,ilnefautjamaisréserverplusd’espacemémoirequenécessairepourstockertesvariables.
C’est pour cela qu’il existe des mots réservés dans le langageArduino, le langage C, pour décider de la quantité d’espacemémoire qu’il faut réserver au stockage de chaque donnée duprogramme.Dans le cas de l’entrée numérique, il n’y a que deuxpossibilités pour la valeur : soit 0, soit 1 (c’est-à-dire soit 0 volt,soit5volts).Le langageCoffreunedizainede taillesdifférentes,quel’onappelledestypesdedonnées.Pournotreprojet,lepluspetittesuffira;ilportelenomboolean.
Commedans les hôtels, avant de pouvoir y dormir, il vautmieuxréserver.EnlangageC,avantdepouvoirstockerunevaleur,ilfaut
réserverl’espace,cequicorrespondàlaphasededéclarationdelavariable.
Voici comment va s’écrire la déclaration de notre premièrevariable:
booleanbValeur;
Maisoùplacercettenouvelle ligne?Dans lapremièreoudans ladeuxièmefonction?Réponse:nidansl’une,nidansl’autre.Nousallonsdéclarer lavariableaudébutdenotre texte source,avant lemotvoiddelapremièrefonctionobligatoire.
En déclarant notre variable à cet endroit, nous en faisons unevariable globale. C’est tout simplement une variable que l’onpourralireetécriredepuisn’importequelendroitduprogramme,doncdepuisl’intérieurden’importequelblocdefonction.Ilnefautpas le faire pour toutes les variables,mais c’est plus simple pourl’instant.
Déclarerlavariablepourréserverdel’espacemémoire,c’estbien,mais le but est tout de même de l’utiliser. Comment faire pourstockeràl’emplacementsymboliséparcettevariablelavaleurquel’on va lire dans la boucle au moyen de la fonctiondigitalRead()?
Souviens-toidelafonctionmathématiquedont j’aiparléplushaut.Lorsqu’unevariablexvaut6,lafonctionf(x)vaut8.Ilenvademêmepourlesfonctionsquirenvoientunevaleur,cequiestlecasdedigitalRead().Quandtuappellescettefonctionenécrivantson nom avec le numéro de la broche qu’elle doit lire, elle vaexécuter toute une ribambelle d’instructions élémentaires puisrenvoyer la valeur à l’endroit où se trouve le nom.C’est grâce àcettemagie que nous pouvons écrire une instruction d’affectationquiconsisteàcopierunevaleurdansunevariable,commececi:
monNomDeVariable=nomFonction(paramètre);
Mettonscelaenpratiqueimmédiatement.
1. Poselecurseurclignotantàgaucheduvdupremier
motvoidduprogrammeetappuiedeuxfoissurla
toucheEntréepourinsérerdeuxlignes.
2. AveclaflècheHautducurseur,remonteàlatoute
premièreligne,puisinsèrel’instructiondedéclaration
suivante:
booleanbValeur;
3. DescendsmaintenantaveclaflècheBasetlesflèches
GaucheetDroite(pluspratiquequ’aveclasouris)
jusqu’àteplaceràgauchedunomdelafonction
digitalRead(7).
4. Insèreàcetendroitlenomdelavariablequenous
avonsdéclarée,uneespace,unsigneégaleetuneautre
espace.
Tudoisobtenirlemêmerésultatquedanslelisting
suivant.
Listing4.3:Ajoutd’unevariable(CH04_Digit3)
/*ARDUIPROG_KIDZ
*CH04A_Digit3.ino
*OEN1703
*/
booleanbValeur;
voidsetup(){
pinMode(7,INPUT);
}
voidloop(){
bValeur=digitalRead(7);
}
5. Contrôletasaisiepuislanceunevérification.
6. Téléversetanouvelleversionduprogrammesurla
carte.
Queremarques-tu?Riendeplusquedanslaversion
précédente.Pourtant,dorénavant,lavaleurrenvoyée
parlafonctiondelectureestbiencopiéedansnotre
variable,etellesetrouvedoncdanslamémoiredes
variables.Ilnousmanquequelquechose.
Leproblèmeestquenoussommesàl’extérieurdumikon,etnousn’avonspasaccèsàtoutcequisepassedanscecarréde3mm.Pourlesavoir,nousallonsutiliserl’outildéjàrencontrédanslechapitreprécédent,quipermetdedemanderaumikondenousrenvoyerdesvaleurs.Nous allons nous en servir pour faire renvoyer la valeurlueafinqu’ellesoitaffichéedansleMoniteursérie.
AffichonslavaleurdansleMoniteursérieL’outilMoniteursériefaitpartiedel’atelierArduino,commetulesais.Pourpouvoirl’utiliserdepuistonprogramme,ilfautd’abordeffectuer un réglage de la vitesse à laquelle les données vonttransiterentrelacarteetlafenêtredumoniteur.
Comme pour le choix du mode d’utilisation de la brochenumérique,nousallonsajouterunappelàunefonctionquinedoit
être réalisé qu’une fois. Cet appel va donc être inséré dans lapremière des deux fonctions obligatoires,setup(). La fonctionquenousallonsajouterestd’unnouveaustyle.Voicicommentdoits’écrirel’appelàcettefonction:
Serial.begin(9600);
Turemarquesd’abordlepointdanslenom.C’estnouveau.Enfait,lenomSerial(quiDOITcommencerparunSmajuscule)estlenomd’unobjet.Oui, toutà fait, tu faisdéjàde laprogrammationorientée objets (un enrichissement du langage C nommé C++) !Maispastropvite.Nousreviendronssurlesobjetsplustard.
Pour l’instant, sache qu’un objet est quelque chose d’encore plusévoluéqu’unesimplefonction.Unobjet«possède»desfonctionsetdesvariables.Pourfaireexécuterunefonctionquiappartientàunobjet,ondoitindiquerd’abordlenomdel’objetpropriétaire,puisunpoint,etlenomdelafonction.
Ici,lafonctionportelenombegin(),quiveutdire«débuter».Ilfaut fournir un seul paramètre numérique, qui est la vitesse decommunication,choisiparmilesvaleursquisontproposéesdanslaliste de sélection du coin inférieur droit du moniteur (revois sinécessairelechapitreprécédent).
Il y a une seconde fonction à utiliser, et c’est la plus importante :cellequivaenvoyer lavaleur luepar lemikonvers l’atelierpourquecelui-ciaffichelavaleurdansleMoniteursérie.
Cetteautrefonctiondel’objetSerialportelenomprintln(),cequisignifie«imprimerpuispasseràlalignesuivante»(lnveutdire«ligne»).Voicicomments’écritl’appel:
Serial.println(valeur);
Passonsàlapratique.
1. Danslafenêtredel’éditeur,cliqueàdroitedusigne
point-virguledelaseulefonctionquisetrouve
actuellementdanslecorpsdelapremièrefonction
obligatoiresetup()etappuiesurlatoucheEntrée
pourcréerunenouvellelignevide.
2. Turemarquesquelecurseurdesaisieest
automatiquementplacéàdeuxcolonnesdedécalage
parrapportàlamargegauche.Onappellecela
l’indentation.Lefaitd’indenteroupasn’aaucune
importancepourlecompilateur.Leprogrammesera
considérécommecorrectmêmesitunemetsaucun
espacedemargegauche.
Enrevanche,celafaitunegrossedifférencedelisibilité
dutextesource.Ilesttrèsimportantdevoiraisémentà
quelniveaututetrouvesdanslesimbrications.Tule
constateraspartoi-mêmedanslesprojetsplus
conséquentsdeschapitressuivants.
3. Saisismaintenantl’instructionsuivante:
Serial.begin(9600);
N’appuiepassurlatoucheEntrée,c’estinutileici.
4. Procèdedelamêmemanièreenteplaçantaprèsle
point-virguledelaseuleinstructiondel’autrefonction,
loop(),etappuiesurlatoucheEntréepuissaisisla
deuxièmenouvelleinstruction:
Serial.println(bValeur);
La nouvelle version du programme est maintenant complète.Commenceparvérifierqu’iln’yapasd’erreurdesaisieaumoyendelacommandeVérifier.
TestduprojetNousallonsenfinrecueillirlesfruitsdenosefforts.
1. Branchelacartesiellenel’estpasencore.
2. Dansl’atelier,utiliseleboutonMoniteursérieenhaut
àdroitepourouvrirlafenêtredumoniteur.
Lafenêtrerefusedes’ouvrirsilacarteArduinon’est
pasconnectéeetdétectée.
Vérifiebienquelefilvolantnetoucherienparson
extrémitélibre.
3. RepositionnesinécessairelafenêtreduMoniteursérie
pourqu’ellesoitvisibleàcôtédecelledutextesource.
4. Danslafenêtredumoniteur,vérifiesenbasàdroite
quelavitessededialogueestbienlamêmequecelle
quetudemandesdansl’instructionSerial.begin(),
soit9600.
Figure4.6:Vérificationdelavitessedetransmission.
Voicienfinlegrandmomentattendu.Utilisela
commandeTéléverserpourtransférertonprojeteten
lancerl’exécution.Tiens-toiprêtàbienobservercequi
vaapparaîtredanslafenêtreduMoniteursérie.
Figure4.7:Affichagedesvaleursnumériques.
Queconstates-tu?Tuvoisdéfilerdes0etdes1sans
cesse.C’esttoutàfaitnormal:lefilsertd’antenneet
récupèretouslesparasitesquitraînentdansl’air.
Danslemondemoderne,ilyadeplusenplusd’ondes
dansnotreenvironnement;cesontcesondesqui
donnentcetaffichageincohérent.
5. Prendsentredeuxdoigtsl’extrémitélibredustrapet
appuielabrochesurleboîtiermétalliquedelaprise
USB,puismaintiens-leappuyé.Observel’affichage
dansleMoniteursérie.Normalement,tunedoisvoir
quedes0.C’estparcequetuforceslavaleurd’entrée
à0V,carlapriseUSB,ouplutôtsonembase,estreliée
àlamasse,c’est-à-direà0V.
Dèsqueturelâchesl’appui,larondedes0et
des1reprend.
Avec ce strap qui pendouille, l’entrée est flottante, et le mikondétectedes0etdes1aufuretàmesuredesparasitescaptésparlefil. Pour certains capteurs, et notamment pour les interrupteurs, ilfaudraévitercetétatfluctuant.Maistoutaétéprévu.
Il suffit d’utiliser une variante dumot réservé qui sert à dire quenousvoulonsutiliserlabrocheenentrée.Eneffet,lemikonpossèdedespetitesrésistancesdébrayablesdanssescircuits.Enactivantunetelle résistance, on oblige l’entrée à être reliée au +5 V, sauflorsqu’on force le courant à rejoindre le 0V. Essayons celaimmédiatement.
Nousenprofitonspourdécouvriruneautrefonctionprédéfiniequisertàralentirunpeul’affichage.C’estunefonctiontrèssimplequise contente de faire patienter pendant le temps indiqué avant dereprendre la suite des opérations. La fonction se nomme fortlogiquementdelay().
Voicidonclesdeuxmodificationsquenousapportonsauprojet:
1. Dansletextesource,cliquejusteaprèslalettreTdu
motINPUTdanslafonctiondeconfiguration.
2. Ajoutealorssansespaceleslettressuivantes,en
commençantparlecaractèredesoulignement:
_PULLUP
Lerésultatdoitcorrespondreàl’instructionsuivante:
pinMode(7,INPUT_PULLUP);
3. Pourralentirunpeul’affichage,nousajoutonsl’appel
defonctionsuivantàlasuitedesdeuxquiexistentdéjà
danslafonctionprincipaledelaboucle:
delay(500);
Lafonctiondelay()faitpatienterpendantlenombre
demillisecondesindiqué.Ici,nousdemandons500ms,
soitunedemi-seconde.
Après activation de la résistance interne de tirage (PULLUP) etajoutdelapause,leprojetdoitavoirl’aspectsuivant:
Listing4.4:Versionfinaleduprojet(CH04_Digit4)
/*ARDUIPROG_KIDZ
*CH04A_Digit4.ino
*OEN1703
*/
booleanbValeur;
voidsetup(){
pinMode(7,INPUT_PULLUP);//MODIFICI
Serial.begin(9600);
}
voidloop(){
bValeur=digitalRead(7);
Serial.println(bValeur);
delay(500);
}
Le qualificatif PULLUP que nous avons ajouté désigne cemécanisme interne consistant à mettre en activité une résistanceentre la tension positive de 5 V et la broche, ce qui force cettebroche à l’état 1, sauf quand nous décidons de la forcer l’état 0.Mettonscelaenpratiquemaintenant.
1. Unefoislesmodificationseffectuées,sauvegardeton
programmesinécessaireaveclacommande
Fichier/Enregistrersouspuisdemandeson
téléversement.Dorénavant,l’affichageestbeaucoup
pluscalmeet,surtout,tunevoisapparaîtrequedes1.
2. Commeprécédemment,faiscontactentrelapointe
libredustrapetleboîtierdelapriseUSB.Tunedois
voirquedes0.
Figure4.8:Testdelectured’uneentréestabilisée.
Nous savonsmaintenant commentexploiteruneentréenumérique.Cette technique va te permettre d’exploiter toute une gamme decapteurs à sortie numérique, c’est-à-dire qui fournissent commerésultatdeleursmesuressoitlavaleur0,soitlavaleur1.
Maisilexisteaussidescapteursanalogiquesquifournissentcommerésultat de leurs mesures une tension variant progressivemententre0Vet5V.Si tubranchesun tel capteur analogique suruneentréenumérique,tun’obtiendrasquelesvaleurssuivantes:
» Lorsquelatensionfournieparlecapteursesituera
entre0Vet0,8Venviron,tuobtiendrasun0.
» Lorsquelatensionserasupérieureà2,8Vet
jusqu’à5V,tuobtiendrasun1.
» Lorsquelatensionseradanslazonegriseentreles
deux,tunepourrasjamaisprévoirsitu
obtiendras0ou1.
Ilfautdoncunautremoyenpourrécupérerunemesureanalogique.C’estàcelaqueservent lesbrochesanalogiquesduconnecteurdubasdetacarte.Nousallonslesdécouvrirdansleprochainchapitre.
RécapitulonsDanscechapitre,nousavonsappris:
» àécriredesappelsdefonctionsprédéfinies;
» àdéclarerunevariable;
» àréglerleMoniteursérieetàafficherdesvaleurs;
» àstabiliseruneentréenumérique.
I
Chapitre5Àl’écoutedumonderéel
AUMENUDECECHAPITRE:
» Lectureanalogique
» Destypesdedonnéesentiers
» Tapremièrefonction
» Uneinstructionconditionnelle
» ContrôlerleformatdansleMoniteursérie
» Unprojetdethermomètre
lyauneénormedifférenceentre lemondedesordinateurset lemonde réel, physique, le monde IRL (In Real Life) : dans le
monde réel, il n’y a pas vraiment de nuit absolument noire, ni dejour absolument clair. Même par une nuit sans lune, on parvientencoreàdevinerdessilhouettes.Mêmeparun jourdepleinsoleilau beau milieu de l’été, nous ne sommes pas éblouis, etheureusement.nécessaire.
Lemonderéelestceluidunioui,ninon.Prenonsl’exempledelapeséedesvalises à l’aéroport.Lesbalancespeuvent, par exemple,être construites pour savoir peser entre 1 g et 50 kg. À raisond’environ1milliarddevoyageursparan,doncautantdevalises,silamesureestsuffisammentprécise,iln’yaurajamaisdeuxvalisespesantexactementlamêmemasse(onneditpaspoids,maismasse).
Sionbranchelabalancesurl’entréenumériqued’unordinateur,onpourraseulementsavoirs’ilyaunevaliseoupas.Celanepermettra
pasdecalculerlemontantdusupplémentàpayerlorsqu’unevalisepèsepluslourdquelalimiteautorisée.
En pratique, on fait des arrondis : on ne pèse pas les valises aumicrogramme près. L’arrondi, c’est un premier pas menant ducontinuduréelaudiscontinudel’informatique.
Alors, comment faire pour que notre mikon sache exploiter unevaleurquin’estpasnumérique?Comment fairepourqu’ilpuisseexploiterl’undesnombreuxtypesdecapteursquisontconçuspourfournir une tension variant entre 0 V et 5 V, en passant par unequasi-infinitédevaleursintermédiaires?
ObservetacarteArduino.TuremarquessurleconnecteurenbasàdroitedetacartelessixbrochesmarquéesA0àA5aveclamentionANALOG IN. C’est bien à ces broches-là que nous allons nousintéresserdanscechapitre.Nousallonsybrancherunéquipementque va envoyer une tension variant progressivement.Mais tu saisqu’unprocesseurtelquelemikonestunemachinebinaire:ellenepeutaccepterquedes0etdes1.Au-dessousd’unecertainetension,cesera0,etau-dessusd’uneautre,cesera1. Ilnefaitpasdans lanuance!Ilyadoncuneastuce.
Cette astuce se nomme CAN, acronyme pour convertisseuranalogique-numérique (en anglais, DAC pour Digital-AnalogConverter).
Le principe du CAN est de comparer la tension sur la broched’entréeàune tensionqu’ilgénèreen interne. Il fonctionne sur lemême principe que le jeu consistant à deviner un nombre.Rappelons-le.
Supposons que je choisisse un nombre entre 1 et 100 et que je tedemandedeledeviner.Pourchaqueessai,jetedissilenombreestsupérieur ou pas.Quelle est laméthode la plus efficace ? Tu vasd’abord proposer 50. Si c’est supérieur à 50, tu vas dire 75. Àchaqueétape,tuviseslamoitiédelaplagedepossibilitésrestantes.LeCANfonctionneexactementdelamêmemanière.Silaplagedetensions possibles va de 0 V à 5 V, le CAN va commencer parcomparer la tensionàmesurerà2,5V.Sielleest inférieure, ilva
réessayer avec 1,25V. Il procède ainsi de suite jusqu’à trouver lavaleurnumériquelaplusproche.
Le CAN du mikon AT328 qui équipe ta carte Arduino offre uneprécision de 10 bits, ce qui signifie qu’il peutdistinguer 1024 niveaux différents.Nous verrons dans le chapitresuivant que la valeur 1024 peut être codée sur 10 bits (c’est ledoublede512codésur9bits, lui-mêmeledoublede l’octetcodésur8bits).
Il existe de plus en plus de capteurs intelligents qui réalisent eux-mêmes la conversion de l’analogique vers le numérique. Ilstransmettentdoncdirectementdesvaleursbinaires enutilisantuneinterfacenomméeI2C.Nousverronscelaplustard.
LeprojetAnaloPassons au montage d’un circuit permettant de vérifier lefonctionnement du convertisseur CAN. Cemontage, comme celuidu chapitre précédent, sera extrêmement simple puisqu’il serésumeraàunfilvolantbranchésurunebroched’entrée.
1. Vérifiequetacarten’estpasbranchée,puisenlève
touslesstrapsquisontéventuellementprésentset
brancheunseulstrapsurlabrocheanalogiqueA0.
2. Vérifiequel’extrémitélibredustrapnetoucheàrienet
penddanslevide.
3. MetslacartesoustensionenconnectantlecâbleUSB
àl’ordinateur.
C’esttout.Nouspouvonsmaintenantpasseràla
rédactiondutextesource.
Figure5.1:Aspectdumontagepouruntestd’entréeanalogique.
ConceptionduprogrammeCe projet ressemble beaucoup à celui du chapitre précédent. Ladifférenceessentielle estquenousallons avoirbesoind’uneautrefonction prédéfinie. Au lieu de digitalRead(), nous allonsutiliser analogRead(). C’est une fonction standard disponibledèsledépartdansl’atelierArduino.Ilsuffitd’indiquersonnom,etelleserareconnue.
L’autre différence se situe au niveau de la variable dans laquellenous allons récupérer la valeur numérique issue du travail duconvertisseur analogique numérique. J’ai dit plus haut que ceconvertisseursavaitgénérerunevaleurentre0et1023.
Le système de comptage humain est décimal. Pour écrire lavaleur999,troischiffressuffisent,maispourécrire1000,ilenfautquatre.Danslanumérotationbinairedesordinateurs,ilfautdixbitsà 0 ou à 1 pour représenter la valeur décimale 1023. Nous yreviendrons dans le prochain chapitre, mais sache déjàque1023décimals’écrit1111111111enbinaire.Situcomptesbien,ilyadixchiffres1,c’est-à-diredixbits.
Notre mikon, comme tous les processeurs existant actuellementdanslemonde,travailleavecdespaquetsde8bitsauminimum,desoctets.Autrementdit,pourstockerlavaleur1023,ilnousfautdeuxoctets.DanslelangageCdenotremikon,cettelargeurdedonnéescorrespondautypededonnéesportantlenomint.
Lemotréservéintestl’abréviationdeintegerquisignifieentier.Les valeurs entières sont celles qui n’ont pas de virgule. Lesnombres 37 ou 655 sont des valeurs entières, maispas 1,25 ni 36,99.Note au passage que, pour séparer les chiffresdesunitésdeschiffresaprèslavirguledanstesprogrammes,tunedois plus utiliser la virgule, mais le point. Tu écrirasdonc1.25et36.99.
Avant de saisir le texte source, je te propose de bien préparer tesconditionsdetravail,commececi:
1. Sil’atelierIDEn’estpasdémarré,fais-le.
2. UtiliselacommandeFichier/Nouveaupourlancerun
nouveauprojet.
3. Fermel’autrefenêtrequiaétéouverteaudémarrage.
4. Prendsl’habituded’attribuerimmédiatementunnom
àtonprojetenutilisantlacommande
Fichier/Enregistrer.Choisiscenomavecsoin.J’aipar
exempleoptépourlenomsuivantpourlapremière
versionduprojetdecechapitre:
CH05_Analo1
Nefaispascommencerlenomduprojetparunchiffre.
L’ateliern’aimepascela.
5. Unefoisquetuesprêt,procèdeàlasaisiedeslignes
dulistingsuivant.
Listing5.1:Textesourcedelaversion1deAnalo
/*ARDUIPROG_KIDZ
*CH05A_Analo1.ino
*OEN1703
*/
intbroLecture=14;//BrocheA0=14
intiValLue=0;
voidsetup(){
pinMode(broLecture,INPUT);
Serial.begin(9600);
}
voidloop(){
iValLue=analogRead(broLecture);
Serial.println(iValLue);
delay(500);
}
RemarquesdelectureTuconstatesque jecommencepardéclarerunepremièrevariablenomméebroLectureen lui donnant la valeur initiale 14. Celapermetd’utiliserlenomdevariablepartoutoùilfaudraitindiquerlenumérodelabrocheanalogique.Turemarquesaupassagequelapremière des broches analogiques prend le numéro suivant aprèscelui de la broche numérique 13. Autrement dit, les brochesanalogiquesA0àA5portentlesnuméros14à19.
La deuxième variable globale que je déclare porte le nomiValLueElleestaussidéclaréedetypeint.J’aiexpliquéplushaut
pourquoiilnousfallaitcetypedevariable.
Nous retrouvons ensuite nos deux fonctions obligatoires. Dans lafonction de préparation setup(), nous réglons notre broched’entréeenmodeentrée(INPUT).Celapeutparaîtresuperflu:unebrocheanalogiqued’entréeestunebroched’entrée,non?Ehbien,non:malgréleurnom,cessixbrochespeuventaussiêtreutiliséesensortie.J’enprofitepourteprévenirquelesbrochesdesortiesonttoujoursnumériques,etqu’ilfaudrauneautreastucepourqu’ellespuissentsimulerunetensionanalogique.Nousverronsceladansleprochainchapitre.
Ladeuxièmeinstructiondelafonctionsetup()estdéjàconnue.Elleconfigure lavitessededialogueentre lacarteet la fenêtreduMoniteursérie.
Dansnotrefonctionprincipale,nouscommençonsparstockerdansnotrevariablelavaleurquiauraétéluesurlabroched’entréeparnotrenouvellefonctionanalogRead().Rappelonscettepremièrelignepourladécomposer:
iValLue=analogRead(broLecture);
Ilyaicideuxopérationsdansuneseuleligne:
» D’abord,nousdemandonsl’exécutiondelafonction
analogRead().Quandsonexécutionestterminée,
cettefonctionvarenvoyerunevaleur;cettevaleurva
d’unecertainefaçonsurgiràlaplacedel’appelàla
fonction.
» Ladeuxièmeopérationconsistesimplementà
recopiercettevaleurrenvoyéedansl’emplacement
mémoirequiestsymboliséparlenomdelavariable.
Lesdeuxinstructionssuivantessontlesmêmesquedanslechapitreprécédent.Nousaffichonslavaleurquenousvenonsdelireavecunsaut de ligne de l’affichage (grâce à la variante
Serial.println()aulieudeSerial.print())puisnousprovoquons une petite pause d’une demi-seconde(500millisecondes).
Passonsauxtests!
TestduprojetAnaloenversion11. UtiliselacommandeTéléverserpourtransférerle
programmeaprèscompilation.
S’ilyauneerreur,relisbienletextesourceenvérifiant
notammentlesaccolades,lessignespoint-virguleetles
parenthèses.
2. Auboutdedeuxoutroissecondes,leprogrammedoit
avoircommencésonexécution.Ouvrelafenêtredu
Moniteursérie.Qu’observes-tu?
Figure5.2:TestdelapremièreversionduprojetAnalo.
Onvoitapparaîtredesvaleursquisesituent
entre200et1000environ.Lavaleurfluctueenfonction
desparasitesdetonenvironnementréel.Tupeuxpar
exempleapprochertontéléphoneportabledelacarte,
cequiauracertainementuneinfluence.
3. Prendsleboutlibredustrapetfais-letoucherle
boîtierdelapriseUSBsurlacarte.
L’affichagedevraitpasserà0puisquetuprésentesune
tensionde0Vsurlabroched’entréeanalogique.
4. Touchelapointedustrapavecundoigtpourvoirsi
celachangelavaleur.
Cetestpermetdeconfirmerquelemikonsaitdétecterunetensionvariable en la transformant en une valeur entre 0 et la limitede1023.
Nous allons utiliser cette possibilité dans le second projet de cechapitre, mais auparavant, progressons dans l’apprentissage destechniques de programmation, puisque c’est le but principal de celivre,apprendreàprogrammer!
La prochaine étape va être d’une importance capitale : tu vasapprendreàdéclareretexploitertapremièrefonction.
TapremièrefonctionCombien de fonctions prédéfinies avons-nous déjà rencontrées aucours du chapitre précédent et du début de celui-ci ?Environ unedizaine.
Il y a tout d’abord les deux fonctions obligatoires setup() etloop().Ellessontentièrementtransparentespourtoi,danslesensoùtuasaccèsà leurcontenu,puisquec’est toiquiécris les lignesentrelesdeuxaccoladesdechacune.
Ilyaensuitelesfonctionsdonttuasutilisélenompourprofiterduservice correspondant. C’est le cas de digitalRead(),delay(),pinMode(),Serial.print() et de sa varianteprintln(), et enfin de analogRead(). Toutes ces fonctionsprédéfiniesconstituentdesboîtesnoires,puisquetuneconnaispasleur contenu exact. Il te suffit de savoir comment les utiliser (lesinvoquer)etquelprofittupeuxentirer.
Il n’est pas interdit de connaître le contenu des fonctionsprédéfinies.Ellessonttoutesfourniesselonlemodeopensource;letextesourceestdoncaccessible,maistuverrascelaplustard.
Chacune des fonctions prédéfinies contient entre une dizaine etplusieurs centaines d’instructions. Tu constates dans l’éditeur queles fonctions reconnuespar l’atelier sontaffichéesenorange.Dèsque tu fais une faute de frappe dans le nom d’une fonctionprédéfinie,tulevoisimmédiatementparcequ’ellenes’affichepasenorange.
Les deux fonctions obligatoires s’affichent dans une couleurspéciale.
Dans le langage de programmation C de l’Arduino, il y a unesoixantaine de fonctions prédéfinies. Tu pourras y ajouter enfonction de tes besoins un nombre non limité de fonctionssupplémentaires,réuniespargroupeslogiquesdansdeslibrairies.
Lepointessentielestqu’ilnefautjamaisutiliserlemêmenompourdeuxchosesdifférentes,commedanslaviecourante.
Ceuxquiapprennent laprogrammationdansuneautre languequel’anglais ont un avantage à ce niveau : les identifiants qu’ils ontenvie d’utiliser pour leurs fonctions et leurs variables risquentrarementd’entrerenconflitavecdesmotsréservésdulangage,cesderniersétanttoujoursenanglais.
Enplusdesfonctions,nousavonsutiliséquelquesmotsréservésdulangage,quis’affichentenbleudansl’éditeur:
» lestroistypesdedonnéesboolean,intetbyte;
» lesmotsINPUTetINPUT_PULLUP;
» uncertainnombredesignesdeponctuation
(parenthèses,accolades,etc.).
Nous avons aussi créé trois identifiants pour trois variablesdifférentes:bValeur,iValLueetbroLecture.
Nousallonsdoncchoisirunjolinompournotrepremièrefonction.Maispetitequestionpréalable:pourquoicréerdesfonctions?
OntravaillemieuxàplusieursEncréantdesfonctions,onrépartit le travaildansplusieursblocs,cequioffredenombreuxavantages:
» Leprogrammeestplusfacileàlireetàcomprendre.
» Leprogrammeestplusfacileàmettreaupoint,c’est-
à-direàdéboguer.
» Unefonctionpeutfacilementêtrecopiéeetréutilisée
dansunautreprojetsiellecorrespondauxmêmes
besoins.
Bref, en créant des fonctions, tu prends la bonne habitude demodulariser.
En guise de première fonction, je te propose d’extraire de lafonction principale loop() les deux lignes d’instructions quieffectuentlalecturedelaprochainevaleurpuisl’affichagedecettevaleur.
Puisque l’heure est venue de choisir le nom de notre nouvellecréation,voicilesrèglesàsatisfaire:
» Tonnomnedoitévidemmentpasentrerenconflit
avecaucundesnomsdéjàconnusparlecompilateur,
doncaucundesnomsdesfonctionsinternesniaucun
motréservé.Biensûr,tuneconnaispasencoretous
lesmotsréservésetnomsdefonctions,maistuverras
qu’ilyapeudechancesdetombersurunhomonyme
enfrançais.
» Ensuite,ilfautprendrel’habitudedenejamaisutiliser
delettresaccentuéesdanslesnoms.Lorsquetuas
besoindesimulerunespace,utiliselecaractèrede
soulignement(_).Jeteconseilleaussid’adopter
l’écritureendosdechameau,commececi:
intdroMaDaire
» Enfin,unebonnepratiqueconsisteàtoujoursutiliser
unverbed’actionpourlesfonctions,cequiestnormal
puisquelesfonctionsagissent.Turéserveslesnoms
statiquesàtesvariables.
Passonsdoncaucodage.
Déclarationd’unefonction1. L’atelierdoitêtreouvertaveclapremièreversiondu
projetencours,maislenouveaunomseraenregistré
vialacommandeEnregistrersous.
2. Sélectionnelesdeuxlignessuivantesetutilisela
commandeÉdition/Couper.
iValLue=analogRead(broLecture);
Serial.println(iValLue);
3. Descendstoutàlafindutextesource,insèreuneligne
d’espaceavecEntréepuiscollelesdeuxlignes
(Édition/Coller).
4. Place-toiaudébutdelapremièredesdeuxnouvelles
lignes,cellequicommencepariValLue,etinsèreune
lignevideaveclatoucheEntrée.
5. Nousallonsinsérericilalignedetêtedelafonction.
Voicid’abordlasyntaxeformelledelatêted’une
fonction:
nomTypenomFonction(){
Commec’estnotrepremièrefonction,nousallons
restermodestes:notrefonctionnerenverrapasde
valeur,cequenousdécidonsencommençantparle
motclévoid.
Poursimplifierencore,lafonctionnevapasattendre
devaleurenentrée,c’est-à-direuneouplusieurs
valeursquisonttransmisesàlafonctionquandelle
démarreetpermettentdefairevarierson
comportement.Onappelleceladesparamètres
d’entrée,etc’estcequel’onindiqueentrelesdeux
parenthèsesaprèslenomdelafonction.Ici,nous
laissonslecoupledeparenthèsesvide.
Lalignedetêtevadoncs’écrireainsisinous
choisissonscommenomdefonctionlireAna():
voidlireAna(){
TupeuxconstaterquecetteligneneseterminePAS
parunpoint-virgule.
6. Place-toienfintoutàlafindetontextesource,donc
aprèslederniersignepoint-virgule.Insèreuneligne
videpuissaisisuneaccoladefermantecontrelamarge
gauche.
}
C’estl’accoladequifermeleblocquiaétéouvertpar
l’accoladeouvranteàlafindelalignedetêtedenotre
fonction.
Sinécessaire,enlèvelesespacespourquecette
accoladesoitbiencontrelamargegauche.Lorsquetu
vascréerdessous-blocs,tupourrasainsifacilement
distinguerlesdifférentsniveauxpardesdécalages
(indentations)dedeuxespacesparniveau.
7. Lanceunevérification.Ladéfinitiondelanouvelle
fonctionestterminée.Encasd’erreur,relis-toibien.
8. Branchelacarteettéléverseleprojet.Ilnesepasse
plusrien,mêmepasbesoind’ouvrirlemoniteurpour
s’enassurer.Pourquoi?
Parcequenousnedemandonsjamaisànotrenouvelle
fonctiondetravailler!Ilfautl’appelerdanslafonction
principaleloop().
Desfonctionsàl’appel
Pourécrireunappelà tafonction, tuprocèdesexactementcommepourunefonctionprédéfinie:tucitessonnom,etcommec’estuneinstruction,tuajoutesunsignepoint-virgule.C’esttout.
1. Remontedanslafonctionprincipaleloop()etplace-
toijusteaprèsl’accoladeouvrante,puisinsèreuneligne
vide.L’éditeurdevinequetuveuxajouterquelque
chosedansleblocdelafonction:ila
automatiquementinsérédeuxespacesparrapportàla
margegauche.Saisisalorslenomquetuaschoisipour
lanouvellefonction,dansmonexemple,lireAna(),
sansoublierlapairedeparenthèsesvideetlesigne
point-virgulequidoitmarquerlafindechaque
instruction.
Raressontleslignesquineseterminentpasparce
signe.
2. Ilneteresteplusqu’àvérifiertestravauxd’éditionen
comparantaveclelistingcompletsuivant.
Listing5.2:Version2duprojetAnalo
/*ARDUIPROG_KIDZ
*CH05A_Analo2.ino
*OEN1703
*/
intbroLecture=14;//BrocheA0=14
intiValLue=0;//
voidsetup(){
pinMode(broLecture,INPUT);
Serial.begin(9600);
}
voidloop(){
lireAna();//MODIF
delay(500);
}
voidlireAna(){//NOUVELLE
FONCTION
iValLue=analogRead(14);
Serial.println(iValLue);
}
TestonsnotrefonctionTu as certainement très envie de voir ta nouvelle fonctionfonctionner!
1. Commenceparunepetitevérificationavecla
commandeVérifier.Lisbienlesmessagesqui
apparaissentdanslepanneauinférieur.S’iln’yapas
d’orange,toutvabien.
S’ilyaquoiquecesoitenorange,revérifietouten
t’aidantdulistingprécédent.
2. TupeuxmaintenantrebrancherlacarteArduinositu
l’avaisdébranchéeetlanceruntéléversement.
OuvreleMoniteursérieetobservelerésultat.Ilest
strictementidentiqueàlapremièreversion.
Tu disposes dorénavant d’une fonction que tu peux copier-collerdans un autre projet telle quelle ou en la modifiant ensuite. Tonprogrammeestdevenumodulaire.
Voyons maintenant comment faire varier le fonctionnement duprogrammeendécouvrantlesinstructionsconditionnelles.
UneinstructionconditionnelleDanslaviecourante,nousfaisonssanscessedeschoixenfonctiondes conditions que nous constatons autour de nous. Quand tu telèves lematin, tu regardes instinctivement tespiedsaumomentdemettreteschaussettes.Autrementdit:
SIpasDeChaussettesALORSmettreChaussettes;
Si,enregardanttespieds,tuconstatesqu’ilyadéjàdeschaussettesautour, tu n’exécutes pas l’instructionmettreChaussettes().Nousallonsréutiliserceraisonnementpourajouteruneinstructionconditionnelledemanièreànepasseràlalignesuivantequ’auboutdequelquesaffichagesdevaleurs.
Nous allons ajouter un bloc conditionnel dans notre fonctionprincipale.Danscebloc,quiseradélimitéparunepaired’accolades(comme tout bloc qui se respecte), nous allons insérer deuxinstructions:unepourprovoquerunsautdeligneetuneautrepourremettreàzérolecompteurauboutde11affichages.
Le bloc conditionnel que nous allons utiliser se fonde sur lemotréservéanglaisifquiveutdire«si».Voicisasyntaxeformelle:
if(condition_vraie){
premièreinstruction;
deuxièmeinstruction;
etc;
}
Si tu veux garder une version de chaque étape de ce projet,commenceparenregistrerlefichierencourssousunnouveaunom,pourmontrerquec’estlatroisièmeétape.
Voicilesdifférentesactionsd’éditionquenousallonsréaliser:
1. Endébutdetextesource,nousallonsdéclarerune
nouvellevariablepournotrecompteur.Jetepropose
dechoisirunnouveautypededonnéespourcette
variable,letypebyte:
bytebCompteur=0;
Pourquoi?Puisquenousvoulonscompter
de0jusqu’à10,ilestinutiledegâcherdelamémoire
avecunevariablequipermettraitdecompter
jusqu’à32767,cequiestlecasd’unevariabledutype
int.Nouspouvonsnouscontenter(etlargement)d’une
variabledetailleinférieure,quin’occupequ’unseul
octet.Justement,letypebytepermetdestockerune
valeurentre0et255.
Aprèscettedéclarationdevariable,nousallonsinsérer
unblocconditionneldanslafonctionprincipale.
Place-toiàlafindelalignequiconstituel’appelàta
nouvellefonctionetappuiesurlatoucheEntrée.
2. Danscettenouvelleligne,àdeuxespacesdubord
gauche,insèrelalignedetêtedunouveaubloc
conditionnel:
if(bCompteur>10){
Tunotesqu’iln’ypasdepoint-virguleici.Cequiest
entreparenthèsesestuneexpression.C’estlemotde
passepourentrerdanslebloc.Sicetteexpressionest
vraie,onpasse.Donc,silavariablevautplusde10,
c’estvrai.Tantqu’ellevautentre0et10(compris),le
testestfauxetlesdeuxinstructionsconditionnelles
sontignorées.Seulelapauseestmarquéepuisonfait
unnouveautourdeboucleprincipale.
3. Insèreensuiteunenouvellelignedanslaquelletu
placesl’instructionquiprovoqueunsautdelignedans
leMoniteursérie:
Serial.println("");
Lecoupledeguillemetsviden’estpasobligatoire,mais ilpermetd’insérerfacilementuntexteplustard.
4. UtiliseànouveaulatoucheEntréepourinsérerlaligne
suivanteafinderemettreà0lecompteurunefoisqu’il
aatteintlavaleurmaximale:
bCompteur=0;
Ilneresteplusqu’àinsérerunelignedefermeturedu
blocconditionnel.Cetteaccoladefermantedoitse
trouveràdeuxespacesdubordgauchepourqu’onla
distinguebiendel’accoladedelafindelafonctionjuste
au-dessous.
}
Vérifiequetonprojetressembleaudébutdecettenouvelleversiondanslelistingsuivant.
Listing5.3:Débutdelaversion3deAnalo
/*ARDUIPROG_KIDZ
*CH05A_Analo3.ino
*OEN1703
*/
intbroLecture=14;//BrocheA0=14
intiValLue=0;
bytebCompteur=0;//AJOUTV3
voidsetup(){
pinMode(broLecture,INPUT);
Serial.begin(9600);
}
voidloop(){
lireAna();
if(bCompteur>10){//AJOUTV3
Serial.println("");//AJOUTV3
bCompteur=0;//AJOUTV3
}//AJOUTV3
delay(500);
}
Pour l’instant, nous avons inséré un bloc contenant deuxinstructionsquineserontexécutéesquesi lavaleurde lavariablebCompteurestsupérieureà10.Puisqu’ellevaut0audépart,celan’arrivera jamais, àmoins de la faire évoluer. C’est ce que nous
allonsfairedansnotrefonctionquivaaugmenterde1lavaleurducompteuràchaquetour,doncchaquefoisqu’elleseraappelée.
Descendsdans la fonctionlireAna()etplace-toi à la finde ladernière instruction pour insérer les deux lignes portant lecommentaire//AJOUTV3:
Listing5.4:Findelaversion3deAnalo
voidlireAna(){
iValLue=analogRead(broLecture);
Serial.print(iValLue);//
MODIFV3
Serial.print("");//
AJOUTV3
bCompteur++;//
AJOUTV3
}
La première des deux lignes sert à aérer l’affichage afin que lesvaleurs ne se collent pas les unes aux autres. Elle se contented’afficherunespace.
C’estlasecondenouvellelignequinousintéresse:
bCompteur++;
Ce double signe++ collé à la fin du nom de la variable est uneversion abrégée pour augmenter la valeur de la variable d’uneunité.Onappellecelal’incrémentation.Lavariablequivaut0audépart finiraainsiparavoir lavaleur11, cequiprovoqueraenfinl’exécutiondublocconditionnel.
Pourdiminuerde1unevaleur, onutilise le signede soustractionsurlemêmeprincipe:
bCompteur--
Tu as peut-être remarqué unemodification que je n’ai pas encorementionnéedanslanouvellefonction:lapremièreutilisationdelafonction d’affichage n’est plus Serial.println(), maisSerial.print(). En effet, nous ne voulons pas provoquer desautdeligneaprèschaqueaffichage.
La Figure 5.3 montre l’aspect du programme complet dans satroisièmeversion.
Turemarqueslesnumérosdelignesenmargegauche.Cesnumérosnesontabsolumentpasajoutésautextesource;ilsneserventqu’aurepérage dans l’affichage. Pour rendre ces numéros visibles, vadans les préférences de l’atelier (Figure 5.4). Sous Windows etLinux, c’est dans le menu Fichier. SousMacOS, les préférencessontdanslemenuArduino.
Figure5.3:ÉditionetexécutiondeAnalo3.
Figure5.4:L’optiond’affichagedesnumérosdelignedanslespréférences.
Si plus tard, tu décides d’utiliser directement les outils decompilationsur la lignedecommande, il faut savoirqu’unboguebizarrepeutseproduireparcequ’ilmanqueunsautdeligneaprèsladernièreaccoladeduprogramme.Tupeuxdoncenajouterune;celanechangerienaurésultatici.
Testonslaversion3Je n’ai plus besoin de t’expliquer comment faire : d’abordVérifier, puis Téléverser après avoir branché si nécessaire lacarte.TuouvresensuiteleMoniteursérieetturegardeslerésultat.N’hésitepasàtoucherleboutdufillibrepourfairevarierlavaleur.
Turemarquesquel’affichageestbeaucouppluscompact.C’étaitlebut.
Comptelesvaleurssurchaqueligne:ilyenabien11.
Puisque nous sommes dans la découverte des fonctions, rendonscelle que nous venons de définir un peu plus intelligente : nousallonsluifairerenvoyerlavaleurducompteur.
RenvoyonsnosvaleursTu saismaintenant qu’il est possible de faire renvoyer unevaleurparunefonctionlorsqu’elleterminesonexécution.
Àvraidire,onpeutenfairerenvoyerplusieurs,maisilfautdanscecas lesstockerdansun tableau,cequenousverronsdansunautrechapitre.
Lorsqu’une fonctiondoit renvoyerunevaleur, il faut toutd’abordindiquerquelseraletypedelavaleur,cequisefaitenremplaçantlemotclévoid,danslalignedetêtedelafonction,parlenomdutypedésiré.Dansnotreexemple,nousvoulonsrenvoyerlecompteurdetours,etcettevariableestdetypebyte.Celanousconviendra.
Parailleurs,si l’ondéclarequel’onvaenvoyerunevaleur,ilfauttenir ses promesses. Dans le cas d’une fonction, cela supposed’ajouteruneinstructionreturnavec,entreparenthèses,lenomdela variable dont on veut renvoyer la valeur. Je crois que tu esmaintenantassezentraînépourcomprendrecommentappliquercesévolutions à la prochaine et dernière version de notre projetsimplementenlisantletextesourcesuivant.
Listing5.5:Version4duprojetAnalo
/*ARDUIPROG_KIDZ
*CH05A_Analo4.ino
*OEN1703
*/
bytebroLecture=14;
intiValLue=0;
bytebCompteur=0;//AJOUT
voidsetup(){
pinMode(broLecture,INPUT);
Serial.begin(9600);
}
voidloop(){//SUIVANTE
SUPPR
if(lireAna()>10){//MODIF
Serial.println("");
bCompteur=0;
}
delay(500);
}
bytelireAna(){//MODIF
iValLue=analogRead(broLecture);
Serial.print(iValLue);
Serial.print("");
return(bCompteur++);//MODIF
}
Troislignesontchangéetuneligneadisparu:
» D’aborddansnotrefonctionlireAna():j’ai
remplacélemotvoidparlemotbytedanslalignede
tête.
» Dansladernièrelignequiaugmentede1lavaleurde
bCompteur,j’aiajoutél’instructionreturnetj’ai
enchâssél’instructionbCompteur++dansles
parenthèsesdereturn.Autrementdit,l’effetdevrait
êtrelerenvoiàl’endroitoùnousappelonslafonction
delavaleurdebCompteurunefoisquecelle-ciaété
augmentéede1.Nousallonsvoirquecen’estpas
exactementcequisepasseenréalité.
» Danslafonctionprincipaleloop(),nousavons
supprimélalignedel’appelàlafonction.Comment?
Pasd’appel,pasd’affichage?Enfait,nousavons
déplacécetappelàlafonctionenl’insérantdansla
conditiondutest:
if(lireAna()>10){
Dorénavant, troisopérationssuccessivesontlieudanscettesimpleligne:
1. Lapremièreactionestl’exécutiondelafonction
lireAna().
2. Auretourdelafonction,lavaleurqu’ellerenvoie
apparaît«àlaplace»dunomdelafonctionsionpeut
dire.
3. Nouspouvonsenfinévaluerl’expressiondetestqui
estdevenuececi:
EST-CEQUEValeurRenvoyéeESTSUPERIEUREA
10?
Leblocconditionneln’estexécutéquesilaréponseà
cettequestionestoui,doncdèsquecettevaleurest
égaleà11.Danslesautrescas,toutleblocestignoréet
onnefaitquelapaused’unedemi-seconde.Mais
rassure-toi:l’appelàlafonctionesttoujourseffectué.
(Commentpourrait-onfaireletestsinon?)
Réalise ces quelques aménagements, puis vérifie et téléverse leprogramme afin de le tester. Observe bien l’affichage dans lafenêtredumoniteuretcomptelenombredevaleursaffichéesavantlesautdeligne.
Ilyaunbogue:12valeurssontaffichées.
Préfixeousuffixe,cen’estpaspareil!Nousvoicifaceànotrepremierboguedelogique.Leprogrammeest considéré comme parfaitement correct pour le compilateur, lapreuveenétantqu’ilacceptedeletéléverserverslacarte.Pourtant,nousfaisons12toursdeboucleavantdechangerdeligne.Qu’est-cequ’ilsepasse?
Enfait,ilfautseméfierdesnotationsabrégéespourincrémenteroudécrémenterunevariable.Lorsquetuécrisvariable++,lavaleurquepossèdelavariableestutiliséed’abord,puiselleestaugmentée.Pour qu’elle soit modifiée avant d’être utilisée, il faut écrire++variable.Subtil,non?
Procèdemaintenant à cettemodificationenécrivantde lamanièresuivanteladernièrelignepuisentéléversantpourvérifierqu’iln’yaplusque11toursdeboucle,commenouslevoulons:
return(++bCompteur);
Puisque le projet fonctionne comme prévu, nous allons pouvoirpasser à autre chose : apprendre à utiliser un premier véritablecomposantcapteur.Jeteproposeuncapteurdetempératureafindesavoir s’il fait chaud dans la pièce où tu te trouves. Ce seraégalementnotrepremiercontactavecuneplaqued’expérimentation.
Figure5.5:LeprojetAnalodanssadernièreversioncorrigée.
UnthermomètreanalogiquePour ce nouveau projet, je vais d’abord indiquer la liste descomposantsrequis,puisnousprocéderonsaumontagephysiqueducircuitavantdepasseràlaprogrammationetauxtests.
ComposantsrequisNousn’auronsbesoinqued’unseulcomposantactifdansleprojet,un capteur de température de la série LM335 ou LM35. La seuledifférence entre ces deux modèles est que le LM35 fournit unevaleur en degrés Celsius, alors que l’autre fournit une valeur enkelvins.Unesimplesoustractionpermetdepasserdel’unàl’autre.
Voicidonclescomposantsrequis:
» tacarteArduinoavecsoncâbleUSB,évidemment;
» uneplaqued’essaioud’expérimentation(unede
demi-taillesuffit);
» uncapteurdetempératureLM35ouLM335;
» unerésistancede1kilo-ohm;
» troisstrapsde5à10cmdelong,mâle-mâle.
LescomposantssontprésentésdanslaFigure5.6.
Figure5.6:AperçudescomposantsduprojetTempera.
LaFigure5.7montreleschémademontagesurlaplaqued’essai.
Figure5.7:SchémademontageduprojetTempera.
Quelques remarques,puisquec’est tonpremiervraimontagedanscelivre:
» Lecapteurdoitêtrepositionnéensortequelaface
platesurlaquelleestinscritlenomdumodèlesoit
verslebas.Lapattedegauchenevapasêtreutilisée;
ellesertàcalibrerlatempératurepourdesmesures
précises.
» Lapattededroitedoitêtrereliéeàlamasse,c’est-à-
direau0V.SurlacarteArduino,celacorrespondaux
deuxbrochesGNDduconnecteurinférieurgauche.
Choisisl’uneoul’autre.
» Enfin,lapattecentraleducapteurdoitêtrereliée,
d’unepart,àlabroched’entréeanalogique(aveclefil
jaune)et,d’autrepart,au+5V,maisenpassant
d’abordparlarésistancede1kohm.
Dans mon schéma d’implantation, j’ai fait partir le fil rouge
beaucoupplusàdroite,pouravoirassezdeplacepour insérer lesdeuxpattesdelarésistancesansqu’ellesoittrophauteau-dessusducircuit, et sans avoir à les raccourcir. En général, il vaut mieuxgarder les longueurs complètes, car on a souvent besoin deréutiliserlescomposants.
LaFigure5.8montreleschémadeprincipecorrespondant.
Figure5.8:SchémadeprincipeduprojetTempera.
Etvoiciletextesourcedelapremièreversionduprojet.
Listing5.6:Version1duprojetTempera
/*ARDUIPROG_KIDZ
*CH05B_Tempera1.ino
*OEN1703
Lectured'uncapteurdetemperature
LM335ouLM35
*/
intbroAna=14;//Entree
analogiqueA0
floatfMesure=0.0;
voidsetup(){
Serial.begin(9600);
}
voidloop(){
prendreTemp();
Serial.print("Tensionlueenmillivolts:
\t");
Serial.println(fMesure,0);
Serial.print("TemperatureenCelsius:
\t");
Serial.println((fMesure/10)-273.15,1
);//SiLM335enkelvins
Serial.println((fMesure/10),1);//Si
LM35enCelsius
Serial.println("-----");
delay(1000);
}
voidprendreTemp(){
fMesure=(float)analogRead(broAna);
fMesure=(fMesure*5000)/1024.0;//
Conversionde0-1023en0-5V
}
Ilyatroisnouveautésdanscelisting:
1. Unnouveautypededonnées,float.
2. L’utilisationdumêmemotréservéfloatentre
parenthèses,verslafinduprogramme.
3. Lesdeuxopérateursarithmétiques*et/pourla
multiplicationetladivision.
LetypenumériqueflottantfloatVoicilanouvelledéclarationendébutdeprogramme:
floatfMesure=0.0;
Nous avons pour l’instant utilisé trois types numériques, tousentiers:
» letypebooleanquinepermetdestockerque0ou1;
» letypeintquipermetdestockerunevaleurentre0et
lenombrepositif+32767,oubienunnombrenégatif
entre–1et–32768;
» letypebytequipermetdestockerunevaleurpositive
entre0et255.
Lorsquetudivisesdeuxnombresetquelerésultatn’estpasentier,tuperdsdelaprécisionavecdesnombresentiers.C’estpourquoiilexiste un type permettant de stocker des valeurs non entières. Parexemple, le résultatde3/2doitdonner1,5,ouplutôt1.5dansnosprogrammes.C’estunevaleurfractionnaire.
Lenouveautypefloatestdoncindispensable,maisilnefautpasenabuser. Lorsque tu n’as pas besoin de nombres fractionnaires,utiliseuntypeentier.Eneffet,letypefloatoccupe4octetsaulieude2pourletypeintet1octetpourbyte.Lorsquetun’asquedeuxou trois variables, cela ne fait pas de différence, mais si tu doisstocker 500 variables, cela occupera presque toute la mémoire
disponible, puisque 500 × 4 = 2000 alors qu’il n’y aque2048octetsd’espacedisponibles.
Lorsquetuveuxstockerunevaleurdansunevariabledutypefloat,ajoutetoujourslamention.0(unpointsuivid’unzéro)àlasuitedelavaleurpourêtrecertainqu’iln’yaurapasdechangementdetypeimprévu,cequel’onappelleuntranstypage.
Observelalignesuivantedanslaboucleprincipale:
Serial.println((fMesure/10)-273.15,1);
Turemarquesqueladivisionpar10defMesureestentouréepardes parenthèses pour que cette opération soit réalisée en premier,avantlasoustraction.
Dans les deux premières instructions utilisant println(), turemarquesqu’ilyaunsecondparamètrequivautsoit0,soit1.Celane concerne que le format de l’affichage et indique le nombre dechiffres à afficher après la virgule. Cela n’a aucun effet sur lavaleurdelavariable
TuremarquesenfindansnotrefonctionprendreTemp(),toutenbas, que nous prenons la même précaution : nous délimitonsl’opérationàréaliserenpremierparunjeudeparenthèses.
SaisieettestduprojetJeteproposemaintenantdesaisircetextesourcepuisdeletester.
Commepournotreessaidetempératureinternedumikon,dèsquequelquesmesuressontaffichées,approchedélicatementundoigtducapteuret touche-lepour transmettreunpeude tachaleur.Tudoisvoir lavaleurcroître.Elledoit redescendre lorsque tuéloignes ledoigt.
Puisquejeteparlesouventd’occupationmémoire,intéressons-nousàunstylededonnéesquiprendbeaucoupdeplace : les textesdesmessages.
Àlachasseaugaspi!Leprojetcomprenddeuxmessagesfixes:
Serial.print("Tensionlueenmillivolts:
\t");
…
Serial.print("TemperatureenCelsius:
\t");
Voyonscombienchacuneconsommed’espacemémoire.
1. Dansletextesource,positionne-toiaprèslepremier
guillemetetdoncavantlalettreTdeTensiondansle
premiermessage.
2. MaintienslatoucheMajusculeenfoncéetouten
utilisantlaflècheducurseurDroiteetencomptantle
nombredecaractères.Situassaisilemessage
exactementcommemoi,tudois
compter30caractères.Cescaractèressontenchaînés
lesunsàlasuitedesautres,etc’estpourquoion
appellecelaunechaînedecaractères(stringenanglais).
\testunmétacaractère
Les deux messages se terminent par un couple de caractères
étrange :unebarreoblique inverse (uneantibarre)et la lettre t.
C’esttoutsimplementlesymboled’unecommandepouravancer
verslamargedroitedequelquespositions(unsautdecolonne).
Celapermetdebienalignerlesvaleursnumériques.
Une fois que tu as compilé le projet, les deux lignes du panneauinférieurindiquentparexemplequelecroquisutilise:
» 3644octetsdelamémoireduprogramme;
» 266octetsdelamémoiredesdonnées.
Uneastucepermetdedemanderdestockerleschaînesdecaractèresdans lamémoireduprogramme,puisque lesmessagesnepeuventpaschangeraucoursdel’exécution(cesontdeschaîneslittérales).Cerestockageestimpossiblepourles«vraies»variables.
LanotationF()Pour qu’une chaîne constante soit stockée dans la mémoire flashréservéeaucodeexécutable, il fautentourer lachaîned’uncoupledeparenthèsesprécédédelalettreFenmajuscule.
Voicicommenttestercettetechniqued’économiedelamémoire:
1. Relancesinécessaireunecompilationsansavoirrien
changéautextesourceafindepouvoirnoter
l’occupationmémoireduprogrammeetdesdonnées.
Dansmonexemple,c’est3646pourleprogramme
et268pourlesdonnées.
2. Place-toiavantleguillemetouvrantdelapremière
chaîneetinsèreuneespace,lalettreFmajusculeetune
parenthèseouvrante.Voicilerésultat:
Serial.print(F("Tensionlueenmillivolts
:\t");
3. Place-toientrelesecondguillemetetlaparenthèsede
lamêmeligne,etinsèreuneautreparenthèse,suivie
d’uneespacepouraméliorerlalisibilité.
4. Faisdemêmepourl’autrechaîne,TemperatureenCelsius…
5. Éventuellement,aveclacommandeFichier/Enregistrer
sous,implanteletextedansunnouveaufichierde
projet.
Voici à quoi doit ressembler le programme. Les deux lignesmodifiéessontimpriméesenitalique:
Listing5.7:Version2deTempera
/*ARDUIPROG_KIDZ
*CH05B_Tempera2.ino
*OEN1703
Lectured'uncapteurdetemperature
LM335ouLM35
*/
intbroAna=14;//EntreeanalogiqueA0
floatfMesure=0.0;
voidsetup(){
Serial.begin(9600);
}
voidloop(){
prendreTemp();
Serial.print(F("Tensionlueenmillivolts
:\t"));
Serial.println(fMesure,0);
Serial.print(F("TemperatureenCelsius
:\t"));
Serial.println((fMesure/10)-273.15,1
);//SiLM335enkelvins
Serial.println((fMesure/10),1);
//SiLM35enCelsius
Serial.println("-----");
delay(1000);
}
voidprendreTemp(){
fMesure=(float)analogRead(broAna);
fMesure=(fMesure*5000)/1024.0;//
Reconversion0-1023en0-5V
}
Relance la compilation et compare l’occupationmémoire avec laprécédente. Normalement, nous n’occupons plus 268,mais 208 octets du précieux espace limité disponible pour lesvariables. C’est tout à fait normal, puisque nous avons réussi àstockerailleursdeuxchaînesdecaractèresde30octetschacune.
Enréalité, les30octetsnesontpasceuxquetucrois.Eneffet, lesdeux caractères (donc 2 octets) \t forment un symbole qui esttransformé en un seul octet ; c’est un code de contrôle. Mais unautre octet est ajouté automatiquement à la fin de chaque chaîne :c’est la valeur 0. Ce 0 terminal sert en langageC à savoir où setermine une série de caractères constituée sous la forme d’unechaîne.OnappellecelaunechaîneAZT.
Àpart cetteoptimisationde l’occupationmémoire, leprogrammedoitfonctionnerexactementdelamêmemanière.
Nous en avons terminé avec ce projet de capture de température.Dans le prochain chapitre, nous allons découvrir commentcontrôlerlemondeextérieurgrâceauxsortiesnumériques.
RécapitulonsDanscechapitre,nousavonsappris:
» àexploiteruneentréeanalogique;
» cequ’estunconvertisseuranalogique-numérique;
» àdéclarerunevariablenumérique;
» lestypesdedonnéesbyte,boolean,intetfloat;
» àcréerunefonctionetàexploiterdesfonctions
prédéfinies;
» àfairerenvoyerunevaleurd’unefonctionavec
return;
» àoptimiserl’espacemémoireaveclanotationF().
L
Chapitre6Parler,c’estagir
AUMENUDECECHAPITRE:
» LaLEDfaitdelarésistance
» Lesbrochesdesortienumériques
» Lesluciolesdansent
» Lehasardquifaitdeschoses
esdeuxprécédentschapitresnousontpermisdevoircommentlemikon s’organise pour être à l’écoute du monde extérieur, enutilisant ses broches comme des yeux et des oreilles, le mode
entrée,numériquepuisanalogique.Voyonsmaintenantcommentlemikonpeut«parler»aumonde.
Dans le mot « microcontrôleur » , tu sais maintenant à quoicorrespond lapartie«micro» : il s’agitdecettepetite lamelledesilicium de 3 mm de côté sur quelques feuilles de papierd’épaisseur.L’autre partie, « contrôleur » , indique qu’il s’agit decontrôler, donc d’influer sur le cours de certains événementsextérieursàlapuce.
Lorsquetuentendsquelquechosequit’intéresse,celatefaitpenseràd’autreschoses,etparfoistepousseàdéclencheruneaction.
Quand tu réalises une action, tu contrôles quelque chose, avec tesmains souvent, avec tes pieds si tu jongles avec un ballon defootball.Pourdonnerunordreouunavis,tuutilisestabouche.
Le mikon a de tout petits bras. Il travaille avec de l’énergieélectrique, mais la quantité d’énergie qu’il peut fournir est très
limitée. Il est naturellement conçu pour donner des ordres à desassistantsquel’onappelledesactionneurs.
Mêmeunprésidentde laRépublique, l’homme lepluspuissantdeson pays, ne peut pas soulever une pierre rien qu’en parlant. Enrevanche,ilpeutdonnerl’ordrededéclarerlaguerreàunpaysquilemenace.
Pourcontrôlerl’environnementaveclemikon,tuvaslefaireparler(généralement en silence) sur une ou plusieurs de ses brochesutiliséescommesor ties ;cesbrochesvontpasserde0à1,et riend’autre. Le mikon offre 14 broches de sortie numériques,identifiéesde0à13(cellesmarquéesDIGITAL).
Pour commencer notre découverte des moyens de contrôle del’environnement du mikon, je te propose un cas particulier : seservir d’une broche de sortie du mikon pour non seulementtransmettre des ordres,mais directement réaliser l’action, c’est-à-direalimenterenénergiel’objetquenousvoulonscontrôler.
Pour une autre distinction entre ordre et action, imagine ceci : tuconstruisunchâteaudecartessurunetable,puistut’enapprochesettu parles assez fort pour le faire s’écrouler uniquement par laparole.Maistuimaginesbienqu’ilyadeslimitesàlapuissancededestructiondelaparole(souffler,c’esttricher).
Dans le monde entier, les sessions de formation ArduinocommencentparleprojetconsistantàallumeretéteindreunediodeLED. Dans cet exemple universel, la diode reçoit son énergie dumikon, alors que lemikondevrait se contenter de transmettre desordres à un interrupteur électronique qui mettrait la diode soustensionethorstension.
Pour me plier à la coutume, je vais commencer par cet exempleuniversel et contrôler unediodeLEDdepuis unebrochede sortieArduino.
UnebellediodeLED
Puisque, dans ce chapitre, j’ai décidé de faire la lumière surplusieurs sujets, intéressons-nous au composant qui va nouséclairer : la diode électroluminescente, que l’on appelle plutôtdiodeLED.
C’est d’abord une diode, c’est-à-dire un composant constitué dedeux tranches de silicium. L’une des tranches est un peu positive(ellemanqued’électrons),l’autreplutôtnégative(elleaunpeutropd’électrons).Lesdeuxtranchessontcolléesl’unecontrel’autre,cequi donne une jonction. Le résultat est que le courant ne peuttraverser la jonction que dans un sens. Lorsque tu la branches àl’envers,ilnesepasserien,commesilefilétaitcoupéàl’intérieur.Quand tu la branches dans le bon sens, elle va laisser passer lecourant.Etpuisquec’estunediodespéciale,unediodeLED,ellevaémettre de la lumière. La seule condition est que la tension soitsuffisante.
Latensiondeseuild’uneLEDdépenddelacouleurqu’elleémet:
» PouruneLEDrouge,latensiondeseuilest
d’environ1,8V.PouruneLEDverteoujaune,elleest
d’environ2V.
» PouruneLEDbleue,latensionminimalequilui
permetdes’allumerestd’environ3V.
» Enfin,pouruneLEDblanche,ilfautfournir
environ3,5V.
Si une LED émet la lumière, elle consomme du courant. Elletransforme de l’énergie électrique en énergie lumineuse et enchaleur. LesLED ne sont pas gourmandes : pour voir briller uneLED en plein jour, il suffit de lui faire traverser un courantde 10 à 20 milliampères (abrégés en mA). Le problème, c’estqu’ellenesaitpasseretenir.
Comparonsavecunelampeàincandescence,cegenredelampequiétaituniversellejusqu’àlafinduderniermillénaire.Supposonsunelampedontlapuissanceestégaleà100watts.Sielleestalimentée
avec l’électricité de la maison (arrondissons à 200 volts), elleconsommera500mA.Laformuleestassezsimple:
Puissance=tensionXcourant,soitP=U.I
Une fois qu’elle consomme ses 500 milliampères, la lampe àincandescence est contente : son filament rougit et elle éclaire lapièce.Ellesestabiliseàcettepuissance.UneLEDnefonctionnepasselon le même principe : elle ne sait pas facilement s’arrêter deconsommerducourant.Voilàpourquoiilfautfreinersesardeursenplaçant toujours un frein à électrons dans lemême circuit que laLED.C’estunerésistance.
Avantdedécouvrircommentchoisirlabonnerésistance,encoreunpetitdétailconcernantlesLED:puisquel’onrisquedelesbrancheràl’envers, il fautpouvoirdistinguerlesdeuxcôtés.Celas’appelleundétrompage.PouruneLED,uncôtéportelenom«cathode»etl’autre,lenom«anode».Lacathodedoittoujoursêtrebranchéeducôtédu0V(lamasse,GND).Biensûr,l’anodeestàbrancherducôtédupôlepositif,soitle+5Vouuneautretensionpositive.
LorsquetuprendslaLEDentrelesdoigts,lapattelapluscourteestla cathode. Pour t’en souvenir, dis-toi que court et cathodecommencentparlamêmelettre.
Figure6.1:UneLEDavecsesdeuxpattesdelongueursdifférentes.
Pour une LED que tu veux réutiliser, si les deux pattes ont étécoupéesàlamêmelongueur,ilteresteunesolution:leboîtierdelaLEDestaplatiducôtédelacathode.
Surlesschémasdeprincipe,lesymboledelaLEDestlesuivant:
Figure6.2:SchémaducomposantLED.
C’est un triangle avec un trait en travers du sens du courant.Lorsqueturegardeslesymboleàl’horizontale,tupeuxdevinerunKmajuscule,deuxcôtésdutriangleformantlesdeuxtraitsenbiaisdelalettreK.DucôtégauchedeceK,c’estlacathode.
Puisqu’ilnousfautprotégerlaLED,ainsiquelabrochedesortiedumikon,voyonscommentutiliserunerésistance.
Savoirfairetomberlatension
LimitonslesdégâtsChacune des broches numériques supporte au grandmaximumdefournir un courant de 40 milliampères. Si le composant que tubranches sur une de ces broches consomme plus de courant, turisquesdedétruirelabroche,lemikon,voirelatotalitédelacarteArduino.
Lesbrochesd’entréeanalogiquesA0àA5peuventenfaitaussiêtreutilisées comme broches de sortie numériques sous lesnuméros14à19.
Pournepasrisquerdedétruirenotrechermikon,jeteproposeunpetit cours d’électronique.N’aie aucune crainte, je vais rester trèsclair.
Dans une rivière, l’eau va dans le sens de la descente à cause del’attractionterrestre.Enélectricité,l’endroitleplushautcorrespond
au pôle positif et l’autre, au pôle négatif. Si tu laisses faire lesélectrons,ilsvontallerleplusvitepossibledel’endroitoùilssonttropnombreuxvers l’endroitoùilsmanquent.Pourdel’eau,c’estl’équivalent d’une cascade : elle détruit tout sur son passage. Enélectricité,c’estuncourt-circuit,quifaitaussidesdégâts.
Il s’agit donc de contrôler la pente, c’est-à-dire la vitesse ducourant. C’est la tension, et elle est mesurée en volts (V). Lecomposantmagiquequivanouspermettrederéduirelatension,etdonclaquantitédecourant,s’appelleunerésistance.
La résistance est le composant électronique le plus simple et lemeilleurmarchéquisoit.Ellen’aqu’unseulrôle:transformerdel’énergie électrique en chaleur.La résistance décide de la quantitédecourantquipassedupôlepositifaupôlenégatifd’uncircuit.Situosaisconnecterlepôle+etlepôle–d’unepileavecunboutdefil(nefaisjamaiscela!),toutel’énergieentropd’uncôtéfonceraitvers le côté négatif, le plus vite possible. Le fil rougirait puisfondrait,etlapilepourraitmêmeexploser.
Enrevanche,si turéunislesdeuxbornesd’unepilede1,5Vavecune résistance de 100 ohms, par exemple, la pile va se viderlentement.CelagrâceàlaformulemagiqueduchercheurallemanddontOhmétaitlenomdefamille.Voicicetteformule:
tension=résistanceXcourant
U=R.I
Enlatransformant,onpeuttrouverlavaleurdelarésistance:
R=U/I
Autrementdit,s’ilya5Vsurunebrochenumériqueetquel’onneveuilleconsommeraumaximumque20milliampèrespournepasendommagerlemikon,ilfautfairelecalculsuivant:
5Vdiviséspar0,02A=250ohms
Si nous faisions cemontage, une des pattes de la résistance seraitbranchée sur la sortienumériqueetonverraitune tensionde5V.L’autrepattedelarésistance,branchéesurlabrochedemasseGND,serait à la tension nulle de 0 V. Autrement dit, la résistance faitchuter la tension de 5 V. Cela s’appelle une différence depotentiel.
Ilyaunedernièrechoseàvérifierquandonchoisitunerésistance:siellenevapastropchauffer.Pourcalculerlapuissancequivaêtreconsommée par une résistance, il suffit d’appliquer une autreformulemagiquetrèssimplequidécouledelaprécédente:
Puissance=tensionXcourant
P=U.I
Dansnotreexemple,latensionestde5Vetlecourantestde0,02A.Lapuissancequevadégagerlarésistancesousformedechaleurestdoncde:
P=5*0,02=0,1soit100milliwatts
Les résistances que l’on utilise en électronique supportent unepuissance maximale de 500 mW ou de 250 mW. On parleégalementdedemi-wattetdequartdewatt.
Ilneresteplusqu’àidentifierlabonnerésistanceunefoisquetuasfait lecalcul.Si tuasacheté lescomposantspermettantderéaliserles projets de ce livre, tu as sans doute déjà remarqué ces petitsobjetsquiressemblentàdesinsectesetportentdesanneauxcolorés.Ce sont les résistances. Les anneaux de couleur servent à enindiquerlavaleur.Voyonscommentlirecesanneaux.
Haussezlescouleurs!Leschercheursquiontdéfinilecodedecouleursdesrésistancessesont inspirés de l’arc-en-ciel. Chaque couleur correspond à unchiffre.Làoùleschosessecorsent,c’estquelenombred’anneaux
n’est pas toujours le même. C’est une question de qualité defabrication.
SituachètesdesrésistancesdansunmagasinousurunsiteWeb,onte livrera des résistances avec une tolérance de précision de 5%.Celasignifiequesitudemandesunerésistancede100ohms,celleque tu vas obtenir pourra faire 95 ou 105ohms.Cela n’a aucuneimportance, car les valeurs n’ont souvent pas besoin d’êtreabsolumentexactes.Leprojetfonctionneradelamêmemanière.
Pourmarquerunerésistanceavecunetolérancede5%,onajouteàla résistance un anneau de couleur or un peu à l’écart des autres.Aveccettetolérance,ilsuffitdetroisautresanneauxpourcoderlavaleur:
» Lepremieranneaucorrespondaupremierchiffre.
» Ledeuxièmeanneaucorrespondaudeuxièmechiffre.
» Letroisièmeanneauindiquelenombredezéros
aprèslesdeuxpremierschiffres.
Voicitoutd’abordcommentdécrypterleschiffres:
0 noir
1 marron
2 rouge
3 orange
4 jaune
5 vert
6 bleu
7 violet
8 gris
9 blanc
Passonsàlapratique:turepèresd’abordl’anneauargentéoudoréet tu le places du côté droit devant toi. Tu lis ensuite les troisanneauxdecouleurenpartantducôtégauche.Prenonsl’exempledelaFigure6.3.
Figure6.3:Exemplederésistance.
Danscetexemple, lescouleurs sont rouge, rouge,marron.Soit2,puis 2, puis 1. C’est la valeur 22 suivie d’un seul zéro,donc220ohms.S’ilyavaitdunoiràlaplacedumarron,ilauraitzéro0,lavaleurseraitdoncde22ohms.
Turencontrerasrarementd’aussifaiblesvaleursdanstesprojets.Engénéral,lesrésistancesquel’onutilisedanslemondeArduinoontdes valeurs entre 100 ohms et 1 million d’ohms, c’est-à-dire1Mohm(mégaohm).
Pour te souvenir de l’ordre des couleurs, tu peux mémoriser laphrasesuivante:
NeMangezRienOuJeVousBrûleVotreGrande
Barbe
Noir Marron Rouge Orange Jaune Vert Bleu
VioletGrisBlanc
Lapremièrelettredechaquemotpermetdesesouvenirdel’ordrecroissantdescouleurs.
Unerésistancecomprenantcinqousixanneauxestunerésistancedetrès grande précision. Dans ce cas, il y a quatre ou cinq anneauxpourleschiffresetunanneaupourlatolérance.Nousn’auronspasbesoind’unetelleprécisiondanslesprojets.
Une dernière chose concernant les résistances, avant de passer aumontage.Tunepeuxpasobtenirn’importequellevaleurauprèsdesfabricantsderésistances.Dessériesontéténormaliséesenfonctiondelaprécision.Voicilesvaleursquel’onpeutacheterdanslasériequi nous intéresse, la série E24 de la tolérance 5 %. Je prendscommeexemplelaplagedevaleursentre100et1000ohms:
100,110,120,130,150,160,180,200,220,
240,270,300,
330,360,390,430,470,510,560,620,680,
750,820,910et1000
Autrementdit,situfaisunpetitcalculetsilarésistancedonttuasbesoin est de 250 ohms, tu ne trouveras pas ce composant. Iln’existe qu’en 240 ou en 270 ohms. Parmesure de précaution, tuprendras toujours une valeur légèrement supérieure, doncici270ohms.
Passonsmaintenantauxexercicespratiques.
UnprojetdelucioleCommençonsparlemontageduprojet.Voicilescomposantsqu’iltefaut:
» lacarteArduinoavecsoncâbleUSB;
» unediodeLEDrouge,verteoubleue;
» unerésistancede220ou270ohms;
» unstrapnoirmâle-mâle;
» unstraprougemâle-mâle;
» unepetiteplaqued’expérimentation:unededemi-
taille(400trous)suffira.
Lemontage1. PrendstadiodeLEDetinsèrelapattelapluscourte,
celledelacathode,danslarangéed’alimentation
du0Vmarquéed’un–(souventmunied’unfiletbleu
surtoutelalongueur)surleborddelaplaque,puis
écarteunpeulesdeuxpattes(sansforcer)pour
pouvoirinsérerl’autrepatte,celledel’anode,dansle
premiertrouàl’intersectionduaetdu1surlaplaque.
Aide-toidelaFigure6.4.
Figure6.4:LaLEDestinsérée.
2. Prendstarésistanceetinsèreunedesespattesdans
letrouàcôtédel’anode,danslamêmerangéedecinq
trous.Insèrel’autrepatteàlamêmehauteurdans
n’importequeltroudel’autredemi-rangée,saufdansle
pluséloigné.
Figure6.5:Larésistanceestenplace.
3. Prendslestrapnoiretinsère-ledanslalignedu0V,
celleaveclesigne-,dansletrousuivant,celuioùtu
viensd’insérerlacathodedeladiodeLED.Insèrel’autre
extrémitédustrap(lacarteArduinon’estpassous
tension!)dansunedesdeuxbrochesmarquéesGND
surleconnecteurdubasdelacarteArduino.
Figure6.6:LacathodeestreliéeàlamasseGND.
4. Prendslestraprougeetinsèreunedesextrémitésà
côtédelarésistance,parexempledansletrouJqueje
t’aijustementinvitéàlaisserlibre.
Figure6.7:Branchementdufild’alimentation+5Vsurlaplaque.
5. Ilnerestequ’àinsérerl’autreextrémitédustraprouge
danslabrocheDIGITAL11delacarteArduino.
Figure6.8:Dernierbranchementau+5V.
Le montage est maintenant terminé. Prends le temps de vérifiertouteslesconnexions.
LaFigure6.9montreleplandemontagecorrespondant.
Figure6.9:Plandemontageduprojet.
EtlaFigure6.10illustreleprincipecorrespondantàceprojet:
Figure6.10:Schémadeprincipeduprojet.
Voilà bien longtemps que nous n’avons pas programmé. Alorsallons-y!
CodonsnotrelucioleUne fois n’est pas coutume, nous allons partir d’un programmeexistant.Ilnenousferapasgagnerbeaucoupdetemps,maiscelatemontreraleprincipe:n’hésitepasàentrerencommunicationavecla communauté des passionnés d’Arduino du monde entier. Tupourraspartagertesprojetsetprofiterdeceuxdesautres.
Dessourisetdesohms
Tupeuxtedemandercommentjesuisarrivéà250ohmspourla
résistance.Voicilesdétailsducalcul.
Je suppose que nous utilisons une LED rouge dont la tension
minimale (le seuil) est de 2 V. Si on dispose d’une alimentation
de 5 V comme celle des broches numériques dumikon, il faut
laisser 2 V à la diode. La résistance doit donc faire chuter la
tension de 3 V. Si je veux limiter le courant à 20 mA, il faut
appliquerlaformulesuivante:
R=3V
----
0,02
soit150ohms
Enchoisissantenviron250ohms,jedonneunebonnemargede
sécurité.Ladiodebrilleramalgrétout,maisunpeumoinsfort.
1. Démarrel’atelierArduinosinécessaire.
2. OuvrelemenuFichieretchoisislesous-menu
Exemplespuislemenu1.Basics.Sélectionneenfin
danscesous-menuletroisièmeexemple,Blink.
Figure6.11:Réutilisationd’unexempleprédéfini.
3. Nousallonscommencerparunpetitnettoyage.Tu
constatesqu’ilyauncertainnombredelignesde
commentairesenanglais.Nousallonstoutesles
supprimer.Place-toiaudébutdeladeuxièmeligneet
sélectionneaveclasourisjusqu’àcellequiprécèdeles
deuxcaractères*/quimarquentlafindublocde
commentaires.
Prendslabonnehabituded’ajouteruncommentaire
pourtonnouveauprojet,parexemplelenomduprojet,
Luciole.
4. Procèdeimmédiatementàlacréationd’unnouveau
dossierpourceprojetaumoyendelacommande
Fichier/Enregistrersous.Choisisunnomcohérent
avecceuxquetuasdéjàutiliséspourlesprojets
précédents.Lefichierd’exemplecorrespondantporte
lenomsuivant:
CH06A_Luciole1
5. Supprimelesautreslignesdecommentairesquise
trouventaudébutetdanslesdeuxfonctions
obligatoires.Tonprojetdevraitavoiràpeuprèsle
mêmeaspectquedanslaFigure6.12.
Figure6.12:LeprojetLucioledanssaversioninitiale.
6. TroisappelsdefonctionsutilisentlemotLED_BUILTIN.
Ils’agitd’uneconstanteprédéfiniedansl’atelier.Elle
symbolisetoutsimplementlenumérodelabroche13,
cellesurlaquelleestconnectéelapetiteLEDorangesur
lacarte.MaisnousavonschoisidebranchernotreLED
externesurlabroche11.
Sélectionnetouràtourlestroisexemplairesdumot
LED_BUILTIN,parexempleendouble-cliquantdansle
mot,etsaisisàlaplacelavaleurnumérique11,cellede
labrochequenousutilisonspourcontrôlernotreLED.
LeprojetdoitavoirlemêmeaspectqueleListing6.1.
Listing6.1:LeprojetLuciole1
/*ARDUIPROG_KIDZ
*CH06A_Luciole1
*OEN1710
*/
voidsetup(){
pinMode(11,OUTPUT);
}
voidloop(){
digitalWrite(11,HIGH);
delay(1000);
digitalWrite(11,LOW);
delay(1000);
}
TupeuxmaintenantutiliserleboutonoulacommandeTéléverserpourcompilerettéléverserleprogrammeverslemikon.
Commeprévu, tuvoisclignoter laLEDàraisond’unchangementpar seconde. Il n’y a rien de bien nouveau pour l’instant : nousutilisons la fonction prédéfinie digitalWrite() qui réclamedeuxparamètresd’entrée: lenumérodelabrocheet lavaleuràyécrire.LesdeuxmotsréservésHIGHetLOWsontdeséquivalentsdesvaleurs1et0.
VoyonsmaintenantcommentajouterunedeuxièmeLEDen faisantalternerl’allumageentrelesdeuxLED.
Deuxluciolesquidansent(Luciole2)
Dans cette deuxième version, nous allons travailler de façon plusconfortable.Aulieud’indiquerdirectementlenumérodesbroches,nousallonsdéclarerdesvariablesendébutdeprogramme.
1. Enregistresituledésiresleprojetsousunnouveau
nomavantdelemodifier.
2. Place-toijusteaprèslecommentaireinitial,doncavant
lalignedetêtedelapremièrefonctionsetup(),puis
insèreuneligned’espaceaveclatoucheEntrée.
3. Insèrelalignededéclarationdevariablesuivante:
byteyBroLED1=11;
4. InsèrelamêmedéclarationpourlasecondeLED:
byteyBroLED2=10;
Lesnomsdesvariablesontétéchoisisainsi:
ypourinformerqueletypeestbyte;
Brocommeabréviationdebroche;
LEDxpouridentifierlabroche.
Tu découvriras dans le chapitre suivant pourquoi j’utilise lesbrochesdanslesensdécroissant.
Nouspouvonsmaintenantprofiterdecesnomsde
variablesdanslesappelsdefonctions.
5. Danslapremièrefonction,modifielesappelsàla
fonctionpinMode()pourqu’ilss’écriventainsi:
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
}
Faisuncopier-collerdelapremièrelignepourinsérerla
seconde.Iln’yaqu’àremplacerle1parun2dansle
nomdelavariable.
6. Danslafonctiondeboucleloop(),effectuelamême
modificationauxdeuxendroitsoùnouscitonsle
numérodelabroche.
digitalWrite(yBroLED1,HIGH);
digitalWrite(yBroLED2,LOW);
7. InsèreunecopiedesdeuxappelsàdigitalWrite()
pourcontrôlerlasecondebroche.Lerésultatdoit
correspondreauListing6.2.
Listing6.2:Version2duprojetLuciole
/*ARDUIPROG_KIDZ
*CH06A_Luciole2
*OEN1710
*/
byteyBroLED1=11;
byteyBroLED2=10;
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
}
voidloop(){
digitalWrite(yBroLED1,HIGH);
digitalWrite(yBroLED2,LOW);
delay(1000);
digitalWrite(yBroLED1,LOW);
digitalWrite(yBroLED2,HIGH);
delay(1000);
}
8. AjouteunesecondeLEDàcôtédelapremière(laisse
quelquesrangéesd'espace)saufquetulabrancheàla
brocheDIGITAL10aulieude11.
9. Tupeuxmaintenanttestertonprogramme.Tudois
voirlesLEDs’allumertouràtour.
Intéressons-nousmaintenantàunenouvellefonctionquipermetdefairevarierunpeulecomportementdetonArduino:lafonctiondegénérationdenombrespseudo-aléatoires.
AllezàThouars!Parmi les fonctions prédéfinies installées en même temps quel’atelierArduino, il y en a une qui permet de générer un nombreentredeuxvaleursdetellemanièrequ’ilnepuissepasaisémentêtreprévisible.Cen’estpasvéritablementunnombreauhasard,etc’estpourquoi on parle de nombre pseudo-aléatoire. Cela suffiragrandementànospremiersessais.
La fonction correspondante porte le nom anglaisrandom(), quisignifie«hasard»enanglais.
Cette fonction est prévue pour renvoyer une valeur numériqueentière;cettevaleurpeutêtretrèsgrande.Pourlarécupérer,ilnousfaut donc déclarer une variable d’un type approprié. Il s’agit icid’unnouveau typequi s’écrit long.Le type longoccupe 4 octets,soitdeuxfoisplusqueletype int.Letype longpermetdestockerenmémoireunnombrevraimentgrand:
entreenviron–2milliardset+2milliards.
Je teproposed’utiliser ce tirageau sortpour fairevarier ledélaid’attentedenosallumagesetextinctionsdeLED(Figure6.13).
Figure6.13:Luciole3dansl’éditeur.
1. Endébutdetextesource,place-toijusteaprèsla
deuxièmedéclarationdevariableetinsèreuneligne
pourajouterladéclarationsuivante:
longgOHasard;
Tupeuxenprofiterpourenregistrercettetroisième
versionduprojetsousunnouveaunom.
2. Descendsdanslafonctionprincipaledeboucleet
place-toiavantlepremierappelàlafonctiondelay().
Insèrecetteligne:
gOHasard=random(50,500);
3. Danslepremierappelàlafonctiondemiseenpause,
remplacelavaleurnumérique(c’estunevaleurdite
littérale)parlenomdelavariablequivientderecevoir
lavaleurtiréeausort.
4. Répètelesétapes2et3pourlasecondeLED.
LerésultatdoitcorrespondreauListing6.3.
Listing6.3:TroisièmeversionduprojetLuciole
/*ARDUIPROG_KIDZ
*CH06A_Luciole3
*OEN1710
*/
byteyBroLED1=11;
byteyBroLED2=10;
longgOHasard;
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
}
voidloop(){
digitalWrite(yBroLED1,HIGH);
digitalWrite(yBroLED2,LOW);
gOHasard=random(50,500);
delay(gOHasard);
digitalWrite(yBroLED1,LOW);
digitalWrite(yBroLED2,HIGH);
gOHasard=random(50,500);
delay(gOHasard);
}
Lance un test du projet. Dorénavant, le clignotement devientimprévisible.
Tuasremarquéquelesdeuxbornesdelaplagedenombresparmilesquels sera réalisé le tirage au sort, 50 à500, sont tellesque lavaleur ne pourra jamais dépasser 499. Autrement dit, prévoir untype long est une gabegie. Mais la fonction est ainsi capable deproduireunevaleurbienplusgrande.
D’ailleurs,voiciuneversionbonusduprojetdans lequel le tirageau sort est réalisé dans une sous-fonction qui renvoie une valeuraprèsl’avoirrapetisséeauformatdutypeint,doncsur2octets.
Listing6.4:VersiondetestduprojetLuciole
/*ARDUIPROG_KIDZ
*CH06A_Luciole4
*OEN1710
*/
byteyBroLED1=11;
byteyBroLED2=10;
longgOHasard;
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
Serial.begin(9600);//Pour
tester
Serial.print("Largeurenoctetsdutype
long:");
Serial.println(sizeof(gOHasard));
}
voidloop(){
digitalWrite(yBroLED1,HIGH);
digitalWrite(yBroLED2,LOW);
delay(hasarder());
digitalWrite(yBroLED1,LOW);
digitalWrite(yBroLED2,HIGH);
delay(hasarder());
}
inthasarder(){
gOHasard=random(50,500);
Serial.println(gOHasard);
return(int(gOHasard));
}
Toutenbas,noustrouvonslafonctionhasarder().Observebienladernièreinstruction:
return(int(gOHasard));
Lamentionint(valeur)force lavaleur renvoyéeàn’occuperque 2 octets. C’est d’ailleurs indispensable puisque nous avonsdéclaré dans la ligne de tête de la fonction qu’elle renverrait unevaleurdutypeint.
Biensûr,silavaleurdépasselespossibilitésdecetypemoinslong,ilyauradelaperte.Cecidit,lecompilateurArduinon’estpasaussisévèrequed’autrescompilateursdelangageCàceniveau.Faisdesessaisenchangeantletypepourleconfirmer.
J’auraispuécriretoutlecontenudelafonctionhasarder()enuneseuleligne:
return(int(random(50,500)));
Il faut bien recompter le nombre de parenthèses ouvrantes etfermantes!
L’autrepointremarquableestl’appelàdelay():
delay(hasarder());
Comme durée de pause, nous faisons un appel à la fonction detirageausort.Etçamarche!
RécapitulonsDanscechapitre,nousavonsvu:
» cequ’estunediodeLED;
» cequ’estunerésistanceetcommentcalculeret
identifiersavaleur;
» commentmonterdesLEDsurdesbrochesdesortie
numériques;
» lafonctiondetirageausortrandom();
» letranstypageavecint().
D
Chapitre7Donneruneimpulsion
AUMENUDECECHAPITRE:
» SortiesanalogiquesPWM
» Changementd’étatlogique
» Lesvaleursbinaires
» Testsimbriquésetbrancheelse
» Lehasardfaitbienleschoses
» Unjeudedevinettenumérique
ans le chapitre précédent, nous avons appris à utiliser lesbrochesdesortiedumikondansleurmodenormal,c’est-à-direenlesfaisantpasserde1à0etde0à1,sansautrepossibilité.
Parfois, il faut fournir une valeur analogique en sortie, donc unetensionquiprogresseparpetitspasentre0Vet5V.Celasupposel’existenced’untraducteur,unpeucommeceluiquiestutiliséparlemikon pour ses entrées analogiques. Pour une sortie, il s’agiraitd’un convertisseur numérique vers analogique. Il fait le travailinverse duCAN (convertisseur analogique-numérique) vu dans leChapitre5.
Pourmaintenirunetrèsfaibleconsommation,lemikondelacarteArduino Uno (un AT328) n’est pas équipé d’un tel convertisseurnumériqueversanalogique(CNAouDAC).CertainsautresmodèlesdelagammeArduinoenpossèdent,maisilssontpluschers.
Toutn’estpasperdu!Tuvaspouvoirprofiterd’unetechniquequipermet de simuler une sortie analogique en faisant variergraduellement la proportion de temps à l’état 1 plutôt qu’àl’état 0 d’une broche de sortie. Cette technique est appelée lamodulation de largeur d’impulsion PWM (Pulse Width
Modulation)oubienMLI(modulationdelargeurd’impulsion).
Lamodulationdelargeurd’impulsion
Le principe consiste à produire un signal carré, c’est-à-dire un
signal qui passe par exemple 500 fois par seconde
de0à1(500Hz).Visuellement,celaressembleauxcréneauxen
haut des murs des châteaux forts (les mâchicoulis). Le jeu
consisteàdéformerlescarrés(Figure7.1).
Figure7.1:Principedelamodulationdelargeurd’impulsionPWM.
Pourenvoyersurlabrochedeuxfoismoinsd’énergiequesielle
restait à 1 tout le temps (comme en numérique), il suffit de
rendreégales laduréeà0et laduréeà1.Onditquelerapport
cyclique est de 50%. Pendant lamoitié du temps, la sortie est
éteinte(0V).
Avec une fréquence de 500 Hz, la sortie est à 0 V
pendant1millisecondepuisà5Vpendant1milliseconde.
L’astuceconsisteàfairevarierladuréerelativedu0etdu1.Pour
simulerunetensionanalogiquede1,25V,jeréduislaproportion
detempsàl’état1à25%.Si j’appliquecegenredesignalàune
diodeLED,ellebrilleraplusoumoinsfortselonlepourcentagede
tempspendantlequelelleseraalimentéeenénergie.
LafonctionanalogRead()La fonction analogRead() s’utilise presque de la mêmemanière que sa collèguedigitalRead()vue dans le chapitreprécédent.Elleattenddeuxparamètres.Voicisasyntaxegénérale:
analogRead(numéro_broche,
valeur_entre_0_et_255);
La seule différence concerne le deuxième paramètre. Au lieud’indiquerundesdeuxmotsréservésHIGHouLOW(quetupeuxremplacer par 1 ou 0), tu indiques une valeur numérique entièreentre0et255.
Cen’estpaslavaleurnumériqueentre0et255quiesttransmisesurlabrochede sortie.Lemikonutilisecettevaleurpourcalculerunrapport cyclique entre 0 % et 100 %. Voici quelques étapes del’équivalence:
Tableau7.1:analogRead()etrapportcycliquePWM
Valeurduparamètre Rapportcyclique
0 0%
64 25%
128 50%
192 75%
255 100%
Passonsàlapratique.Nousallonsréutiliserlemontagedelafinduprécédentchapitre,celuiquicomportaitdeuxdiodesLED.
Auniveauduprogramme,nousallonségalementrepartird’unedesversionsduprojetLuciole,laversionLuciole2.
LeprojetBinarNousallonsréutiliserundetesprojetsantérieurs.Situn’avaispasenregistré les différentes étapes, tu peux recharger le fichierd’exemple fourni avec le livre comme je l’explique dans lessectionssuivantes.
MontageduprojetNous réutilisons sans aucune modification le circuit Luciole duchapitre précédent. Je t’invite à y revenir si tu as besoin de lereconstruire.
Figure7.2:RappeldumontageréutiliséduprojetLuciole.
RecyclagedecodeVoicicommentprocéderpourdébuterlenouveauprojet.
1. Démarrel’atelierArduinosinécessaire,puisutilisela
commandeFichier/Ouvrirpourchargerleprojetdela
version2deLuciole.Dansmesexemples,ilportele
nomsuivant:
CH06A_Luciole2
Situneretrouvespastonprogramme,cen’estpastrès
grave:tupeuxaussiressaisirlesquelqueslignesdu
Listing7.1quisuit.
2. Procèdeimmédiatementàl’enregistrementduprojet
sousunnouveaunom,pournepasmodifierpar
mégardeleprojetdonttut’inspires.Voicilenomque
j’aichoisi:
CH07A_Binar1
3. Danslescommentairesdetêtedefichier,modifiece
quidoitl’être,notammentlenomduprojet.
4. CompareleListing7.1àcequetuvoisàl’écran,ajoute
touteslesnouvelleslignes,puismodifieleslignesselon
lesconseilsquejedonneunpeuplusbas.
Listing7.1:Version1deBinar
/*ARDUIPROG_KIDZ
*CH07A_Binar1(deCH06A_Luciole2)
*OEN1711
*/
byteyBroLED1=11;
byteyBroLED2=10;
byteyAnaOUI=200;//PWM
byteyAnaNON=0;
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
}
voidloop(){
analogWrite(yBroLED1,yAnaOUI);
analogWrite(yBroLED2,yAnaNON);
delay(1000);
analogWrite(yBroLED1,yAnaNON);
analogWrite(yBroLED2,yAnaOUI);
delay(1000);
}
La lecture de ce listing t’est certainement devenue beaucoup plusfacilequecelledetonpremiercontactavecunprogramme!
Quelquesexplicationss’imposentcependant.
DéclarationsglobalesLes deux variables globales pour déclarer les deux broches desortie n’ont pas changé. Je les avais choisies en prévoyant deréutiliser le programmedu chapitre précédent.En effet, toutes lesbroches numériques ne permettent pas de simuler une sortieanalogique PWM. Sur la carte Arduino Uno, seules les brochessuivantessontutilisables:
3,5,6,9,10et11
Il n’y a donc que 6 broches sur 14 qui peuvent servir de sortiespseudo-analogiques.
Si tu utilises les broches 5 et 6 en tant que sorties analogiquesPWM, tu remarqueras peut-être qu’il est impossible de régler cessorties au minimum, c’est-à-dire à 0. C’est un petit défaut connumaisgénéralementsansinconvénient.
Nous déclarons ensuite deux nouvelles variables qui portent desnomsquipeuventt’étonner.Expliquons-nous.
La première lettre permet de symboliser le typebyte. Comme lalettrebestdéjàutiliséepourletypeboolean,j’aichoisilalettreyqui fait partie du nom byte. L’abréviation ana signifieévidemment « ANAlogique » . La fin de chacun des deux nomscorrespondàl’étathaut(OUI)oubas(NON).
Turemarquesque jedonnecommevaleur initialeàyAnaOUI lavaleur200.C’estunpeumoinsquelavaleurmaximalequiestégaleà255,maiscelasuffitlargementàfairebrillerlesdiodesLED.
Tu pourras tester le contrôle de l’intensité lumineuse des diodesLEDenmodifiantuniquementlavaleuràcetendroit.Enindiquantparexemple10aulieude200,lesLEDnebrillerontpresqueplus,voirepasdutoutpourcertaines.
Le fait que les LED s’allument encore, même avec une valeurde10oude20,prouvequecen’estpasunetensionanalogiquequiest fournie sur la sortie.Lesdiodes reçoivent toujoursde tempsàautreunepetiteimpulsionà5V,maissirarementqu’ellesn’ontpasletempsdefournirbeaucoupdelumière.
PréparationPassons à la fonction de préparation setup(). Il n’y a aucunedifférenceparrapportauprojetLuciole,maisonpeut faireuneremarque : d’après les données du constructeur, il n’est pasobligatoiredepréparerlesbrochesparcesdeuxinstructionssionveutlesutilisercommesortiesanalogiques.Maispuisqu’ellenen’apas d’effet négatif, je trouve qu’il vaut mieux conserver cettehabitude.
TraitementsPassons à la fonction principale loop(). Les quatre appels à lafonctiondigitalRead()doiventêtreremplacésparlanouvellefonctionanalogRead()etlesecondparamètredechaqueappeldoitêtreremplacéparlavaleurappropriée:
» HIGHestremplacéparyAnaOUI.
» LOWestremplacéparyAnaNON.
Figure7.3:Laversion1duprojetprêteàêtretéléversée.
TestdeBinar1Vérifiebientesaménagements,puislanceuntéléversement.Assure-toiqu’iln’yapasdemessageorangedanslepanneauinférieur.
Lorsque l’on fait des modifications progressives dans un textesource, on est tellement impatient que l’on se focalise sur leurseffets sur le montage au lieu de vérifier l’absence d’erreurs.Parfois,onestdéçuparcequeladernièreretouchenesembleavoireuaucuneffet.Enfait(etcelam’estarrivé),uneerreurdansletextesource empêche le nouveau téléversement ; la carte continue àexécuterl’ancienneversionduprojet.Tevoilàaverti.
Tunedois remarquer aucunedifférence avec leprojet numériqueLuciole. Si tu réduis la valeur de yAnaOUI à 5, les LED vontbrillertrèsfaiblementouplusdutout.
Les résistances utilisées peuvent être un peu trop faibles pourcertainsmodèlesdeLED.Situconstatesqu’uneLEDrestebrillanteavec une valeur très faible, remplace sa résistance par unerésistancede470ohms.
Jusqu’à présent, les choses étaient simples. Passons à la vitessesupérieure.Nous allons introduire des variables d’état et des testsconditionnels.Tusaurastout,àconditiondepoursuivre.
Soyonslogiques(Binar2)Danscettedeuxièmeversion,nousallonsabandonner la techniqueélémentaireconsistantàallumerunediodeLEDquandonenéteintuneautre.Cette fois-ci,nousallonsutiliserunevariabled’étatquipourraêtreégaleà0ouà1.Nouspourronsainsidéciderd’allumeroud’éteindrelasecondeLEDenfonctiond’untestdecettevariabled’état.
Nousallonsdoncdéclarerunevariablecommececi:
booleanbEtatU=0;
Je propose ce nom parce que c’est une variable du type booléen,que c’est une variable d’état et qu’elle concerne ce qui va être lechiffredel’unitéd’unprojetdecompteurbinaire.
Danslaboucleprincipale,nousallonspouvoirtestercettevariableet inverser son état à chaque tour de boucle. Mais voyons
directementceladansletextesource.
Listing7.2:Version2deBinar
/*ARDUIPROG_KIDZ
*CH07A_Binar2
*OEN1711
*/
byteyBroLED1=11;
byteyBroLED2=10;
byteyAnaOUI=100;
byteyAnaNON=0;
booleanbEtatU=0;//AJOUT
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
for(inti=0;i<100;i++){
analogWrite(yBroLED1,i);delay(20);
}
for(inti=100;i>0;i--){
analogWrite(yBroLED1,i);delay(20);
}
}
voidloop(){
if(bEtatU==0){//
Comparaison
analogWrite(yBroLED1,yAnaOUI);
}
else{//SINON
analogWrite(yBroLED1,yAnaNON);
}
bEtatU=!bEtatU;//
Inverseur
if(bEtatU){
analogWrite(yBroLED2,yAnaNON);
}
else{
analogWrite(yBroLED2,yAnaOUI);
}
delay(1000);
}
Saisis ce texte source en repartant de la première version que tuenregistressouslenomBinar2.
Tiensbiencomptede ladifférenceentremajusculesetminusculesdanslesnomsdesvariables.
Dans la fonctionsetup(), j’ai ajouté deux boucles de répétitionpour montrer le contrôle que nous avons dorénavant sur laluminositédelapremièreLED.
La fonction principale loop() a été entièrement remaniée.Voyonsd’abordlessixpremièreslignesdelaboucleprincipale:
if(bEtatU==0){//
Comparaison
analogWrite(yBroLED1,yAnaOUI);
}
else{//SINON
analogWrite(yBroLED1,yAnaNON);
}
Voicilemodèledeceblocconditionnel:
if(condition){
instruction1;
instruction2;
}
else{
instruction1;
instruction2;
}
Juste après le mot if, nous indiquons entre parenthèses unecondition sous la forme d’une expression. Il s’agit en fait d’unequestion à laquelle il sera répondu pendant l’exécution. Ici, nouscherchonsàsavoirsibEtatUestégalà0,oupas.Notebienlefaitqu’ilyadeuxsignes==quisesuivent.Cen’estpasuneerreur.
Unseulsigne=estuneopérationdecopie.Deuxsignes==formentunopérateurdecomparaison.
Si tu n’avais indiqué qu’un seul signe = dans l’expression, leprogrammen’auraitrientrouvéàyredire,maislapremièrediodeLEDresteraitalluméeenpermanenceparcequel’expressionestuneinstructiondecopiedelavaleur0danslavariablebEtatU.Etcetteopérationdecopieesttoujoursvraie(heureusement!),doncégaleà1.
S’ilestvraiquebEtatUvaut0àcemoment,lecontenudesdeuxaccolades du if est exécuté. Ici, nous allumons la première diodeLED.
Silavariabled’étatnevautpas0,l’instructiondublocifn’estpasexécutée. En revanche, puisque nous avons prévu une deuxième
branchequicommenceparelse(sinon), celle-ci seraexécutée, cequiferaéteindrelapremièrediodeLED.
Une fois que la LED1 a été allumée ou éteinte, nous réglons leprochain état que devra prendre la LED au tour suivant.L’instructionestétonnante:
bEtatU=!bEtatU;
Iln’yaqu’unsigne=,doncc’estunecopiede lavaleurdedroitedans lavariabledegauche.Maisqu’est-cequecepetit signepointd’exclamation?Undétail?Non,cepetitsigne!auneffeténorme:il inverse lavaleur.Si lavariablevaut1, ellevautensuite0aprèscetteautocopieinverseuse!
Nousarrivonsenfinaudeuxièmeblocconditionnel,construitsurlemême schémaque lepremier.Cependant, l’expressionestbizarre.Ellene compareplus rien.C’estune techniqueautorisée : il suffitque la variable citée possède une valeur différente de 0 pour quel’expressionsoitconsidéréecommevraie,etqueletesteréussisse.Ici, si la variable d’état vaut 1, nous éteignons la seconde diodeLED.Sinon,nousl’allumons.
Tu remarques qu’il n’y a pas de signe point-virgule après laparenthèse droite de l’expression de test du if. De nombreuxdébutantsfontl’erreurd’ajouterunsigne;àcetendroit.
DestestscompactssansaccoladesIl faut un certain temps pour s’habituer à toutes ces nouvellesaccolades, mais elles sont indispensables, sauf dans un casparticulier : lorsqu’il n’y a qu’une seule instruction dans unebrancheconditionnelle,lesaccoladessontsuperflues.Cecidit,ilestconseilléde lesprévoirmêmedanscecas : si tuajoutesplus tardune seconde instruction sans délimiter un bloc, l’erreur sera
difficile à repérer. Seule la première sera exécutée de manièreconditionnelle.Lanouvelleleseradanstouslescas.
Le Listing 7.3montre exactement la fonctionloop()du mêmeprogramme, mais plus compact. J’ai ajouté des espaces dans lesbrancheselsepourrendrelerésultatplusesthétiqueetpluslisible.Lesespacesnesontpasprisesencompteàcetendroit.
Listing7.3:Fonctionloop()compactedeBinar2
voidloop(){
if(!bEtatU)analogWrite(yBroLED1,
yAnaOUI);
elseanalogWrite(yBroLED1,
yAnaNON);
bEtatU=!bEtatU;
if(bEtatU)analogWrite(yBroLED2,
yAnaNON);
elseanalogWrite(yBroLED2,
yAnaOUI);
delay(1000);
}
ConclusionApparemment,nousensommestoujoursaumêmepoint:lesdeuxdiodes LED clignotent en alternance. Pourtant, la raison pourlaquellelasecondeLEDs’allumeestdevenueplusintelligente.Sonétatchangeenfonctiond’unevariablequicontrôleégalementl’étatdel’autrediodeLED.Nousallonspousserceraisonnementunpeu
plus loin dans la prochaine version du projet. Nous allons ainsivisualiserlecomptagebinaire.
Unplusunégalezéro?Tu as appris à compter selon le système décimal. Il est presqueuniversel, mais ne l’a pas toujours été : les enfants mayasapprenaientàcompteraveclesdixdoigtsdeleursdeuxmainsetlesdixdoigtsdeleursdeuxpieds.Ilscomptaientdoncenbase20.Maisque signifie compter en base 10 comme nous le faisons sansréfléchir?
En décimal, tu te sers des chiffres 0 à 9. Une fois arrivé à 9, turetombesà0,maistuutilisesundeuxièmechiffrepourreprésenterlapremièredizaine.Unefoisarrivéà99,turetombesà0danslesunités et dans les dizaines ; tu écris un premier chiffre dans lapositiondescentaines.
Ces règles de numérotation sont exactement les mêmes pour lemikonetpourtouslesordinateursactuelsdanslemonde.Laseuledifférence est qu’il ne possède que deux chiffres pour compter :le0et le1.Arrivéà1,onretombedéjàà0,avecuneretenuequidevientunedeuzaine.
Tuaspeut-êtredéjàvu lecompteurkilométriqued’unevoitureunpeu ancienne. Il est constituédeplusieurs petites rouesportant leschiffres0à9.Àlahauteurdu9,unergotdépasseafind’entraînerd’uncranlarouesituéeàsagaucheaupassagedu9versle0.Onappellececompteurunodomètre.
Figure7.4:Odomètred’unvéhiculeautomobile.
Ennumérotationbinaire,onneparlepasdedizainesetdecentaines,maisdedeuzaine,dequatraine,dehuitaine,deseizaine,etc.Etonenparleausingulier ilnepeutyavoirqu’uneseuledeuzaine,uneseulequatraine,etc.
Àchaquechiffrebinairecorrespondunbit,maistouslesbitsn’ontpas lamêmeimportance.Ennumérotationdécimale, lechiffredescentaines vaut 100 fois plus que le chiffre des unités. Ennumérotationbinaire,lechiffredelaquatrainevautquatrefoisplusquelechiffredel’unité.LeTableau7.2comparelesdeuxbases:
Tableau7.2:Comparaisonentrenumérationsdécimaleetbinaire
Positionduchiffre 4 3 2 1
Endécimal millier centaine dizaine unité
Valeurdécimale 1000 100 10 1
Enbinaire huitaine quatraine deuzaine unité
Valeurdécimale 8 4 2 1
Voicicommentcompterenbinairede0à8(Tableau7.3):
Tableau7.3:Numérationde0à8enbinaire
Décimal Binaire
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
LSBetMSB
Le bit de l’unité, celui situé le plus à droite, est celui dont le
changementalemoinsd’effetsurlavaleurglobale.C’estdoncle
bit lemoinssignificatif.Pour ledésigner,onutiliseengénéral le
sigleanglaiscorrespondant,LSB,quisignifieLeastSignificantBit.
Inversement, le chiffre le plus à gauche est celui qui a le plus
d’effetsur lavaleur.C’est lebit leplussignificatif,etonl’appelle
bitMSB(MostSignificantBit).
Nous allons commencer par voir comment faire compter notreprogrammeenbinairede0à3.D’aprèsleTableau7.3,onvoitquedeuxbitssuffiront.Celatombebien,puisquenousavonsdéjàdeuxdiodesLED sur notremontage.Analysons les états successifs desLED(Tableau7.4):
Tableau7.4:QuelleLEDallumeretéteindre?
Endécimal DiodeMSB(la2) DiodeLSB(la1)
Zéro 0 0
Un 0 1
Deux 1 0
Trois 1 1
Zéro 0 0
etc.
Voici le raisonnement : la LED1 de l’unité s’allume et s’éteintalternativement. La LED des deuzaines doit changer d’état(s’allumerous’éteindre)lorsquelaLED1del’unitéretombeàl’étatbas(à0),c’est-à-direlorsqu’elles’éteint.Etseulementdanscecas.C’estdoncunefoissurdeux.
L’astuce consiste à prévoir une variable dans laquelle tonprogrammesesouviendradel’étatprécédentdeladiodeLED1del’unité.Ilnefaudrachangerl’étatdeladiodeLED2deladeuzainequelorsquelesdeuxconditionssuivantesserontréunies:
» ladiodeLED1del’unitéestéteinteET
» ladiodeLED1del’unitéétaitalluméeautour
précédent.
Biensûr,laLED1esttouràtouralluméeetéteintequandoncompteen binaire. Mais en raisonnant comme je le propose ici, nouspourronsappliquerlemêmealgorithmepourcontrôlerleschiffresbinairessuivants:laquatraineavecl’étatdeladeuzaine,lahuitaineavecceluidelaquatraine,etc.
UnpetitalgorithmeAvant de passer à la rédaction du code, il est toujours conseilléd’écrirelesgrandeslignesdufonctionnementprévu.
1. Ilnousfautajouterunevariablepourmémoriserl’état
précédentceluiencourspourladiodeLED1del’unité.
2. Ilfautajouteruneinstructionpourmémoriserl’état
courantdanscettenouvellevariablepourl’état
antérieuravantdemodifierl’étatcourant.
3. Ilfautenfinajouteruneinstructionconditionnelle
contenantdeuxexpressionsdetestpourdéciders’il
fautinverserounonl’étatdeladiodeLED2dela
deuzaine.
Onpeutcomptersurlui(Binar3)Nousrepartonsdeladernièreversiondenotreprojet,Binar2.
1. OuvrelefichierduprojetBinar2etréalise
immédiatementunecopiesousunnouveaunom,par
exempleBinar3.
2. Danslasectioninitialedesdéclarations,ajouteles
deuxdéclarationsdevariablessuivantes:
booleanbPrecU=0;
booleanbEtatD=0;
LalettreUsignifieUnitéetlalettreD,Deuzaine.
3. Auniveaudelafonctiondepréparationsetup(),tu
peuxsupprimerlesdeuxinstructionsquifaisaientune
animationd’accueilsurlaLED1.
4. Audébutdelafonctionprincipaleloop(),ajouteune
instructionpourmémoriserdansnotrenouvelle
variablebPrecUlecontenuactueldelavariabled’état
del’unité.Celadeviendral’étatprécédent:
bPrecU=bEtatU;
5. Place-toijusteavantledeuxièmetestconditionnelet
insèreletestsuivantenfaisantbienattentionau
nouveausymbole&&:
if((!bEtatU)&&(bPrecU))bEtatD=!
bEtatD;
Lapartienouvelleestl’expressiondetest:
((!bEtatU)&&(bPrecU))
Ilyaenfaitdeuxexpressionsquisontévaluées
chacuneàpart,puislerésultat(vraioufaux)de
chacuneestcombinégrâceaunouvelopérateur
logique&&.
Ilyaquatrepossibilités.Uneseulefaitréussirletestet
doncinverserlavaleurdebETatD:lesdeuxsous-
expressionsdoiventêtrevraies(valeurdifférentede0).
ObserveleTableau7.5quiestunetabledevérité:
Tableau7.5:Tabledevéritédutest
ValeurbEtatU ValeurbPrecU Testréussi?
0 0 Non
0 1 OUI
1 0 Non
1 1 Non
Onpeut formulercettedoubleconditionainsi.Attention : ilya lesigneinverseur!audébutdunomdelavariable:
SIl'étatactueldel'unitén'estPASvrai
(soninverseestvrai)
ET
SIl'étatprécédentdel'unitéESTvrai
ALORSInverserl'étatdelavariabled'état
deladeuzaine.
(sinonnerienfaire)
Cequirevientàdirececi:
SIlaLED1estéteinte
ET
SIlaLED1étaitalluméeautourprécédent
ALORSnousexécutonsl'instruction
d'inversion.
Autrementdit,pourqueletestéchoue,ilsuffitquel’étatactueldeladiodeLEDdel’unitésoitd’êtrealluméeoubienilsuffitqu’elleaitdéjàétééteintedansletourprécédent.
Tu remarques les espaces que j’ai ajoutées autour des deux sous-expressions;celafacilitelalecture.
L’écriture!bEtatUestdéroutanteaudébut.Cetteexpressionestvraie lorsque l’inverse est faux. La variable doit donc contenir lavaleur0pourquel’expressionvaille1parinversion.
Ilneresteplusqu’àcomparercequetuassaisiauListing7.4.
Listing7.4:Version3deBinar
/*ARDUIPROG_KIDZ
*CH07A_Binar3
*OEN1711
*/
byteyBroLED1=11;
byteyBroLED2=10;
byteyAnaOUI=200;
byteyAnaNON=0;
booleanbEtatU=0;
booleanbPrecU=0;//AJOUT
booleanbEtatD=0;//AJOUT(Dpour
deuzaine)
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
//Plusd'animation
}
voidloop(){
bPrecU=bEtatU;
//AJOUT
if(!bEtatU)analogWrite(yBroLED1,
yAnaOUI);//MODIF
elseanalogWrite(yBroLED1,
yAnaNON);
bEtatU=!bEtatU;
if((!bEtatU)&&(bPrecU))bEtatD=
!bEtatD;//AJOUT
if(bEtatD)analogWrite(yBroLED2,
yAnaOUI);//MODIF
elseanalogWrite(yBroLED2,
yAnaNON);
delay(1000);
}
TestdeBinar3Comme d’habitude, branche si nécessaire ta carte Arduino,téléverse le programme, corrige-le s’il le faut, puis admire lerésultat.Leslettresclignotentencomptantde0à3ennumérotationbinaire.
Si tu enlèves la pause delay(), toutes les LED vont sembleralluméesenpermanence,tellementleprogrammevavite.
Montons enpuissance en faisant compter de0 à15.Cela supposed’installerdeuxautresdiodesLED.
UnquartetenbinaireSais-tucommentonappellelamoitiéd’unoctet?Toutsimplementunquartet.C’est cequenousallonspouvoir contrôlerdanscettedernièreétapeduprojet.
MontagedeBinar4Pour le montage, il suffit de dupliquer les deux circuits de LEDexistantspourenavoirquatreautotal:
Figure7.5:MontageavecquatrediodesLED.
1. Branchesurlaplaqued’essaiunetroisièmeetune
quatrièmediodeLED.
SitubranchesuneLEDàl’envers,ellenes’allumera
pas,maiscelaneferapasdedégâts.Distinguebien
anodeetcathode.
2. Ajouteunerésistanceàchacune.
3. Brancheunstrapentrelarésistanceetdeuxautres
brochesdesortienumériques:
pourlatroisièmeLEDdequatraine,branche-toisurla
broche9;
pourladernièreLEDdehuitaine,branche-toisurla
broche6.
Jerappellequetouteslesbrochesnumériquesne
permettentpasdetravaillerenpseudo-analogique
PWM.
4. Vérifietonmontage.
C’esttoutcequ’ilyaàfaire.Passonsaucodage.
TextesourcedeBinar4VoicimaintenantletextesourcedelaquatrièmeetdernièreversionduprojetBinar.Lis-led’abord.Mesexplicationssontàlasuite.
Listing7.5:Version4deBinar
/*ARDUIPROG_KIDZ
*CH07A_Binar4
*OEN1711
*/
byteyBroLED1=11;//U=Unite
byteyBroLED2=10;//D=Deuzaine
byteyBroLED3=9;//Q=Quatraine
byteyBroLED4=6;//H=Huitaine
byteyAnaOUI=100;
byteyAnaNON=0;
booleanbEtatU,bEtatD,bEtatQ,bEtatH=0;
booleanbPrecU,bPrecD,bPrecQ,bPrecH=0;
//AJOUT
voidsetup(){
pinMode(yBroLED1,OUTPUT);
pinMode(yBroLED2,OUTPUT);
pinMode(yBroLED3,OUTPUT);
pinMode(yBroLED4,OUTPUT);
}
voidloop(){
//LEDUNITE
bPrecU=bEtatU;
if(!bEtatU){bEtatU=1;}
else{bEtatU=0;}
agir(yBroLED1,bEtatU);
delay(50);//DELAIPEDAGOGIQUE
//LEDDEUZAINE
bPrecD=bEtatD;
if((!bEtatU)&&(bPrecU)){
bEtatD=!bEtatD;
agir(yBroLED2,bEtatD);
}
delay(50);
//LEDQUATRAINE
bPrecQ=bEtatQ;
if((!bEtatD)&&(bPrecD)){
bEtatQ=!bEtatQ;
agir(yBroLED3,bEtatQ);
}
delay(50);
//LEDHUITAINE
bPrecH=bEtatH;//Utilesi
extension8bits
if((!bEtatQ)&&(bPrecQ)){
bEtatH=!bEtatH;
agir(yBroLED4,bEtatH);
}
delay(500);
}
voidagir(bytebroche,booleanvaleur){
if(valeur)analogWrite(broche,yAnaOUI);
elseanalogWrite(broche,yAnaNON);
}
Monexempleoccupe60lignes.Celacommenceàêtreremarquable.On est loin de Blink. Quelques commentaires ne seront donc pasinutiles.
LesdéclarationsglobalesDans la têteduprogramme,nous trouvonsdeuxdéclarationspourles deux nouvelles diodes LED. Tu remarques qu’elles sontbranchées sur les broches 9 et 6, qui sont capables de fournir unsignalPWM.
Au sujet des variables d’état, nous ne faisons plus dans le détail :nous déclarons quatre booléens pour l’état actuel et quatre autres
pourl’étatprécédent.
Onpourrait«pinailler»enfaisant remarquerquenousdéclaronsbPrecH,maisqu’ellenesertàrien.Eneffet,elleseraitutilepourunecinquièmeLED.Enguised’exercice,tupeuxcréeruneversionàhuitLEDpourcompterde0à255.
LaconfigurationinitialeNousdéclaronsenmodesortielesdeuxnouvellesbroches.Iln’yariend’autreàajouterdanslapréparation.
LaboucleprincipaleElle évolue beaucoup, en apparence. Nous trouvons quatre blocs,donttroistrèssimilaires.PourlaLEDdel’unité,nousnecherchonspas l’étatantérieur :nousnouscontentonsd’inverser l’état,cequejefaisdefaçontrèsexplicite.Tusaistoiaussiécrirelamêmeactiondefaçonbeaucouppluscompacte:
bEtatU=!bEtatU;
La grande nouveauté est l’introduction d’un appel à une nouvellefonctionquej’aidécidédenommeragir().Ellevanousépargnerde répéter les appels à analogWrite() dans chaque blocd’instructionsdesdiodesLED.Situdescendsenbasdutextesource,tu trouves lecorpsdecettenouvelle fonction.Tuconstatesqu’elleest polyvalente : elle est appelée quatre fois, avec des valeurs deparamètresdifférentes,évidemment.
J’ajouteenfinunepetitepauseque tupeuxenleversi tu ledésires.Ellepermetdevoir latransitionentreuneLEDet laLEDsuivante(quivautledouble).
Dans les trois sous-blocs des LED de deuzaine, quatraine ethuitaine, tu constates que le test réunit deux expressions, commedéjàvudans laversionprécédenteduprojet.Noteaupassageque
nous n’appelons la fonction agir() que lorsqu’il faut changerd’état.Autrementdit,silaLEDétaitallumée,ellelerestelorsqueletestneréussitpas.
NousenavonsmaintenantterminéavecleprojetBinar.Appliquonstoutes ces connaissances pour créer un jeu de devinette binaire,Devinum.
VoiciMaîtreDevinumCeprojetestunjeudesociété.Tuvaspouvoirréunirtesamispouressayer de décoder le plus vite possible des valeurs binaires quivont être présentées successivement sur quatre diodes LED, doncunevaleurdécimaleentre1et15(le0n’estpasintéressant,puisquetoutestéteint).Chacunnotesesréponsessurunboutdepapier.
Une fois les dix valeurs affichées, le programme va montrer lesbonnesréponsesdanslafenêtreduMoniteursérie.Vouscomptezlenombredebonnesréponsesettenezvosscores.
Lesdixvaleursvontêtretiréesausort.Nousexploitonsàceteffetlafonctionrandom().
Pour nous épargner de devoir déclarer dix variables et de lesmanipulerl’uneaprèsl’autre,nousallonsprofiterd’unetechniqueextrêmementimportanteenprogrammation:letableaudevaleurs.
Letableau:variablesenfamillesUntableauestunevariablecollective.Ilporteunnometpossèdeuntype,commelesvariablessimples.Ladifférenceestqu’ilpermetderegrouper plusieurs variables du même type. Pour accéder àchacuned’elles,ilfaututiliserunenotationspécialeaveclapositionde la variable par rapport au début du tableau (un indice). Voicil’écrituregénériquedeladéclarationd’untableau:
typenomTableau[nombre_d'éléments];
Voicicommentdéclareruntableaudedixentiers:
intnomTableau[10];
Etvoici comment stockerunevaleurdans la troisièmecasede cetableau:
nomTableau[2]=255;
J’ai bien écrit « dans la troisième case » , pas « dans ladeuxième».L’indiceentrecrochetsdésignelacasedanslaquelleonveutécrireoudepuislaquelleonveutlire,maisencommençantla numérotation à 0. La dixième case correspond donc àl’indice9etlapremièrecase,àl’indice0.C’estunedeserreurslesplusfréquentesdesdébutantsquedesetromperd’unecase.
Lestableauxconstituentunoutiltrèspuissantetonpeutaiséments’yperdre. Dans mon autre livre, Programmer pour les Nuls, jemontre un tableau à trois dimensions : un tableau qui contient untableau dans chacune de ces cases, et ce tableau imbriqué contientlui-mêmeuntroisièmetableaudanschaquecase!
Bien sûr, avec la mémoire très limitée du mikon, déclarer untableau à plusieurs dimensions va vite épuiser l’espace mémoiredisponible.
Lecturedirected’unbit:bitRead()L’autre nouveauté de notre projet est l’utilisation d’une fonctionprédéfiniequipermetde testerdirectement lavaleurd’unbitdansune valeur numérique. Il s’agit de la fonction bitRead(). Elles’utilisedelamanièresuivante:
bitRead(valeur_à_scruter,rang_du_bit);
Le premier paramètre contient la valeur qui peut être sur 8,16ou32bits.
Le secondparamètredésigne lenumérodubit, unpeucommeunindice.D’ailleurs,lanumérotationcommenceiciaussià0.
Parexemple,lavaleurdécimale254s’écritainsienbinaire:
11111110
Seul lebitde rang0 (celuidedroite)està0.Pourobtenirun testfondésursavaleur,onpeutécrirececi:
if(bitRead(valeur,0)){instructionssi
lebit0està1;....}
Parexemple,poursavoirsiunnombreestpairouimpair,ilsuffitde tester sonbitde rang0 (lebitdepoids faible,LSB,vudans leprojetprécédent).Touteslesvaleursnumériquesbinairesdontlebitde poids faible est à 1 sont nécessairement impaires. Tu l’as sansdouteremarquédanslesallumagesdeLEDduprojetprécédent.
Voyonsmaintenant le code source deDevinum. Les explicationsviennentàlasuite.
Listing7.6:TextesourcedeDevinum
/*ARDUIPROG_KIDZ
*CH07B_Devinum
*OEN1711
*/
#definePAUSE400
#defineLUMIN100
constbyteyLed1=11;
constbyteyLed2=10;
constbyteyLed4=9;
constbyteyLed8=6;
byteayTablo[10];//Lefameuxtableau!
voidsetup(){
pinMode(yLed1,OUTPUT);
pinMode(yLed2,OUTPUT);
pinMode(yLed4,OUTPUT);
pinMode(yLed8,OUTPUT);
Serial.begin(9600);
Serial.println("***BienvenuechezDEVINUM
***");
}
voidloop(){
for(bytei=0;i<10;i++){
ayTablo[i]=random(1,15);
Serial.println("");
Serial.print(ayTablo[i]);
afficherBin(ayTablo[i]);
toutEteindre();
}
afficherReponses();
attendreSaisie();
}
voidafficherBin(bytebNum){
if(bNum==0)return;
Serial.print("\tBinaire");
if(bitRead(bNum,0))agir(yLed1,LUMIN);
elseagir(yLed1,0);
if(bitRead(bNum,1))agir(yLed2,LUMIN);
elseagir(yLed2,0);
if(bitRead(bNum,2))agir(yLed4,LUMIN);
elseagir(yLed4,0);
if(bitRead(bNum,3))agir(yLed8,LUMIN);
elseagir(yLed8,0);
delay(PAUSE*3);
}
voidagir(bytebBroche,bytebValeur){
analogWrite(bBroche,bValeur);
Serial.print(boolean(bValeur));
}
voidtoutEteindre(){
analogWrite(yLed8,0);
analogWrite(yLed4,0);
analogWrite(yLed2,0);
analogWrite(yLed1,0);
delay(PAUSE*3);
}
voidafficherReponses(){
delay(PAUSE*10);
Serial.println();
Serial.println("MaitreDevinumtedonne
lessolutions:");
for(bytei=0;i<10;i++){
Serial.print(ayTablo[i]);
Serial.print("¦");
}
Serial.println();
Serial.println("******************");
Serial.println("Clicdanszonedesaisie
enhautduMoniteur...");
Serial.println("...puisEspaceetEntree
pourautrepartie!");
}
voidattendreSaisie(){
while(Serial.available()==0);
//Vigilanceici
while(Serial.available()>0)
Serial.read();
Serial.flush();
}
AnalysedutextesourceQuatre-vingts lignes. De plus en plus fort ! Tu remarques que leprogramme ressembledans certainesparties à ladernièreversiondeBinar.Pourtant, j’aiprisunmalinplaisirànepas réutiliser lesnomsdesvariables.C’estvolontaire. Il fautentraîner tescapacitésd’adaptation.Lalogiqueestquasimentlamême,maislesnomssontdifférents.
Pourcréercetextesource,tupeuxnéanmoinspartirdeBinar4,enenregistrantleprojetsouslenomDevinum.
1. Démarreunnouveauprojet(Fichier/Nouveau)ou
réutiliseBinar4.
2. Danslasectiondesdéclarationsglobales,tu
remarquesdeuxnouvellesinstructionsqui
commencentparunsigne#:
#definePAUSE400
#defineLUMIN100
Ilnes’agitpasdevariablesmaissimplementde
symbolesquiserontremplacésparlavaleur
numériquelorsquel’ateliervacompilerleprogramme.
Autrementdit,partoutoùtuvasciterlemotPAUSE(en
lettrescapitales,c’estuneconvention),cemotsera
remplacéparlavaleur400.L’énormeavantageestque
celapermetdecentraliserlavaleur.Pourchangerla
vitessed’exécutiondetouteslesphasesdujeuenune
seulefois,iltesuffirademodifierlavaleurnumérique
associéeàPAUSE.Ilenvademêmepourlaluminosité
desdiodesLEDaveclemotLUMIN.Cesontdessortes
desynonymes.
3. Ladernièredéclarationglobalecorrespondànotre
fameuxtableau.Nousl’avonsdéjàprésentéplushaut.
Lafonctiondepréparationnecontientriende
particulier,maistunotesunmessagedebienvenuequi
s’afficheradansleMoniteursérie.
Laboucleprincipaleestétonnammentbrève.Ellese
résumequasimentàunegrandebouclederépétition
for.Toutelapartiedequestionnementdujeuest
réunieàcetendroit.
4. Nouscommençonsparstockerdanschaquecasedu
tableaulavaleurrenvoyéeparlafonctionquiréalisele
tirageausort.Turemarquesquenousappelonsla
fonctionrandom()avecunevaleurentre1et15.En
effet,sinousavionschoisileslimites0à15,lafonction
auraitparfoisrenvoyélavaleur0,quin’estpastrès
facileàdevinerpuisquerienn’estallumé.
Danschaquetourdeboucle,nousappelonsd’abord
unefonctionpourafficherlavaleursurlesquatreLED,
puisuneautrepourfaireunetransitionenéteignant
touteslesLED.
Unefoissortisdedixtoursdeboucle,nousaffichons
lesréponsesetattendonslasaisied’uncaractèredans
leMoniteursériepourlancerlapartiesuivante.
5. LafonctionafficherBin()n’abesoinderecevoiren
entréequelavaleurqu’elledoitafficher.C’esticique
nousutilisonslanouvellefonctionbitRead().Tu
remarquesquenousappelonsuneautrefonction
depuiscettefonction,lafonctionagir().
6. J’aiplacéladéfinitiondelafonctionagir()juste
aprèslaprécédentepourplusdeconfort.Quelavaleur
soitnulleounon,nousréalisonsdeuxactions:
l’allumageoul’extinctiond’unediodeLEDetl’affichage
d’un1oud’un0.
LafonctiontoutEteindre()neréclameaucun
commentaire.
7. DanslafonctionafficherReponse(),nous
présentonslesdixvaleursquisonttoujoursprésentes
dansletableau.Noteaupassagequelepréfixedunom
dutableauestay:aestlapremièrelettredumot
anglaispourtableau,array.Lalettreyrappellequ’il
s’agitd’untableaudevaleursdutypebyte.
8. Nousarrivonsàladernièrefonction,
attendreSaisie().Ellecontientdeuxlignes
étonnantes:
while(Serial.available()==0);
while(Serial.available()>0)
Serial.read();
Cegenred’écriturepeutfacilementdeveniruntrounoir,uneboucleinfinie.Eneffet,derrièrelaconditiondumotwhile,doncaprèsladernière parenthèse fermante, il doit y avoir une instruction, oumême plusieurs si tu ajoutes une paire d’accolades pour faire unbloc.S’iln’yaquelesignepoint-virgulesansinstruction,labouclevaserépétertantquelaconditionentrelesparenthèsesrestevraie.
La fonction Serial.available() renvoie une valeurdifférentede0siquelquechoseaétésaisidans leMoniteursérie.Autrement dit, dans notre exemple, tant que la fonctionSerial.available() renvoie la valeur 0, l’expression estvraie,etnouscontinuonsàappelersanscesselamêmefonctionenboucle. Cela permet d’attendre la saisie d’un caractère pourdémarreruneautrepartie.
Si aucun caractère n’est jamais saisi dans leMoniteur série, nousresteronsdanscettebouclejusqu’àlafindumonde.Ilfautdoncêtretrès attentif avec le signe point-virgule isolé dans les boucles derépétition.
Dans la seconde ligne, nous utilisons la même fonction, mais ensensinverse.Sinousavonsatteintcettedeuxièmeinstruction,c’estque quelque chose a été saisi. Mais il faut continuer à lire lescaractèresunparuntantqu’ilyenrestedanslamémoireduclavier.
Cette précaution permet d’éviter d’enchaîner deux partiessuccessives lorsque l’on frappe par mégarde plusieurs caractèresavantdevaliderparlatoucheEntrée.
Pour plus de précautions, nous ajoutons un appel àSerial.flush() pour vider la zone mémoire des caractèressaisis.Enanglais,flushsignifie«purger».
Etmaintenant,ons’amuse!N’hésite pas à tester le programme avec des amis. Parmi lesaméliorations que je te propose d’envisager, voici les plusévidentes:
» Pourrendrelejeuplusdifficile,ilsuffitderéduirela
duréedepause.Commej’utilisedesmultiplesdecette
valeurinitiale,lechangementserarépercutépartout.
» Tupeuxaugmenterlenombredechiffresàdeviner,
cequisupposed’effectuerplusieursretouches.Ilfaut
changerlesdimensionsdutableaudansles
déclarations,etmodifierl’indicedanslaboucleforqui
utilisecetableau.Jerappelleaupassagequel’indicede
répétitioncommenceà0pourqu’ilpuisseservir
simultanémentd’indicedansletableau.La
valeur0sertàlirelapremièrecasedutableau.
» Uneaméliorationbienvenueconsisteàrelancerle
tirageausortsilavaleurrenvoyéeestlamêmequela
précédente.Ilesttropfaciledefairedevinerdeuxfois
desuitelemêmenombre.Tupeuxchercherla
solutiontoutseul.Quelquesindices:ilfautune
variablepourlavaleurprécédenteetunenouvelle
fonctionquilanceunnouveautiragetantqu’ilya
doublon.Lasolutionsetrouvedans
l’exempleCH07B_Devinum2.
Pour bien jouer àDevinum, placez-vous devant les LED de sortequecelledel'unitésoitàdroitedevanttoi.C'estleLSB!
RécapitulonsDanscechapitre,nousavonsvu:
» l’utilisationdesbrochesnumériquescommesorties
analogiquesgrâceàlatechniquePWM;
» lestestsconditionnelsetlesbouclesderépétition;
» lestableauxdedonnées;
» l’utilisationduMoniteursérieenaffichageetensaisie.
Dans les prochains chapitres, nous allons mettre en pratique lesconnaissancesdécritesdanscetteSemaine2.
IIISemaine3:Sonetlumière
Aumenudecettesemaine:
Chapitre8:Tabaguettemagique
Chapitre9:Quepersonnenebouge!
Chapitre10:Levoleurdecouleurs
A
Chapitre8Tabaguettemagique
AUMENUDECECHAPITRE:
» Uncapteurdelumièreinvisible
» Unelibrairieavecdesobjetsquiontdelaclasse
» Lagaredetriageswitchcase
» Untableaudetableaux
imerais-tu avoir une baguette magique ? Tu pourrais ainsicommandertoutessortesd’équipementsenenvoyantdesordresde façon invisible. Je suis certain que tu penses déjà à la
télécommandedutéléviseuroudelachaînestéréo.Ilyatellementde boutons sur ce genre d’objet ! Il y a sans doute un code partouche, et un code numérique.Mais comment faire pour capturercescodesafind’influersurunprogrammeArduino?
Le principe est proche de celui qu’utilisent les marins pourcommuniquerentredeuxbateaux:avecunpharedontonouvreetfermelecouverclepourl’allumeretl’éteindre.C’estdoncuncodebinaire, constitué de 0 et de 1. Mais pour que la baguette soitvraimentmagique,ilfaudraitquelerayonsoitinvisible.
Comme toutes les ondes, les ondes lumineuses vibrent à unecertaine fréquence.L’œilhumaindétecteunegammeassez limitéedefréquences:cesontlescouleursdelalumière.Endehorsdecetteplage,nousnevoyonspaslesondes,etpourtantellesexistent.
Heureusement que nous ne voyons pas toutes les ondesélectromagnétiques : stationsde radio, radiosdespompiers et despoliciers,réseauxWi-Fi,téléphonesGSM,radarsdesavionsetdes
aéroports,etc.Nousserionsaveuglés!
Hormislaplagevisible,ilyadeuxpossibilités:unefréquenceplusgrandeoupluspetite.Lesfréquences inférieuresàcellede laplusbasse fréquence détectée par unœil correspondent àmoins rougeque le rouge foncé. Cela s’appelle l’infrarouge. Tout le mondepossèdeaumoinsunexemplairedel’émetteurd’ondesinfrarougesqu’ilnousfaut:unetélécommande(Figure8.1).
Figure8.1:Unetélécommandecommeilenexistedesmillions.
Quand on appuie sur une touche, la télécommande émetenviron 40 000 éclairs de lumière infrarouge par seconde. Ceséclairs représentent des suites de 0 et de 1 binaires. C’est ce quipermet de transmettre les codes numériques des touches de latélécommande.
Figure8.2:Traind’ondesinfrarouged’unetélécommande.
Par exemple, supposons que la touche de la première chaînecorresponde au code numérique 2500 et celui de la deuxièmechaîne, au code 2600. Comment le récepteur du signal va-t-il
distinguer l’envoi de 2500 puis de 2600 de l’envoi en une foisde25002600?
LebonprotocoleImagineque tu rentresdansuneboulangerie et que tudisesd’unetraitececi:«Bonjour,jevoudraisunebaguette,merci,aurevoir.»Si laboulangèreasuffisammentd’humour,elle répondra,pendantque tu refermes la porte : «Bonjour, oui bien sûr, 1,10 euro s’ilvousplaît,bonne journée.»Cen’estpas lebonprotocole : il fautd’abord dire ta première phase, attendre la réponse de laboulangère,direlaseconde,etc.
Pour les codes d’une télécommande, un protocole détermineégalement la façon dont elle doit transmettre les valeurs. Lesprotocoles des télécommandes sont presque normalisés, mais pastotalement. Il y a plusieurs normes car plusieurs fabricants. C’estpour cette raison que l’on trouve dans le commerce destélécommandes dites universelles, c’est-à-dire qui peuvents’adapteràunemarqueouuneautre.
Dans ses grandes lignes, le protocole définit d’abord des codesspéciauxpourdirequ’uncodede toucheva être envoyé,puisquel’envoi est terminé. Mais toute cette analyse va te demander unénormetravaildecodage,non?
Bonnenouvelle:d’autrespassionnésd’Arduinoontdéjàréfléchiàce problème et ont écrit les fonctions permettant de bien recevoirlescodesd’unetélécommandeinfrarouge.Toutescesfonctionsontétéréuniesdansunconteneurappelélibrairieetquetupeuxutilisergratuitementgrâceàl’espritcollaboratifArduino.
Grâce à ces fonctions, tu peux directement récupérer les valeursnumériquesdescodesdes touchesquiontété reçues.Maisau fait,reçuescomment?
Uncapteurd’ondesIR
Bonne nouvelle : pour posséder ta baguette magique, il suffit debranchersurlacarteArduinouncapteurdelumièreinfrarougequine vaut que 1 ou 2 euros et de récupérer une télécommande dontl’appareil commandé a rendu l’âme.Tupeux aussi emprunter unetélécommandedelamaison,carcelanevapasl’endommager.
Tu en sais assez pour te lancer dans la création du projet. Enpratique,chaquecodereçupourraitcontrôlerunebrochedesortienumériquepour,parexemple,activerunrelais,démarrerunmoteurélectrique,faireémettreunsonsurunecarteson,etc.
Mais ce livre a pour but premier de faire découvrir des basessolides en programmation. Je ne vais donc pas te demander desortir le fer à souder.Nous allons nous servir des codes détectéspoursélectionnerdesmembresdephrase,cequidonneraunesortedejeudecréationlittéraire.
ExpressiondesbesoinsNousallonspuiserdansunstockdemots,doncdansdesvariables.Pour que le résultat soit intéressant, il nous faut pouvoir choisirparmi trois possibilités pour chaque morceau de phrase (sujet,verbe, adverbe, complément), ce qui revient à déclarer douzevariables.
Jeteproposedefairequatretoursdesélection.
Àchaquetour, tu tapessurunedestrois touchesdetélécommandequenousprévoyonsdedétecter(enignoranttouteslesautres).
» Aupremiertour,tusélectionnesunsujetparmitrois.
» Audeuxièmetour,tusélectionnesunverbeparmi
trois.
» Autroisièmetour,tusélectionnesunadverbeparmi
trois.
» Auderniertour,tusélectionnesuncomplément
parmitrois.
Comme nous n’utilisons pas d’écran LCD pour l’affichage, lerésultatseramontrédanslafenêtreduMoniteursérie.Biensûr,leschoix peuvent aussi changer l’état de plusieurs broches de sortienumériquesouanalogiques.
Leprojetvaêtreréaliséentroisétapes:
1. Créationdelapartiedécodagedestouches.
2. Ajoutdelalogiquedesélectiondesactionsenfonction
dechaquetouche.
3. Créationd’unconteneuràdonnéespourconstruireles
phrases.
Commençons par la partie proche du matériel : la détection descodesdetouches.
MontageduprojetBagMagikLe montage va être simplissime, puisque nous n’avons besoind’installerquelecapteurinfrarougepuisdebranchersestroisfils.Iln’yamêmepasderésistanceàajouter.
Voicitoutdemêmelapetitelistedescomposantsàréunir:
» lecapteurinfrarougedetypeTSOP38238;
» uneplaqued’essai,mêmeunetoutepetite;
» tacarteArduinoavecsoncâble;
» troisstrapsmâle/mâle,sipossibleunrouge,unnoir
etunjauneouvert.
IdentifionslecomposantcapteurEn observant le capteur TSOP38238 de près, tu constates qu’ilpossèdeunefacebombée,avecunevitresombre,destinéeàlaisserentrer la lumière infrarouge. Voici l’aspect général de ce capteur(Figure8.3).
Figure8.3:Lecapteurinfrarouge.
Pourlerepéragedestroispattesducapteur,c’esttrèssimple.Tiensle capteur entre deux doigts devant toi, en sorte de voir la facebombée:
1. Lapattedegauche(No1)estlapattedesortiedu
signal.
2. Lapattedumilieu(No2)vaverslamasseouGND.
3. Lapattededroite(No3)doitêtrebranchéeaupôle
positif,le5V.
Nouspouvonspasseraumontage.
1. Insèrelecapteurdanstroisrangéesdelaplaque
d’essai,demanièreàpouvoirajouterunboutdestrap
danschacunedesrangées(Figure8.4).
Figure8.4:Montageetbranchementducapteurinfrarouge.
2. Insèreunstrapnoirdanslarangéedelapattedu
milieuetl’autreboutdansunedesdeuxbrochesGND
duconnecteurenbasàgauchedelacarteArduino.
3. Branchelestrap(jaunesipossible)dusignalentrela
rangéedelapremièrepatteducapteuretlabroche
DIGITAL10dansleconnecteurduhautdelacarte.
4. Brancheenfinlefilrougeentrelarangéedelapatte
numérotroisducapteuretlabroche5Vduconnecteur
enbasàgauchedelacarte.
5. Vérifielesbranchementsenrelisantlaprocédure.
Nouspouvonsmaintenantpasseràlarédactiondu
textesource.
Rédactiondutextesourcede
BagMagik1Danslapremièreversionduprojet,nousallonsseulementvérifierque la télécommande renvoie des codes et quenous réussissons àlesdécoder.
Pourfacilitercedécodage,nousallonsutiliserdesfonctionsquisetrouvent dans une librairie créée spécialement pour exploiter uncapteur d’ondes infrarouges tel que le TSOP que nous venonsd’implanter. Il faudra installer cette librairie. Pour ce faire, nousdevronsnousfamiliariseraveclaprogrammationobjets.
Commence par saisir le texte source suivant sans t’inquiéter deslignes qui contiennent des techniques encore inconnues. Il y a eneffet plusieurs nouveautés importantes que je présente après leListing8.1.
Listing8.1:Version1deBagMagik
//BagMagik1
//OEN170314
//Iciviendrauneligne
constintbroCapteurIR=10;//
Broche10pourlecapteur
IRrecvoCapIR(broCapteurIR);
decode_resultsoCodeIR;
voidsetup()
{
Serial.begin(9600);
oCapIR.enableIRIn();//Démarre
récepteurIR
Serial.println("Appuiesurunetouchede
latelco(V1)...");
}
voidloop(){
if(oCapIR.decode(&oCodeIR)){
//
Serial.println(oCodeIR.value,DEC);
Serial.println();
digitalWrite(13,HIGH);
oCapIR.resume();//Code
suivant
delay(250);
}
}
Lapremièreversiondecenouveauprojetn’estpasbeaucouppluslonguequelesprojetsprécédents,maiselleprésenteunenouveautéimmense:ilyadesobjets.Alors,qu’est-cequ’unobjet?
Desobjetspourprogrammer!Jusqu’àmaintenant,tuasutilisé:
» desfonctions,quiconsommentdutempspour
réaliserdesactions;
» desvariables,quiconsommentdel’espacepour
stockerdesdonnéesenmémoire.
Dans lemonde physique, il est souvent logique de regrouper desactions et des informations.Par exemple, unmarteau est constituéd’un manche d’une certaine couleur et d’une tête d’une autrecouleur.Cesontlesdonnéesdumarteau,sesattributs.Lemarteauaégalement la fonction clouer(), qui concentre une énergie
importante sur une surface dure pour, par exemple, enfoncer desclous.
Demême,unanimalpossèdedesattributsetdesactions.Ilestd’unecertaine couleur, il a un certain nombre de pattes, il sait manger,courir,crier,etc.
Les chercheurs enprogrammationont assezvite compris l’intérêtderéunirdesactionsetdesdonnéesdansunpetitconteneurportantunnom.Imaginelestroisvariablesetlestroisfonctionssuivantes:
intiCouleur;
intiPoids;
floatfTaille;
voidcourir(vitesse);
voiddormir(temps);
voidaboyer(volume);
On peut réunir ces six définitions dans un joli coffret que l’onappelleuneclasse.Lesélémentsappartiennentàcetteclasse.Si jenommelaclassechien, jepeuxensuitecréerunobjetàpartirdecetteclasse,cequisignifieinstancierlaclasse.
Pour créer un objet à partir d’une classe, j’utilise le nom de laclassecommesic’étaitunnouveautype.Voicil’écrituregénérique:
nomClassenomNouvelObjet();
Etvoiciunexempleconcretdecréationd’objet:
chienmonToutou();
Je peux ensuite lire et écrire les données qui appartiennent à cetobjetcommececi:
monToutou.iPoids=12;
Jepeuxdéclencheruneactiondel’objetainsi:
monToutou.aboyer(3);
La variable et la fonction, pardon la méthode, appartiennent àl’objet. Pour les utiliser, il est obligatoire d’ajouter le « nom defamille»,c’est-à-direlenomdel’objetpropriétaire,avecunpointséparateur.
Les classes et les objets offrent de nombreux avantages que tudécouvrirasentempsutile.
PremieressaidecompilationAprèsavoir saisi le texte sourcedeceprojet (ou l’avoir récupérédanslesexemples,maisc’estencodantqu’ondevientcoderon),jete propose de lancer une vérification. Inutile de brancher la carte.Nousnesommespasencoreprêtsàtéléverserleprogrammedanslemikon.
1. Lanceunecompilationdutextesourceparla
commandeVérifier.
Normalement,celanedoitpasbiensepasser.Tudois
voirapparaîtreplusieurslignesdemessagesenorange
danslepanneauinférieurdel’atelier(Figure8.5).
Cetteerreuresttoutàfaitnormale.Nouscitonsdansletextesourceunidentifiant,quiestceluidel’objetIRrecv,maislecompilateurnetrouveaucunedéfinitioncorrespondante,nidansletextesource,ni dans aucune des librairies prédéfinies installées d’office avecl’atelier. La librairie qu’il faut ajouter à notre atelier doit êtrerécupéréesurleWebpuismiseenplaceaubonendroit.
Figure8.5:Compilationimpossibleparabsencedelibrairie.
InstallonsunelibrairiePlusieurslibrairiessontdisponiblespourgéreravecplusdeconfortun capteur infrarouge tel que celui implanté dans la carte d’essai.Parmicelles-ci,ilyenaunequiremplittrèsbiensonoffice:cellede Ken Shirriff. Elle est bien sûr gratuite et disponible avec sontextesource.
Lenomquedoitporterlesous-dossierdanslequellalibrairieserarendue disponible pour l’atelier devra s’écrire exactementIRremote. Lorsque tu télécharges la librairie sur le Web, elleporteunnompluslong,qu’ilfaudradoncmodifier.
1. AvectonnavigateurWeb,accèdeàlapaged’accueildu
gisementcorrespondantàlalibrairieIRremote,surle
sitegithub.Tupeuxfaireunerecherchedegithub
IRremotepouréviterdesaisirl’adresse:
https://github.com/z3t0/Arduino-IRremote
2. Tuvoisapparaîtreunelistedenomsdefichiers.Surla
droitesetrouveunboutonvertquetucliquespour
choisirl’optionDownloadZIP.
Figure8.6:Paged’accueildugisementdelalibrairie.
3. Uneboîtestandardestapparuepourtedemanderce
quetuveuxfairedufichierarchive.Répondsquetu
veuxenregistrerlefichier.Turemarquesquelefichier
porteunnomdifférentdeIRremote.
Figure8.7:Boîtestandarddetéléchargement.
4. Uneautreboîtetedemandededéciderdulieude
stockagedel’archive.Choisisparexempleledossier
Téléchargements.
Figure8.8:Choixdulieudestockagedel’archive.
Ledossierdelalibrairieestmaintenantprêtàêtre
réimplanté.
5. Démarresinécessairel’atelierArduino.Danslemenu
Croquis,choisisInclureunebibliothèquepuis
sélectionnelacommandeAjouterlabibliothèque
.ZIP.
Figure8.9:Commandedechargementd’unelibrairieauformatarchive.
Uneboîtedechoixdefichierapparaît(Figure8.10).
Figure8.10:Choixdufichierarchivedelibrairie.
6. Naviguejusqu’àtondossierTéléchargementset
sélectionnelefichier,puisconfirmeavecOuvrir(ou
double-cliquelenomdirectement).
Iln’yaplusqu’àpatienterunpetitpeu.
7. Quittel’atelierArduino.
La librairie est maintenant disponible, mais pour plus de sûreté,nousallonsmodifiersonnom.
RenommonslalibrairieLalibrairieaétéimplantéedansMesdocuments,Arduino.
1. Ouvretonnavigateur,FinderouGestionnairede
fichiers,etaffichelecontenududossiersuivant(soit
Documents,soitMesdocuments):
Documents,Arduino,libraries
Tudoisvoiraumoinsundossier,celuidelalibrairiequi
vientd’êtreinstallée:
Figure8.11:Accèsaudossierdelalibrairie.
2. Sélectionnelenomdudossier(chezmoi,ils’écrit
Arduino-IRremote-master)etutiliselacommande
detonsystèmepourchangerlenom(c’estengénéral
Renommerouparsimpleclicdanslenom).
Voicilenouveau(etvéritable)nomdelalibrairie:
IRremote
Attentionauxmajusculesetminuscules!
3. Démarrel’atelierArduino.Normalement,ledernier
projetencoursestrechargé,doncBagMagik1
(recharge-lesinécessaire).
4. Lanceunevérification.Dorénavant,elledoitréussir,
malgréquelquesmessagesenorange.
Figure8.12:Compilationréussie,avecdesmessages.
Compilation:erreursouavertissements?
Jusqu’à présent, lorsque tu voyais un message orange, c’étaitmauvaissigne : le textesourceprésentaituneerreurempêchantdecompiler.Maistouslesmessagesnesontpasaussigraves.Ilexistedesavertissements(warnings,enanglais)quetupeuxconsulterouignorer, car ils n’empêchent pas de générer le fichier binaire àtéléverser.
Un réglage de la sévérité du compilateur est disponible dans lespréférences.Audépart, ilestrégléàfond: touslesmessagessontaffichés. Tu peux diminuer la sévérité d’un cran pour affichermoinsd’avertissements:
1. Dansl’atelierArduino,ouvrelemenuFichier
(WindowsetLinux)oulemenuArduino(MacOS)pour
choisirPréférencesetouvrirlaboîtedesoptions.
Figure8.13:Lespréférencesdel’atelierArduino.
2. Ouvrelalistedel’optionAvertissementsdu
compilateuretsélectionnePlusaulieudeTout.
RefermelaboîteenvalidantparOK.
Nous allons (enfin) tester le programmepuis revenir sur chacunedesnouvellestechniquesqu’ilcontient.
TestdeBagMagik1Si tuesarrivéàcettesection,c’estque leprogrammesecompile.Les deux messages « Le croquis utilise… » et « Les variablesglobales…»sontapparus.
1. Rebranchelacarteetattends2à3secondes.
2. Lanceletéléversement.N’hésitepasàadopterle
raccourciclaviercorrespondantàlacommande
Téléverser:c’estCtrl+U.
3. OuvrelafenêtreduMoniteursérieetattendsle
premiermessage.
4. Dèsquelemessaged’accueilapparaît,prendsta
télécommandeetviselecapteurinfrarouge.Appuiesur
l’unedestoucheslesplusfacilesàtrouver(nousallons
lesdétecterdanslaversionsuivanteduprogramme).
Figure8.14:ExécutiondeBagMagik1.
Situvoisdescodesayantlavaleur4294967295,ignore-
les.Cesontdescodesderépétitionparcequelatouche
aétéappuyéeunpeutroplongtemps.
VoiciparexemplelecodedelatoucheLECTdema
télécommandedetypeNEC:
1988694255
Biensûr,tatélécommandevaenvoyerd’autresvaleurs
pourlesmêmestouches.
5. Prendsdequoinoterlesvaleursnumériquesdes
touchesquetuveuxutiliser.Iltefautchoisirtrois
touches.J’aiparexemplechoisilestouchesLECT,
PAUSEetAV.RAP.d’unetélécommandequiappartenait
àunvieuxmagnétoscope.
Conserve bien tes codes, car nous allons en avoir besoin dans laprochaineversionduprojet.Maisd’abord,partonsàladécouvertedutextesourceavecunepremièrequestion.
Commentlecompilateursait-iloùtrouverlesdéfinitionsdeclassespourcréerdesobjetsdansleprogramme?Enluiindiquantoùallerleschercher,pardi!
Encasdeconflitdelibrairies...
Normalement, lesimplefaitdechangerlenomdudossierdela
librairie en IRremote suffit à régler un éventuel problème de
conflit avec une autre librairie. Si l’erreur de compilation est
toujours là, il faut supprimer cette autre librairie, quitte à la
réinstallerplustardquandtuenaurasbesoin.Siturencontresce
problème,sers-toidesexplicationsquej’airenvoyéestoutàlafin
decechapitre.
Unedirectived’inclusionTonprogrammenepeut pas utiliser les nouvelles fonctionsde ceprojetsimplementparcequetucitesleurnomdanstontextesource.Lorsquetuécrisunappelàunefonction,lecompilateurtrouvelesinstructions de la fonction (car il a besoin de les compiler)seulementdanslesdeuxcassuivants:
» C’estunefonctionprédéfinie,installéeenmême
tempsquel’atelierIDE.C’estlecasdetoutesles
fonctionsvuesjusqu’àprésent:pinMode(),
digitalRead(),etc.
» C’estunefonctionlocale,c’est-à-direunefonctionque
tuascréée,etdontlecorpsavectoutesles
instructionssetrouveunpeuplusbasdanslemême
textesource.Nousavonsdéjàcrééaumoinsune
fonction«personnelle»dontnouspouvionschoisirle
nom.
Endehorsdecesdeuxcas, tudois informer lecompilateurque tuvas utiliser une fonction qui se trouve dans une librairiecomplémentaire.
Pour réaliser cette déclaration, il faut ajouter tout au début duprogramme ce que l’on appelle une directive. Les directivescommencenttoujoursparunsigne#(etneseterminentjamaisparunsignepoint-virgule!).
Ici,ilnousfautladirective#includequel’onfaitsuivreparlenomdelalibrairie.Voicicommentl’utiliser:
#include<nomFichierDeLibrairie>
Ladirectiveestsuiviedunomd’unfichierditd’en-tête(fichier.hcommeHeader).Cefichierdoitsetrouverdanslesous-dossierdela librairiequenousavons installée.Voici ladirectivequiestdéjàprésentedansnotretextesource(voirleListing8.1):
#include<IRremote.h>
Lorsque le nom du fichier est entouré d’un signe plus petit < àgaucheetd’unsigneplusgrand>àdroite,celasignifiequel’atelierdoit chercher ce fichier dans tous les dossiers standard deslibrairies, c’est-à-diredans le sous-dossierlibrariesde là où
estinstalléleprogramme.Dansnotrecas,ils’agitdusous-dossierlibrariesdeMesdocuments,Arduino.
En revanche, lorsque le nom du fichier à inclure est entouré deguillemets, le fichier est d’abord cherché dans le dossier du textesourcedetonprojet.
Lacompilationréussitparcequedeuxconditionssontremplies:
» LalibrairieIRremoteestinstallée.
» Unedirectiveindiquequ’ilfautallerfouillerdanscette
librairiepourtrouvercequin’estpasdéfinidansle
textesourcelui-même.
Voyonsdoncàquoinoussertcettelibrairie.Revoicilecodesourcedansl’éditeur,afindeserepérerfacilementgrâceauxnumérosdelignesenmargegauche(Figure8.15).
Figure8.15:ÉditiondeBagMagik1.
Comments’utiliseunobjet?Observeladeuxièmelignedans lesdéclarationsglobalesendébutdefichier(numérodeligne7):
IRrecvoCapIR(broCapteurIR);
Celaressembleàunedéclarationdevariable,saufqueletypeestundrôle de type. Ce n’est ni int, niboolean, ni long, nivoid,etc.C’estparcequec’estunnomdeclasse.Lalibrairiequenousavonsinstallée,IRremote,contient ladéfinitiondecetteclasse.Laligneci-dessussertàcréerunobjetquivaincarnerunrécepteurd’ondesinfrarouges.
Lors de la création de l’objet, nous devons fournir entreparenthèses le numéro de la broche sur laquelle doit travaillerl’objetpourinterrogerlecapteurinfrarouge.
Cettedéclarationcréeenungestel’objetettouteslesvariablesqu’ilpossède(lesdonnéesmembres).
Danslalignesuivante,noustrouvonsuneautrecréationd’objet:
decode_resultsoCodeIR;
Je suis allé vérifier parmi les nombreux fichiers que regroupe lalibrairieIRremote:cesecondobjetestbeaucoupplussimplequeleprécédent. Ilnedéfinitaucunefonction,seulementdesvariables(desdonnéesmembres).
J’ai pris soin de faire commencer tous les noms d’objets par lalettreminusculeo, pour que tu saches à toutmoment qu’il s’agitd’unobjet,etnond’unevariableoud’unefonction.
Préparationdel’objetDanslafonctiondeconfigurationsetup(), iln’yaqu’uneligneremarquable,ladeuxième:
oCapIR.enableIRIn();
Cette instruction est un appel à une fonction de l’objet (uneméthode). Cetteméthode fait démarrer le récepteur infrarouge ensortequ’ilse tienneprêtàdétecterdescodes.Lafonctionporte lenom enableIRIn(), (« activer entrée infrarouge » ), maiscommeelleappartientàunobjet,nousdevonspréciser lenomdel’objetpropriétairedelafonctionenséparantlesdeuxparunpoint.
Unefonctionquiappartientàunobjetestengénéraldésignéesouslenomde
méthode(ouparfoisdefonctionmembre).
Utilisationdel’objetNous arriverons ensuite directement dans la fonction de boucleloop().
Cette fonction principale est entièrement occupée par un blocconditionnel if. Autrement dit, lorsque l’expression de test estfausse, on passe directement au tour suivant sans rien faire, pasmêmelapaused’unquartdeseconde.
Étudionscetteexpressionconditionnelle(ligne18):
if(oCapIR.decode(&oCodeIR)){
L’expressionàtesterestenfaitunappelàunefonction,pardonuneméthode de notre objet oCapIR ! Cette méthode decode()renvoieunevaleurdifférentede0siuncodedetoucheaétédétecté.
Ce qui est intrigant est le petit caractère & (on dit « ETcommercial»)quiestaccoléaudébutdunomdel’objetoCodeIR.CesimplecaractèreauneimportanceénormedansleslangagesdeprogrammationdetypeCtelqueceluidel’atelierArduino.
Normalement, lorsque tu indiques le nom d’une variable dans lesparenthèses d’un appel de fonction, c’est la valeur que possède lavariable à cemoment qui est transmise à la fonctionpour qu’elletravailleavec.
Maisici,noustransmettonsàlafonctiondecode()unobjet.Cetobjetn’apasdevaleurausenshabituel:ilcontientdesvariablesquipossèdent chacuneunevaleur.Nuance.Grâce au symbole&, c’estl’adresse à laquelle est stocké l’objet dans la mémoire qui esttransmiseàlafonction.Celle-cipeutainsiremplirlesvariablesdel’objet,cequinouspermettrad’yaccéderensuitepourenobtenirlavaleur.
Ouf ! C’est peut-être l’heure de faire une petite pause, non ?N’hésite pas à relire le paragraphe précédent. Comprendre cemécanismevabeaucouptefaireprogresser.Etdis-toiquesiunpetitcarrédesablepeutenfairesonaffaire,tudoispouvoiryparveniraussi.
Laméthodedecode()aundoubleeffet:
» Ellerenvoieunevaleurdifférentede0seulementsi
ellenerevientpasbredouille.
» Elleremplitunélémentdedonnéesdel’objetoCapIR
avecunevaleurquicorrespondàlatoucheenfoncée
surlatélécommande.
Pour certainsmodèles de télécommandes qui envoient une valeurspécialeencasderépétitiondetouche,ilpeutêtreutiled’ajouterunautretestafind’ignorercecodederépétition.Saurais-tuécrirecetteinstruction?(Réponseenfindechapitre.)
La lignesuivantedemandede lire lavaleurde ladonnéenomméevaluequi appartient ànotreobjetoCapIR.Tu constates que cen’estpas toiquiaschoisi lenomde ladonnée.Cenomestdéfinipar la classe dont est issu notre objet. Voilà pourquoi le nomcompletestmoitiéanglais,moitiéfrançais.Nousfaisonsafficherla
valeur au format décimal par l’option DEC. (Nous pourrionsl’afficherenhexadécimalavecl’optionHEX.)
Suit une instruction facile pour allumer la LED 13 soudée sur lacarte,cequipermetdeconfirmerquandunappuisurunetoucheaétédétecté.
Nousarrivonsàl’avant-dernièreligne:
oCapIR.resume();
Ils’agitd’unappelàuneautreméthodedenotreobjet.Laméthoderesume()sertàreconfigurerl’objetpourqu’ilsoitprêtàcapterleprochaincodedetouche.
Après ces longues explications, je pense que le programme t’estdevenu moins étrange. Nous créons des objets et nous utilisonsleursméthodes et leurs données grâce à la notation fondée sur lepointentrenomd’objetetnomd’élémentd’objet.
Laversion2deBagMagikLa première version du projet nous a permis de vérifier que lecapteur fonctionnait et détectait bien les codes des touches de latélécommande. Nous pouvons maintenant envisager de fairecontrôlerlalogiqueduprogrammeparlestouchesfrappées.Nousallons en profiter pour découvrir une nouvelle techniqued’exécutionconditionnelle,leblocswitch..case.
LagaredetriageswitchTu possèdes sans doute un telliphone (les anglophones disent«smartphone»)?Tuasdoncsansdouteinterrogéetpersonnaliséta messagerie vocale. Tu connais donc le principe des menusvocaux:
«Pourécoutervosmessages,tapez1.Pourmodifiervotre
annonce,tapez2…»
Pour programmer les réponses à ces questions, tu peux alignertouteunesériedetestsdanscestyle:
if(touche==1)lireMsg();
if(touche==2)modifierAnnonce();
//...
if(touche==9)toutEffacer();
Lorsquelavaleuràtesterrestelamêmedansplusieurscas,lemotcléswitchpermetd’éviterlamultiplicationdetestsfondéssurif:
switch(touche){
case1:
lireMsg();
break;
case2:
modifierAnnonce();
break;
//...
case9:
toutEffacer();
break;
default:
//sitoucheinconnue?
}
LeswitchestdélicatPlusieursremarques:
1. Ils’agitbiend’unbloc:ilyauneaccoladesurlaligne
detêteetuneautretoutenbaspourfermerlebloc
switch.
2. Lenombredecasn’estpaslimité,maislavaleurà
comparerdoitêtrefigée,c’est-à-direêtreune
constante.Soittuindiquesdirectementunevaleur
commenouslefaisonsici,soittudéclaresune
constanteendébutdeprogramme:
constlongLECTURE=1988694255;
Tupeuxdanscecasécrire:
caseLECTURE:
Enrevanche,tunepeuxpasindiquerunnomde
variableaprèscase.
3. Touslescasdoiventseterminerparl’instruction
break;pourignorertouslescassuivantsjusqu’à
l’accoladefermantedublocentier.Situl’oublies,les
cassuivantsserontexécutés,mêmesilavaleurne
convientpas.C’estunvraipiège,maisc’estparfois
utile.
Nouspouvonsmaintenantvoircommentceblocswitchestutilisédansleprojet.Ils’étendsurpresque20lignes!
Listing8.2:Version2deBagMagik
//BagMagik2
//OEN170315
#include<IRremote.h>
constintbroCapteurIR=10;//
Broche10pourlecapteur
IRrecvoCapIR(broCapteurIR);
decode_resultsoCodeIR;
unsignedlonggTouche;//AJOUT2
constlongREPET=4294967295;//AJOUT2
voidsetup()
{
Serial.begin(9600);
oCapIR.enableIRIn();//Démarre
récepteurIR
Serial.println("Appuiesurunetouchede
latelco(V2)...");
}
voidloop(){
if(oCapIR.decode(&oCodeIR)){
gTouche=oCodeIR.value;
digitalWrite(13,HIGH);
switch(gTouche){
case1988694255://Touche
LECT
Serial.println(gTouche,DEC);
Serial.println("*Touche1");
break;
case1988739135://Touche
AV.RAP
Serial.println(gTouche,DEC);
Serial.println("**Touche2");
break;
case1988743215://Touche
AV.RAP
Serial.println(gTouche,DEC);
Serial.println("***Touche3");
break;
caseREPET://Codede
repetition
break;
default:
break;
}
Serial.println();
oCapIR.resume();//Code
suivant
}
gTouche=0;
delay(250);
}
Dans la première ligne du bloc switch, nous utilisons commevaleuràtesterunevariabledéclaréeendébutdeprogrammedutypelong, c’est-à-direunevariabledeux fois plus spacieusequ’un int.Cette variable gTouche contient la valeur qui a été extraite del’objetoCodeIRquelqueslignesplushaut.
Ledeuxièmesous-bloccaseindiquecommevaleurlecodedécimaldelatouchedelecture.Biensûr,tudoisremplacercettevaleurparlecodedelatouchequetuaschoisiesurtatélécommande.
LorsquelavaleurdegToucheestidentiqueàcettevaleurlittérale,nous exécutons les trois instructions qui suivent. Les deuxpremièresserventà afficherlavaleurainsiqu’unpetitmessage,et
latroisièmeestlafameuseinstructionspécialebreak;qu’ilnefautjamaisoublier.
Les deux sous-blocs suivants permettent de capturer d’autrestouches.Pourfinir,jeprévoisunfourre-toutquis’appelledefault:.Tupeuxyplacerdesinstructionsspéciales,commefaireafficherunmessagepourdireque la touchefrappéen’estaucunedecellesattendues.
Turemarquesque je remets lavariablegToucheà0à la findutraitement.
Lesautresinstructionsexistaientdéjàdanslapremièreversion.
Tupeuxmaintenantlanceruntestdecetteversion2.Voicicequetudevraisobteniraprèsavoirutilisélatélécommande(Figure8.16).
Figure8.16:Exécutiondelaversion2deBagMagik.
Vérifiequeleprogrammereconnaîtbienlestroistouchesquetuaschoisies.
Pourlaversionfinaledenotreprojet,jeteproposededécouvrirunautreconceptessentieldeprogrammation:letableaudevaleurs.
Laversion3deBagMagikNous allons nous servir de notre télécommande pour puiser dansunesortedepetitdictionnairecontenantdessujets,desverbes,desadverbesetdescompléments.Maiscommentfairepourautomatiserlalectured’unevaleurparmiplusieurs?
Nousdécidonsdepuiserdanslestockdemotssuivant:
» troissujets;
» troisverbes;
» troisadverbes;
» troiscompléments.
Nous ferons quatre tours de boucle pour faire choisir avec latélécommanded’abordlesujet,puisleverbe,etc.
Il va falloir déclarer douze variables pour les douze mots. Lalogiquevaressembleràceci(enpseudocode):
Sitouche1ETTour1AfficherSujet1
Sitouche2ETTour1AfficherSujet2
Sitouche3ETTour1AfficherSujet3
Sitouche1ETTour2AfficherVerbe1
Sitouche2ETTour2AfficherVerbe2
Sitouche3ETTour2AfficherVerbe3
Sitouche1ETTour3AfficherAdverbe1
Sitouche2ETTour3AfficherAdverbe2
Sitouche3ETTour3AfficherAdverbe3
Sitouche1ETTour4AfficherComplément1
Sitouche2ETTour4AfficherComplément2
Sitouche3ETTour4AfficherComplément3
Ouf!Commentfairepournepasavoirtoutescesvariables?
Lasolutionestletableaudedonnées.Nousenavonsdéjàutiliséunpour créer le jeu de lecture binaire Devinum. Mais c’était untableaulinéaire,commeuntrain,untableauàuneseuledimension:
byteayTablo[10];//ProjetDevinum
Pourquoi ne pas entrer dans la seconde dimension ? Allez, onsaute!
Siuntableaupossèdedeuxdimensions,onpeutimaginerdeslignesetdescolonnes,bref,commeunvraitableau,oucommelespixelsd’unécranquisontaussienlignesetencolonnes.
Ilnousfautquatrelignesettroiscolonnes.Maisdequoi?Queltypede données ? Le type chaîne de caractères, c’est-à-dire plusieurscaractèresàlaqueueleuleu.
Pourunseulcaractère,letypeestchar,commedans:
charmaLettre='b';
Turemarquesquelalettreestdélimitéepardesapostrophes.
Pourdéclarerunechaîne,cesontdesguillemets:
constcharmaPhrase="Quandondescenden
ville.";
Enréalité,unechaîneestungroupedecaractères,doncuntableau.Pour en stocker plusieurs dans un tableau, il faut une écriturespécialepourletype:
constchar*monTablo={"Mot1","Mot2",
"Mot3"};
Turemarques:
» Lesigneastérisque*accoléaunomdutypechar.Il
signifiequenoustravaillonsavecl’adressemémoire
dudébutdechaquechaîne.Jen’endispasplusici,car
lespointeurssontunsujetassezsophistiqué.
» Leschaînessontséparéespardesvirguleset
l’ensembleestemballéentredeuxaccolades.
» Lesdéclarationscommencentparlemotconstqui
officialiselefaitquecesmotssontstatiques,définis
dèsledépartetnepeuventpaschangerpendant
l’exécutionduprogramme.Situn’indiquespasconst,
celafonctionnemaisilyauradesavertissementslors
delacompilation.
Pourcreuserlesujetdespointeurs(etd’autres),jeteconseillemonautrelivrechezlemêmeéditeur,ProgrammerpourlesNuls.
Voicidonccommentnouspouvonsinstallerenmémoireuntableaudemots.Nousindiquonslesdeuxdimensionsentredeuxpairesdecrochets après le nom du tableau. Les espaces en trop servent àrendreleslignesetcolonnespluslisibles.
constchar*tabmots[4][3]={
{"Sujet1","Sujet2","Sujet3"},
{"Verbe1","Verbe2","Verbe3"},
{"Adverbe1","Adverbe2","Adverbe3"},
{"Comple1.","Comple2.","Comple3."}
};
Pour puiser un mot dans le tableau et l’afficher, nous écrironscommececi:
Serial.print(tabmots[tour][0]);
En fonction de la valeur detour, cela affichera Sujet1, Verbe1,Adverbe1ouComple1.
Nousallonsainsipouvoirautomatiser l’utilisationdu tableaudansnotre bloc conditionnel switch. Découvrons donc le texte sourceavantdepasserautest.
Listing8.3:Version3deBagMagik
//BagMagik3
//OEN170315
#include<IRremote.h>
constintbroCapteurIR=10;//Broche
num10pourlecapteur
IRrecvoCapIR(broCapteurIR);
decode_resultsoCodeIR;
unsignedlonggTouche;
constlongREPET=4294967295;
bytemot=0;//
AJOUT3
char*tabmots[4][3]={//AJOUT3
{"Je","Lechat","Lavoisine"},
{"mange","pense","bouge"},
{"sanscesse","lentement","parpur
plaisir"},
{"lanuit.","lemidi.","depuisdeux
jours."}
};
voidsetup()
{
Serial.begin(9600);
oCapIR.enableIRIn();//Démarre
récepteurIR
Serial.println("Appuiesurunetouchede
latelco(V3)...");
}
voidloop(){
if(oCapIR.decode(&oCodeIR)){
if(mot>3)mot=0;//
AJOUT3
gTouche=oCodeIR.value;
afficherCode(gTouche,mot);//
AJOUT3
digitalWrite(13,HIGH);
oCapIR.resume();
mot++;//
AJOUT3
}
if(mot>3){Serial.println();mot=0;
}//AJOUT3
}
//AJOUT3
voidafficherCode(unsignedlongcode,byte
tour){
switch(code){
case1988694255://ToucheLECT
Serial.print(tabmots[tour][0]);
break;
case1988739135://Touche
PAUSE
Serial.print(tabmots[tour][1]);
break;
case1988743215://Touche
AV.RAP
Serial.print(tabmots[tour][2]);
break;
//caseREPETinutile,voirdefault:
default:
mot--;
break;
}
}
Saisis ce texte source en repartant de la précédente version,BagMagik2. J’indique les nouveautés par des commentaires definsdelignes.
AnalysedeBagMagik3Nousdéclaronsunenouvellevariablepouravancerd’uneligneàlasuivante dans le tableau, d’abord parmi les sujets, puis parmi lesverbes,etc.Cettevariablemotvavarierentre0et3,puisrevenirà0:
bytemot=0;
Arrive ensuite l’énorme déclaration du tableau de mots. Observebien les virgules et les accolades internes. Voici lemême tableauaprèsajoutd’espacesd’alignement:
char*tabmots[4][3]={
{"Je","Lechat","Lavoisine"
},
{"mange","pense","bouge"
},
{"sanscesse","lentement","parpur
plaisir"},
{"lanuit.","lemidi.","depuisdeux
jours."}
};
Rien n’a changé dans la fonction de préparation setup(). Laboucleprincipaleamaigri:toutleblocswitchestvenuformerlecontenu d’une nouvelle fonction qui est appelée depuis loop()seulementquandunetoucheestdétectée.
Maisd’abord,noustestonslavariablequidécidedunumérodutourde boucle. Si elle vaut plus de 3, c’est que nous avons fait quatretours (de 0 à 3). Nous repartons donc au début d’une nouvellephrase:
if(mot>3)mot=0;
Nous récupérons le code de touche dans une variable commeauparavant,puisnousappelonslanouvellefonctionaveccecodeetlenumérodetour:
afficherUnMot(gTouche,mot);
Nousn’oublionspasd’incrémenterlecompteurdetours:
mot++;
Une fois sortis du bloc conditionnel, nous pouvons tester si laphrase est terminée et, si oui, provoquer un saut de ligne tout enremettantlecompteurà0:
if(mot>3){Serial.println();mot=0;}
Voyonslesnouveautésdelafonctionquenousappelonset,d’abord,salignedetête:
voidafficherUnMot(unsignedlongcode,byte
tour){
Ellenerenvoierien,maisattenddeuxparamètresd’entrée:lecodede toucheet lenumérode tour.Tuconstatesque lenom localdesdeuxvariables peut être différent du nomd’origine :codepourgToucheettourpourmot.C’estunebonnepratique.
Lasuitedelafonctionnousestdéjàconnue.Lavraienouveautéestl’accèsàunmotdutableau,commececi:
Serial.print(tabmots[tour][0]);
Cetteinstructionlitlemotstockéàl’intersectionentre:
» lapremièrecolonnedutableau(lacolonne0);
» lalignedésignéepartourquipeutvaloirentre0et3.
Uneparticularité concerne labranche fourre-toutdefault.Nousyfaisons reculer le compteur de tours d’une position avecmot--.Pourquoi?Parcequenousnevoulonspaspasseràlalignedemotssuivantesilatouchefrappéen’estaucunedecelleschoisiespourlejeu.
Etmaintenant,enavantpourlestests!
Testduprojet1. TéléverseleprojetpuisouvreleMoniteursérie.
2. Dèsquelemessagedebienvenueapparaît,combine
dedifférentesmanièreslestroistoucheschoisiespour
générerdesphrasesplusoumoinsloufoques.
Sais-tucombiendephrasesdifférentestupeux
générer?
Voiciunaperçudesphrasespossibles(Figure8.17).
Figure8.17:QuelquesphrasesproduitesavecBagMagik3.
RécapitulonsEtvoiciencoreunchapitrecopieuxquisetermine!Nousavonsvu:
» l’exploitationd’uncapteurinfrarouge;
» l’installationetl’utilisationd’unelibrairiedefonctions
etdeclasses;
» unpremieraperçudelaprogrammationorientée
objets;
» lesblocsconditionnelsswitchcase;
» lestableauxàdeuxdimensionsetleschaînes.
Nous pouvons ainsi clore la Semaine 2. Dans la suivante, nousallons mettre en pratique, par des projets simples, toutes lestechniquesquenousvenonsdedécouvrir.Àtoutdesuite(aprèsunpeuderepos!).
Réponsepourl’instructiondefiltragedecodederépétitionCette instruction est à insérer juste après le premier testconditionneldeBagMagik2,danssonbloc:
if(oCodeIR.value==4294967295)
oCapIR.decode(&oCodeIR);
L
Chapitre9Quepersonnenebouge!
AUMENUDECECHAPITRE:
» Encoredesinfrarouges?
» LecapteurPIR
» Faitesdubruit!
» Tonsystèmed’alarmepersonnelle
a lumière infrarouge ? Oui, celle qui sert aux télécommandes.Maisellenesertpasqu’àchangerdechaînesur son téléviseur.Tout ce qui n’est pas à lamême température que les objets qui
l’entourentpeutêtredétectéparsonrayonnementinfrarouge.
Biensûr,ladétectionseramoinsfacileavecunanimalàsangfroidtelqu’unserpent.Jenetegarantisdoncpasquelesystèmed’alarmequenousallonsconstruiredanscechapitrevapermettrededétecterl’arrivéede l’anacondagéant.Enrevanche,celafonctionneraavecunêtrehumain(pasunrobot)etparfoismêmeavecunpetitanimaldecompagnie,sileréglagedesensibilitélepermet.
Lecapteurquenousallonsutiliserestdutypetoutourien:soitiladétectéunmouvement,soitiln’ariendétecté.Lasortieestdoncdutypenumériquebinaire:soit0,soit1.
Cedétecteurdeproximitéestengénéraldésignéparlesfabricants«capteurPIR».LesdeuxlettresIRsignifient«InfraRouge».LalettrePadeuxsignifications:ProximitéouProche:
1. C’estuncapteurdeproximité,parcequ’ilne
fonctionnequ’àquelquesmètresaumaximumdesa
cible.
2. C’estuncapteurconçupourdétecterlesondes
infrarougesproches,dansunegammedefréquences
justeinférieureàcellesdescouleursdelumière
visibles.Ilexisteaussidesinfrarougesmoyenset
lointainsquenousn’étudionspasici.
ThéorieducapteurPIRL’apparencephysiqueducapteurPIResttrèsdifférentedecelledesautres capteurs. Il comporte en effet une demi-boule en plastiquetranslucide. C’est en fait une lentille de Fresnel qui concentrecorrectement les rayons infrarouges pour qu’ils viennent serejoindresurlatoutepetitesurfaceducapteurquiestcachésousledôme.
Voici l’aspect d’un capteur PIR avec son dôme reconnaissable(Figure9.1).
Figure9.1:VuecôtécircuitetcôtélentilleducapteurPIR.
Le capteur fonctionne par comparaison des deux moitiés de sonchamp de détection, en découpant ce dernier en zones grâce à lalentille(Figure9.2).
Figure9.2:LalentilledeFresnelconcentrelesrayonsinfrarouges.
PratiqueducapteurPIRLorsqu’il estmis sous tension, il faut laisser au capteur quelquessecondes pour qu’il dresse le tableau de son champ de détection.Rien ne doit bouger pendant cette phase de calibration. Une foisqu’elle est terminée, le capteur est capable de détecter lamoindredifférenceparrapportàlasituationqu’ilaétablie.C’estpourcetteraisonqu’ilfautégalementluilaisserunpetittempsdepauseaprèschaquedétectionpourqu’ilreconstruisesonmodèle.
Imagine que tu démarres le capteur puis que tu viennes t’asseoirdans son champ de vision. Il va détecter les mouvements quicorrespondentàtonarrivée.
Siturestesensuiteassissansbougerpendantquelquessecondes,lecapteur va reconstruire l’image du champ de détection fixe. Cettenouvelleimagevatenircomptedetonrayonnementinfrarouge,ettunevasplusdéclencher le capteur.Mais il te suffirade leverundoigtpourledéclencherensuite.
MontageducircuitGardien
Lemontageducircuitducapteurestextrêmementsimplepuisqu’ilsuffitderelierses troisbrochesà tacarteArduino.Tun’asmêmepasbesoindepasserparuneplaqued’essai.Cecidit,jeteconseillede l’utiliser, car tu auras besoin de cette plaque pour brancher unsecondcomposantdanslasuiteduchapitre.
Aucune résistance n’est à ajouter. Le capteur possède son proprerégulateurdetension.
1. Prendsunstraprougemâle-femelleafindepouvoir
brancherlecôtéfemelledanslabrochemarquée5V
ouVccducapteur.Branchelecôtémâlen’importeoù
dansundesdeuxrailsdedistributionrougesmarqués
+ou5Vsurlaplaqued’essai.
Sitoncapteurestdotédebrochesfemellespourses
sorties,utilisedesstrapsmâle-mâle.
2. Branchelabrochedusignal(normalementlabroche
marquéeOUTdumilieusurlecapteur)avecunstrap
jaune,vertouorangemâle-femelleentrelecapteuret
labrochenumérique7duconnecteurDIGITALsurla
carteArduino.
3. Brancheunstrap(noirdepréférenceoumarron)entre
labrochedemasseGNDducapteuretundesdeux
railsdedistributionbleusounoirsmarqués–ouGND
surlaplaqued’essai.
4. Avecunstrapmâle-mâlerouge,relielerail+5Vdela
plaqueàlabroche5Vdelacartepuis,avecunnoir,le
rail–(GND)àunedestroisbrochesGNDdelacarte
Arduino.
Lemontageestterminé!
Figure9.3:MontageduprojetGardien.
L’écrituredutextesourcepourraitnousréserverquelquessurprises.Nous n’allons donc pas nous jeter la tête la première dans larédaction, classique erreur du débutant en programmation. Nouspassons par une première phase d’étude de l’algorithme, c’est-à-diredesgrandeslignesdelalogiquedefonctionnement.
L’algorithmededétection1. Audépart,lecapteurdoitfairel’inventairedecequ’il
voitetcalculerl’équilibreentrelesdeuxmoitiésdeson
champdesurveillance.
Lecapteurdemandequelquessecondes(de10à30)
pourdresserceportraitIRdelascène.C’estla
calibrationinitiale(étalonnage).
2. Maisaprèschaquedétection,lascèneayantsans
doutechangé,ilfautànouveaulaisserlecapteur
refairel’analysedecequ’ilvoit.
Ilfautdoncinterdirelaréactionàunenouvelle
détectionpendantcetemps.Eneffet,ladétectionpar
lecapteurabienlieumaisellen’estpasexploitable.Il
fautquelecalmesoitrevenupourdétecterunvrai
nouveauchangement.
Nousallonsavoirbesoind’unevariablebooléenneque
l’onvaarmer(1)pourautoriserladétection,et
désarmer(0)pourlasuspendre.Nommons-la
bOKDetect.
3. Ilfautaussidémarrerunchronomètredèsqu’une
détectionaeulieu,maissurtoutnepaslerelancertant
qu’iln’yaplusdemouvement.Sinon,onn’arrivejamais
auboutdutempsderecalibration.
Ilfautdoncprévoirunesecondevariablebooléenne
quel’onvaarmer(mettreà1)pourforcerle
redémarrageduchronomètre,etdésarmerpour
l’interdire.JelanommebRedemarrerKrono.
4. Pourmesurerl’écoulementdutempsderecalibration,
nousprévoyonsunevariablespacieuse(dutypelong)
quivamémoriserunnombredesecondesdepuisle
démarrageduprogrammeeninterrogeantlafonction
prédéfiniemillis().Poursavoirsiletempsde
recalibrationestécoulé,ilsuffirad’interrogerà
nouveaucettefonction.
Parexemple,silechronoaétédémarréà15secondes,
avecunepausede5secondes,ladétectionserade
nouveauautoriséeseulementquandl’appelà
millis()renverraaumoinslavaleur21.
5. Ladonnéequivadéterminerlalogiqued’actionest
l’étatdelabrochedesignalducapteurPIR.
Sielleestà1(HIGH),ilyaeuMouvement.
Sielleestà0(LOW),c’estlasituationdeCalmeplat.
6. Voicilesblocsconditionnelsàécrire:
Situationdecalmeplat
a. SICalmeplatETSIDétectionsuspendueETSITemps
derecalibrationécoulé:
Armerladétection.
b. SICalmeplatETSIDétectionsuspendueMAISTemps
derecalibrationpasécoulé:
Nerienfaire(Laisserladétectionsuspendue).
c. SICalmeplatETSIRedémarragechronoautorisé(un
mouvementvientd’êtredétecté):
Lancerlechronomètredelapausederecalibration.
Empêchersonredémarrageavantlaprochaine
détection.
Situationdemouvementdétecté
a. SIMouvementdétectéMAISDétectionsuspendue
(pendantlarecalibration)
AutoriserRedémarragechronodepause(prolongela
recalibration).
b. SIMouvementdétectéETSIDétectionarmée:
Déclencherl’alarme.
Suspendreladétection.
AutoriserRedémarragechronoderecalibration.
Lancerlechronoconsisteàrécupérerl’heureactuellecommeheurede départ de la recalibration grâce à la fonction standardmillis().
LaFigure9.4montrel’algorithmecorrespondant.
Figure9.4:Algorithmed’exploitationducapteurPIR.
RédigeonsletextesourceGrâceànotreétudepréalable, l’écriturevaêtreassez facile.Nousallons définir quelques variables globales, écrire le code decalibration dans la fonction setup() puis, dans la boucleprincipale,prévoirdeuxgrosblocsconditionnels:
» lepremierblocpourlecasoùrienn’aétédétecté;
» lesecondbloclorsquelecapteurvientdedétecterun
mouvement.
Voici d’abord le texte source complet tel que je te propose de lesaisir (ou de le récupérer dans l’archive des exemples si cela teparaîttroplong).TupeuxchoisircommenomdeprojetGardien.
Jerappellequ’ilestconseillédeprendreletempsdesaisirlecodepourencoremieuxlemaîtriser.
Listing9.1:Version1duprojetGardien
//Gardien1
//OEN170321
constbyteyBroPIR=7;
constbyteyBroLED=13;
constbyteyTempsKalib=10;//Max30
secondes
unsignedlonggDebutKrono;
unsignedlonggPause=1000;//Max
5000millis
booleanbOKDetect=true;
booleanbRedemarrerKrono;
/////////////////////////////
voidsetup(){
Serial.begin(9600);
pinMode(yBroPIR,INPUT);
pinMode(yBroLED,OUTPUT);
digitalWrite(yBroPIR,LOW);
Serial.println("**ProjetGARDIEN.
Calibrationdusenseur.");
Serial.print("**Quepersonnenebouge.On
patiente.");
for(inti=0;i<yTempsKalib;i++){
delay(1000);
Serial.print(".");
}
Serial.println("C'estparti!");
delay(50);
}
////////////////////////////
voidloop(){
if(digitalRead(yBroPIR)==LOW){
if(bRedemarrerKrono){
gDebutKrono=millis();
bRedemarrerKrono=false;
}
if(!bOKDetect&&((millis()-
gDebutKrono)>gPause)){
bOKDetect=true;
delay(50);
bavarder(1);
}
}
if(digitalRead(yBroPIR)==HIGH){
if(bOKDetect){
bavarder(0);
Serial.println("Alarme!Alarme!
Alarme!");
delay(50);
bOKDetect=false;
}
bRedemarrerKrono=true;
}
}
voidbavarder(bytebType){
if(bType==0){
Serial.println("---");
Serial.print("Quelquechosebouge.
Instant:");
Serial.print(millis()/1000);
Serial.println("secondes");
}
if(bType==1){
Serial.print("Lecalmeestrevenuau
boutde:");
Serial.print((millis()-
gPause)/1000);
Serial.println("secondes");
}
}
Enroutepourlavisiteguidée:
1. Endébutdeprogramme,nousdéclaronstrois
constantespourlesdeuxbrochesetpourladuréede
calibration.Cetteduréeestàchoisir
entre10et30secondes,selonlemodèleexactdu
capteurdonttudisposes.Unevaleurde10convient
généralement.
2. Nousdéfinissonsensuitedeuxvariablestrès
spacieuses,dutypeunsignedlong,cequipermetde
compterjusqu’à4milliardsdemillisecondes,soit
environ45jourssansmouvementavantquele
chronomètrerepartede0:
unsignedlonggDebutKrono;
unsignedlonggPause=1000;//Max5000
millis
Ladeuxièmevariabledutypelongauraitpuêtreplus
compactepuisquenousn’ystockonspasdevaleur
supérieureà5000.Nousaurionsmêmepulachoisirde
typeconst.Pourquecesoitcohérentavecsacollègue,
nousavonsuniformiséletype.Audiable,lesvarices!
Tuconstatesaupassagequeladuréederecalibration
estplusfaiblequecelledupremierdémarrage.
3. Noustrouvonsensuitelesdeuxvariablesdecontrôle
dutypebooleandontnousavonsparlédansl’étudede
l’algorithme.Nousdonnonsàlapremièrelavaleur
initialetrue(1)afind’êtreprêtsdèsledépartàdétecter
unmouvement.
booleanbOKDetect=true;
booleanbRedemarrerKrono;
4. Nousarrivonsensuitedanslafonctiondepréparation
setup().Labouclederépétitionforpermetd’imposer
undélaidedixfoisunesecondepourlaisserletemps
aucapteurd’inventoriersonchampdevision:
for(inti=0;i<yTempsKalib;i++){
delay(1000);
Serial.print(".");
}
5. Nousarrivonsalorsdanslaboucleprincipale.Onvoit
clairementqu’ilyadeuxblocsconditionnels.Chacun
contientunoudeuxsous-blocsconditionnels.
6. Lepremierblocconditionnelgèrel’absencede
mouvement:
if(digitalRead(yBroPIR)==LOW){
Danscecas,nouscommençonsunenouvellephasede
recalibrationseulementsilavariable
bRedemarrerKronolepermet:
if(bRedemarrerKrono){
gDebutKrono=millis();
bRedemarrerKrono=false;
}
7. Lesecondtestestpluscompliquécarilesthybride:
if(!bOKDetect&&((millis()-
gDebutKrono)>gPause)){
Puisquelaconditionréunitdeuxexpressionspar
l’opérateur&&(ET),lesdeuxdoiventêtrevraies(valeur
différentede0)pourqueletestpasse.Cetestne
réussitquesi:
a. ladétectionn’estPASautorisée(!
bOKDetect);
ETSI
b. simultanément,letempsderecalibration
minimals’estécoulé.Pourlesavoir:
noussoustrayonsaunombredesecondesactuel
(letempsécoulételquerenvoyéparlafonction
standardmillis())letopdépartstockédansla
variableduchronomètre;
nouscomparonscettevaleurautempsdepause
derecalibrationminimal.
((millis()-gDebutKrono)>gPause)
Ondoitavoirautantdeparenthèsesouvrantesquede
parenthèsesfermantes.
Siletestréussit,nousautorisonsànouveaula
détection:
bOKDetect=true;
Turemarquesl’appelàunefonctionbavarder()avec
leparamètreégalà1.Cettelignepeutêtremiseen
commentairessitun’aspasbesoindel’affichage.Pour
lemoment,c’estleseulmoyenquenousayonsde
savoirquel’alarmesedéclenche.
8. L’autreblocconditionnelgèrelecasd’unedétection
parlecapteur.Siunmouvementaétédétecté,nousne
déclenchonspasobligatoirementl’alarme,mais
seulementsiladétectionaétéautorisée.Siellenel’est
pas,nousnouscontentonsdefaireredémarrerle
chronomètre,carunnouveaumouvements’est
présentéalorsquenousétionsdéjàenphasede
reconstructiondel’image.Jacquesadit:«Pas
bouger!»
Iciaussi,nousappelonslafonctionbavarder()avec
leparamètreégalà0.
9. Nousarrivonsenfinàcettefonctionlocalequi
s’occupedetouslesaffichages,encasderecalibration
etdedétection.
TestduprojetUne fois le programme saisi ou chargé, vérifie toutes lesinstructionspuislanceuntéléversementaprèsavoirbranchélacarteArduino.
Dèsquelacompilationaréussi,ouvrelafenêtreduMoniteursérie.Àpartirdecemoment,nebougeplusdutout.Observelepassagedelaphasedecalibration(Figure9.5).
Ne t’inquiète pas si la détection ne semble pas fonctionnerimmédiatementaprèslafindelacalibration.Ilfautparfoisunpeuplus de temps au capteur, d’autant que cela dépend également du
réglagedesdeuxpotentiomètresquisontnormalementprésentssurlecircuitducapteur.
RéglagesfinsL’un des potentiomètres du capteur sert à régler la portée de ladétection qui peut aller de quelques centimètres à 6 m environ.L’autrepotentiomètre sert à réglermanuellement ledélaiminimalavant la prochaine détection. A priori, il n’est pas nécessaire detoucheràcesréglages,saufs’ilsontétémodifiésparerreur.Danscecas,tuferasdesessaispartâtonnementssuccessifs.
Notre capteur fonctionne donc correctement, mais dans cettepremièreversion, nousne faisonsqu’afficherunmessagedans leMoniteursérie.Voyonsdonccommentutiliserunhaut-parleurpourfaireretentirunevéritablealarmesonore.
Figure9.5:ExécutiondeGardien1.
UnealarmeaudioLe son est un phénomène analogique : une corde ou une peau detambourvibrent commeunebalançoire jusqu’à revenir à l’état derepos.Commentgénérerdusonavecunemachinenumérique?
Faitesdubruit!Sur un tambour : la peau est tendue. Quand on la frappe, elle estrepousséeenarrière.Dufaitqu’elleestélastique,ellerevientunpeutrop,puisrepartenarrière,etc.
Dansunhaut-parleur,l’équivalentdelapeauestlamembrane.Elleestmaintenueenplaceparunaimantenformedebâton.Cetaimantestpermanent.Ilcréeunchampmagnétiquesansavoirbesoind’êtrealimenté.
Onenroulesansserrerautourdubâtonunebobinedefiletonfixelamembrane en papier à cette bobine. Les deux bouts de fil sontreliésàdeuxbornesisolées.
Quand du courant passe dans la bobine, cela crée un champmagnétique qui fait coulisser la bobine et donc la membrane enpapier sur le bâton, ce qui repousse l’air de part et d’autre. Lerésultats’entend,commelesvibrationsd’unepeaudetambour.
Chaquealler-retourdelabobinegénèreuneondedansl’air,commeune vaguelette à la surface de l’eau. Si la bobine fait 440 allers-retours en une seconde, on dit que la fréquence du son estde440Hz(hertz).
L’unité«hertz»aétéchoisieenl’honneurduchercheurallemandHeinrichRudolfHertz(1857-1894).
Figure9.6:Principed’unhaut-parleur.
Enfaisantalternerl’étatd’unebrochedesortienumériquedenotremikon,ondoitpouvoirgénérerunson?C’estcequenousallonsprouver.
LaFigure9.7montre l’onde tellequ’enregistrée avec lapremièreversiondenotreprojet.L’outilutiliséestAudacity.
Figure9.7:Visualisationd’uneondeacoustique.
Commençonsparconstruirelecircuit.
MontagedeSonnerPourfairenostests,nousn’avonsbesoinqued’unpetithaut-parleuretd’unerésistancede100à270ohms.
Unedes valeurs-clés des haut-parleurs est l’impédance. C’est unpeu comme une résistance et on utilise d’ailleurs la même unité,l’ohm.Ladifférenceestquecetteimpédancevarieenfonctiondelafréquence. La plupart des petits haut-parleurs ont une toute petiteimpédance de 8 ohms. Il faut donc ajouter une résistance pourprotéger le mikon. Une valeur de 220 ou 270 ohms conviendra.Cela va énormément limiter le courant dans la bobine du haut-parleur,maisilresteraassezd’énergiepourquetul’entendes.
Si tu récupères un des haut-parleurs des oreillettes d’un casquestéréo, l’impédance est souvent de 32 ohms. Tu peux dans ce cas
choisirunerésistanceplusfaible,parexemplede100ohms.
Voicicommentmontercecircuit:
1. Silehaut-parleurn’estpasmunidedeuxfilssoudés,et
puisquenousnefaisonsaucunesoudure,procède
ainsi:
a.Sacrifiedeuxstrapsavecaumoinsuncôtémâle,un
rougeetunnoir.Pourchacund’eux,coupele
connecteurd’uncôté,dénudelefilsur1cmpuis
entortille-lesurlui-même.
b.Faispasserleboutd’unfildansuneoreillede
connexionduhaut-parleur(Figure9.8),faisuneboucle
etentortillelesdeuxbrinspourquelaconnexion
tienne.Biensûr,situtiresdessus,celanerésisterapas.
c.Faisdemêmepourl’autrefil.
Figure9.8:Lesbornesdeconnexionduhaut-parleur.
2. Installelarésistancede220ou270ohmssurlaplaque
d’essai,unepattedansleraildunégatif(0V)etl’autre
pattedansunerangéelibre.
3. Connecteleraildunégatifdelaplaqueàl’undes
connecteursdemasseGNDdelacarteArduino.
4. Branchelefilnoirduhaut-parleurdanslarangéedela
plaqueoùarrivelarésistance.
5. Branchelefilrougeduhaut-parleuràlasortie
numérique8duconnecteurDIGITALdelacarte
Arduino.
Lemontageestterminé(Figure9.9).
Figure9.9:MontageduprojetSonner.
Pousserl’airavecdes0etdes1!Pour déplacer la bobine, il nous suffit d’envoyer avecdigitalWrite()une alternancede1 et de0 sur la brochedesortie.Cequivadéciderdelafréquencedelanote(sahauteur)estletempspendantlequelnousallonsresterdanslemêmeétathautoubas.
Nousallonsécrireunebouclederépétitiondanscestyle:
1. Mettrelasortieàl’état1(ducourantpassedansla
bobinequisedéplace).
2. Attendreuntoutpetitpeuavantdebasculer.
3. Mettrelasortieàl’état0(labobineestramenéeau
reposparl’aimant).
4. Attendreuntoutpetitpeuavantderebasculer.
Les étapes d’attente 2 et 4 vont déterminer la hauteur. Au lieud’utiliser la fonction delay(), bien connue maintenant, nousadoptons sa variante mille fois plus précise,delayMicroseconds().
digitalWrite(iBroSON,1);
delayMicroseconds(hauteur);
digitalWrite(iBroSON,0);
delayMicroseconds(hauteur);
Cesquatreétapesvontêtrerépétéesaumoinscentfoispourquelesonsoitbienaudible(àmoinsde10tours,onn’entendplusqu’unplop).
CodagedeSonner1Nous déclarons deux variables de type int dans la boucleprincipale:
iHauteur=800;
iDuree=100;
La première contient des millisecondes et l’autre, un nombre detoursdebouclederépétition.
Aprèsl’émissiond’unbip,nousimposonsundélaipourleséparerdusuivant.
Listing9.2:CH09B_Sonner1.ino
//Sonner1
//OEN170325
constintyBroSON=8;
voidsetup(){
pinMode(yBroSON,OUTPUT);
}
voidloop(){
intiHauteur=800;
intiDuree=100;
for(inti=0;i<iDuree;i++){
digitalWrite(yBroSON,1);
delayMicroseconds(iHauteur);
digitalWrite(yBroSON,0);
delayMicroseconds(iHauteur);
}
delay(200);//Entre2bips
}
Après avoir saisi ce programme, vérifie si nécessaire lesbranchements,puistéléverse.
Si le son est trop fort, augmente la valeur de la résistance (sansoublierdedébrancherd’abord!).
Nous venons de créer un son typique des alarmes de tous lesappareilsnumériques.Rapidementénervant,non?
Au lieu de gérer nous-mêmes la production du son, voyonscommentprofiterd’unefonctionstandardinstalléeenmêmetempsquel’atelierArduino:lafonctiontone().
Sonne,ohtone()Lafonctiontone()etsacollèguenoTone()sontdéfiniesdansune librairie standard. Il n’y a donc pas besoin d’ajouter unemention#include"NomLibrairie"audébutdenotreprojet.
Les deux différences majeures avec digitalWrite() sontcelles-ci:
» nouspouvonsdirectementindiquerenhertzla
hauteurdelanoteàjouer;
» lanotecontinueàêtreémiseencontinu.C’est
pourquoiilfaututiliserl’autrefonction,noTone(),
pourretrouverlesilence.
CodagedeSonner2
Listing9.3:CH09B_Sonner2.ino
//Sonner2
//OEN170325
constbyteyBroSON=8;
voidsetup(){
pinMode(yBroSON,OUTPUT);
}
voidloop(){
intiHauteur=440;//LeLAdes
musiciens
intiDuree=200;
sonner(iHauteur,iDuree);
delay(500);//Silence
entrenotes
}
voidsonner(intiFreq,intiLongueur){
tone(yBroSON,iFreq);
delay(iLongueur);
noTone(yBroSON);
}
Lance un test. Le résultat sonore est quasiment identique.Dorénavant, bien des choses deviennent envisageables. Parexemple:
» PouriHauteuretiDuree,tupeuxdéfinirdeux
tableauxdevaleurscontenantleshauteursetles
duréesdesnotesd’unemélodie.
» Tupeuxprofiterd’unfichierdedéfinitionnommé
pitches.hquicontientuneéquivalenceentreles
fréquencesetdesnomsdelaplupartdesnotes
audibles.Ilfautdanscecasajouterunedirective
#include"pitches.h"endébutdefichieretplacerune
copiedecefichierdanslemêmesous-dossierquele
textesource.
Allonsunpeuplusloinenconcevantuneanimationsonorepourunsignald’alarme.
Unesirènesansécailles
La musique et les mathématiques sont très liées. Pendant desmillénaires, les quatre matières principales à l’école (lequadrivium)étaient:
» l’arithmétique,
» lagéométrie,
» lamusique,
» l’astronomie.
Lesonet leschiffres font trèsbonménage.Et lemikonadore leschiffres!
Pour concevoir une vraie sirène qui monte dans les aigus etredescend,ilsuffitdecréerdeuxbouclesderépétition:
» unebouclequimontedehertzenhertz;
» unesecondebouclequidescenddehertzenhertz.
Celavaconstituerunaudiomotif!
Passonsdirectementàlamiseenpratique.Jeproposedebalayerlaplagedefréquencesentreleladudiapasonet2000Hz.
Listing9.4:CH09B_Sonner3.ino
//Sonner3
//OEN170325
constbyteyBroSON=8;
voidsetup(){
pinMode(yBroSON,OUTPUT);
}
voidloop(){
alarmer();
//delay(500);//Facultatif
}
voidalarmer(){
constintiBasse=440;
constintiHaute=2000;
for(inti=iBasse;i<iHaute;i++){
tone(yBroSON,i);
delay(1);
}
for(inti=iHaute;i>iBasse;i--){
tone(yBroSON,i);
delay(1);
}
noTone(yBroSON);
}
TestdeSonner3J’imagine que tu devines quel résultat tes oreilles vont pouvoirvérifier : une vraie sirène d’alarme ! Dans la prochaine section,nousallonsréinjecterlafonction
CommentairessurSonner3Dans la fonction alarmer(), nous trouvons deux blocs derépétition comme prévu. Tu constates que j’ai déclaré les deuxvariablesiBasse etiHaute (des constantes en fait) de façonlocale et non en début de programme comme d’habitude. Cela aplusieursconséquences:
» Cesvariablesn’existentquedanslafonction;situ
tentesdelesciterailleurs,parexempledansloop(),
lecompilateurvaterépondrequ’ilnelesconnaîtpas.
Lesvariablesappartiennentàlafonction,unpeu
commelesdonnéesd’unobjetvuesdansleChapitre8.
» Situdéfinisunevariableglobalehomonyme,ellesera
masquéeparlavariablelocale.
» Encopiant-collantleblocdelafonctionalarmer(),
nousemportonsavecnoustoutcequ’illuifautpour
travailler.
RetouraugardienPuisque nous disposons d’une fonction d’alarme audio, voyonscommentlaréinjecterdansleprojetGardiendudébutdechapitre.
NousallonsinjecterlasirènedepuisleprojetSonner3,c’est-à-direlecorpsdelafonctionalarmer().
Listing9.5:Version2duprojetGardien
//Gardien2
//OEN170321
constbyteyBroPIR=7;
constbyteyBroLED=13;
constbyteyTempsKalib=10;//Max30
secondes
constbyteyBroSON=8;//AJOUT
unsignedlonggDebutChrono;
unsignedlonggPause=100;//Max5000
booleanbOKDetect=true;
booleanbRedemarrerKrono;
/////////////////////////////
voidsetup(){
Serial.begin(9600);
pinMode(yBroPIR,INPUT);
pinMode(yBroLED,OUTPUT);
pinMode(yBroSON,OUTPUT);//
AJOUT
digitalWrite(yBroPIR,LOW);
Serial.println("**ProjetGARDIEN.
Calibragedusenseur.");
Serial.print("**Quepersonnenebouge.On
patiente.");
for(inti=0;i<yTempsKalib;i++){
delay(1000);
Serial.print(".");
tone(yBroSON,440,200);//
AJOUT
}
Serial.println("C'estparti!");
delay(50);
}
////////////////////////////
voidloop(){
if(digitalRead(yBroPIR)==LOW){
if(bRedemarrerKrono){
gDebutChrono=millis();
bRedemarrerKrono=false;
}
if(!bOKDetect&&((millis()-
gDebutChrono)>gPause)){
bOKDetect=true;
delay(50);
bavarder(1);
}
}
if(digitalRead(yBroPIR)==HIGH){
if(bOKDetect){
bavarder(0);
Serial.println("Alarme!Alarme!
Alarme!");
alarmer();
//AJOUT
delay(50);
bOKDetect=false;
}
bRedemarrerKrono=true;
}
}
voidbavarder(bytebType){
if(bType==0){
Serial.println("---");
Serial.print("Quelquechosebouge.
Instant:");
Serial.print(millis()/1000);
Serial.println("secondes");
}
if(bType==1){
Serial.print("Lecalmeestrevenu.
Instant:");
Serial.print((millis()-
gPause)/1000);
Serial.println("secondes");
}
}
////NOUVEAU
voidalarmer(){
constintiBasse=440;
constintiHaute=2000;
for(inti=iBasse;i<iHaute;i++){
tone(yBroSON,i);
delay(1);
}
for(inti=iHaute;i>iBasse;i--){
tone(yBroSON,i);
delay(1);
}
noTone(yBroSON);
}
RetouchesdeGardien2Nousinséronsquatrenouvellesinstructionsdanslecodeexistantetcollons tout à la fin du bloc de la fonctionalarmer() depuisSonner3.ino.
Les insertions sont marquées par le commentaire de ligne //AJOUT.Voicicesajouts:
» Toutaudébut,unedéclarationpourlabrochedu
haut-parleur.
» Danssetup(),uneinstructionpourpréparerla
brocheduhaut-parleurensortie.
» Toujoursdanssetup(),uneinstructionpourémettre
unbip:
tone(yBroSON,440,200);
Situobservesbien,ilyauntroisièmeparamètre(200).
Ilestfacultatifetpermetdelimiterladuréed’émission
duson.
» Enfin,encasdedétectionautorisée,nousappelons
notrenouvellefonctionpoursirénerdeboncœur!
Ceci termine le projet d’alarme. Avant de clore le chapitre, je teproposeuntestd’auditiongratuit.
TestonsnosoreillesLepetitprojetbonusquisuitestàmanieravecprécaution:
1. Ilémetdessonstrèsaigus.Mieuxvautéloignerles
chiensquecelapourraiténerver.
2. Nousutilisonsunpetithaut-parleuràtoutfairequiest
incapabled’émettredessonstrèsaigusaussibienque
lessonsdumilieuduspectresonore,soitde200Hzà
4000Hz.
3. Nelaissepasleprogrammefonctionnerencontinu.
Le principe consiste à partir d’une note de base et à monter enfréquenceenajoutantàlanotecourantelavaleurdelanotedebase.Tuvoisqu’elleestdéfinieentantquesynonymepar#define.
Listing9.6:CH09C_TestOreilles.ino
//TestOreilles
//OEN170325
#defineDIAPA440
intyBroSON=8;
voidsetup(){
pinMode(yBroSON,OUTPUT);
Serial.begin(9600);
Serial.println("Attentionlesoreilles!!
!");
}
voidloop(){
intiNote;
for(iNote=DIAPA;iNote<10000;iNote
+=DIAPA){
tone(yBroSON,iNote);
Serial.print("Onentendencorececi?:
");
delay(800);
Serial.print(iNote);
Serial.println();
}
noTone(yBroSON);
}
TestonsletestPour faire le test, il suffit d’écouter jusqu’à quelle fréquence tuentendslanote(Figure9.10).
Attention : ce test n’est pas du tout scientifique. Il procurenéanmoins une idée de ce vastemonde des fréquences aiguës quidonnentleurcouleurauxsonsmusicaux,tousplusgraves.Lesaigussontlessonsharmoniques.
Figure9.10:Letestd’audition.
La note la plus aiguë d’un piano a une fréquenced’environ4400Hz.
RécapitulonsDanscechapitre,nousavonsvu:
» commentutiliseruncapteurdemouvementPIR;
» cequ’estunalgorithme;
» commentutiliserunhaut-parleur.
N
Chapitre10Levoleurdecouleurs
AUMENUDECECHAPITRE:
» TroisdiodesLEDenune
» Mélangeonslesteintes
» Lecapteurdecouleurs
ous venons d’apprendre à produire de façon contrôlée desondes sonores qui sont des ondes mécaniques. Voyonsmaintenant comment faire la même chose avec des ondes
électriques : créer n’importe quelle nuance de lumière visible etreconnaître une nuance pour la reproduire (plus ou moinsfidèlement).
DesondeslumineusesPresquetoutcequetuvoisavectesyeuxestd’unecertainecouleurparceque lamatièremange la lumière.Quandunobjetestéclairéavec de la lumière blanche (transparente plutôt), il avale certainescouleursetn’enrenvoiequ’unebienprécisequidevientlacouleurdecetobjet.Unobjetestrougeparcequ’ilsoustraittouteslesautrescouleurssauflerouge.C’estlasynthèsesoustractive.
Figure10.1:Effetdelasynthèsesoustractive.
Plus les tons de peinture que tumélanges sont nombreux, plus lerésultat s’approche d’un brun presque noir. Les matières secombinentpourneplusrienrenvoyer.
En revanche, avec de la lumière, c’est l’inverse. Les énergiess’additionnent ! Plus tumélanges de couleurs, plus tu vas vers leblanc.Lasynthèseadditive,c’estcequefontlesjeuxdelumièreauthéâtreetauconcert.
Figure10.2:Lespectredescouleursvisibles.
Lalumière,cesontdesondesélectromagnétiques.Quiditonde,ditfréquence.Letableausuivantmontrelesfréquencesdescouleursdel’arc-en-ciel.C’estaveccesvaleursquenousallons jouerdanscechapitre.
Tableau10.1:Valeursdescouleursprincipales
Couleur Longueurd’onde Fréquenceentérahertz
Ultraviolet(UV) moinsde380 plusde850THz
Violet 380–450nm 668–789THz
Bleu 450–495nm 606–668THz
Vert 495–570nm 526–606THz
Jaune 570–590nm 508–526THz
Orange 590–620nm 484–508THz
Rouge 620–750nm 400–484THz
Infrarouge plusde750 moinsde500THz
Untérahertzvaut1000gigahertz.
Ce qui est magique avec la lumière, c’est que les ondess’additionnent. En musique, il existe aussi un bruit blanc, un peucomme lorsque tu enfonces toutes les touches du piano enmêmetemps. C’est beaucoup moins transparent pour tes oreilles que lalumièredujour!
Par rapport au spectre des ondes lumineuses (Figure 10.3), àgauche,cesontlesfameuxrayonsultravioletsquinousbronzentetnous brûlent sur la plage. Encore plus à gauche arrivent lesméchantsrayonsXpuis,encoreplusaigus,lestrèsméchantsrayonsgammadelaradioactivité!
Du côté droit commence le domaine des infrarouges que nousconnaissonsbienmaintenant.Encoreplusgraveenfréquence,nousarrivons en terrain connu : radars, micro-ondes, téléphonesportables,radio…bref,encoredesondes.Heureusementqu’ellesnesontpasvisibles,nousserionsaveuglés!
Figure10.3:Lespectredesfréquencesdelalumière.
Mais que peut-on faire avec des diodes LED ? Il en existe deplusieurscouleurs, rouge,vert, jauneetbleu,et…c’est tout.Jenecompte pas les LED infrarouges, ni les LED ultraviolettes (celaexiste).
Lasolutionpourjoueraveclesteintesestladiodetricolore.
LadiodeLEDuniverselleLaLEDtricolore,diteLEDRGB(leGsignifieGreen),réunitdansune même capsule translucide une LED rouge, une verte et unebleue.Dufaitque leboîtiern’estpas transparent, les troissourcesdelumièresediffusentassezpoursemélanger.
Puisqu’il y a trois diodes LED, il nous faut six fils, deux pourchacune,n’est-cepas?Voyons…Sionréunissaitlestroisbrochesd’uncôtésurunebrochecommune,celafonctionneraitaussibien,non?
C’estbienlecas:ladiodeLEDtricoloren’aquequatrebroches.Enconséquence,ilyadeuxvariantes:
» soitonréunitlestroisanodes(reliéesaupôleplus),et
c’estunediodeàanodecommune,AC(ouCAen
anglais);
» soitonrelielestroiscathodes(reliéesàlamasse
GND),etc’estunediodeàcathodecommune,CC.
Figure10.4:Brochesd’uneLEDRVBàanode(gauche)etàcathodecommune.
Si tu récupèresuneLEDRGBqui aperdu sapochette, tunepeuxpas savoir si c’est uneAC ou une CC.Heureusement, il suffit detester.Si tuasunmultimètre,règle-lesur«ohmmètre» .Dansunsens,lecourantnepassepas;larésistanceestinfinie.Quandtuastrouvé le sens passant, repère la broche de la sonde rouge dumultimètre : c’est l’anode. Si c’est la broche la plus longue, c’estunediodeAC.
LalogiquedecontrôleestinverséeentreACetCC:
» AvecunediodeCC,onéteintlaLEDenamenant
chaqueanodeau0V.Dufaitquelacathodeestreliée
au0Venpermanence,aucuncourantnepasseplus.
Pourobtenirdublanc,onportelestroisanodesau5V
(1logique).Dufaitquelacathodeestreliéeau0V,le
courant(limitéparlarésistance)passe.
» Enrevanche,avecunediodeAC,onéteintlaLEDen
amenant5Vsurchaquecathode,doncaumême
potentielquel’anode,etaucuncourantnepasse.
CC semble plus naturel puisque l’intensité de lumière estproportionnelleàlavaleur.
SortiesnumériquesAvecunpilotagenumériquepardigitalWrite(),onpeutdoncobtenirlesseptteintesdelasynthèseadditive(voirFigure10.2):
» lestroiscouleursprimairesrouge,vertetbleu;
» lestroiscouleurssecondairesjaune(rouge+vert),rose
(rouge+bleu)etbleuciel(bleu+vert);
» etbiensûrleblancaveclestroisdiodesallumées.
Iln’yaqueseptteintespossiblesennumérique.
SortiesanalogiquesPWMPour avoir plus de choix dans les couleurs, nous allons utilisernotrebottesecrète:lessortiesnumériquesquisimulentdessortiesanalogiquesaveclemodePWMetlafonctionanalogWrite().
EnmodePWM,ondisposede256intensitéspossiblespourchaquecouleur primaire (de 0 à 255). Pour notre premier programme,nousallonsnouslimiterauxdeuxvaleursextrêmes:
» 0=éteinte;
» 255=lumièremaximale.
Voyonsd’abordcommentmonterlecircuitdanslesdeuxvariantespossibles.
MontageAC(anodecommune)deTricolore
Lesquatrefilsnécessairesserontsipossibleceux-ci:
» orangepourlerouge;
» vertpourlevert;
» blancpourlebleu;
» rougepourle5V.
1. ImplanteladiodeLEDdansquatredemi-rangéesdeta
plaqued’essai(Figure10.5).
Figure10.5:Schémademontageàanodecommune.
Jeconseilled’insérerlabrochecommune(anode,ici)en
décalaged’untroupourfaciliterlerepéragepuisquetu
nevoispluslesdifférencesdelongueurdespattes.
2. Implanteunerésistancede270ohmsentrechacune
desdemi-rangéesd’unedestroiscathodesR,V,Betla
demi-rangéed’enface.
3. Connectechacunedestroisdemi-rangéesoùarrivent
lesrésistancesàtroisbrochesnumériquesdelacarte
Arduino.
LabrochepourlerougesurlasortieDIGITAL3,laverte
surlasortie5etlableuesurlasortie6.
4. Connecteparunfilrougel’anodecommuneau5Vde
lacarteArduino.
Le montage est terminé. Pour ceux qui ont une LED à cathodecommune,voicilemontageinversé.
Variantedumontageàcathodecommune(CC)Voici les différences par rapport aux explications de la sectionprécédente:
» Pourles4fils,lerougedu5Vnesertplus,maisilfaut
unnoirpourlamassedelacathodecommune.
» Lesliaisonsdestroiscouleurssontlesmêmesque
pouruneanodecommune,saufquecesonttrois
anodes.
» Lacathodecommunedoitbiensûrêtrereliéeàla
masse(unedestroissortiesGNDdelacarte).
CodagedeTricoloreACPourplusdeconfort,nousallonsdéfinirdeuxfonctionslocales.Lapremièrevadéciderdelaluminositédestroiscouleursenattendantquatreparamètres:
» l’intensitépourlerouge,levertetlebleu;
» laduréedecetétatd’allumage.
Lasecondefonctionlocalesesertdelapremièrepourtoutéteindre.
PourlimiterletravaildereprisesituasbesoindefairefonctionnerleprogrammeavecunediodeLEDàcathodecommune, jedéfinissixsynonymespardesdirectives#define.
Danscettepremièreversion,j’allumeprogressivementchacunedestrois LED tour à tour. Nous obtenons ainsi les trois couleursprimairesensynthèseadditive.
Listing10.1:TextesourcedeCH10_Tricolore1
//Tricolore1
//OEN170327
#defineRMIN255//SiAnodeCommune(AC)
#defineVMIN255
#defineBMIN255
#defineRMAX0
#defineVMAX0
#defineBMAX0
constbyteyBroROUGE=3;
constbyteyBroVERT=5;
constbyteyBroBLEU=6;
voidsetup(){
allumerRVB(RMAX,VMAX,BMAX,500);//Blanc
allumerRVB(RMIN,VMIN,BMIN,500);//Noir
}
voidloop(){
for(bytei=RMIN;i>RMAX;i--){
allumerRVB(i,VMIN,BMIN,10);
}
eteindre(100);
for(bytei=VMIN;i>VMAX;i--){
allumerRVB(RMIN,i,BMIN,10);
}
eteindre(100);
for(bytei=BMIN;i>BMAX;i--){
allumerRVB(RMIN,VMIN,i,10);
}
eteindre(100);
}
voidallumerRVB(byterouge,bytevert,byte
bleu,inttemps){
analogWrite(yBroROUGE,rouge);
analogWrite(yBroVERT,vert);
analogWrite(yBroBLEU,bleu);
delay(temps);
}
voideteindre(inttemps){
allumerRVB(RMIN,VMIN,BMIN,temps);
delay(temps);
}
Varianteàcathodecommune
Grâce aux directives#define, nousmodifions facilement le textesourcepouruneLEDtricoloreaveccathodecommune(CC).
PouruneCC,ilfautfairedeuxretouches:
1. Inverserlesvaleursdessixdirectives#define:
#defineRMIN0//SiCathodecommune(CC)
#defineVMIN0
#defineBMIN0
#defineRMAX255
#defineVMAX255
#defineBMAX255
2. Inverserlalogiquedestroisbouclesderépétition(en
rouge,lesdeuxchangements):
for(bytei=RMIN;i<RMAX;i++){
CetteretoucheestàfairetroisfoispourlestroisLED.
TestduprojetTéléverse le projet et ouvre grands les yeux. Chaque LED doitbrillerdeplusenpluspuiss’éteindre.
AjoutonslescouleurssecondairesPuisque la synthèse additive permet d’obtenir trois couleurssecondaires,enrichissonsnotrepaletteavecdujaune,duroseetdubleuciel!
1. Enregistreleprojetsousunnouveaunom,par
exempleTricolore2.
2. Positionne-toijusteavantl’accoladefermantedela
fonctionprincipaleloop()etajoutetoutlebloc
suivant.Cesonttroisautresblocsderépétition.
Listing10.2:ExtraitdutextesourcedeTricolore2
//DEBUTDUPROGRAMMETricolore1
//AJOUTCOULEURSSECONDAIREDANSloop()
for(bytei=RMIN;i>RMAX;i--){
allumerRVB(i,i,BMIN,10);
}
eteindre(100);
for(bytei=VMIN;i>VMAX;i--){
allumerRVB(RMIN,i,i,10);
}
eteindre(100);
for(bytei=BMIN;i>BMAX;i--){
allumerRVB(i,VMIN,i,10);
}
eteindre(100);
//SUITEDUPROGRAMMETricolore1
TestduprojetC’est simple : téléverse et admire ! En éteignant la lumière, c’estencore plus joli. Puisque nous travaillons en pseudo-analogique,nous pouvons créer des nuances, beaucoup même, plusde16millions(256x256x256).
Mais calmons-nous. Nous allons nous contenter de combiner lesteintesdeuxàdeux:
» durougemaximal,nousréduisonslerougetouten
augmentantlevert;
» unefoislevertresplendissant,nouslediminuonstout
enaugmentantlebleu;
» unefoislebleubienbrillant,nouslediminuonstout
enaugmentantlerouge.
Celasimuleassezbienlapalettedel’arc-en-ciel.
Toutestdanslanuance!Puisque nous pouvons mélanger les couleurs, voyons commentpasserpartouteslesnuancesdel’arc-en-ciel.
Tudevinesqu’ilvas’agirdecommencerparunecouleurquenousfaisons monter, puis nous la réduisons tout en faisant monter laprimairesuivante.L’astuceconsisteàutiliseruntableau:
bytetyPrimaires[3];
Les trois cases du tableau mémorisent les valeurs d’intensité destroisLED.Audébutdechaque tourdeboucle,nous restockons lavaleurminimale:
tyPrimaires[0]=RMIN;
tyPrimaires[1]=VMIN;
tyPrimaires[2]=BMIN;
Danschaquetour,nousnetravaillonsqu’avecdeuxdestroisLED:la LED dont l’intensité est en train de diminuer et celle dontl’intensitévaaugmenter.Pouraccéderauxbonnescasesdutableau,nous exploitons deux variables servant d’indices vers ces deuxcases:
byteyColDimi=0;
byteyColAugm;
Listing10.3:TextesourcedeArkenciel
//Arkenciel
//OEN170327
#defineRMIN255//Sianodecommune
#defineVMIN255
#defineBMIN255
#defineRMAX0
#defineVMAX0
#defineBMAX0
constbyteyBroROUGE=3;
constbyteyBroVERT=5;
constbyteyBroBLEU=6;
voidsetup(){
allumerRVB(RMAX,VMAX,BMAX,200);//Pleins
feuxpuis
allumerRVB(RMIN,VMIN,BMIN,200);//Noir
}
voidloop(){
bytetyPrimaires[3];
byteyColDimi=0;
byteyColAugm;
tyPrimaires[0]=RMIN;
tyPrimaires[1]=VMIN;
tyPrimaires[2]=BMIN;
for(bytei=RMIN;i>RMAX;i--){
allumerRVB(i,VMIN,BMIN,10);
}
for(yColDimi=0;yColDimi<3;yColDimi
+=1){
yColAugm=(yColDimi==2?0:yColDimi
+1);//NOUVEAU
for(inti=255;i>0;i-=1){
tyPrimaires[yColDimi]=(255-i);//
+=1siAC
tyPrimaires[yColAugm]=i;//-
=1siAC
allumerRVB(tyPrimaires[0],
tyPrimaires[1],tyPrimaires[2],10);
delay(5);
}
}
eteindre(1500);
}
voidallumerRVB(byterouge,bytevert,byte
bleu,inttemps){
analogWrite(yBroROUGE,rouge);
analogWrite(yBroVERT,vert);
analogWrite(yBroBLEU,bleu);
delay(temps);
}
voideteindre(inttemps){
allumerRVB(RMIN,VMIN,BMIN,temps);
delay(temps);
}
Pourfaired’abordmonter l’intensitéde laLEDrougeseule,nousutilisonsunebouclesimple:
for(bytei=RMIN;i>RMAX;i--){
allumerRVB(i,VMIN,BMIN,10);
}
La partie essentielle est la double boucle juste après. Dans lepremier niveau, nous organisons trois tours de boucle en nousbasantsuryColDimiquiprogressede0(LEDrouge)à2 (LEDbleue).
for(yColDimi=0;yColDimi<3;yColDimi+=
1){
Dans cette boucle, nous faisons un test qui utilise un nouvelopérateur : l’opérateur ternaire symbolisé par un signe pointd’interrogation.Voicisasyntaxegénérique:
(expression?instruction_si_vraie:
instruction_si_fausse)
Voicicommentnousl’utilisons:
yColAugm=(yColDimi==2?0:yColDimi+
1);//NOUVEAU
L’expressionavantlepointd’interrogationpeutêtresoitvraie,soitfausse.Ici,noustestonssiyColDimivaut2.
» Sic’estvrai,noussélectionnonsl’instructionjuste
aprèslesigne.Ici,nouscopionsdonclavaleur0dans
lavariablesituéetoutàgauche(yColAugm).
» Sic’estfaux(nousn’avonspasatteintladernièredes
troisLED),nousexécutonsl’instructionsituéeaprèsle
signedeux-points.Ici,nousrendonsyColAugm
supérieurede1aunumérodeLEDdeyColDimi.Cela
désignebienlaLEDsuivante.
Souviens-toidesdeuxsignes,d’abordlepointd’interrogation,puisledeux-points.Tu remarquesqu’il n’y a aucunpoint-virguledanslesinstructions.C’estuneécritureunpeuspéciale,jel’avoue.Alorspourquoi?
C’estsimplementpluscompactqueleblocsuivantquiaexactementlemêmeeffet:
if(yColDimi==2){
yColAugm=0;
}
else{
yColAugm=yColDimi+1;
}
Unefoisceschoixdecasesdetableauxréglés,ilneresteplusqu’àremplir avec des valeurs décroissantes pour la première des deuxLEDetcroissantespourl’autre:
for(inti=255;i>0;i-=1){
tyPrimaires[yColDimi]=(255-i);//+=1si
AC
tyPrimaires[yColAugm]=i;//-=1si
AC
Si tu utilises une LED à cathode commune, il faut inverser lesprogressions comme suggéré dans les commentaires de fins delignes.
TestduprojetTéléverse le projet pour admirer le passage par une foule denuances.
Passons maintenant à un autre projet qui nous servira à piloterautomatiquementlanuanceaffichéeparlaLEDtricolore.
LecapteurdecouleursTCS34725Nousallonsmaintenantdécouvrirunnouveautypedecapteur.C’estunesorted’œilélectroniquequisaitvoirlescouleurs.
Lecomposantprincipalsetrouveenpleinmilieuducircuit.C’estlapuce justeàdroitedupavéblancet jaunequiest laLEDservantàilluminerl’objetàanalyser.Lapucen’estpasopaque:tupeuxvoirla surface semi-conductrice. Cette surface est remplie de petitescellulessensiblesà la lumière.Chaquecelluleestdotéed’un filtrepournelaisserpasserquelalumièrerouge,verteoubleue.
Cette puce est accompagnée de quelques composants pourl’exploiter. La Figure 10.6 montre l’aspect général du modulecapteur.
À la différence du détecteur de mouvement PIR et du capteur derayons infrarouges, lemodule ne se limite pas à trois broches desortie. Il en a sept, parmi lesquelles bien sûr la broche du positif(marquée3V3,mais5Vconviennentaussi)etcelledupôlenégatifGND de l’alimentation. Tu vois les sept bornes dans le bas de laFigure10.6.
Figure10.6:Lemodulecapteurdecouleurs.
Ce module est bien plus sophistiqué qu’un capteur simple. Il nefonctionne pas en tout ou rien. Pour transmettre une valeur decouleur pour trois couleurs différentes, il faut envoyer plusieursoctetsdedonnéeslorsqu’ilestinterrogé.Pourtant,parmitouteslesbroches du module, une seule sert à renvoyer des données, labrocheSDA.Commentest-cepossible?GrâceàlanormeI2C.
I2CpourcommuniquerI2C signifie Inter-IntegratedCircuit. C’est un jeu de règles (unprotocole)quidéfinitcommentdoiventdialoguerdeuxéquipementsélectroniques ou plus. Au départ, c’est la société Philips qui ainventé la norme TWI (TwoWire Interface) en 1982. Ce nomanglais indiquequec’estune interfacequin’abesoinquededeuxfils(wire).Comment?IlsuffitdebrancherunfildedonnéessurlabrocheSDA(DApourDAta)etunfilpourlestopsd’unehorlogesurlabrocheSCL(CLpourCLock).
C’estunprotocolededialogueensérie,c’est-à-direquelesvaleursbinaires sont transmises l’une après l’autre.Au début du chapitre,nous avons construit une sorte d’interface parallèle, puisqu’il y
avait un fil pour chacune des trois diodes LED. Pour les allumertoutes trois enmême temps, nous avonsmis les trois broches desortieàl’étatcorrespondant.C’estunecommandeenparallèle.Biensûr, transmettrehuit bits enparallèlevahuit foisplusviteque lestransmettre à la queue-leu-leu. De nos jours, les circuits sontdevenus tellementperformantsque lemode sériedevient suffisantdanspresquetouslesdomainesd’emploi.
Ilexisteunautreprotocoledecommunicationsériebeaucoupplusrépandu et que tu utilises certainement : le protocole USB, le Ssignifiant « Série » . EnUSB 3.1, le débit va jusqu’à unmilliardd’octetsparseconde!
Dans la norme I2C, les bits de données sont envoyés l’un aprèsl’autre au rythmedu signald’horloge.C’estunvéritabledialoguequi est établi entre unmaître (lemikon) et un esclave (lemodulecapteur) : lemodule peut recevoir le code d’une commande, puisréagir en renvoyant le résultat de l’action déclenchée par cettecommandedanslemodule.
Figure10.7:ExempledesignalI2C.
TudevinesquecerichedialoguefaitdeséquencesStart,d’envoidecommandes, d’envoi de données et de séquences Stop réclame ungrand nombre d’instructions. Pour simplifier l’utilisation dumodule,nousallonsdonctireravantaged’unelibrairiedefonctionsdéjà toute programmée. Mais procédons d’abord au montage ducircuit.
NomenclaturedeVolKoolVoicilescomposantsàréunir:
» Uneplaqued’essai.Tupeuxréutiliserlaplaque
d’essaisurlaquelletuasimplantéladiodeLED
tricolore.Jesupposequetuasassezdeplaceàcôtéde
cettediode.
» Uncapteur.Pourlemodulecapteur,ilfaut
absolumentdisposerd’unmodèletotalement
compatibleavecceluidelasociétéAdafruitsousla
référenceTCS34725.Nousavonseneffetbesoindela
librairiequiaétéécriteparAdafruitpourcemodule.
Leproblèmequipeutseposerestquelasociété
Adafruit(etsesrevendeurs)proposecemodulesans
avoirsoudéleconnecteurdesortiesurlecircuit.Le
connecteurestlivré,maislessouduresrestentàfaire
etellessontassezdélicatescarlescontactssonttrès
procheslesunsdesautres.Iln’yaquedeuxsolutions:
soittuconnaisquelqu’unquipeuttefaireces
soudures,soittuutiliseslaméthodededépannage
quejeprésenteplusbas.
» Desfilsdeconnexion.Tuaurasbesoindequatrefils
pourraccorderlemoduleàlacarteArduino.Situas
déjàinstalléunraild’alimentationpositifetunautrede
masseGNDsurlaplaque,tuprendrasl’alimentation
surlesrails.
» Unevis(option).Situnedisposespasd’uneversion
dumoduleavecleconnecteursoudé,prévoisune
petitevisàboisaveclaquelletupourrasfixerle
modulesurunechutedeboisparunedesesoreilles.
MontagedeVolKoolProcédonsmaintenant aumontage. Si possible, ne démonte pas lemontageprécédentavecsaLEDtricolore.Nousallonsleréutiliser.
1. Sileconnecteurdumodulen’estpassoudé,fixele
moduleavecunevissurunepetiteplaquedebois.Sile
connecteurestsoudé,insèreleconnecteursurla
plaqued’essai.
2. RelieparunfilvertoubleulabrocheSDAdumoduleà
labrocheanalogiqueA4surlacarteArduino.
3. RelieavecunfiljauneoublanclabrocheSCL(horloge)
àlabrocheanalogiqueA5surlacarteArduino.
4. RelielabrochedemasseGNDàlamassedelaplaque
oudelacarte.
5. Relielabrochedupositif3V3àlabroche5Vdurail+
delacarte.Pasd’inquiétude,lemodulecomporteun
régulateuretaccepteaussi5V.
6. Situn’aspasdeconnecteursoudé,ilfautsacrifierune
extrémitédechacundesquatrefilsencoupantun
connecteur,puisendénudantlefilsur2cmetenle
torsadant.Tufaisensuitepasserchaquefildansletrou
delabrochecorrespondante,puisturebouclesen
torsade.Fixeletoutavecunpointdecolle.Cen’estpas
unesolutionélégante,maissitunetiresplussurle
module,celadevraittenir.
Figure10.8:MontagedeVolKool.
Lemontageestterminé,maisnousnepouvonspaspourautantnouslancer dans un premier test. Il faut d’abord installer la librairieappropriée.
InstallonslalibrairiedumoduleLalibrairieofferteparlasociétéAdafruitestreconnueparl’atelierIDE Arduino comme faisant partie des plus demandées. Tu peuxdonc procéder sans crainte à son installation avec le module degestiondeslibrairies.
1. Démarrel’atelierArduinosinécessaire.
2. OuvrelemenuCroquisetchoisisInclureune
bibliothèque(librairie).
3. ChoisislacommandeGérerlesbibliothèques.
Tuvoisapparaîtreuneboîteprésentantlalistedes
librairiesdéjàinstalléesetcellesquipeuventl’être.
Figure10.9:Installerunelibrairie.
4. Danslazonedesaisieenhautàdroite,saisislestrois
lettresTCS.Celasuffitàfiltrerl’affichage.
Normalement,lapremièrelibrairiedelalisteestcelle
dontnousavonsbesoin,AdafruitTCS34725.
5. Cliquedanslasurfacedelalibrairie.Tuvoisapparaître
àdroiteunboutonInstaller.Clique-le.
Patienteunpeu.Lalibrairievaêtreinstalléeavecses
exemples.
6. Quittel’atelieretredémarre.
ChargeonsleprogrammedetestPourleprogrammedetest,tupeuxpartirdeceluiquiaétéinstalléd’officeaveclalibrairie:TCS34725.
1. Dansl’atelier,ouvrelemenuFichierpuislesous-
menuExemples.SélectionneGérerlesbibliothèques.
2. Descendsdanslalistejusqu’aunomdelalibrairieque
tuviensd’installer,AdafruitTCS34725.Accèdeau
sous-menu(Figure10.10)etsélectionnel’exemple
TCS34725.
Figure10.10:ChargementduprogrammedetestTCS34725.
3. SauvegardeleprogrammesouslenomVolKool1.
Tu peux aussi saisir l’exemple suivant qui en est inspiré. Ladifférenceestquej’aiaménagél’exempleenfrancisantlesnomsdevariablesetdefonctions.
CetexemplefaitpartiedeceuxfournisaveclelivresurlesitesouslenomCH10C_VolKool1.
Listing10.4:TextesourcedeVolKool1
//VolKool1
//OEN170327
#include<Wire.h>
#include"Adafruit_TCS34725.h"
/*ExempledelalibrairieAdafruitTCS34725
*/
/*SCLsurbrocheA5,SDAsurA4,VDDsur
3.3VetGNDsurGND*/
//Uneseuleligneici:
Adafruit_TCS34725oVolKool=
Adafruit_TCS34725(TCS34725_
INTEGRATIONTIME_700MS,TCS34725_GAIN_1X);
voidsetup(void){
Serial.begin(9600);
if(oVolKool.begin()){Serial.println(
F("Capteuractif!"));}
else{
Serial.println(F("TCS34725absent.Voir
lesconnexions!"));
while(1);}
}
voidloop(void){
uint16_tiR,iV,iB,iC,iTempera,lux;
oVolKool.getRawData(&iR,&iV,&iB,&iC);
iTempera=
oVolKool.calculateColorTemperature(iR,iV,
iB);
lux=oVolKool.calculateLux(iR,iV,iB);
Serial.print("Temp.decouleur:");
Serial.print(iTempera,DEC);
Serial.print("K-");
Serial.print("Lux:");Serial.print(lux,
DEC);
Serial.println("-");
Serial.print("Rouge:");Serial.print(iR,
DEC);Serial.print("");
Serial.print("Vert:");Serial.print(iV,
DEC);Serial.print("");
Serial.print("Bleu:");Serial.print(iB,
DEC);Serial.print("");
Serial.print("C:");Serial.print(iC,
DEC);Serial.print("");
Serial.println();
Serial.println("");
}
Ce programme est inspiré de celui proposé par Adafruit sous lenomTCS34725.
Endébutdeprogramme,nousdemandonsd’utiliser le contenudedeuxlibrairiesdefonctions:
#include<Wire.h>
#include"Adafruit_TCS34725.h"
La seconde librairie est celle que nous venons d’installer. Lapremière,Wire.h,estinstalléed’office.EllecontientlesfonctionspourexploiterleprotocoleI2Cquirégitledialogueentrelemikonetlecapteur.
Nous commençons par créer un objetoVolKool à partir de laclassenomméeAdafruit_TCS34725.Cettecréationestréaliséeenappelantuneméthodeavecdeuxparamètres.L’instructionestsilonguequ’ellenetientpassurunelignedecelivre,maisc’estbienuneseuleligne:
//Uneseuleligneici:
Adafruit_TCS34725oVolKool=
Adafruit_TCS34725(TCS34725_
INTEGRATIONTIME_700MS,TCS34725_GAIN_1X);
Dans la fonction de préparation, nous vérifions que le capteur estprêtavec
unappelàoVolKool.begin().
Danslaboucleprincipale,turemarquesunétrangenomdetypededonnées:
uint16_tiR,iV,iB,iC,iTempera,lux;
Lemotcléuint16_testbienlenomd’untypededonnées.C’estuneversion abrégée de unsigned int, mais obligatoirement sur deuxoctets(16bits).Celarendleprogrammeplusportableversunautremikon.Eneffet,celuidelacarteUnoestsur16bits,maisd’autresprocesseurs fonctionnent avec une largeur de 32 bits pour lesentiers,d’autressur8bitsseulement.Aveccetypeexact,tuobligeslecompilateuràutiliserdeuxoctetspourlesvariablesconcernées.
Nous enchaînons ensuite avec trois appels à des fonctions de lalibrairiepourpeuplernossixvariables:
oVolKool.getRawData(&iR,&iV,&iB,&iC);
iTempera=
oVolKool.calculateColorTemperature(iR,iV,
iB);
lux=oVolKool.calculateLux(iR,iV,iB);
» Lapremière,getRawData(),rapatrielesvaleursdes
troiscomposantesdecouleursetlaluminosité
globale.
» Ladeuxième,calculateColorTemperature(),
récupèrelatempératuredecouleur.
» Ladernière,calculateLux(),obtientl’intensité
lumineuseexpriméedansl’unitéstandard,lelux.
Lafinduprogrammen’estqu’unesuited’affichages.
Iln’estpasnécessaired’ajouterunappelàdelay()pourralentirles affichages. Le mikon est suffisamment occupé avec tous cesappels.
TestonslecapteurdecouleursRéunis quelques objets ayant une surface unie d’une couleur bienmarquée.Des fruits, des surligneurs, des jetons de jeu de société,etc.
1. TéléverseleprojetetouvrelafenêtreduMoniteur
série(Figure10.11).
Figure10.11:Affichagedescomposantesdecouleurs.
2. Approcheunpremierobjetducapteur.Lecapteurest
myope.Ilfautvraimentallerpresqueaucontact.
3. Lisetcomparelesvaleurs.Selonlacouleurdel’objet,
unedescomposantesvaaugmenterdevaleurbien
plusquelesdeuxautres.
Normalement,tudoisconstaterquelesvaleursdescouleursvarientcorrectement en fonction de la couleur de l’objet présenté. Nous
sommesprêtsàdonnernaissanceauvoleurdecouleurs!
Copier,c’estbeau(VolKool2)Pourterminerleprojet,nouscombinonslecapteurdecouleursàladiodeLEDRGBdespremiersprojetsduchapitre.
Si tu avais entre-temps démonté la partie Tricolore du circuit,revoislaprocédureautourdelaFigure10.5plushaut.
Leprojetvadeveniruncircuitfermé:
» Nouscaptonsenentréetroisvaleursdecouleurs.
» Nouslestraitonsdanslemikonenappliquantune
correctiondegamme.
» NousdécidonsensortiedelateintedelaLED
tricolore.
Le texte sourcene comportequ’unevraienouveauté : la tabledesgamma.
Listing10.5:TextesourcedeVolKool2
//VolKool2
//OEN170327
#include<Wire.h>
#include"Adafruit_TCS34725.h"
//Résistancede220ohmsurles3LED.
//Silavertebrilletrop,doublelavaleur
desarésistance
#definebrRouge3
#definebrVerte5
#definebrBleue6
#defineanodeCommtrue//Indiquerfalsesi
cathodecomm.
//Tabledesgamma
bytetabGamma[256];
Adafruit_TCS34725monTCS=
Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS,
TCS34725_GAIN_4X);
voidsetup(){
Serial.begin(9600);
Serial.println("Levoleurdecouleurs!");
if(monTCS.begin()){
Serial.println("Capteuractif.");
}else{
Serial.println("PasdeTCS34725...
verifierlesbranchements.");
while(1);
}
pinMode(brRouge,OUTPUT);
pinMode(brVerte,OUTPUT);
pinMode(brBleue,OUTPUT);
//MerciPhilBpourlatablegamma.
//Ellerééquilibrelaluminositéselon
l'œilhumain.
for(inti=0;i<256;i++){
floatx=i;
x/=255;
x=pow(x,2.5);
x*=255;
if(anodeComm){
tabGamma[i]=255-x;
}else{
tabGamma[i]=x;
}
//Serial.println(tabGamma[i]);
}
}
voidloop(){
uint16_tclear,iRO,iVE,iBL;
monTCS.setInterrupt(false);
delay(60);//Patiente
50mspourlalecture
monTCS.getRawData(&iRO,&iVE,&iBL,
&clear);
monTCS.setInterrupt(true);
Serial.println();
Serial.print("C:\t");Serial.print(clear);
Serial.print("\tR:\t");Serial.print(iRO);
Serial.print("\tG:\t");Serial.print(iVE);
Serial.print("\tB:\t");
Serial.println(iBL);
//CalculdesvaleurshexapourleWeb
uint32_tsum=clear;
floatr,g,b;
r=iRO;r/=sum;
g=iVE;g/=sum;
b=iBL;b/=sum;
r*=256;g*=256;b*=256;
Serial.print("Couleursweb\t\t");
Serial.print((int)r,HEX);
Serial.print((int)g,HEX);
Serial.print((int)b,HEX);
Serial.println();
Serial.print("Couleursdebase\t");
Serial.print((int)r);Serial.print("");
Serial.print((int)g);Serial.print("");
Serial.println((int)b);
analogWrite(brRouge,tabGamma[(int)r]);
analogWrite(brVerte,tabGamma[(int)g]);
analogWrite(brBleue,tabGamma[(int)b]);
delay(1000);
}
LatabledesgammaSans la correction de gamma, certaines teintes vont semblerbeaucouppluslumineusesquelesautres.L’œilhumainestentraînédepuisdesmilliersd’annéesà repérer sanourrituredans ledécor
enpleinjour,maislanuit,ildoitbienvoirarriverunprédateurquiviendrait troubler son sommeil. Le résultat est que les teintesmoyennes telles que les diodes LED les présentent sont troplumineuses.
Lacorrectiongammaconsisteà réduire la luminositédecertainesvaleursplusqued’autres.
Le bloc qui s’en charge dans l’exemple utilise une variable nonentière:elleestdutypefloat.Cetypepermetdestockerunevaleuravecdeschiffresderrièrelavirgule.
for(inti=0;i<256;i++){
floatfGam=i;
fGam/=255;
fGam=pow(fGam,2.5);
fGam*=255;
if(anodeComm){
tabGamma[i]=255-fGam;
}else{
tabGamma[i]=fGam;
}
//Serial.println(tabGamma[i]);
}
Ici,nousstockons256valeursdecorrectiondansuntableau.
Tupeuxvoirqu’unevaleurnonentièreestécriteavecunpointenlangageArduino, commedans laquatrième lignedublocpour lefacteurdecorrectionde2,5:
fGam=pow(fGam,2.5);
Dans les calculs, il y a une division et une multiplication, toutesdeuxécritessousformeabrégée:
fGam/=255;//CommefGam=fGam
/255;
fGam=pow(fGam,2.5);
fGam*=255;//CommefGam=fGam
*255;
Nous utilisons aussi la fonction pow(), qui fait un calcul depuissance.
TestduprojetConnectelacarteettéléverse.
Unefoisleprogrammedémarré,présenteunobjetcolorédevantlecapteur.
Le Moniteur série te donne une information utile : la valeurhexadécimale des trois composantes, telle que tu peux l’indiquerdanstoutprogrammefonctionnantsurleWeb:
» danslespagesHTML;
» danslesfeuillesdestylesCSS;
» danslesinstructionsJavaScript.
Parexemple,45A04Ccorrespondàunvertmoyen.
Lanotationhexadécimalevadeseizeenseizeetnondedixendix.Les lettresAàF symbolisent les chiffreshexa10à15.Lavaleurd’exemple45A04Csediviseentroiscouples:
» 45pourlerouge,soit4seizaines+5=69;
» A0pourlevert,soit10seizaines+0=160;
» 4Cpourlebleu,soit4seizaines+12=76.
Tu peux tester et trouver toutes les nuances sur un des nombreuxsitesd’aideàlaconceptionWeb,commehttp://html-color-codes.info.
Pourvérifierl’effetdelacorrectiondegamma,testeànouveauleprojetArkenciel:lesteintesnesontpasaussibienéquilibrées.
ObservelaLEDtricolore:elledevraitprendrequasimentlamêmeteintequel’objet.
Figure10.12:LeMoniteursériedeVolKool2.
Figure10.13:TestdeVolKool2.
Félicitations!TumaîtrisesmaintenantlessonsetleslumièresavectacarteArduino.
RécapitulonsDanscechapitre,nousavonsvu:
» lesondesdelumièreetcommentgénérerdes
nuances;
» ladiodeLEDRGB;
» uncapteurdecouleursetsalibrairie.
IVSemaine4:Letempsdeslettres
Aumenucettesemaine:
Chapitre11:Letempsliquide
Chapitre12:Unpeud’échologie
D
Chapitre11Letempsliquide
AUMENUDECECHAPITRE:
» Desafficheursavecducaractère
» L’alphabetdumikon
» Prendstontemps
ans les précédents chapitres, nous avons appris au mikon àcommuniquer avec le monde des humains en envoyant desdonnées par le câble USB vers l’ordinateur, ce qui a permis
d’afficher du texte et des valeurs numériques dans la fenêtre duMoniteur série. Ce canal de communication restera toujoursindispensablepourréaliserlamiseaupointdesprojets.
MaistacarteArduinocommenceàenavoirassezd’êtreretenueparunfilàlapatte.Commentpeut-onfaireafficherunmessageoudesvaleursenn’alimentant lacarteArduinoqu’avecunepile, c’est-à-direendébranchantenfinlacartedelaliaisonUSB?
Bienvenue dans le vastemonde des afficheurs.Du plus simple auplus sophistiqué, tu disposes de toute une palette de composantspermettantd’afficherdutexteoudesgraphiques.Faisonsd’abordletourdesdifférents typesd’afficheursdisponibles. Je teproposeraiensuitedechoisiruntypeenparticulier,pourquelemontagerestesimpleetquelaprogrammationnesoitpastropcomplexe.
Les sections suivantes présentent les grandes catégoriesd’afficheursdisponibles.
MatricedeLEDIl suffit de réunir plusieursdiodesLEDminiatures sous formedelignesetdecolonnes,etdenoyerletoutdansunboîtiercarré.Lesplus répandus de ces composants offrent 8 lignes sur 8 colonnes,soit64LED.
Tu devines que pour connecter ce genre de matrice à une carteArduino, il va falloir un grand nombre de fils. Il ne te resteraensuite plus beaucoup de broches disponibles pour faire autrechose.
Figure11.1:MatricedeLEDS8x8.
AfficheurseptsegmentsC’est le plus ancien composant d’affichage. Le principe est dedéformerlesLEDpourqu’ellesaientnonpluslaformed’unpoint,maiscelled’untraitnommésegment(Figure11.2).
Figure11.2:Vuegénéraled’unafficheurLEDseptsegments.
Onpeutainsiafficher tous leschiffresainsiqu’uncertainnombrede lettres,maispas toutes.Eneffet, avec sept segments seulement,lestraitsobliquesnesontpaspossibles(Figure11.3).
Figure11.3:Quelquesdessinsdechiffresdansunafficheurseptsegments.
Pour afficher quatre chiffres, ce qui est souvent le cas pour lescodes d’entrée des immeubles, il faut donc quatre afficheurs à cesegment,cequisupposeenthéorie4fois8connexions,soit32filsàbrancher.Halte-là!TutesouviensquelacarteArduinoetdonclemikonn’offrentque14sortiesnumériques.Onestloinducompte.
Desparallèlesensérie
L’être humain est ingénieux. Il cherche toujours une solution
lorsque c’est possible. Pour piloter quatre afficheurs sept
segments lorsque l’on n’a pas assez de broches de sortie, on
utiliseuncircuit spécialappelé registre àdécalage (shift register).
Cecomposantreçoitlesdonnéesl’uneaprèsl’autresuruneseule
entrée, bit après bit, et les stocke dans ses petites cases de
mémoire(lesregistres)endécalantd’unecaseaprèschaquebit.
Il possède huit sorties en parallèle, un peu comme lorsque les
chevauxdecourseviennentenfileindienneseplacercôteàcôte
dans leursboxessur la lignededépart.Lorsque l’onenvoieune
commandespéciale(lesignaldudépart),l’étatdeshuitsortiesest
rendu accessible en même temps à ce qui y est branché, par
exemplel’afficheur.Aveccettetechnique,ilsuffitdequatrefilsde
donnéespourpiloterquatreafficheursàseptsegments. Jen’en
dirai pas plus dans ce livre, car des afficheurs plus polyvalents
sontdorénavantdisponiblesàbascoût.
AfficheursLCDLatroisièmeetdernièrecatégorieestcelledesafficheursàcristauxliquides ou LCD (liquid crystal display). Il y a deux sous-catégories:
ÉcransLCDalphanumériquesUn afficheur LCD alphanumérique ne peut afficher que descaractères de l’alphabet et quelques signes de ponctuation. Lesafficheurs les plus courants offrent 16 caractères affichables parligne et 2 lignes. Leur référence comprend souvent la mention«1602»;tudevinespourquoi.
Figure11.4:AfficheurLCDalphanumérique.
AfficheursLCDgraphiquesLesafficheursLCDgraphiquesontdesécranscomposésd’unetrèsgrandequantitédepoints (lespixels).Les téléviseurs et les écransd’ordinateursontdesafficheursLCDgraphiques,etlestelliphonesenonttousun,souventtactile.
Figure11.5:AfficheurLCDgraphiquecouleur.
Jenevaisutiliserdanscechapitrequelemodèleleplussimple,quiest l’afficheur LCD alphanumérique, ou afficheur LCD en modetexte. Les afficheurs graphiques coûtent beaucoup plus cher etdemandentbeaucoupplusdetravailauprocesseur.
Un écran LCD en mode texte demande beaucoup moins detraitementauprocesseurparcequ’ilpermetuniquementd’afficheruncaractèreparmitousceuxquisontprédessinésdanssamémoirelocale.CesontlescaractèresASCII.Voyonscelaendétail.
ToujoursavoirboncaractèreDès les débuts de l’informatique, il a été nécessaire de se mettred’accord sur une série de codes numériques en correspondanceavecdesdessinsdelettresdel’alphabet.LesAméricainsétantdéjààce moment en avance dans la science informatique, c’est unstandard américain qui a été choisi pour la correspondance entrecodeetdessinsdeslettres:lecodageetlatableASCII.
Cet acronyme ASCII (prononce « aski » ) signifie American
StandardCodefor InformationInterchange.Enbon français,c’estunstandardaméricainpouréchangerdesinformations,sous-entenduentreunordinateuretunêtrehumain,maiségalemententredeuxordinateurs.
Pour afficher et imprimer facilement du texte, la solution la plusefficaceconsisteàstockerdirectementdans l’écran,plutôt lacartevidéo, ou dans l’imprimante tous les dessins des caractères (cequ’onappelledesglyphes).Ilneresteensuiteplusqu’àattribueruncodenumériqueàchaquedessin.
Dans la tableASCII, les lettres de l’alphabet anglais deA àZ (enlettresmajuscules)correspondentauxcodesnumériquessuivants:
Tableau11.1:CodesASCIIdeslettresenmajuscules
Valeurdécimale Dessin
65 A
66 B
67 C
etc.
90 Z
Leschiffresde0à9sontcodésainsi:
Tableau11.2:CodesASCIIdeschiffres
Valeurdécimale Dessin
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
57 9
Grâce à cette convention, pour afficher ou imprimer la lettre Amajuscule, il suffit d’envoyer le code 65 à l’écran ou àl’imprimante.
Etpourafficherlavaleurnumérique65,ilfautenvoyerl’octet65?Pasdutout!CherchedansleTableau11.2!Pourafficherlesdeuxchiffres6et5,ilfautenvoyerlesdeuxcodes54et53.Ilnefautpasconfondre les valeurs numériques (le mikon ne sait rien traiterd’autre)etlesdessinsdeschiffres.
Enplusdes26lettresdel’alphabetenmajusculesetdes10chiffres,la tableASCIIcontient l’alphabeten lettresminuscules,des signesde ponctuation ainsi qu’un certain nombre de caractères qui ne
peuvent être ni affichés, ni imprimés. Ce sont des caractères decontrôleoud’échappement.Cesonttouslescodesinférieursà32.
C’estparmicescodesquesetrouveceluipouravancerdeplusieurscolonnesvers ladroite,c’est-à-dire la tabulation (Tab)et lesdeuxcodesquirestentomniprésentsdenosjours:
» lecodedepassageàlalignesuivante(LineFeedou
NewLine);
» lecodedesautdepage(FormFeedouCarriage
Return).
Ilssontinsérésdanstouslesfichiersdesapplicationspourmarquerdesfinsdeparagraphesoulafindufichier.
L’ASCIIétendu,maisilrestecalmeIlsuffitd’unseuloctetpourtouslescodesnumériquesdeslettresetdessymbolesdelatableASCII.Audépart,onnepouvaitutiliserqueles caractères anglais. Il n’y avait pas de place pour les lettresaccentuéesdufrançais,lessignesspéciauxdel’allemand,etc.
C’est au début des années 1980 que le nombre d’utilisateursd’ordinateurs personnels a augmenté dans les pays nonanglophones.Ilsontalorsréclamédepouvoirécriredestextesavecleurscaractères spécifiques.Desaccordsontétépassésentreceuxqui étaient chargés de la norme ASCII et les organismes dedifférentspaysenleurattribuantl’espacecorrespondantauxvaleursde 128 à 255, c’est-à-dire la deuxième moitié de la plage depossibilitésd’unoctet.
Maisc’étaitunesituation temporaire :chaquepaysavaitsaproprepagedecode.Siquelqu’unenvoyaitunfichierécritavecuneautrepagedecodequecelledudestinataire,cederniervoyaitdessignesbizarresoudifférentsdeceuxquis’ytrouvaientàl’origine.
Denos jours, la situation est quasiment réglée, surtoutdepuisquelesprogrammesse rendentcompatiblesavec lanormeuniverselleUnicodeetUTF-8.C’estnotammentlecasdespagesWeb.Ildevientenfin possible de mélanger du chinois, de l’espagnol et du hindidansunmêmeparagraphe.
Maiscespossibilitésvont largementau-delàdesbesoinsquenousavons avecnotrepetite carteArduino.Nous allonsnous contenterde la table ASCII de base, et au départ uniquement des lettres enmajusculesdel’anglais.Pasd’accent,pasdeminuscules.Voicidonccette fameuse tableASCIIquedes centainesdeprogrammeursontun jourou l’autre cherchée sous les tasdepapiersde leurbureau(Figure11.6).
Dans la colonnedesvaleursbinaires, les zérosdegauchene sontpas montrés. Après tout, les prix dans les magasins ne sont pasécrits003,99€nonplus.
Tu as remarqué la colonne Octal ? C’est une autre base denumération que certains programmeurs adorent. Huit est unmultiplededeux,cequiestunebonnechose.Pourlavaleur101dela lettreA, c’est facile : une soixante-quatraine, aucunehuitaine etun,cequifaitbien65décimal.
Figure11.6:LatableASCIIavecsesvaleursdansplusieursbases.
DonnéesASCII(char)Deux types de données sont spécialement prévus pour manipulerdescaractères:letypecharetletableaudecaractères.
Letypecharestunentiersur8bits.Tupeuxl’utilisercommetouteautre valeur numérique, mais il sert d’abord à stocker descaractères,commececi:
charmaLettre='A';
lcd.print(maLettre);
lcd.print(char(65));
lcd.print(65);
Les deux premiers affichages ci-dessus ont le même effet. Letroisièmeaffichelavaleurnumérique65etnonlalettreA.
Nousavonsdéjàutilisédestableauxdecaractèresetnousallonsenvoird’autresdanslasuiteduchapitre.
Latechniqued’affichageUnécranLCDutiliseune inventiongénialequiconsisteàorienterdes petits cristauxmobiles, parce que liquides, soit dans un sens,soitdans l’autre.Dansunsens, lescristauxsont invisibles,etdansl’autre, ils forment une tache noire. L’énorme avantage de cettetechniqueestqu’unefoisquelescristauxsontorientésdansunsensoudansl’autre,ilsyrestentsansconsommerd’énergie.L’afficheurLCD est donc tout à fait adapté aux appareils électroniques quifonctionnentsurpiles.
Pour afficher les symboles, l’afficheur LCD propose unematriceélémentaire,commeunemosaïqueconstituéedecinqpointsdanslesens horizontal sur sept points dans le sens vertical. Entre deuxsymboles,unespaceverticalestréservépourespacerleslettres.Ilyaaussienbasune lignedepoints réservéeausoulignementouaucurseurdepositionnement.
L’utilisationde l’afficheur devient très simple : tu lui transmets lavaleurnumériquedusignequetuveuxfaireafficheretsapositiond’affichage. L’afficheur reçoit cette valeur et s’en sert pour allerchercher le dessin dans sa table ASCII stockée en mémoire. Parexemple,pourlavaleur65,ilvachercherlacasecorrespondantauAmajusculeetallumelespointsenconséquence.Voicilatabledesdessins de caractères de l’écran LCD que nous utilisons(Figure11.7).
La lettre A est à l’intersection de la colonne 0100 et de laligne 0001. Le Amajuscule en ASCII correspond donc bien à lavaleurdécimale65.Lequartetsupérieur(Upper)s’écrit0100(seullebitdes64està1)etlequartetinférieur(Lower)vaut0001.
Dans certains composants, on utilise aussi un codage spécialnommécodageBCD.
Figure11.7:DessinsdesmosaïquesdecaractèresLCD.
LecodagehybrideBCD
BCDsignifieBinaryCodedDecimal.C’estuneastucequiconsisteà
coder en binaire chaque chiffre décimal sur quatre bits.
Comparons:
Sij’écrislavaleur65duAenbinairenormal,j’obtiens01000001,
c’est-à-dire1fois64et1fois1.
Sij’écrislamêmevaleur65endécimalcodébinaire,j’obtienstout
autre chose. Le 5 décimal devient 0101 (1 fois 4 et 1 fois 1) et
le6devient0110(1fois4et1fois2).
Aupremierabord,cen’estpastrèsfuté.Encodantchaquechiffre
décimal à part, on perd de la capacité de codage :
après99décimal,ondoitutiliseruntroisièmequartetalorsqu’en
binairepur,onpeutallerjusqu’à255avecdeuxquartets.
L’encodage BCD a malgré tout sa raison d’être : il simplifie
certainesopérationsdanslescircuitsélectroniques.
Nousensavonsmaintenantassezsurlathéoriedel’afficheurLCD.Passonsàlapratique,encommençantparchoisirnotrecomposantprincipal.
Montaged’unécranLCDIlexistedenombreuxmodèlesd’afficheursLCDquifonctionnentàpartirdumêmecircuitélectroniqueHitachi.Lemodèleexactn’estpas important. L’essentiel est que ton afficheur comporte 2 lignesde 16 caractères. Ceci dit, s’il en offre plus, mes projetsfonctionnerontaussi.
Là où les choses se corsent, c’est que les afficheurs LCD sontprévuspresquetouspourrecevoirlavaleuràafficherenparallèle.Puisqu’uncodeASCIIestsurhuitbits,ilfautdonchuitbroches.Etce n’est pas tout !Voici tous les branchements à prévoir pour unécranLCD:
» huitfilspourleshuitbrochesdedonnées;
» deuxfilspourl’alimentation5VetGND;
» deuxautresfilspouralimenterlerétroéclairagede
l’écran;
» troisfilspourdessignauxdecommande;
» aumoinsunfilpourcontrôlerlecontraste.
Sijecomptebien,celafaitseizefilsàbrancherdontonzequivontoccuperdessortiesnumériquesdelacarteArduino.Autrementdit,ilneteresteensuiteplusquetroissortiesnumériquespourpiloterunautreappareil,ousimplementallumerdesdiodesLED.
Voici par exemple le circuit que j’avais prévu de te demander deconstruire.Onletrouveàenviron6ou7euros.Quandj’aivuquelemoduleenfichablecoûtaitmoinsde11euros,j’aichangéd’avis.Tuconstatesquelechantierétaitbienavancé:)
Figure11.8:Projetdecâblaged’unécranLCDnu(abandonné).
Ilyadeuxsolutionsàcessoucis:
1. TouslesécransLCDdecettegammesavent
fonctionnerendeuxtempsavecseulementquatre
brochesd’entréepourlesdonnées.Ilsuffitdese
mettred’accordavecleprogrammepourqu’ilenvoie
d’abordlepremierdemi-octet(unquartet),puisle
second.C’estunesortedeliaisonentreparallèleet
série.Ongagnequatrebroches.
2. L’autresolutionestradicale:elleconsisteàsouder
l’écranLCDsurunecartequipossèdelesmêmes
dimensionsquelacarteArduino.Cettecartefillesera
dotéesurledessousdubonnombredeconnecteurs
mâlespourpouvoirenficherlacartefillepar-dessusla
carteArduino,enquelquesortecommesielle
protégeaitsamère.C’estpourquoilescartes
d’extensionpourArduinoquis’enfichentpar-dessus
portentenanglaislenomshield,quisignifie
«bouclier».Latechniquedesdeuxdemi-octetsestbien
sûrconservée.
Labonnenouvelleestqueplusieursfabricants
proposentcegenredemodulepréconstruit.Iln’yaplus
qu’àlepayer,ledéballer,l’enficherettéléverserlebon
programme(avecunelibrairieappropriée,biensûr).
Personnellement, cela me déçoit un peu de ne plus pouvoir voirmon joli mikon. Mais cela offre un tel avantage par rapport aucâblaged’unspaghettidefilsquejemesuisfaituneraison.
Tuasdoncdeuxpossibilitésauniveauducomposantd’affichage:
» soitturéunisunécranLCDnu,unepelotedefilsetdu
courage;
» soittut’équipesd’unmoduleshieldécranLCD.
Je teconseille fortementcette secondesolution,et jevaismontrercommentmonterleprojetavecunmodèlebienprécisdecartefille:le module LCD de la société DFRobot sous la référenceDFR0009(Figure11.9).
Figure11.9:LacarteshieldDFR0009.
Cerise sur l’écran, cette carte est dotée, en plus de l’écran, d’unpotentiomètre pour régler la luminosité et de cinq boutons-poussoirs(plusunboutonReset)pourdenouveauxprojetsquejetelaisseimaginer!
Variantes ! Le circuit Toshiba HDC 44780 existe en versionjaponaiseUA00oueuropéenneUA02.Laseuledifférenceconcernela partie étendue des codes ASCII, c’est-à-dire les valeurssupérieuresà127.Ilyadanslaversionjaponaisetouteunesériedekana.
ImplantationdelacartefilleL’énorme avantage de la solution de la carte fille est qu’il n’y aaucunautrecomposantàajouter,etaucunfilàconnecter.N’est-cepasmagique?
1. Déballesoigneusementlacartedesonjoliemballage.
Tuvoisqueledessouscomportedenombreuses
broches.Ellesvonts’enficherdanslesconnecteursde
lacarteArduino.
2. PrendslacarteLCDpardeuxcôtésdansunemainet
lacarteArduinodansl’autre.Observel’espaceentreles
deuxcartes.Entenantlesdeuxcartesunpeudebiais,
positionnelapremièrebrocheLCDdanslepremier
trouArduinodechaquecôté(donclaA5/SCLetlaVCC
quiestau-dessusdelaDIGITAL0).N’appuiequ’àpeine.
Figure11.10:Insertiondelacarteshield.
3. Enfonceprogressivement,sansforcerlesdeux
rangéesdeconnecteurs,jusqu’àcequelesdeuxcartes
soientparallèles.Ilestnormalquelesdeuxderniers
contactsArduinocôtéDIGITALetcôtéANALOGIN
(côtépriseUSB)restentlibres.
4. Etvoilà!Lemontageestdéjàterminé.
Voyonssansplustardercequ’onpeuttirerdecetafficheur.
L’écranLCDutilise les septbrochesDIGITAL4à10ainsique labrocheanalogiqueA0.Ilnefautpasessayerdelesutiliserpourunautrecomposant.
Pourlestrèscourageux
Si tu veux câbler un écran LCD nu, voici l’essentiel des
branchements:
Signal Contact
del’écran
BrocheArduino
Vss 1 MasseGND
VDD 2 Positif5V
Contraste(VE) 3 Curseurdepotentiomètre
RegisterSelect 4 Digital8
Read/Write 5 MasseGND
Enable(E) 6 Digital9
DonnéeD4 11 Digital4
DonnéeD5 12 Digital5
DonnéeD6 13 Digital6
DonnéeD7 14 Digital7
Anode
Rétroéclairage
15 +5V
Cathode
Rétroéclairageà
16 MasseGND(Lesbroches15
et16sontparfois
part.)
Pour le réglage du rétroéclairage, il faut un potentiomètre
de10kohm.Uneborneau5V,uneborneàlamasseetlecurseur
àlabroche3del’écran.
KristaLiklebavardCommepremierprojetd’affichage,jeteproposedeprogresserendeuxétapes:
1. Affichagededeuxmessagesfixesoccupantlesdeux
lignes.
2. Affichagededeuxmessagesavecuneanimation.
AnalysonslaréponseAvant de coder, voyons s’il faut installer d’abord une librairiecomplémentaire.C’estun réflexeà adopter.Cet afficheurLCDestbasésurlecircuitleplusrépandu,leToshibaHDC44780.Tuserasdoncheureuxd’apprendreque la librairiequ’il fautaétéacceptéepar les créateursArduino comme librairie standard.Elle est doncinstalléedèsledépart.Vérifionscela.
1. Dansl’atelier,ouvrelemenuCroquis,puislesous-
menuInclureunebibliothèqueet,enfin,Gérerles
bibliothèques.Lafenêtredegestionapparaît.
2. Danslazonederechercheenhautàdroite,cliquepuis
saisislespremièreslettresdeLiquid.Lalistese
restreint(Figure11.11).
Figure11.11:LalibrairieLiquidCrystalestbieninstallée.
Normalement,lalibrairiequ’ilnousfautest
mentionnée.SonnomexactestLiquidCrystal.Elle
estindiquéecommedetypeBuilt-In(interne),ce
quiconfirmequ’elleestprésented’office.
Nouspouvonsdoncyfaireréférencedansnostextes
sourcesparunedirective#include.
LesfonctionsessentiellesPourexploiterunafficheurLCDàdeuxlignes,nousavonsbesoindepouvoirfairetroisopérations:
» Choisiroùafficherleoulesprochainscaractèresen
positionnantlecurseur(invisiblenormalement).Nous
utiliseronslafonction,pardon,laméthoded’objet
nomméesetCursor().
» Demanderl’affichaged’untexte,unouplusieurs
caractèresàlafois,avecprint().
» Effacertoutl’écran,avecclear().
Puisquelalibrairieestorientéeobjets,nousallonscommencerparcréer un objet à partir de la classe prédéfinie. Ici, elle se nommeLiquidCrystal, tout simplement.Pour l’objet, restons sobres :ceseralcd.
Lestroisméthodesserontbiensûrqualifiéesparlenomdel’objetquilespossède,commedanslcd.setCursor().
RédactiondeKristaLik1Commetusaislefairemaintenant,saisisletextesourcesuivantoubien charge-ledepuis le dossier des exemplesdu livre. Il porte lenomsuivant:
CH11A_KristaLiq1
Listing11.1:TextesourcedeKristaLik1
//KristaLiq1
//OEN170331
#include<LiquidCrystal.h>
LiquidCrystallcd(8,9,4,5,6,7);
voidsetup(){
lcd.begin(16,2);
}
voidloop(){
lcd.setCursor(0,0);
lcd.print("Salut,Arduikidz!");
delay(900);
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Cavatibien?");
delay(900);
lcd.clear();
}
//BONUS
voidtest(){
for(inti=128;i<256;i++){
lcd.print(char(i));
delay(100);
}
}
VisiteguidéeLacréationdel’objetnommélcd(soninstanciation)estclassique.Nous indiquonssixnumérosdebrochesenparamètres. Ici,pasderisque de se tromper puisque tu n’as rien câblé ! La lecture desparamètrestepermetdeconfirmerquellesbrochesnepeuventplusserviràautrechose.
LiquidCrystallcd(8,9,4,5,6,7);
Unechoseàmémoriserestlasyntaxedupositionnementdecurseur.Lesparamètressontlessuivants:
lcd.setCursor(colonne,ligne);
Lenumérodelignenepeutêtrequesoit0,soit1,puisqu’oncompteàpartir de0. Je trouve illogique l’ordredesdeuxparamètres.Ondevraitd’abordchoisirlaligne,puislacolonne.Qu’enpenses-tu?
J’ai laissé une routine en bonus. Pour la faire tourner, ajoute unappelverstest()dans laboucleprincipale.Danscette fonction(ici,cen’estpasuneméthode),jedemanded’afficherlaconversionen type charde la valeur fournie. Vois ce qui se passe quand tuenlèvesletype(quidevienticiuntranstypeur).
TestduprojetRelis-toi et téléverse. Tu dois voir tes deux premiers messages(Figure11.12).
Figure11.12:Kristalik1enpleineaction.
Uncoupjetevois,uncoupjenetevoispas
Une petite astuce. Insère les trois instructions suivantes
n’importe où dans la fonction principale pour masquer et
réafficher ce qui est actuellement présenté à l’écran. Cette
opérationnechangerienaucontenu.
lcd.noDisplay();
delay(900);
lcd.Display();
Dans une boucle de répétition, cela permet de faire clignoter
l’affichage,parexemplepourattirerl’attention.
Dudessin?Non,dutexteaniméVoiciunevarianteduprojetquiaffichelesmessagesuncaractèreàlafois,commeavecuneffetdedéroulé.
Lefichiersourceportelenomsuivant:
CH11A_KristaLiq2
Listing11.2:TextesourcedeKristaLik2
//KristaLiq2
//OEN170331
#include<LiquidCrystal.h>
#defineLIG10
#defineLIG21
LiquidCrystallcd(8,9,4,5,6,7);
chartcMsg[2][17]={"Jesuislemikon",
"M'entends-tu?"};//
!
voidsetup(){
lcd.begin(16,2);
}
voidloop(){
lcd.setCursor(0,LIG1);
lcd.print(tcMsg[0]);//!
matrixer(1);
delay(2000);
lcd.setCursor(0,LIG2);
lcd.print(tcMsg[1]);
matrixer(0);
delay(2000);
}
voidmatrixer(booleansens){
for(byteyTour=0;yTour<16;yTour++)
{
lcd.setCursor(yTour,(sens?LIG1:LIG2));
//!
lcd.print("");
lcd.setCursor(yTour,(sens?LIG2:LIG1));
lcd.print(tcMsg[sens][yTour]);
delay(100);
}
}
Jedéclareuntableaudedeuxchaînesdecaractèresavecunecasedeplusquelalongueurmaximale.Pourquoi?Pourpouvoirstockerlecaractèrespécialquimarquelafind’unechaîneenlangageC.C’estlavaleur0.Onappelleceschaînesdeschaînesàzéroterminal.
chartcMsg[2][17]={"Jesuislemikon",
"M'entends-tu?"};
Pour afficher chaque chaîne, j’indique seulement l’indiceapproprié:
lcd.print(tcMsg[0]);
Dans la fonction matrixer(), j’utilise à nouveau l’opérateurternaire:
lcd.setCursor(yTour,(sens?LIG1:LIG2));
//!
LesecondparamètreseraégalàLIG1sisensestdifférentde0,etàLIG2s’ilestnul.
Pouraccéderunàunauxcaractèresd’unechaîne,j’utiliseledoubleindice:
lcd.print(tcMsg[sens][yTour]);
Lanceuntest.Tuvoisquechaquecaractèredelanouvellelignefaitdisparaîtreceluidel’autreligne.
Figure11.13:KristaLik2aumilieudesesaffichages.
KristAlpha,passibêteVoyons maintenant comment produire de l’affichage de façonentièrementnumérique,doncàpartirdescodesdecaractères.Nousallons afficher tout l’alphabet en majuscules et en minuscules, etmêmequelqueschiffresetsignesdeponctuation.
Lefichiersourceportelenomsuivant:
CH11B_KristAlpha
Listing11.3:TextesourcedeKristAlpha
//KristAlpha
//OEN170331
#include<LiquidCrystal.h>
#defineLIG10
#defineLIG21
#defineADEB65
#defineAFIN97
LiquidCrystallcd(8,9,4,5,6,7);
voidsetup(){
lcd.begin(16,2);
Serial.begin(9600);
analogWrite(10,200);//RÉTROÉCLAIRAGE
}
voidloop(){
alphabetiser(0);
delay(1000);
lcd.clear();
alphabetiser(32);
delay(1000);
lcd.clear();
alphabetiser(-32);
delay(1000);
lcd.clear();
}
voidalphabetiser(byteySaut){
byteligne=0;
bytecol=0;
for(byteyTour=ADEB;yTour<AFIN;
yTour++){
lcd.setCursor(col++,ligne);
lcd.print(char(yTour+ySaut));
if(yTour==ADEB+15){
ligne++;
col=0;
}
delay(200);
}
}
L’appelsuivantpermetdecontrôlerlaluminositédel’écran:
analogWrite(10,200);//RÉTROECLAIRAGE
Dans la fonction alphabetiser(), une boucle affiche lescaractères de toute une plage de codes ASCII. Je prends soin depasserenligne2auboutde16positions.
Téléverseetteste.Tudoisvoirleslettresenmajuscules,lesmêmesenminuscules,puisdessignesetdeschiffres.
Figure11.14:KristAlphaconnaîtlesminuscules!
Essaye de voir ce qui se passe quand tu définis une plage tropgrande, donc avec plus de caractères que la place disponible surl’afficheur(32).
KristaProverbe,qu’onseledise!
Je t’invite maintenant à une sorte de jeu du cadavre exquis. Leprogrammevacombinerpartirageausortledébutd’unephraseàlafind’uneautre.
Bien sûr, nous allons déclarer une foule de chaînes de texte quiservirontdematièrepremière.
Lefichiersourceportelenomsuivant:
CH11C_KristaProverbe
Listing11.4:TextesourcedeKristaProverbe
//KristaProverbe
//OEN170331
#include<LiquidCrystal.h>
#defineLIG10
#defineLIG21
LiquidCrystallcd(8,9,4,5,6,7);
#defineMAXSUJ11
chartcSujet[MAXSUJ][17]={
"Nefaispas",
"N'oubliepas",
"Neregardepas",
"Nepensepas",
"Neracontepas",
"Raconteleur",
"Ignoredonc",
"Neniepas",
"Nedoutepasde",
"Nedispas",
"Croisvraiment"};
#defineMAXOBJ10
chartcObjet[MAXOBJ][17]={
"cequejefais.",
"cequejevois.",
"cequej'aime.",
"cequejedis.",
"cequejecrois.",
"cequejepense.",
"cequetupenses",
"cequetufais.",
"cequ'ilsfont.",
"n'importequoi."};
bytebHasaS,bHasaO=0;
byteyPrecSuj,yPrecObj=0;
voidsetup(){
lcd.begin(16,2);
Serial.begin(9600);
randomSeed(analogRead(1));
}
voidloop(){
bHasaS=tirerAuSort(yPrecSuj,MAXSUJ);
yPrecSuj=bHasaS;
bHasaO=tirerAuSort(yPrecObj,MAXOBJ);
yPrecObj=bHasaO;
derouler(bHasaS,bHasaO);
delay(1000);
lcd.clear();
Serial.print("Sujet:");
Serial.print(bHasaS);
Serial.print("Objet:");
Serial.println(bHasaO);
}
bytetirerAuSort(byteprec,byteplafond){
bytebNbr;
bNbr=random(0,plafond);
while(bNbr==prec){
Serial.print(bNbr);
bNbr=random(0,plafond);
}
return(bNbr);
}
voidderouler(byteyChoiS,byteyChoiO){
byteyTour=0;
lcd.setCursor(0,LIG1);
for(yTour=0;yTour<16;yTour++){
lcd.print(tcSujet[yChoiS][yTour]);
delay(50);
}
delay(500);
lcd.setCursor(0,LIG2);
for(yTour=0;yTour<16;yTour++){
lcd.print(tcObjet[yChoiO][yTour]);
delay(100);
}
delay(200);
}
Enlisantlecodesourcelentement,tunedoispasavoirdesurprises.Quelquesremarquescependant:
randomSeed(analogRead(1));
Ici,nousutilisonslafonctionstandardquiremélangeleschiffresdugénérateur de nombresrandom() afin que le tirage soit moinsrépétitif. Comme valeur, nous lisons ce qui traîne sur une brocheanalogiqueflottante.
Nousréutilisonsunefonctiondetirageausortdédoublonnantequenous avons déjà rencontrée dans le Chapitre 7, dans l’exemplebonusCH07B_Devinum2.
Laséried’affichagesdemiseaupointvers leMoniteursériepeutêtresupprimée.Elletemontrequ’encasdetiragedumêmenombre,ilyaretirage.
Figure11.15:Unproverbesynthétique.
Lance un téléversement et regarde le mikon s’essayer à l’art del’écriture.Ilyaplusdecentcombinaisonspossibles.Certainessontétranges, d’autres fendantes. Tu peux en ajouter à ta guise, maisn’oublie pas d’augmenter les indices des tableaux MAXSUJ etMAXOBJenconséquence!
N’hésite pas à varier la durée d’affichage. Tu peux, par exemple,garderlamêmephraseaffichéependantuneminuteavec:
delay(60000);
Revenonsàunprojetàusagepratiquegrâceàunautrecomposant:lemoduled’horloge.
Est-cequeletempsvieillit?Lemikon sait compter le temps qui passe.Nous nous en sommesservis avec la fonction millis() qui renvoie le nombre desecondesécouléesdepuislamisesoustensiondelacarte.
Le problème, c’est que le mikon (c’est un comble) n’a pas demémoire au sens où il perd l’heure quand son alimentation estinterrompue.
Pourdisposerdel’heuresansdevoirlarégleràchaquedémarrage,et pour avoir au passage aussi la date année/mois/jour, il faut uncircuitspécialisé.OndésignecegenredecircuitsouslenomRTC,Real-TimeClockouhorlogetempsréel.
Un des circuits d’horloge les moins chers porte la référenceDS1307. Il se dérègle un peu au cours du temps (de quelquesminutesparmois),maisc’est largementsupportable.Pourentirerprofit, il faut luiajouterquelques résistanceset, surtout,uncristaldequartz,commelemikon.
Plutôtquedeselancerdanslacréationdumontage,jeteproposedechercherdanslecommerceunmoduled’horlogepréfabriquébasésur le DS1307. Il en existe de nombreux modèles. Voici lesquestionsà teposerpourque toncircuitsoitcompatibleavecmesexemples:
1. Lecircuitd’horlogedoitêtreunDS1307.
LecircuitDS3231estbeaucoupplusprécis,car
compenséentempérature,maisilestpluscher.
2. LasortiedoitêtredetypeI2C(surdeuxbrochesSCLet
SDA).
3. Lemoduledoitcomportersurl’autrefaceunporte-pile
pourrecevoirunepileenformedejeton
CR2032(tensionde3,6V).
4. Sipossible,lesbrochesdeconnexiondoiventêtredéjà
soudéesoubienunconnecteurfemelledoitêtre
présent.
Pour ce livre, j’ai utilisé lemodèle TinyRTC (Figure 11.16). Lescomposants sont sur une face et le porte-pile sur l’autre. Tu peuxvoir les contacts de connexion. Les broches n’étaient pas soudéeslorsdel’achatsurcemodèle.
Figure11.16:LemodulehorlogeTinyRTCbasésurlecircuitdu1307.
MontageIl n’y a aucun composant supplémentaire à prévoir. Comme lecircuitestminuscule, il fautnéanmoins lefixerquelquepart.Pour
le mien, j’ai enfiché le module dans un coin d’une petite plaqued’essai.Celasupposequelesbrochesdesortiesontsoudées.
Situnepeuxpasfairesouderlesquatrecontacts,iltefautfixerlecircuit surun support,par exempleavecde l’adhésif,puisutiliserl’astuce (pas très glorieuse) indiquée dans le projet Sonner duChapitre9pourfairelesconnexions.
Maisavantd’enficheroudefixerlaplaque,mieuxvautinstallerlapile boutonCR2032 car elle se trouve dessous. Le + doit être ducôtérestantvisible.
Quatre broches seulement sont à connecter. Les autres peuventresterinutilisées:
» lesdeuxbrocheshabituellespourl’alimentation:GND
(parfoismarquéeVss)et5V(marquéeparfoisVcc);
» lesdeuxbrochespourledialogueI2C:SDAetSCL.
Un des avantages de la carte fille de l’écran est que plusieursconnexionsdelacarteArduinosontremontéesetdoncdisponiblespartraverséesurlacarteécran.
Observelecoinenbasàdroitedelacarteécran:tuyretrouveslesbrochesdesentréesanalogiques.LeprotocoleI2Cutilisejustementles deux dernières,A4 etA5.Pour plus de confort, le fabricant aprévu pour chaque broche analogique une paire de brochesd’alimentation.Tupeuxainsirassemblerlesquatrearrivéesdefilsdumodulehorlogedanscecoindelacarte(Figure11.17).
Figure11.17:Lemodulehorlogefixéetconnecté.
Voicilesdeuxbranchementspourlesdonnées:
» LefilquivientdelabrochededonnéesSDAducircuit
horlogeestàbrancherdanslapriseanalogiqueA4.
» Lefilquivientdelabroched’horlogeSCLducircuit
horlogeestàbrancherdanslapriseanalogiqueA5.
Jenetefaispasl’affrontdeterappelerqu’ilfautcommed’habitudebrancher lesdeuxautresfilspouralimenter lemoduleenénergie,soitle5VetlamasseGND.
Etc’esttout.Passonsàl’installationdelalibrairiequivasimplifierl’utilisationdumodulehorloge.
InstallationdelalibrairiePlusieurs librairies sontdisponiblespourgéreruncircuithorlogeDS1307.Toutesdéfinissentaumoinsuneclassequipermetdecréerunobjetdetypetemps.Cetobjetsaitfourniràlademandeladateet
l’heure actuelles. Il suffit d’appeler la méthode appropriée del’objet.
Lalibrairiequ’ilnousfautportelenomRTClib.
1. Démarrel’atelierArduinosinécessaire.Ouvrelemenu
Croquis,puislesous-menuInclureunebibliothèque
et,enfin,Gérerlesbibliothèques.Lafenêtrede
gestionapparaît.
2. Danslazonederechercheenhautàdroite,cliquepuis
saisislespremièreslettresdeRTC.Plusieurslibrairies
sontproposées(Figure11.18).
Figure11.18:InstallationdelalibrairieRTClib.
3. SélectionnelalibrairieportantlenomRTClibby
AdafruitetcliqueàdroitesonboutonInstaller.
Avantderéalisernotreprojet,ilfautprocéderàunpremierréglagedel’horlogeenfaisantexécuterunprogrammedédié.
Réglagedel’horlogeLecircuitdoitêtresynchroniséavecladateetl’heureréellesdetonlieu de vie. Je suppose que ton ordinateur est correctement réglé,carc’estdeluiquenousallonsfairerécupérerlesvaleursaumoyend’unpetit programmeque tu n’auras à exécuter qu’une fois aprèschaquechangementde lapile (etencore).Et lapiledureplusieursannées.
Ce programmeutilitaire est livré avec la librairie, parmi d’autresexemples.
1. Dansl’atelier,ouvrelemenuFichier,lesous-menu
Exemples,puislacatégorieRTClibquiadûapparaître
toutenbas.Lesquelquesexemplessontlistés.
2. Sélectionneceluiportantlenomexactds1307tout
court.
3. Letextesourceapparaît.Enleparcourant,tuvoisqu’il
vaafficherbeaucoupdechosesdansleMoniteursérie.
Lesouci,c’estquelavitessededialogueestrégléeà
57600baudsaulieudes9600quinoussuffiraient
amplement.
Situnecoordonnespaslesvitesses,lamiseàl’heure
ducircuitseferatoutdemême,maistunepourras
rienlireàl’écran.
4. Situveuxpouvoirlirelesaffichages,soitturèglesla
vitessedanslafenêtreduMoniteursérieà57600,soit
tumodifiesleprogramme.
Jeconseilledenepastoucheràlavitessedansle
moniteur,d’autantquenousauronsuneautreretouche
àappliqueraucodesource.
5. Danslapremièrelignedelafonctionsetup(),
remplacececi:
Serial.begin(57600);
parceci:
Serial.begin(9600);
6. Sauvegardetaversionretouchéedutextesource
ds1307sousunnombienàtoi.J’aifournilaversion
modifiée,ettraduite,tantqu’onyest,dansles
exemplessouslenomCH11C_ds1307.
7. Lanceuntéléversement/exécutionetouvrelafenêtre
duMoniteursérie.
Nesoitpastroppressépourouvrirlafenêtre.Attends
queletéléversementsoitterminé;sinon,tuvascréer
unconflitd’accèsàlaliaisonUSB.
Letempsd’ouvrirlesyeuxetlecircuitds1307estdéjà
synchronisé!Enrevanche,situlisbienlesdates
affichéesetlapromessed’uncommentairedutexte
source,tudevraisrepérerunpetitsouci.
Bonsang,maisc’estbiensûr!Voyonslecommentaireaudébutdusecondgrosblocd’instructionsd’affichage:
//calculateadatewhichis7daysand30
secondsintothefuture
Si je traduisbien, il indiquequenousallons calculer ladatequ’ilseradans7jourset30secondes.Si tucalculesdetête, tuvasvoirquecen’estpasbon.Kézaco?
Figure11.19:Lecalculdeladatefutureestbizarre…
Le calcul se fait dans l’instruction suivante. Elle crée un secondobjet de type date/heure en le réglant avec la date actuelleaugmentée de ce que renvoie la méthode TimeSpan(). Et cetteméthodeabesoindequatreparamètresd’entrée:
DateTimefuture(now+TimeSpan(7,12,30,6));
Cesvaleurs7,12,30,6tedisentquelquechose.Le7estsansdoutepour le nombre de jours. Mais le 12 ? Et si le 30 est pour les
secondes,àquoicorrespondle6?
Autravail,inspecteurMinute!Onpasseenmodedébogage.Tusaisque les librairies complémentaires sont stockées dans le sous-dossier libraries de ton dossier de travail Arduino ? Parexemple,surmamachine,c’estdansMesdocuments,enréalitéici:
C:\Users\ton_nom\Documents\Arduino\libraries\RTClib
Dans ce dossier, nous trouvons le fameux fichier d’en-tête(extension.h)quiestcitédansletextesource:
#include"RTClib.h"
Si j’ouvre ce fichier dans un éditeur (pas un traitement de texte,STP!NotePad++estgratuitetexcellent),jepeuxfairechercherlaméthodepoursavoircommentelledoitêtreappelée.Onparleaussidesignaturedeméthode.Voicicequejetrouve:
Figure11.20:DéclarationdelaméthodeTimeSpan().
Oui, il y a plusieurs déclarations pour la même méthode, maisexpliquercelanousmèneraitvraimentàplusde500pages.Regardelalignesélectionnée:
TimeSpan(int16_tdays,int8_thours,int8_t
minutes,int8_tseconds);
D’accord.Ilfautindiquerdansl’ordrelejour,l’heure,laminuteetlasecondededécalage.L’exempledemandedoncd’avancerdansletemps de 7 jours, 12 heures, 30 minutes et 6 secondes, pasde7jourset30secondes!
OnsepermetdecorrigerunexempleArduino?Allons-y.
1. Resauvegardetontextesourceparprécaution.
2. Modifiealorsl’appelàTimeSpan()commececi:
DateTimefuture(now+TimeSpan(7,0,0,30)
);
3. Compile,téléverseetouvreleMoniteursérie.Toutva
mieux,non?
Figure11.21:Messagesderéglageducircuithorloge.
Etmaintenant,unprojet.NousallonscombinernotreécranLCDetle module RTC (amusants, tous ces acronymes, quand on lesconnaît).
LeprojetTokanteQuiditnouvelleclasse,ditnouvelobjet.
Ici,nousavonsmêmedeuxnouveauxobjetsà instancier.Endébutde code source, nous créons l’objet principal qui va incarner lecircuithorloge:
RTC_DS1307rtc;
Danslaboucleprincipale,nouscréonsàrépétitionunobjetdetypedate/heure:
DateTimeoDaH=rtc.now();
Nous répétons la création puisqu’il faut redemander l’heure sanscesse.C’esténervant,cetempsquichangesanscesse,non?:)
Lasuitevaconsisteràextraireunparunles«morceaux»dedateetd’heuredecetobjet.
Tu remarques la petite astuce pour parer à l’absence du zéro desdizainespourlesvaleursde0à9:
yMois=oDaH.month();
if(yMois<10)lcd.print('0');
lcd.print(yMois,DEC);
Commeiln’yaqu’uneinstructiondansleblocconditionnel,jemepassedesaccolades.
Le reste du programme est classique, si tu as lu ce livre dansl’ordre. On peut noter que les jours de semaine commencent ledimanche, à lamanière anglo-saxonne (le dimanche correspond àl’indice0dansletableaudesnomsdejours).
Listing11.5:TextesourcedeTokante
//Tokante
//OEN170331
#include<LiquidCrystal.h>
#include<RTClib.h>
#defineLIG10
#defineLIG21
LiquidCrystallcd(8,9,4,5,6,7);
RTC_DS1307rtc;
constbyteRETROECL=10;
charjourSemaine[7][5]={"Dim.","Lun.",
"Mar.","Mer.",
"Jeu.","Ven.",
"Sam."};
byteyMois,yJour,yH,yM,yS;
voidsetup(){
lcd.begin(16,2);
Serial.begin(9600);
if(!rtc.begin()){
lcd.println("ModuleRTCintrouvable!");
while(1);
}
}
voidloop(){
DateTimeoDaH=rtc.now();
lcd.setCursor(0,LIG1);
lcd.print(oDaH.year(),DEC);
lcd.print('/');
yMois=oDaH.month();
if(yMois<10)lcd.print('0');
lcd.print(yMois,DEC);
lcd.print('/');
yJour=oDaH.day();
if(yJour<10)lcd.print('0');
lcd.print(yJour,DEC);
lcd.print("");
lcd.print(jourSemaine[oDaH.dayOfTheWeek()]);
lcd.setCursor(4,LIG2);
yH=oDaH.hour();
if(yH<10)lcd.print('0');
lcd.print(oDaH.hour(),DEC);
lcd.print(':');
yM=oDaH.minute();
if(yM<10)lcd.print('0');
lcd.print(oDaH.minute(),DEC);
lcd.print(':');
yS=oDaH.second();
if(yS<10)lcd.print('0');
lcd.print(oDaH.second(),DEC);
delay(1000);
//lcd.clear();
}
Allez,ontéléverseetonregardelejoliafficheurLCD.Tusaiscréerunehorloge(Figure11.22).
Si tu vois s’afficher un avertissement (warning) pendant lacompilation,pasdesouci,d’autantqu’ilneconcernepastonprojet,maislalibrairie.UnjeunePadawannevapastenterdevoircequ’ilfaudraitcorrigerdansletextesourced’unelibrairie.
Figure11.22:TonhorlogeArduino.
Pour clore le chapitre, je te propose une variante qui permet degérerunautrefuseauhoraire.
Listing11.6:VariationTokanteFuzo(extraits)
//TokanteFuzoExtraits
//Jerajoutetroislignesendébutdetexte
:
#defineFUZO6
//AJOUT
#defineVILLE"BEIJING"
//MAX7car.!
charTokyo[]={196,179,183,174,179};//
AJOUT
//...
//...
//...
//Lanouvellefonctionenfindeprogramme
:
voidafficherHeure(DateTimeDT,bytepays){
yH=DT.hour();
yH+=pays;//AJOUT
//Testersi>23=>-24
if(yH>23)yH-=24;//AJOUT
if(yH<10)lcd.print('0');
lcd.print(yH,DEC);
lcd.print(':');
yM=DT.minute();
if(yM<10)lcd.print('0');
lcd.print(yM,DEC);
lcd.print(':');
yS=DT.second();
if(yS<10)lcd.print('0');
lcd.print(yS,DEC);
if(FUZO){//AJOUT
lcd.print("");
if(FUZO==7)lcd.print(Tokyo);else
lcd.print(VILLE);
}
}
Par rapportà laversiondebase, j’ai faitunpeudeménage.Cetteopération se nomme la refactorisation. Au lieu d’une longuefonctionprincipale,j’aidistribuéletravailentretroisroutinesquelafonctionappelletouràtour.C’estpluslisible.
En début de texte, j’ai défini la constante FUZO que tu peuxmodifierpourchangerdepays.Quandellevaut7,j’affichelenomdeTokyo enkana.Quand elle vaut autre choseque0, j’affiche lenomdelavilledéfinidanslalignesuivante.
On téléverse et on regarde. Tu remarques un test au début deafficherHeure(). En effet, s’il est 23 heures à Paris, enajoutant 7 heures, on a bien l’heure au Japon, mais l’affichageindique30!Voilàpourquoiilfautsoustraire24.
Figure11.23:Unfuseauhoraireorientaletdescaractèresjaponais!
Du fait que le module afficheur est doté de cinq boutonsprogrammables, une extension du projet consisterait à détecter unouplusieursdecesboutonspour,parexemple,passerd’unfuseauàunautre.Saurais-tut’ensortirsansexplications?Jedonneraipeut-être la solutionavec le fichierarchivedesexemples sur le sitedel’éditeur.
Lesboutonsdel’afficheurDFR0009
Cemoduleutiliseuneastucepourne consommerqu’une seule
brocheanalogiquedumikon, labrocheA0 (ou14). Lesboutons
sontreliésàdesrésistancesdevaleurcroissante,cequipermet
delesdistinguerenmesurantlavaleurconvertie:
if(iValAna>1000)returnbtnNONE;
if(iValAna<50)returnbtnRIGHT;
if(iValAna<250)returnbtnUP;
if(iValAna<450)returnbtnDOWN;
if(iValAna<650)returnbtnLEFT;
if(iValAna<850)returnbtnSELECT;
if(adc_key_in<850)returnbtnSELECT;
Grâceàreturn,dèsqu’untestréussit,onquitte lafonction
avecl’identifiantdubouton.Tuensaisassezpourt’éclater!
Installeunblocswitchoùilfautetl’affaireestdanslesac.
RécapitulonsDanscechapitre,nousavonsvu:
» lesdifférentstypesd’afficheurs;
» l’exploitationd’unafficheurLCDalphanumérique;
» quelquesjongleriesavecdeschaînesdecaractères;
» larecherchedescausesd’unpetitsouci;
» lacréationd’unehorlogetempsréel.
A
Chapitre12Unpeud’échologie
AUMENUDECECHAPITRE:
» Lemondedessonsqu’onn’entendpas
» Palperl’environnement
» Uninstrumentbizarre
prèsavoir faitunpeude littératuredans lesprécédentsprojets,retournons à ce vaste domainequi est celui des ondes.Qu’ellesoit électromagnétique ou acoustique, une onde permet de
transporter de l’information. Et l’information, c’est la matièrepremièredetoutordinateur!
Nousavonsapprisàcontrôler:
» desondeslumineuses;
» desondesinfrarouges;
» desondesacoustiques.
Pour ces dernières, ce n’étaient que des ondes audibles par leshumains.Demêmequel’ondécouvreàpeinequellesformesdevienous attendent au fond des gouffres océaniques, on commence àpeineàaborderlevastemondedesultrasons.
Moi,jedisouïe!
Peut-onvoirlesyeuxfermés?Oui,avecsesoreilles!C’estcequefontdenombreusesespècesanimales,àcommencerbiensûrparleschauves-souris.Cepetitmammifèreémetdetrèscourtesimpulsionsàdes fréquencesallant jusqu’à100kHz,soitcinq foisplusque laplus aiguë des notes que peut entendre un (jeune) humain. Tudevinesquelachauve-sourisestpasséemaîtredansl’utilisationdece sonar, car c’est ce qui lui permet denepasmourir de faimenattrapantdesinsectesenpleinvoletparunenuitd’encre.
D’ailleurs, certains insectes auraient développédes capacités pourpercevoirces impulsionsafindechangerde trajectoireauderniermoment.Pasbêtes,lespetitesbêtes!
L’acronyme sonar signifie SoundNavigation And Ranging, enfrançais « navigation et mesure de distance par le son » . Leprincipeestquasimentlemêmequeceluiduradar,saufqueleradarutilisedesondesradioélectriques.
Les mammifères marins vont encore plus haut que notre Batmandans les aigus : le marsouin monte jusqu’à 150 kHz. Tous lescétacés se servent des ultrasons pour communiquer sur de trèslonguesdistances,carlesonsepropagetrèsbiendansl’eau.
Plusprèsdenous,noschiensentendentjusqu’à40kHzetnoschats,jusqu’à60kHz.
Les montages de ce livre qui émettent des sons utilisent un haut-parleurbonmarché. Il ne risquepasdedevenir capabled’émettredessonsaussiaigus.
Figure12.1:Quelquesanimauxultrasoniques.
L’humain a bien compris l’intérêt des ultrasons. Depuis plusieursdizaines d’années, les futures mamans passent des échographies.Lessous-marinsutilisentunsonarpourrepérerleursennemis.Lesindustriels font des contrôles non destructifs en envoyant desultrasonsdansdumétalpourvoirs’ilcachedesdéfauts.Ilexisteraitmêmedescanonsmilitairesàultrasons.
De façon moins belliqueuse, l’utilisation la plus répandue desultrasonsconsisteàfairedelatélémétrie,c’est-à-diredelamesurededistance.Voyonscommentcréernotrepropretélémètre.
Toncapteurd’ultrasonsPourmesurerunedistance, il fautémettreune impulsiondansunefréquence ultrasonore puis se tenir prêt à réceptionner l’écho quirebonditsurl’obstacle.Ilfautdoncunémetteuretunrécepteur.
FonctionnementVoicid’abordleprincipedelatélémétrieàultrasons(Figure12.2).
Figure12.2:Principedusonar.
Choseincroyable,tupeuxacquérirtonpropreémetteur/récepteuràultrasons pour quelques euros.Voici lemodèle que je te proposed’apprendreàcontrôler(Figure12.3).
Figure12.3:LecapteurHC-SR05.
Comme pour d’autres capteurs des chapitres précédents, il y a uncôtépourlapartiecapteurproprementdite(ilyenamêmedeuxici)etuncôtépourlecircuitdecontrôle.
LemodèleHC-SR05offrecinqbrochesdesortie.LeSR04enaunedemoins,maisrestecompatible.Sionmetdecôtélesdeuxbrochesdel’alimentation(lesfilsrougeetnoir),ilenrestetrois:
» labrochemarquéeTNG(quidevraits’écrireTRGselon
moi,pourTrigger,puisqu’ellesertàémettre
l’impulsion);
» labrochemarquéeECHOquisertàrecevoirl’écho
aprèslerebondsurl’obstacle;
» unetroisièmebrochemarquéeOUTdontnousne
nousservonspasdanscelivre.
Je suis persuadé que la mention TNG est le fruit d’une faute defrappechezlefabricant.
Laséquencedecommandeducapteurestlasuivante:
» Ildoitrecevoiruneimpulsiond’aumoinsdix
microsecondessursabrocheTRG,cequiactivele
modedétection.
» Lemoduleémetalorshuitondescarrées(haut/bas)
à40kHzetattendleretourdel’écho.
» Lorsquel’échorevient,labrocheECHObasculedans
l’étathautetyresteautantdetempsqu’ils’estécoulé
entrel’envoietleretour.
» Ilneresteplus,danstonprogramme,qu’àmesurerce
nombredemicrosecondesensurveillantle
changementd’étatdecettebroche.
Le montage ne va donc pas être bien compliqué. C’est plutôt auniveaude la durée d’exécutiondes instructions qu’il faudra restervigilant.Procédonsdoncaumontage.
MontagedeTelemasterDeux possibilités te sont offertes selon que tu as ou pas déjàdémontél’afficheurLCDduprécédentprojet.
Montagesansl’afficheurSi l’afficheur n’est pas installé sur la carte Arduino, il suffit deréaliserlesbranchementssuivants:
1. Insèrelescinqbrochesducapteurdanscinqrangées
d’uneplaqued’essai.
Organise-toipourquelesdeuxcylindresducapteur
soientdirigésversl’extérieurdelaplaqueafinquerien
negêneletrajetdel’impulsion.
2. Brancheunfilrougeentrele5V(VCC)ducapteuret
le5VdelacarteArduino.
3. BrancheunfilnoirentrelamasseGNDducapteuret
l’unedecellesdelacarte.
4. Brancheunfilblanc,jauneouvertentrelabroche
d’émissionTNGetlabrochenumérique11delacarte.
5. Brancheunfild’uneautrecouleurentrelabroche
ECHOducapteuretlabroche12delacarte.
Lemontageestterminé.
MontageaveclacarteshieldAfficheurLCDSi la carte fille de l’afficheur est toujours en place, lesbranchementssontlessuivants:
1. Branchelesdeuxfilsd’alimentation5VetGNDoùtu
veuxsurlacarteLCD.Ilyapleindecontacts
disponibles.
2. BranchelabrocheTNGàlabrocheD11quiest
rapportéeenhautdelacartefille.Notequeles
numérosdesbrochesduconnecteurmâlenesontpas
dansl’alignementverticaldesbrochesdelacartemère
Arduino.Sers-toiduschémaillustréàlaFigure12.4.
Figure12.4:Branchementducapteuràl’afficheur.
3. BrancheenfinlabrocheECHOsurlabroche
numériqueD12del’afficheurLCD.
Figure12.5:LemontagedeTelemasterLCD.
Passonsmaintenantaucodage.
RédactiondutextesourcedeTelemasterPourexploiter l’émetteur/récepteuràultrasons, ilsuffitd’écrirelamécaniquequicorrespondauprincipequej’aiindiquéplushaut.
Troisétapessontnécessaires:
1. Émissiond’uneimpulsiontrèscourte,icide10µs.
2. Activationd’unefonctionquivasemettreàl’écoutedu
retourdel’échoendémarrantunchronomètre.
3. Calculdudélaideretourdel’écho.Onobtientainsi
unevaleurenmicrosecondes.
Dansl’air,l’ondesonoresedéplaceàenviron340m/s.C’estpourcette raison que tu vois éclater les feux d’artifice avant de lesentendre.
Un simple calcul permet de trouver que le son avance de 1 cmen29µs.Ilneresteplusqu’àdiviserlenombredemicrosecondesqu’il a fallu pour recevoir l’écho par cette valeur. Il ne faut pasoublier de multiplier la mesure par deux parce que nous avonschronométré le temps de l’aller et du retour.La distance est doncégaleàlamoitiédecettedurée.
Il n’y aqu’une seulenouvelle fonctionquenous allonsdécouvrirdansletextesourcequisuit.Ils’agitdepulseIn().
fDistance=pulseIn(brRetourEcho,HIGH);
Son premier paramètre est le numéro de la broche de retour del’écho;lesecondparamètreestl’étatqu’ilfautsurveiller.
Dans notre exemple, nous lui demandons de surveiller l’état haut(HIGH)decettebroche.Celasignifiequelafonctionvasemettreen
attente jusqu’à détecter le passage de l’état bas à l’état haut. À cemoment,ellevacommenceràfairetournersonchronomètrepourl’arrêterquandlabrocheredescendraàl’étatbas.
J’aichoisiunevariableàvirguleflottantepourstockerladistanceavecletypefloat.
floatfDistance;
La préparation et l’émission de l’impulsion utilisent la fonctiondigitalWrite():
digitalWrite(brEnvoiPulse,HIGH);
Saisis ou récupère ce texte source. Le nom proposé estTelemaster.
Listing12.1:TextesourcedeTelemaster
//Telemaster
//OEN170402
#definebrEnvoiPulse11//BrocheTNG
ducapteur
#definebrRetourEcho12//Broche
ECHOducapteur
floatfDistance;
voidsetup()
{
Serial.begin(9600);
pinMode(brEnvoiPulse,OUTPUT);
pinMode(brRetourEcho,INPUT);
}
voidloop()
{
//Pouruneimpulsionde10micro-secondes
digitalWrite(brEnvoiPulse,LOW);
delayMicroseconds(2);
digitalWrite(brEnvoiPulse,HIGH);
delayMicroseconds(10);
digitalWrite(brEnvoiPulse,LOW);
//Palpationdumonde
fDistance=pulseIn(brRetourEcho,HIGH);
Serial.print("Valeurbruteen
microsecondes=");
Serial.println(fDistance,0);
//Vitessedusonde340m/sdonc29us
parcm.
fDistance=fDistance/(29*2);
Serial.print(fDistance,0);//Nombrede
décimales
Serial.println("cm");
delay(300);
}
TestdemesureTéléverseleprojetverslacarte.Unefoisletéléversementterminé,ouvrelafenêtreduMoniteursérie.
Approche alors ta main du capteur. Lorsque tu fais varier ladistance, tu dois voir la valeur affichée dans lemoniteur changer
(Figure12.6).
Figure12.6:MesuresdedistancedansleMoniteursérie.
LavarianteTelemasterLCDSi tu as conservé en place la carte Afficheur LCD, tu peux trèsfacilementfaireafficherladistancesurcetécran.Ilsuffitd’ajouterlesaménagementssuivants:
» endébutdelisting,unedirectived’inclusiondela
librairie;
» puisuneinstructionpourcréerl’objetlcd;
» danssetup(),uneinstructionpourdémarrerle
dialogueavecl’écran;
» dansloop(),unappelàunenouvellefonctionque
nousdéfinissons;
» enfin,lecorpsdecettenouvellefonctionquiva
s’occuperdel’affichagesurl’écran.
Toutcelaestrassemblédanslesextraitsdelistingsuivants.
Listing12.2:ExtraitsdutextesourcedeTelemasterLCD
//TelemasterLCD
//OEN170402
//AJOUTERENHAUT
#include<LiquidCrystal.h>//
AJOUT
LiquidCrystallcd(8,9,4,5,6,7);//
AJOUT
//AJOUTERDANSsetup()
lcd.begin(16,2);//AJOUT
//AJOUTERALAFINDEloop()
affLCD();//AJOUT
//AJOUTERENBAS
voidaffLCD(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Distanceencm:");
lcd.setCursor(4,1);
lcd.print(int(fDistance));
}
Voici à quoi ressemble l’affichage d’une mesure sur cet écran(Figure12.7).
Figure12.7:Mesurededistancedansl’afficheurLCD.
RendretonmontageautonomePuisque tu as un écran local et un capteur, tu peux rendre tonmontage indépendant de l’ordinateur. Il suffit de te procurer unporte-pile (ou coupleur) pour une pile 9 V. La carte Arduinopossèdeunconnecteur rondquenousn’avons jamaisutilisé. IlestdumêmecôtéqueleconnecteurUSB.C’estleconnecteurnoirdanslecoininférieurgauchedelacarte.
C’est làque tupeuxbrancher le jackstandardiséde tonporte-pile.N’hésite pas à essayer ! Dans ce cas, pour économiser la pile, tupeuxprofiterduréglagedurétroéclairageenleréduisantunpeu.Ilsuffit d’ajouter l’instruction suivante à la fin de la fonction depréparationsetup():
analogWrite(10,50);//
RÉTROÉCLAIRAGE
Lesecondparamètrepeutallerde0à255.
Voyons maintenant comment transformer notre télémètre en undrôled’instrumentdemusique.
LeprojetTaprochpa
La transformation de notre projet Telemaster en instrument demusique est fort simple : nous y ajoutons un haut-parleur etcontrôlons sa fréquenceen fonctionde ladistance.Plus l’obstacleseraprocheducapteur,pluslesonseraaigu.
MontageduprojetQue tu aies ou non laissé en place l’afficheur LCD, il reste unebroche numérique disponible à côté des 11 et 12 qui servent aucapteuràultrasons.C’estlabroche13.Voicicommentprocéder:
1. Raccordeundesfilsduhaut-parleuràlaplaqued’essai
danslamêmedemi-rangéequ’unerésistance
de100ohmsenviron(moinssic’estunhaut-parleurde
casque32ohms).Del’autrecôtédelarésistance,
raccordeunfilàlabrochenumérique13.
2. Raccordel’autrefilduhaut-parleuràlamasseoùtuen
trouvesune.
Lemontageestterminé.
CodageAuniveaudutextesource,tupeuxrepartirdeTelemasteroudeTelemasterLCD en l’enregistrant sous le nouveau nomTaprochpa.
Voicilesaménagementsàprévoir:
1. Ajoutd’unedirectivepourdéfinirlabrocheduhaut-
parleur,donclaD13.
2. Ajoutdanslafonctiondepréparationd’uneinstruction
pourréglerlabrocheaudioensortie.
3. Ajoutd’unblocconditionnelàdeuxbranchesàlafin
delaboucleprincipale.Cettepartieconditionnelleest
visibledansleListing12.3.
4. Définitiond’unefonctionduChapitre9quej’ai
réutiliséeenlamodifiant.
Je t’invite donc à apporter les modifications à ta copie du projetinitialcommejeteleproposedanslelistingsuivant(enitalique).
Listing12.3:TextesourcedeTaprochpa
//Taprochpa
//OEN170402
#definebrEnvoiPulse11//BrocheTNG
ducapteur
#definebrRetourEcho12//Broche
ECHOducapteur
#defineyBroSON13//Broche
haut-parleurAJOUT
floatdistance;
voidsetup()
{
Serial.begin(9600);
pinMode(brEnvoiPulse,OUTPUT);
pinMode(brRetourEcho,INPUT);
pinMode(yBroSON,OUTPUT);//
AJOUTSORTIEAUDIO
}
voidloop()
{
//Impulsionde10micro-secondes
digitalWrite(brEnvoiPulse,LOW);
delayMicroseconds(2);
digitalWrite(brEnvoiPulse,HIGH);
delayMicroseconds(10);
digitalWrite(brEnvoiPulse,LOW);
distance=pulseIn(brRetourEcho,HIGH);
distance=distance/(29*2);
Serial.print(distance,0);
Serial.println(“cm“);
if(distance<80)alarmer(distance);
//AJOUT
else{tone(yBroSON,440,5);delay(500);
}//AJOUT
}
//RecyclagedeCH09B_Sonner3
voidalarmer(intpalpe){
intiFreq=40000/palpe;
tone(yBroSON,iFreq);
delay(20);
noTone(yBroSON);
}
TestaudioTéléverseleprojetetouvretesoreilles.Enfonctiondeladistanceàlaquelletuplacesunobstacle,lesonvavarierenhauteur.
Tu peux tenter de faire de la musique comme avec une sciemusicale. Le capteur est de temps en temps perdu : il indique ladistance maximale lorsque les ultrasons sont mal renvoyés. Celafonctionnemieuxavecunefeuilledepapierépaisouunmorceaudecartonqu’avectamain.
RécapitulonsDanscechapitre,nousavonsvu:
» commentémettreuneimpulsion;
» commentreccueillirladuréed'uneimpulsion;
» commentasservirunefréquenceàunedistance.
AnnexeMémentoetfuturs
Toutehistoireaunefin,ettoutlivreaussi.Avantdenousquitter,jete propose quelques sujets pour t’aider à poursuivre ton chemindanslefabuleuxmondedelaprogrammation.
PetitmémentodulangageArduino
Lelangagedel’ArduinoestinspirédulangageC,maisiln’enoffrepastouslesélémentslesplusrécents,commelesfonctionslambda.Ilsuffitnéanmoinsaudomained’emploid’unmikon.
FonctionsinternesCesfonctionssonttoujoursdisponiblesdèsquel’atelierestinstallé.
Fonctionsd’entrée/sortie(numérique,analogique)Cesontlesfonctionsfondamentales.Nouslesavonstoutesutiliséesdanslelivre.
pinMode(broche,mode)
digitalRead(broche)
analogRead(broche)
digitalWrite(broche,valeur)
analogWrite(broche,valeur)-PWM
tone(),noTone()
shiftOut(broche,BrocheHorloge,OrdreBit,
valeur)
pulseIn(broche,valeur)
MesuredutempsBien distinguer les deux couples : un travaille avec desmillisecondes,l’autresavecdesmicrosecondes.
millis(),micros()
delay(ms),delayMicroseconds(µs)
ArithmétiqueLaplupartdecesfonctionsserventàfairedescalculs.Lafonctionmap()est intéressante : elle convertit une plage de valeurs versuneautre.Parexemple,situreçoissurunebrocheanalogiqueunevaleur entre 0 et 1 023, tu peux, avec cette fonction, compresservers la plage entre 0 et 255, pour contrôler la luminosité d’unediodeLED.
map(valeur,toLow,fromHigh,toLow,toHigh)
min(x,y),max(x,y),abs(x),constrain(x,a,
b),
pow(base,exposant),sq(x),sqrt(x),
sin(rad),cos(rad),tan(rad)
randomSeed(seed),random(min,max)
CommunicationL’objet (enfait, laclasse)Serialest leseulpour lequel iln’estpas nécessaire d’ajouter une directive#include en début de textepourdéclarerlenomdelalibrairiequicontientlaclasse.
Il sert, et tu le sais, à communiquerpar liaison sérieouUSB,parexemplepourleMoniteursériedel’atelier.
TypesdedonnéesLestypesdedonnéesintetlongsontsignés,saufmentioncontraireunsigned.Autrementdit, le type intpermetdestockerunevaleurpositive ou négative, ce qui divise par deux l’étendue des valeurspossibles.
boolean(1bit)
char,byte(8bits)
int(16bits)
long
float
double
tableau[]
void
Je fournis dans le dossier P4 des exemples un petit programmepourtesterlestaillesdestypesdedonnées.Ilportecenom:
zTypesData.ino
Voicicequis’affichedansleMoniteursériequandceprogrammeestlancé:
sizeof(boolean)=1
sizeof(byte)=1
sizeof(char)=1
sizeof(short)=2
sizeof(int)=2
sizeof(long)=4
sizeof(float)=4
sizeof(double)=4
sizeof(int8_t)=1
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int64_t)=8
sizeof(uint8_t)=1
sizeof(uint16_t)=2
sizeof(uint32_t)=4
sizeof(uint64_t)=8
sizeof(char*)=2
sizeof(int*)=2
sizeof(long*)=2
sizeof(float*)=2
sizeof(void*)=2
Plafonddutypebyte=255
Plafonddutypeint=32767
Plafonddutypeunsignedint=65535
ConstantesprédéfiniesLesdeuxpremièreslignesci-dessoussontéquivalentesauxvaleursnumériques1et0.
HIGH¦LOW
true¦false
INPUT¦OUTPUT
INPUT_PULLUP
StructuresdecontrôleNous avons utilisé certaines de ces structures, en tant que blocsconditionnels.Lemotclécontinuesert à abandonner la suitedesinstructions en remontant au prochain tour d’une boucle derépétitionfor.
if,if...else
for,while,do...while,
break,continue
switchcase
return
Pourallerplusloin...S’ilfallaitécrireunvolume2pourcelivre,nousydécouvririonsdenouveauxcapteursetdenouveauxactionneurs.
D’autrescapteursParmilescapteursquit’attendent,jeveuxciterceux-ci:
» Détecteurdebruit:poursavoirs’ilyadubruitou
pas.C’estenquelquesorteunmicrophoneenmode
tout-ou-rien.
» Photorésistance:savaleurvarieenfonctiondela
quantitédelumièrereçue.C’estcommeuncapteurde
couleurquinevoitquedugris.
» Capteurdepression:pourdétecterunappuiouun
contactphysique.
» GPS:pourrecueillirdescoordonnéesspatiales.
» Accéléromètre:pourquelemikonsaches’ilalatête
àl’enversetàquellevitesseilsedéplacedans
l’univers.Cesmodulessedistinguentparlenombrede
degrésdeliberté.
D’autresactionneursDèsquelecourantqu’ilfautcontrôlerdevienttropimportantpourlesdélicatesbrochesdumikon,ilfaututiliserunbrasdelevier.
Letransistor:unbrasdelevierLetransistorestunesortedesandwichdedeuxdiodescolléestête-bêche.
Un petit changement sur une broche (la base) provoque un groschangemententrelesdeuxautres(l’émetteuretlecollecteur).
LerelaisLerelaisprendlerelais.Avecpeudecourantpourchangersonétat(ouvertou fermé),onpeutcontrôleruncourantbienplus fort.Engénéral, il ne faut pas brancher une sortie dumikon directement,maispasserparuntransistor.
Leservo-moteurLe servo-moteur est le composant essentiel de tout projet derobotique.Ilsepilotesimplementavecuneimpulsiondontladuréedétermine l’angle de rotation du bras du servo. Et la librairierequise,Servo,estinstalléed’office.
Etdelacommunication!IlexisteenfinpourArduinodesmodulesEthernet,WiFi,Bluetooth,etc.IlyamêmeunevarianteArduinoYunqui réunitsur lamêmecarte un mikon comme tu le connais et un autre processeurfonctionnantsousLinux!
Listesratures!Denombreuxlivresvontplusloindansl’apprentissagedel’artdela programmation. Et les télécours (lesMOOC, traduit en FLOT)fleurissentsurleweb.Jemepermetsdeciterunautrelivrechezlemêmeéditeur,dumêmeauteur,qui s’enchaînebienaveccelui-ci :ProgrammerpourlesNuls(2eéditionauminimum).
LesexemplesArduinopréinstallés
Danslesous-menuFichier/Exemplesde l’atelierArduino, tuasaccèsàplusieursdizainesd’exemplessimples(catégorieExemplesinclus)quejeteconseilledeparcourir.
Voisnotammentlacatégorie8.Stringsquiprésentedesfonctionsde traitement de chaînes de texte à partir de la classe d’objetsString.
Note:letextesourcedesexemplesn’estpasencorefrancisé.
Je rappelle que lorsque tu installes une librairie, les exemplesqu’elle contient viennent en général s’ajouter au sous-menu desexemples.
Masélectionderevendeurs(oùacheter)
Parmilesrevendeurssurlatoile,j’aiétabliunerelationprivilégiéeaveclasociétéLetMeKnowquis’estorganiséepourréuniretavoirenstocktouslescomposantsrequissouslaformed’unkitauprixleplusjuste.
TupeuxterendresurplaceàParisoucommandervialeurboutiqueweb.Voicidoncmabonneadresse:
http://letmeknow.fr/shop/
Maistueslibredecommanderailleurs.Voicimalisterestreintederevendeurs sur la toile (enordre alphabétique). J’ai commandéaumoinsunefoischezchacunetleserviceétaitsatisfaisant.
» Conrad
» GoTronic
» LetMeKnow
» RobotShop
» Selectronic
» SemaGeek
» StQuentinRadio.
» VDRAM
Tousvendentparcorrespondance.Lefaitdelesciternem’engageévidemmentpas.
RemerciementsMerciàmeschersettendresMartine,Eva,DérecketLéonardpouravoirsupportémonabsencetouslessoirspendanttantdesemaines.
Uugrandsalutàtoutel’équiped’ingénieriequimefaitl’honneurdesupportermonhumour:Jeroen,Melinda,Ralf,Stéphane,Sekouettouslesautrescollègues.
Sommaire
Couverture
ProgrammeravecArduinoens’amusantpourlesnuls
Copyright
Introduction
L’étatd’espritdulivre
Résumédel’histoire(plandulivre)
Pourréaliserlesprojets
LacommunautéArduino
I.Semaine1:Miseenroute
Chapitre1.Quelestcetanimal?
TonmikonestunATmega328
C’estquoisontravail?
Tacarte,c’estuneUno
Écouteretparler:lesentréesetsorties
Uncerveauvideàlanaissance?
Séquencepratique:testonsnotrebébé
Langagesdehautetdebasniveau
Récapitulons
Chapitre2.L’atelierducyberartisan
Installationdel’atelierArduinoIDE
Installationdel’atelier
Premierdémarragedel’atelierIDE
Compilationdetest...
…ettéléversementdetest
Autresoutils
Récapitulons
Chapitre3.Letourdechauffe
Accéderausitedulivre
Découvronslemoniteurdel’atelier
Récapitulons
II.Semaine2:Parleretécouterlemonde
Chapitre4.Àl’écoutedumondeennoiretblanc
Partird’unefeuilleblanche(oupresque)
Projet1:détectionsuruneentréenumérique
Notrepremièrevariable
Récapitulons
Chapitre5.Àl’écoutedumonderéel
LeprojetAnalo
Tapremièrefonction
Uneinstructionconditionnelle
Renvoyonsnosvaleurs
Unthermomètreanalogique
Récapitulons
Chapitre6.Parler,c’estagir
UnebellediodeLED
Savoirfairetomberlatension
Unprojetdeluciole
Deuxluciolesquidansent(Luciole2)
Récapitulons
Chapitre7.Donneruneimpulsion
LafonctionanalogRead()
LeprojetBinar
Soyonslogiques(Binar2)
Unplusunégalezéro?
Onpeutcomptersurlui(Binar3)
Unquartetenbinaire
VoiciMaîtreDevinum
Récapitulons
III.Semaine3:Sonetlumière
Chapitre8.Tabaguettemagique
Lebonprotocole
Uncapteurd’ondesIR
MontageduprojetBagMagik
RédactiondutextesourcedeBagMagik1
Compilation:erreursouavertissements?
Comments’utiliseunobjet?
Laversion2deBagMagik
Laversion3deBagMagik
Récapitulons
Chapitre9.Quepersonnenebouge!
ThéorieducapteurPIR
PratiqueducapteurPIR
Unealarmeaudio
Retouraugardien
Testonsnosoreilles
Récapitulons
Chapitre10.Levoleurdecouleurs
Desondeslumineuses
LadiodeLEDuniverselle
Ajoutonslescouleurssecondaires
Toutestdanslanuance!
LecapteurdecouleursTCS34725
Copier,c’estbeau(VolKool2)
Récapitulons
IV.Semaine4:Letempsdeslettres
Chapitre11.Letempsliquide
MatricedeLED
Afficheurseptsegments
AfficheursLCD
Toujoursavoirboncaractère
Montaged’unécranLCD
KristaLiklebavard
Dudessin?Non,dutexteanimé
KristAlpha,passibête
KristaProverbe,qu’onseledise!
Est-cequeletempsvieillit?
LeprojetTokante
Récapitulons
Chapitre12.Unpeud’échologie
Moi,jedisouïe!
Toncapteurd’ultrasons
LeprojetTaprochpa
Récapitulons
Annexe.Mémentoetfuturs
PetitmémentodulangageArduino
Pourallerplusloin...
LesexemplesArduinopréinstallés
Masélectionderevendeurs(oùacheter)
Remerciements