Accueil > Arduino > Et main alors ?
samedi 9 mai 2015, par
Quiconque a déjà un peu programmé en C ou en C++ sait bien qu’un programme commence toujours par une fonction main()
et que celle ci est obligatoire.
En arduino il semblerait que le main ait disparu puisque que l’on voit seulement les fonctions setup()
et loop()
dans la plupart des exemples.
En fait le main se trouve dans le fichier main.cpp du sous répertoire hardware/arduino/avr/cores/arduino/main.cpp
de votre dossier d’installation. En compagnie d’autres fichiers indispensables qui sont utilisés pour générer le programme qui est effectivement chargé dans le microcontrôleur.
Voici le contenu de main.cpp :
#include <Arduino.h> //Declared weak in Arduino.h to allow user redefinitions. int atexit(void (*func)()) { return 0; } // Weak empty variant initialization function. // May be redefined by variant files. void initVariant() __attribute__((weak)); void initVariant() { } int main(void) { init(); initVariant(); #if defined(USBCON) USBDevice.attach(); #endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0; }
On voit que l’on appelle d’abord les fonctions init() et initVariant() qui servent à initialiser l’API arduino ( notamment le timer 1 pour la fonction millis()
et delay()
ainsi que le convertisseur analogique/numérique pour analogRead()
), puis l’initialisation de la communication USB pour les modèles avec périphérique USB intégré (leonardo,...), ensuite (une seule fois) la fonction setup()
et enfin la fonction loop()
dans une boucle infinie. Le test du flag serialEventRun
permet de remplir un buffer avec les caractères éventuellement reçus par le port série
(voir www.arduino.cc/en/Tutorial/SerialEvent).
Si on le souhaite on peut écrire sa propre fonction main()
. Celle ci prendra alors la place de la fonction originale lors de l’édition de liens. Ce n’est pas forcément une bonne idée car on risque de ne plus pouvoir utiliser certaines fonctions de l’API arduino et perdre la compatibilité avec certaines librairies. De plus la portabilité vers d’autres cartes et la compatibilité de votre programme avec les versions futures d’arduino ne sont plus garanties. Mais c’est parfois nécessaire par exemple si vous voulez initialiser les timers ou le convertisseur d’une manière différentes sans passer par la fonction init()
.
Voici un exemple minimaliste pour faire clignoter une led :
/* Arlotto 2015 : Minimal led blink without init and delay */ #include <Arduino.h> void uglyDelay(unsigned long time); int main(void){ pinMode(13,OUTPUT); for(;;) { digitalWrite(13,0); uglyDelay(100000L); digitalWrite(13,1); uglyDelay(100000L); } return 0 ; // should never go there } void uglyDelay(unsigned long time){ unsigned long i ; // volatile keyword is necessary to prevent compiler optimization volatile unsigned long v ; for( i=0 ; i < time ; i++) { v++; } }