2014-04-15 16 views
10

Tôi có vòng lặp này, làm cách nào để kết thúc vòng lặp?cách dừng arduino vòng lặp

void loop() { 
     // read the pushbutton input pin: 

     a ++; 
     Serial.println(a); 
     analogWrite(speakerOut, NULL); 

     if(a > 50 && a < 300){ 
     analogWrite(speakerOut, 200); 
     } 

     if(a <= 49){ 
     analogWrite(speakerOut, NULL); 
     } 

     if(a >= 300 && a <= 2499){ 
      analogWrite(speakerOut, NULL); 
     } 

Trả lời

8

Arduino đặc biệt cung cấp hoàn toàn không có cách nào để thoát khỏi chức năng loop của họ, như trưng bày bởi các mã mà thực sự chạy nó:

setup(); 

for (;;) { 
    loop(); 
    if (serialEventRun) serialEventRun(); 
} 

Bên cạnh đó, trên một vi điều khiển không có bất cứ điều gì để thoát để ở nơi đầu tiên.

Điều gần nhất bạn có thể thực hiện là dừng bộ xử lý. Điều đó sẽ ngừng xử lý cho đến khi thiết lập lại.

+11

Làm cách nào để ngăn chặn bộ xử lý? – Brent

+1

@Brent: Bằng cách tắt ngắt và đưa bộ xử lý vào trạng thái ngủ. Bạn có thể bọc nó trong một vòng lặp vô hạn để thực hiện chắc chắn hơn không bao giờ tiếp tục. –

+0

Tôi nghĩ rằng "return" sẽ làm như vậy –

8

Matti Virkkunen nói đúng, không có cách "phong nha" để dừng vòng lặp. Tuy nhiên, bằng cách nhìn vào mã của bạn và đưa ra một số giả định, tôi tưởng tượng bạn đang cố gắng tạo ra một tín hiệu với một tần số nhất định, nhưng bạn muốn có khả năng ngăn chặn nó.

Nếu đó là trường hợp, có một số giải pháp:

  1. Nếu bạn muốn tạo ra các tín hiệu với đầu vào của một nút bạn có thể làm như sau

    int speakerOut = A0; 
    int buttonPin = 13; 
    
    void setup() { 
        pinMode(speakerOut, OUTPUT); 
        pinMode(buttonPin, INPUT_PULLUP); 
    } 
    
    int a = 0; 
    
    void loop() { 
        if(digitalRead(buttonPin) == LOW) { 
         a ++; 
         Serial.println(a); 
         analogWrite(speakerOut, NULL); 
    
         if(a > 50 && a < 300) { 
          analogWrite(speakerOut, 200); 
         } 
    
         if(a <= 49) { 
          analogWrite(speakerOut, NULL); 
         } 
    
         if(a >= 300 && a <= 2499) { 
          analogWrite(speakerOut, NULL); 
         } 
        } 
    } 
    

    Trong trường hợp này chúng tôi đang sử dụng ghim nút làm INPUT_PULLUP. Bạn có thể đọc số Arduino reference để biết thêm thông tin về chủ đề này, nhưng tóm lại, cấu hình này đặt một điện trở pullup nội bộ, theo cách này bạn chỉ có thể kết nối với mặt đất mà không cần điện trở bên ngoài. Lưu ý: Điều này sẽ đảo ngược các cấp của nút, LOW sẽ được nhấn và HIGH sẽ được giải phóng.

  2. Tùy chọn khác sẽ sử dụng một trong các bộ hẹn giờ phần cứng tích hợp để nhận hàm được gọi định kỳ có gián đoạn. Tôi sẽ không đi sâu được here 's một mô tả tuyệt vời của nó là gì và làm thế nào để sử dụng nó.

+0

wow, tganks cho thông tin. Il đọc qua các tài liệu tham khảo và thử điều này. – Beep

3

Ba tùy chọn mà tôi suy nghĩ:

1) End void loop() với while(1) ... hoặc tương đương như tốt ... while(true)

void loop(){ 
    //the code you want to run once here, 
    //e.g., If (blah == blah)...etc. 

    while(1)  //last line of main loop 
} 

Tùy chọn này chạy mã của bạn một lần và sau đó đá Ard vào vòng lặp vô hình "vô hình". Có lẽ không phải là cách tốt nhất để đi, nhưng theo như xuất hiện bên ngoài, nó được công việc làm.
Ard sẽ tiếp tục vẽ hiện tại trong khi nó quay chính nó trong một vòng tròn vô tận ... có lẽ người ta có thể thiết lập một loại hẹn giờ chức năng đặt Ard ngủ sau rất nhiều giây, phút, v.v. looping ... chỉ là một ý nghĩ ... chắc chắn có thư viện ngủ khác nhau ở đó ... xem ví dụ, Monk, Lập trình Arduino: Bước tiếp theo, pgs., 85-100 để thảo luận thêm về điều này.

Thứ hai) Tạo chức năng "dừng vòng lặp chính" với điều khiển có điều kiện cấu trúc làm cho thử nghiệm ban đầu của nó thất bại trong lần vượt qua thứ hai.
Điều này thường đòi hỏi phải khai báo một biến toàn cầu và có chức năng " " dừng vòng lặp chính "chuyển đổi giá trị của biến khi chấm dứt. Ví dụ:

boolean stop_it = false;   //global variable 

void setup(){ 
    Serial.begin(9600); 
    //blah... 
} 

boolean stop_main_loop(){  //fancy stop main loop function 

    if(stop_it == false){ //which it will be the first time through 

     Serial.println("This should print once."); 

     //then do some more blah....you can locate all the 
     // code you want to run once here....eventually end by 
     //toggling the "stop_it" variable ... 
    } 
    stop_it = true; //...like this 
    return stop_it; //then send this newly updated "stop_it" value 
        // outside the function 
} 

void loop{ 

    stop_it = stop_main_loop();  //and finally catch that updated 
            //value and store it in the global stop_it 
            //variable, effectively 
            //halting the loop ... 
} 

Được cấp, điều này có thể không đặc biệt đẹp, nhưng nó cũng hoạt động.
Nó đá Ard vào vòng lặp vô hình "vô hình" khác, nhưng thời gian này là trường hợp liên tục kiểm tra các điều kiện if(stop_it == false) trong stop_main_loop() mà tất nhiên không vượt qua mọi lần sau lần đầu tiên.

3rd) Một lần nữa có thể sử dụng biến toàn cục nhưng sử dụng cấu trúc if (test == blah){} đơn giản thay vì chức năng "dừng vòng chính" ưa thích.

boolean start = true;     //global variable 

void setup(){ 

     Serial.begin(9600); 
} 

void loop(){ 

     if(start == true){   //which it will be the first time through 



      Serial.println("This should print once.");  

      //the code you want to run once here, 
      //e.g., more If (blah == blah)...etc. 

    } 

start = false;    //toggle value of global "start" variable 
           //Next time around, the if test is sure to fail. 
} 

Chắc chắn có những cách khác để "stop" mà pesky vô tận vòng lặp chính nhưng ba cũng như những người đã được đề cập nên giúp bạn bắt đầu.

30

Điều này không được xuất bản trên Arduino.cc nhưng thực tế bạn có thể thoát ra khỏi quy trình lặp với lối thoát đơn giản (0);

Điều này sẽ biên dịch trên khá nhiều bảng bạn có trong danh sách bảng của bạn. Tôi đang sử dụng IDE 1.0.6. Tôi đã thử nghiệm nó với Uno, Mega, Micro Pro và thậm chí cả Adafruit đính

void loop() { 
// All of your code here 

/* Note you should clean up any of your I/O here as on exit, 
all 'ON'outputs remain HIGH */ 

// Exit the loop 
exit(0); //The 0 is required to prevent compile error. 
} 

tôi sử dụng này trong các dự án mà tôi dây vào một nút để pin reset. Về cơ bản vòng lặp của bạn chạy cho đến khi thoát (0); và sau đó chỉ tồn tại trong trạng thái cuối cùng. Tôi đã thực hiện một số robot cho trẻ em của tôi, và mỗi lần nhấn một nút (thiết lập lại) mã bắt đầu từ đầu của hàm loop().

+0

Tôi cũng đã sử dụng nó. Tại sao điều này không phổ biến hơn/được sử dụng? – sscirrus

+1

Đây là cách thư viện C thích hợp để tạm dừng bộ vi xử lý và đánh giá bằng cách tháo gỡ nó chính xác những gì tôi đề xuất trong một bình luận ở trên, tức là vô hiệu hóa ngắt và đi vào vòng lặp vô hạn. Nó cũng sẽ là tốt để đưa bộ vi xử lý vào trạng thái ngủ nếu nó hỗ trợ điều đó, để bảo tồn năng lượng. (Lưu ý rằng trong C++ code exit (0) cũng có thể chạy các destructor toàn cục trước khi tắt). @Beep Đây phải là câu trả lời được chấp nhận. –

+1

Không hoạt động với esp8266. Lỗi trình biên dịch. 'Trong hàm 'vòng lặp': tham chiếu không xác định đến 'thoát' ' –

2

này sẽ tắt ngắt và đặt CPU vào giấc ngủ (vĩnh viễn cho đến khi reset/điện bật lên):

cli(); 
sleep_enable(); 
sleep_cpu(); 

Xem thêm http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, để biết thêm chi tiết.

+0

vui lòng kiểm tra [URL] này (http://stackoverflow.com/tour), sẽ hữu ích để giúp bạn nâng cao chất lượng nội dung của mình –

Các vấn đề liên quan