Code pour une exécution unique dans Arduino

12

Question: Où dois-je mettre le code si je veux qu'il ne s'exécute qu'une seule fois par démarrage Arduino?

Contexte: J'ai tendance à utiliser mon Arduino pour effectuer des tâches qui doivent être exécutées une fois par cycle d'alimentation. (Par exemple, mon robot ne devrait avancer qu'une fois à chaque fois que je l'allume - plus que cela, et il pourrait tomber de la table.)

Le "modèle" standard Arduino IDE se compose d'un loop()et d'une setup()fonction. Le setupcode est exécuté une fois par cycle d'alimentation et loopest redémarré chaque fois qu'il se termine.

Je vois deux approches pour coder "1 tâches ponctuelles:"

Méthode 1: "boucle une fois"

void setup() {
  //do setup stuff
}

void loop() {
  //do task

  while(1) ; //Repeat forever, preventing function from re-starting
}

Méthode 2: "Installation uniquement"

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

Forme de question plus détaillée: L'une de ces méthodes est-elle "meilleure" du point de vue matériel / logiciel? (par exemple, la fonction a-t-elle quelque chose de "spécial" setup, comme si elle ne pouvait fonctionner que pendant si longtemps?)
Et, si elles sont les mêmes du point de vue matériel / logiciel, existe-t-il une "meilleure pratique" ou une manière standard d'écrire du code pour ces situations dans la communauté Arduino?

apnorton
la source
Une certaine utilisation de la exitcommande est discutée dans arduino.stackexchange.com/questions/188/…
TheDoctor

Réponses:

13

Je suis un peu confus par votre question. Vous demandez où vous souhaitez placer les fonctions de configuration une fois par démarrage, puis discutez de la fonction de configuration. C'est à cela que sert la fonction de configuration.

En tant que telle, la fonctionnalité de configuration unique va dans la fonction de configuration.

FWIW, si vous regardez dans le fichier qui appelle les fonctions setupet loop:

#include <Arduino.h>

int main(void)
{
    init();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

À toutes fins utiles, les deux options sont complètement identiques. Dans les deux cas, vous obtenez une boucle d'attente occupée vide. Franchement, je m'attendrais à ce que les deux options différentes émettent probablement le même code machine de toute façon, donc le tout n'est pas un problème.

Remarque:
if (serialEventRun) serialEventRun();semble être une fonction pour vous permettre d'attacher une fonction qui est appelée lors de la réception de données série, mais si vous ne définissez pas de fonction void serialEvent(){}dans votre code, elle se compilera complètement et ne sera pas présente dans le code machine produit.

Connor Wolf
la source
C'est bizarre d'accepter une réponse qui n'est pas (encore) la plus votée. Mais, voir la main()définition de la fonction était vraiment utile à ma question. (Et, vous ne donnez un consensus avec le groupe à l' aide au setuplieu de loop). Merci de votre aide.
apnorton
1
@anorton - En cas de doute, regardez sous les couvertures. Je trouve que la plate-forme Arduino est pratique pour le prototypage, mais c'est en grande partie juste du code standard. Comprendre ce qu'il fait peut être extrêmement utile pour décider comment concevoir quelque chose.
Connor Wolf
6

J'utilise généralement la méthode 2, mais je finis par le faire:

void setup() {
  //do setup stuff

  //do task
  init(); //Do start-up initialization steps
}

void init() {
  // do tasks on startup
}

void loop() {
  //do looping code
}

Avec la configuration ci-dessus, cela permet à mon code d'être encore plus organisé.

Steven10172
la source
la meilleure réponse à ce jour +1, merci mec tu m'as sauvé!
Kyle
5

Je préférerais fortement la méthode 2. Si vous prévoyez d'ajouter du code pour gérer les entrées, les sorties, etc., c'est facile avec la méthode 2 - il suffit de le remplir loop(), mais nécessite de retravailler / refactoriser la méthode 1.

Matthew G.
la source
3

Il n'y a pas de limite de temps sur la fonction de configuration. Je préfère la méthode 2 car la boucle peut être remplie avec tout ce dont vous avez besoin plus tard.

Le docteur
la source
1

Allez-y avec la deuxième méthode. C'est à cela que sert la fonction de configuration. C'est aussi beaucoup plus facile à lire. N'importe quoi dans le loop()implique qu'il sera exécuté en boucle.

sachleen
la source
0

Comme la plupart des autres réponses, j'opterais pour la méthode 2.

Mais j'essaierais d'éviter l'appel, par la bibliothèque Arduino, à un vide loop()qui fait que l'Atmel consomme "beaucoup" de courant pour rien.

Éditer:

Comme l'ont souligné certains commentaires, l'utilisation de delay()in loop()ne changera rien à la consommation électrique.

Par conséquent, si vous souhaitez réduire la consommation d'énergie une fois votre setup()course terminée, vous devrez jouer avec les modes de veille Atmel. Vous pouvez jeter un œil à cet article qui montre comment gérer les modes de sommeil à partir de vos croquis Arduino; il fait plus que simplement mettre l'Atmel en veille, mais c'est une bonne (et simple) lecture si vous voulez jouer avec les modes de veille.

jfpoilpret
la source