Код одноразового виконання в Ардуїно


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функції, як-от вона може працювати лише стільки часу?)
І, якщо вони однакові з точки зору апаратних та програмних засобів, чи існує "найкраща практика" або стандартний спосіб написання коду для цих ситуацій у громаді Ардуїно?


Деяке використання 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()який змушує "Атмель" споживати "багато" струму ні за що.

Редагувати:

Як зазначалося в деяких коментарях, використання delay()в loop()ньому нічого не змінить споживання енергії.

Отже, якщо ви хочете зменшити споживання енергії після setup()запуску, вам доведеться грати з режимами сну Atmel. Ви можете подивитися цю статтю, яка показує, як поводитися з режимами сну зі своїх ескізів Ардуїно; це більше, ніж просто укладання Atmel спати, але це добре (і просте) читання, якщо ви хочете грати з режимами сну.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.