Kode untuk eksekusi satu kali di Arduino

12

Pertanyaan: Di mana saya meletakkan kode jika saya ingin mengeksekusi hanya sekali per startup Arduino?

Latar Belakang: Saya cenderung menggunakan Arduino saya untuk melakukan tugas yang harus dijalankan satu kali per siklus daya. (Misalnya, robot saya hanya boleh bergerak maju sekali setiap kali saya menyalakannya - lebih dari itu, dan mungkin jatuh dari meja.)

"Arduino IDE" template standar terdiri dari loop()dan setup()fungsi. The setupkode dijalankan sekali per siklus kekuasaan, dan loopini kembali dimulai setiap kali selesai.

Saya melihat dua pendekatan untuk kode "tugas 1 kali:"

Metode 1: "Ulangi sekali"

void setup() {
  //do setup stuff
}

void loop() {
  //do task

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

Metode 2: "Pengaturan saja"

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

Bentuk pertanyaan yang lebih terperinci: Apakah salah satu dari metode ini "lebih baik" dari pengertian perangkat keras / lunak? (mis. adakah yang "istimewa" tentang setupfungsi tersebut, seperti hanya dapat berjalan begitu lama?)
Dan, jika mereka sama dari perspektif perangkat keras / lunak, apakah ada "praktik terbaik" atau cara standar penulisan kode untuk situasi ini di komunitas Arduino?

apnorton
sumber
Beberapa penggunaan exitperintah ini dibahas di arduino.stackexchange.com/questions/188/…
TheDoctor

Jawaban:

13

Saya agak bingung dengan pertanyaan Anda. Anda bertanya di mana Anda ingin meletakkan fungsi pengaturan sekali per startup, dan kemudian mendiskusikan fungsi pengaturan. Untuk itulah fungsi pengaturan.

Dengan demikian, fungsi pengaturan satu kali masuk dalam fungsi pengaturan.

FWIW, jika Anda melihat di file yang memanggil para setupdan loopfungsi:

#include <Arduino.h>

int main(void)
{
    init();

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

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

Untuk semua maksud dan tujuan, kedua opsi ini sepenuhnya identik. Either way, Anda mendapatkan loop sibuk-tunggu kosong. Terus terang, saya berharap dua opsi yang berbeda mungkin memancarkan kode mesin yang sama, jadi semuanya bukan masalah.

Catatan:
if (serialEventRun) serialEventRun();tampaknya menjadi fasilitas yang memungkinkan Anda untuk melampirkan fungsi yang dipanggil saat menerima data serial, tetapi jika Anda tidak mendefinisikan suatu fungsi void serialEvent(){}dalam kode Anda, itu akan mengkompilasi sepenuhnya dan tidak hadir dalam kode mesin yang diproduksi.

Connor Wolf
sumber
Rasanya aneh menerima jawaban yang bukan (belum) terpilih tertinggi. Tapi, melihat main()definisi fungsi sangat membantu pertanyaan saya. (Dan, Anda menunjukkan konsensus dengan grup dengan menggunakan setupalih-alih loop). Terima kasih untuk bantuannya.
apnorton
1
@anorton - Jika ragu, lihat di balik selimut. Saya menemukan platform Arduino nyaman untuk prototyping, tetapi sebagian besar hanya kode boilerplate. Memahami apa yang dilakukannya bisa sangat membantu dalam memutuskan bagaimana merancang sesuatu.
Connor Wolf
6

Saya biasanya menggunakan Metode 2, tetapi akhirnya melakukan ini:

void setup() {
  //do setup stuff

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

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

void loop() {
  //do looping code
}

Dengan pengaturan di atas memungkinkan kode saya menjadi lebih teratur.

Steven10172
sumber
jawaban terbaik sejauh ini +1, terima kasih Bung Anda menyelamatkan saya!
Kyle
5

Saya akan sangat menyukai Metode 2. Jika Anda berencana untuk menambahkan kode untuk menangani input, output, dll, mudah dengan Metode 2 - cukup isi loop(), tetapi membutuhkan pengerjaan ulang / refactoring dalam Metode 1.

Matius G.
sumber
3

Tidak ada batasan waktu pada fungsi pengaturan. Saya lebih suka metode 2 karena loop dapat diisi dengan apa pun yang Anda butuhkan nanti.

Dokter
sumber
1

Jelas pergi dengan metode dua. Untuk itulah fungsi pengaturan ada. Lebih mudah dibaca juga. Apa pun yang ada di loop()dalamnya akan dijalankan dalam satu lingkaran.

sachleen
sumber
0

Seperti kebanyakan jawaban lain, saya akan menggunakan metode 2.

Tapi saya akan mencoba untuk menghindari panggilan, oleh perpustakaan Arduino, ke sebuah tempat kosong loop()yang membuat Atmel mengkonsumsi "banyak" arus tanpa bayaran.

Edit:

Seperti yang ditunjukkan beberapa komentar, menggunakan delay()di tidak loop()akan mengubah apa pun menjadi konsumsi daya.

Oleh karena itu, jika Anda ingin mengurangi konsumsi daya setelah Anda setup()menjalankan, Anda harus bermain dengan mode tidur Atmel. Anda dapat melihat artikel ini yang menunjukkan cara menangani mode tidur dari sketsa Arduino Anda; itu tidak lebih dari sekadar membuat Atmel tertidur, tetapi itu adalah bacaan yang bagus (dan sederhana) jika Anda ingin bermain dengan mode tidur.

jfpoilpret
sumber