Код для одноразового исполнения в Ардуино


12

Вопрос: куда мне поместить код, если я хочу, чтобы он выполнялся только один раз за запуск Arduino?

Предыстория: я склонен использовать свой Arduino для выполнения задач, которые должны выполняться один раз за цикл питания. (Например, мой робот должен двигаться вперед только один раз при каждом его включении - более того, и он может упасть со стола.)

Стандартный Arduino IDE «шаблон» состоит из loop()и setup()функции. setupКод выполняется один раз за цикл питания и loopповторно запускается каждый раз , когда он заканчивает.

Я вижу два подхода к коду "1 время задачи:"

Способ 1: «Цикл один раз»

void setup() {
  //do setup stuff
}

void loop() {
  //do task

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

Способ 2: «Только настройка»

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

Более подробная форма вопроса: является ли один из этих методов «лучше» с точки зрения аппаратного или программного обеспечения? (например, есть ли что-то «особенное» в setupфункции, например, она может работать только столько времени?)
И, если они одинаковы с точки зрения аппаратного и программного обеспечения, существует ли «наилучшая практика» или стандартный способ написания кода для таких ситуаций в сообществе Arduino?


Некоторое использование exitкоманды обсуждается в arduino.stackexchange.com/questions/188/…
TheDoctor

Ответы:


13

Я немного смущен вашим вопросом. Вы спрашиваете, где вы хотите разместить функции настройки один раз при запуске, а затем обсуждаете функцию настройки. Вот для чего предназначена функция настройки.

Таким образом, единовременные функции настройки входят в функцию настройки.

FWIW, если вы посмотрите в файл , который вызываетsetup и loopфункции:

#include <Arduino.h>

int main(void)
{
    init();

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

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

Для всех намерений и целей эти два варианта полностью идентичны. В любом случае, вы получите пустой цикл ожидания ожидания. Честно говоря, я ожидал бы, что два разных варианта в любом случае, вероятно, будут генерировать один и тот же машинный код, так что все это не проблема.

Примечание:
if (serialEventRun) serialEventRun();похоже, это средство, позволяющее вам присоединить функцию, которая вызывается при получении последовательных данных, но если вы не определите функцию void serialEvent(){}в своем коде, она будет полностью скомпилирована и не будет присутствовать в производимом машинном коде.


Странно принимать ответ, который (пока) не набрал наибольшее количество голосов. Но, видение main()определения функции было действительно полезно для моего вопроса. (И вы указываете согласие с группой с использованием setupвместо loop). Спасибо за помощь.
apnorton

1
@anorton - Если сомневаешься, посмотри под одеялом. Я нахожу платформу Arduino удобной для создания прототипов, но в основном это всего лишь стандартный код. Понимание того, что он делает, может быть чрезвычайно полезным при принятии решения о том, как что-то спроектировать.
Коннор Вольф

6

Я обычно использую метод 2, но в конечном итоге делаю это:

void setup() {
  //do setup stuff

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

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

void loop() {
  //do looping code
}

С вышеупомянутой настройкой это позволяет моему коду быть еще более организованным.


лучший ответ до сих пор +1, спасибо, чувак, ты спас меня!
Кайл

5

Я бы настоятельно предпочел метод 2. Если вы когда-либо планируете добавить код для обработки ввода, вывода и т. Д., Это легко сделать с помощью метода 2 - просто заполните loop(), но требует переделки / рефакторинга в методе 1.


3

Нет ограничений по времени для функции настройки. Я предпочитаю метод 2, потому что цикл может быть заполнен всем, что вам нужно позже.


1

Определенно идти со вторым способом. Для этого есть функция настройки. Гораздо легче читать. Все, что в нем loop()подразумевается, будет выполнено в цикле.


0

Как и большинство других ответов, я бы пошел на метод 2.

Но я бы попытался избежать вызова библиотеки Arduino к пустому значению, loop()которое заставляет Atmel потреблять «много» тока ни за что.

Редактировать:

Как отмечалось в некоторых комментариях, использование delay()in loop()ничего не изменит на энергопотребление.

Следовательно, если вы хотите снизить энергопотребление после setup()запуска, вам придется поработать в спящих режимах Atmel. Вы можете взглянуть на эту статью, в которой показано, как работать с режимами сна из ваших набросков Arduino; он делает больше, чем просто переводит Atmel в спящий режим, но это хорошее (и простое) чтение, если вы хотите играть в режимах сна.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.