รหัสสำหรับการประมวลผลครั้งเดียวใน Arduino


12

คำถาม:ฉันจะใส่รหัสได้ที่ไหนถ้าฉันต้องการให้รันเพียงครั้งเดียวต่อการเริ่มต้นของ Arduino?

พื้นหลัง:ฉันมักจะใช้ Arduino เพื่อทำงานที่ควรดำเนินการหนึ่งครั้งต่อรอบการใช้พลังงาน (ตัวอย่างเช่นหุ่นยนต์ของฉันควรขับไปข้างหน้าหนึ่งครั้งทุกครั้งที่เปิดเครื่อง - ยิ่งไปกว่านั้นและมันอาจตกลงมาจากโต๊ะ)

Arduino template "IDE" มาตรฐานประกอบด้วย a 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 สะดวกในการทำต้นแบบ แต่ส่วนใหญ่เป็นเพียงรหัสสำเร็จรูป การทำความเข้าใจกับสิ่งที่ทำอยู่นั้นมีประโยชน์อย่างมากในการตัดสินใจว่าจะออกแบบบางสิ่งบางอย่าง
Connor Wolf

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 ขอบคุณที่คุณช่วยฉันด้วย!
Kyle

5

ฉันชอบวิธีที่ 2 มากหากคุณวางแผนที่จะเพิ่มรหัสเพื่อจัดการอินพุตเอาต์พุต ฯลฯ เป็นเรื่องง่ายด้วยวิธีที่ 2 - เพียงกรอกloop()แต่ต้อง reworking / refactoring ในวิธีที่ 1


3

ฟังก์ชั่นตั้งค่าไม่ จำกัด เวลา ฉันชอบวิธีที่ 2 เพราะการวนซ้ำสามารถเติมได้ทุกอย่างที่คุณต้องการในภายหลัง


1

แน่นอนไปกับวิธีที่สอง นั่นคือสิ่งที่ฟังก์ชั่นตั้งค่ามีไว้ มันอ่านง่ายขึ้นเช่นกัน สิ่งใดในความloop()หมายว่ามันจะถูกเรียกใช้ในลูป


0

ตามคำตอบอื่น ๆ ส่วนใหญ่ฉันจะไปหาวิธีที่ 2

แต่ฉันจะพยายามหลีกเลี่ยงการโทรจากห้องสมุด Arduino ไปสู่พื้นที่ว่างloop()ที่ทำให้ Atmel ใช้กระแส "มาก" ในปัจจุบันโดยไม่ทำอะไรเลย

แก้ไข:

ในขณะที่ความคิดเห็นบางส่วนชี้ให้เห็นถึงแม้ว่าการใช้delay()ในloop()จะไม่มีอะไรเปลี่ยนแปลงการใช้พลังงาน

ดังนั้นหากคุณต้องการลดการใช้พลังงานเมื่อคุณsetup()วิ่งคุณจะต้องเล่นกับ Atmel sleep mode คุณสามารถดูบทความนี้ที่แสดงวิธีจัดการกับโหมดสลีปจากภาพร่าง Arduino ของคุณ มันเป็นมากกว่าแค่การทำให้ Atmel เข้าสู่โหมดสลีป แต่เป็นการอ่านที่ดี (และง่าย) ถ้าคุณต้องการเล่นกับโหมดสลีป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.