Mã để thực hiện một lần trong Arduino


12

Câu hỏi: Tôi phải đặt mã ở đâu nếu tôi muốn nó chỉ thực thi một lần cho mỗi lần khởi động Arduino?

Bối cảnh: Tôi có xu hướng sử dụng Arduino của mình để thực hiện các tác vụ nên được thực hiện một lần trên mỗi chu kỳ nguồn. (Ví dụ: robot của tôi chỉ nên lái về phía trước một lần mỗi khi tôi bật nó - hơn thế nữa và nó có thể rơi khỏi bàn.)

"Mẫu" Arduino IDE tiêu chuẩn bao gồm một loop()và một setup()chức năng. Các setupmã được chạy một lần mỗi chu kỳ quyền lực, và loopđược tái bắt đầu mỗi khi nó kết thúc.

Tôi thấy hai cách tiếp cận mã "nhiệm vụ 1 lần:"

Phương pháp 1: "Lặp lại một lần"

void setup() {
  //do setup stuff
}

void loop() {
  //do task

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

Phương pháp 2: "Chỉ thiết lập"

void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

Dạng câu hỏi chi tiết hơn: Là một trong những phương pháp này "tốt hơn" từ ý nghĩa phần cứng / phần mềm? (ví dụ như là có bất cứ điều gì "đặc biệt" về setupchức năng, giống như nó chỉ có thể chạy cho rất nhiều thời gian?)
Và, nếu họ đều giống nhau từ góc độ phần cứng / phần mềm, là có một "thực hành tốt nhất" hoặc cách tiêu chuẩn của việc viết mã cho những tình huống trong cộng đồng Arduino?


Một số cách sử dụng exitlệnh được thảo luận trong arduino.stackexchange.com/questions/188/,
TheDoctor

Câu trả lời:


13

Tôi hơi bối rối trước câu hỏi của bạn. Bạn hỏi nơi bạn muốn đặt các chức năng thiết lập một lần mỗi lần khởi động, và sau đó thảo luận về chức năng thiết lập. Đó là chức năng thiết lập dành cho.

Như vậy, chức năng thiết lập một lần đi trong chức năng thiết lập.

FWIW, nếu bạn nhìn vào các tập tin đó gọisetuploopchức năng:

#include <Arduino.h>

int main(void)
{
    init();

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

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

Đối với tất cả ý định và mục đích, hai tùy chọn hoàn toàn giống nhau. Dù bằng cách nào, bạn sẽ có được một vòng lặp bận rộn chờ đợi. Thành thật mà nói, tôi mong đợi hai tùy chọn khác nhau có thể phát ra cùng một mã máy, vì vậy toàn bộ điều này không phải là vấn đề.

Lưu ý:
if (serialEventRun) serialEventRun();dường như là một phương tiện cho phép bạn đính kèm một hàm được gọi khi nhận dữ liệu nối tiếp, nhưng nếu bạn không xác định hàm void serialEvent(){}trong mã của mình, nó sẽ biên dịch hoàn toàn và không có trong mã máy được sản xuất.


Cảm thấy kỳ lạ khi chấp nhận một câu trả lời không (chưa) được bình chọn cao nhất. Nhưng, nhìn thấy main()định nghĩa hàm thực sự hữu ích cho câu hỏi của tôi. (Và, bạn có chỉ ra sự đồng thuận với nhóm sử dụng setupthay vì loop). Cảm ơn sự giúp đỡ của bạn.
apnorton

1
@anorton - Khi nghi ngờ, hãy nhìn vào bìa. Tôi thấy nền tảng arduino thuận tiện cho việc tạo mẫu, nhưng phần lớn chỉ là mã soạn sẵn. Hiểu những gì nó đang làm có thể rất hữu ích trong việc quyết định làm thế nào để kiến ​​trúc sư một cái gì đó.
Sói Connor

6

Tôi thường đi với Phương pháp 2, nhưng cuối cùng lại làm điều này:

void setup() {
  //do setup stuff

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

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

void loop() {
  //do looping code
}

Với thiết lập ở trên, nó cho phép mã của tôi được tổ chức nhiều hơn.


câu trả lời tốt nhất cho đến nay +1, cảm ơn anh bạn đã cứu tôi!
Kyle

5

Tôi rất thích Phương pháp 2. Nếu bạn từng có kế hoạch thêm mã để xử lý đầu vào, đầu ra, v.v., thì dễ dàng với Phương pháp 2 - chỉ cần điền vào loop(), nhưng yêu cầu làm lại / tái cấu trúc trong Phương pháp 1.


3

Không có giới hạn thời gian trên chức năng thiết lập. Tôi thích phương pháp 2 hơn vì vòng lặp có thể được lấp đầy với bất cứ điều gì bạn cần sau này.


1

Chắc chắn đi với phương pháp hai. Đó là những gì chức năng thiết lập là có. Nó cũng dễ đọc hơn nhiều. Bất cứ điều gì trong loop()ngụ ý nó sẽ được chạy trong một vòng lặp.


0

Như hầu hết các câu trả lời khác, tôi sẽ dùng phương pháp 2.

Nhưng tôi sẽ cố gắng tránh cuộc gọi, bởi thư viện Arduino, để trống loop() khiến Atmel tiêu thụ "rất nhiều" dòng điện mà không có gì.

Biên tập:

Như một số ý kiến ​​chỉ ra mặc dù, sử dụng delay()trong loop()sẽ không thay đổi gì để tiêu thụ năng lượng.

Do đó, nếu bạn muốn giảm mức tiêu thụ năng lượng sau khi setup()chạy, bạn sẽ phải chơi với chế độ ngủ Atmel. Bạn có thể xem bài viết này cho thấy cách đối phó với các chế độ ngủ từ bản phác thảo Arduino của bạn; nó không chỉ đơn thuần là đưa Atmel vào chế độ ngủ mà còn là một cách đọc tốt (và đơn giản) nếu bạn muốn chơi với các chế độ ngủ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.