Plusieurs fonctions Void

Bonjour à tous, voilà je me pose une petite question, imaginons que j'ai une fonction void loop () principale et plusieurs sous fontions void x (), ma question est la suivante, si la sous fonction void x() est appelée, la fonction principale void loop () continue t elle de tourner ou est ce la sous fonction qui prend le relais ?

Merci pour votre aide. :slight_smile:

Salut,

Un AVR est incapable d'exécuter plusieurs tâches à la fois. La fonction loop() va appeler la fonction x(). La fonction x() s'exécute et une fois terminée, on revient dans la fonction loop() :
loop() ---> x() ---> loop()

ok merci beaucoup pour ta réponse :slight_smile:

Exact. dans l'AVR, il faut imaginer que chaque ligne de ton programme est numérotée de 0 à ... N par exemple, avec la ligne "void setup(){" numérotée 0. le numéro de ligne est appelé "adresse". le µP possède un compteur programme qui démarre à 0 après le reset. L'AVR exécute les lignes une par une, donc ligne 0, ligne 1 etc etc. exemple :

 0 void setup(){
 1   pinMode (13, OUTPUT);
 2   digitalWrite (13, LOW);
 3 }

 4 void Loop(){
 5   allumeLed();
 6   eteindLed();
 7 }

 8 void allumeLed(){
 9   digitalWrite(13, HIGH);
10 }

11 void eteindLed(){
12   digitalWrite(13, LOW);
13 }

Le compteur démarre à n=0, donc exécute la ligne 0, puis la ligne 1, jusqu'à la ligne 5, où l'appel de la fonction allumeLed() est interprétée en n = 8, alors n passe de 5 à 8 en sauvegardant dans un coin de sa tête la valeur avant le saut : 5, et le µP continue sur sa lancée, n = 8, 9... à 10, l’accolade veut dire "retourne d'où tu viens", donc n revient à 5 et continue d'être incrémenté : 6. ben la ligne 6 lui dit de sauter à 11, même principe, n = 11, 12, à 13, il retourne à 7 où il interprète un saut à 4 et ainsi de suite.

si on suit les valeurs de n, ça donne n = 0, 1, 2, 3, 4, 5, 8, 9, 10, 6, 11, 12, 13, 7, 4, 5, 8, 9, 10, 6, 11, 12, 13, 7, 4, 5, 8... L'AVR exécute les fonctions, mais les lignes de code une par une.

En réalité, ce simple code génère un millier de lignes d'assembleur (codage compréhensible par le coeur de l'AVR), mais le principe reste le même, un code l'un après l'autre avec des "sauts".

1 Like

super explication merci.

donc petite question, je réalise actuellement un programme assez lourd avec pas mal de mesures (tachymetre, température, etc) dans la fonction loop (), est il préférable de tout mettre dans la boucle loop ou bien de séparer ce qui est possible de séparer en sous-fonction, par exemple des commandes (ordre de démarrage, arrêt, de moteur, pompe, etc.. ?) , tout en laissant bien entendu les conditions du lancement de ces sous-fonctions dans la boucle principale.

1 Like

Il est préférable de faire des fonctions que tu appelleras dans la boucle Loop(), ce sera plus facile à lire et à maintenir.

donc deuxième solution, ok merci.

Cela a t il un impact sur la vitesse d’exécution et de traitement, je pense que oui ?

Chaque fois que tu rentre et que tu sort d'une fonction le µC utilise quelques cycles machine pour faire sa petite cuisine, mais c'est minime.

Salut,

Pareil que Jean-François, je suis partisan des fonctions. Une fonction réalisant une action précise. Le code est plus lisible, plus simple à maintenir. Et puis ça évite de dupliquer du code à chaque fois que tu veux faire la même chose.

Concernant l'impact, il est très variable. ça dépend des paramètres passés à la fonction, des optimisations que va faire le compilateur, etc... Si la fonction n'est appelée qu'à un seul endroit, tu peux utiliser le mot clé inline. Dans la mesure du possible, le compilateur optimisera la fonction pour en réduire ou annuler l'impact.

++

Bonjour,

Toujours faire des fonctions séparé pour chaque traitements, cela permet de ne pas se perdre dans un méli mélo de code.

En ajoutant "static inline" devant une fonction le compilateur l'intégrera dans la fonction "mére" sans ajouter la moindre instructions en plus = même performances.
(Par contre si tu l'utilise plusieurs fois le code va prendre du poids)
De même si tu as des variables globales dans ton code ajoute un "static" devant et le compilateur saura qu'il peut les optimiser si besoin.

Attention: les variables globales utilisaient dans une interruption doivent être déclaré "volatile" et non "static", dans le cas contraire tu auras des bug et/ou un fonctionnement incohérent.

Tu peut aussi faire plusieurs fichiers .ino dans le même dossier que ton fichier .ino principal.
Il seront ouvert (à la réouverture du fichier principal) dans des onglets séparé et aggloméré bout à bout avant d'être compilé.

Hello everyone,
Sorry but I just tried a sample of what you give as an example (note: loop instead of Loop) and the Led only blinks once.

Win 8.1
IDE 1.6.12

I will open a new topic for the use of 5 leds with an Attiny85 because I encounter a loop problem!

Bonjour à tous,
Désolé mais je viens de faire un essai de ce que vous donnez en exemple (remarque: loop a la place de Loop) et la lampe ne clignote qu'une fois .

Win 8.1
IDE 1.6.12

J'ouvrirai un nouveau sujet pour l'utilisation de 5 leds avec une Attiny85 parce que je rencontre un problème de loop !

... j'ai apporté une petite modif au code et il fonctionne bien ( sorry ) , l'exemple donné par Super_Cinci n'était pas à prendre à la lettre... ce que j'avais fait ... bêtement.

const int led = 12;
void setup(){
  pinMode (led, OUTPUT);
  digitalWrite (led, LOW);                                                                                                               
}
void loop(){
  allumeLed();
  eteindLed();
}

void allumeLed(){
  digitalWrite(led, HIGH);
   delay(100);
}

void eteindLed(){
  digitalWrite(led, LOW);
   delay(100);
}