Código para ejecución de una sola vez en Arduino

12

Pregunta: ¿Dónde pongo el código si quiero que se ejecute solo una vez por inicio de Arduino?

Antecedentes: tiendo a usar mi Arduino para realizar tareas que deberían ejecutarse una vez por ciclo de encendido. (Por ejemplo, mi robot solo debe avanzar una vez cada vez que lo enciendo, más que eso, y podría caerse de la mesa).

La "plantilla" estándar de Arduino IDE consta de una loop()y una setup()función. El setupcódigo se ejecuta una vez por ciclo de encendido y loopse reinicia cada vez que finaliza.

Veo dos enfoques para codificar "tareas de 1 vez:"

Método 1: "bucle una vez"

void setup() {
  //do setup stuff
}

void loop() {
  //do task

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

Método 2: "solo configuración"

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

Forma de pregunta más detallada: ¿Es uno de estos métodos "mejor" desde el punto de vista del hardware / software? (por ejemplo, ¿hay algo "especial" en la setupfunción, como si solo pudiera ejecutarse durante tanto tiempo?)
Y, si son iguales desde una perspectiva de hardware / software, ¿existe una "mejor práctica" o una forma estándar de escribir código para estas situaciones en la comunidad Arduino?

Apnorton
fuente
Se exitdiscute el uso del comando en arduino.stackexchange.com/questions/188/…
TheDoctor

Respuestas:

13

Estoy un poco confundido por tu pregunta. Pregunta dónde desea colocar las funciones de configuración de una vez por inicio y luego analiza la función de configuración. Para eso es la función de configuración.

Como tal, la funcionalidad de configuración única se incluye en la función de configuración.

FWIW, si buscas en el archivo que llama a las funciones setupy loop:

#include <Arduino.h>

int main(void)
{
    init();

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

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

Para todos los efectos, las dos opciones son completamente idénticas. De cualquier manera, obtienes un bucle vacío de espera ocupada. Francamente, esperaría que las dos opciones diferentes probablemente emitan el mismo código de máquina de todos modos, por lo que todo no es un problema.

Nota:
if (serialEventRun) serialEventRun();parece ser una función que le permite adjuntar una función que se solicita al recibir datos en serie, pero si no define una función void serialEvent(){}en su código, se compilará por completo y no estará presente en el código de máquina producido.

Connor Wolf
fuente
Se siente extraño aceptar una respuesta que no es (todavía) la más votada. Pero, ver la main()definición de la función fue realmente útil para mi pregunta. (Y, sí indica un consenso con el grupo con el uso en setuplugar de loop). Gracias por tu ayuda.
apnorton
1
@anorton: cuando tenga dudas, mire debajo de las sábanas. Creo que la plataforma arduino es conveniente para la creación de prototipos, pero es en gran parte solo un código repetitivo. Comprender lo que está haciendo puede ser tremendamente útil para decidir cómo diseñar algo.
Connor Lobo
6

Normalmente voy con el Método 2, pero termino haciendo esto:

void setup() {
  //do setup stuff

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

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

void loop() {
  //do looping code
}

Con la configuración anterior, permite que mi código esté aún más organizado.

Steven10172
fuente
la mejor respuesta hasta ahora +1, gracias amigo, me salvaste!
Kyle
5

Preferiría encarecidamente el Método 2. Si alguna vez planea agregar código para manejar entradas, salidas, etc., es fácil con el Método 2: solo complete loop(), pero requiere reelaboración / refactorización en el Método 1.

Matthew G.
fuente
3

No hay límite de tiempo en la función de configuración. Prefiero el método 2 porque el bucle puede llenarse con lo que necesite más tarde.

TheDoctor
fuente
1

Definitivamente ve con el método dos. Para eso está la función de configuración. También es mucho más fácil de leer. Cualquier cosa en el loop()implica que se ejecutará en un bucle.

Sachleen
fuente
0

Como la mayoría de las otras respuestas, elegiría el método 2.

Pero trataría de evitar la llamada, por la biblioteca Arduino, a un vacío loop()que hace que el Atmel consuma "mucha" corriente por nada.

Editar:

Sin embargo, como algunos comentarios señalaron, usar delay()in loop()no cambiará nada al consumo de energía.

Por lo tanto, si desea reducir el consumo de energía una vez que se setup()ha ejecutado, tendrá que jugar con los modos de suspensión Atmel. Puedes echar un vistazo a este artículo que muestra cómo lidiar con los modos de suspensión de tus bocetos de Arduino; hace más que solo poner el Atmel a dormir, pero es una buena (y simple) lectura si quieres jugar con los modos de sueño.

jfpoilpret
fuente