題:
循環延遲是否節省能量?
Ryan Detzel
2018-02-14 21:49:26 UTC
view on stackexchange narkive permalink

我注意到大多數示例代碼段在循環中總是會有延遲,即使程序正常執行不需要它。

我只能假定添加了此代碼段,因為人們在不理解的情況下進行複制和粘貼發生了什麼,但讓我開始思考是否添加延遲也可以節省電源。

如果我有一個循環來檢查某些輸入的更改,是否可能添加 delay(10) 節省一些週期並因此省電?

不會。即使延遲也會“使用”週期。
尼克·加蒙(Nick Gammon)的強制性參考:https://www.gammon.com.au/forum/?id = 11497。關於能源。
@MarkLakata。怎麼樣yield()
@MarkLakata多線程?在Arduino中? 99.99%的時間沒有真正的調度程序,並且在其他情況下,在0.01%的情況下,延遲函數不會“釋放”調用線程(延遲實現就像for循環一樣,什麼也不做)
七 答案:
Kwasmich
2018-02-14 21:52:18 UTC
view on stackexchange narkive permalink

不,它什麼都不做會消耗能量。

您絕對應該讓MCU進入睡眠狀態並在事件中喚醒,或者使用看門狗定時器在預定的時間段後喚醒。

gre_gor
2018-02-14 22:04:27 UTC
view on stackexchange narkive permalink

延遲函數並沒有做任何特別的事情。它基本上只是在while循環內倒數毫秒,然後用 micros()計時。

  void delay(unsigned long ms){uint32_t start = micros(); while(ms > 0){yield(); while(ms > 0 &&(micros()-start)> = 1000){ms--;開始+ = 1000; }}}  
調用yield()有點特殊,但是是的,它仍然是一個繁忙的等待,它花費大部分時間來運行指令。
@PeterCordes調用yield()沒什麼特別的。那隻是一個(弱定義的)函數,什麼都不做。它在那裡是允許其他庫或代碼覆蓋它並實現某種協作線程的方法,但是默認代碼則不允許,因此它什麼也不做。這不像在VB中調用`yield()`那樣將程序流釋放回OS ...
@Majenko:謝謝,我認為`yield`暗示著一個多任務操作系統,而不僅僅是存根以防萬一。 (是的,我在想它的字面意思是[POSIX`sched_yield(2)`](http://man7.org/linux/man-pages/man2/sched_yield.2.html),這暗示著Arduino運行了像Linux這樣的完整操作系統。當我自己不使用任何開發板(RPi / Arduino /任何東西)時,很難跟踪它們運行什麼。
arducode
2018-02-15 04:28:07 UTC
view on stackexchange narkive permalink

否,當您連接到外部傳感器時,通常會在void loop()中插入一小段延遲(最多100毫秒),以穩定讀數。但這與功耗無關。例如,以下是示例草圖“ AnalogInSerialOut”中的第49-52行:

  // //在下一個循環之前等待2毫秒// //模數轉換器穩定/ /最後一次讀取後:delay(2);  
EngrAbbas
2018-02-16 11:12:11 UTC
view on stackexchange narkive permalink

是否可以添加delay(10)節省一些週期,從而節省功耗?

否, delay()函數只是將代碼暫停指定的時間。

如果要節省電能,可以以節省能源的方式調整電路組件,或者如果要節省電能,則要消耗時間以等待時間。在Arduino上消耗能量時,您可以使用麵包板設置(說明此處此處),也可以使用內部看門狗定時器以一定的時間間隔睡眠和喚醒。 此處介紹了有關看門狗計時器的更多教程。

乾杯!

MABC
2020-07-16 16:24:27 UTC
view on stackexchange narkive permalink

以上答案是錯誤的,至少對於NodeMCU 0.9(ESP-12板)ESP8266來說,我也對Firebeetle ESP8266板進行了測試。由於我有一個USB測試儀,因此我可以檢查如果循環方法為空,則這些板消耗的電流約為 70mA-80mA ,但是在延遲(ms)期間,它們的消耗電流約為 20mA-30mA

這是所評論的板的延遲功能:

  void __delay(unsigned long ms){if(ms){os_timer_setfn(&delay_timer,(os_timer_func_t *)&delay_end ,0); os_timer_arm(&delay_timer,ms,ONCE); } else {esp_schedule(); } esp_yield(); if(ms){os_timer_disarm(&delay_timer); }}  

我還沒有進一步研究為什麼延遲功能可以節省這麼多的功耗。

Duncan C
2020-07-17 05:16:07 UTC
view on stackexchange narkive permalink

我懷疑答案取決於您使用的Arduino類型。

ESP8266是基於ARM的,我相信ARM芯片包括電源管理電路,子系統會自動進入低功耗狀態不使用它們時。基於ARM的Arduino在執行延遲時可能會比在其他事情上使用更少的功率。

我不認為AVR芯片具有任何電源管理功能,因此它們具有全部的矽芯片。始終點亮”。就是說,CMOS邏輯電路在切換狀態時確實比在空閒狀態下使用更多的功率,因此,即使是基於AVR的Arduino在使用delay()函數時也會比在運行使用算術單元的指令時使用更少的功率, UART和芯片的其他子系統。

通過將Arduino置於睡眠模式,您將獲得更好的節能效果。

在AVR上,delay()使用ALU。
是的,我想它將使用ALU來查看是否經過了足夠的時間。我的意思是作為芯片不同子系統的一個例子,而不是一個準確的清單,但要指出一點。
Edgar Bonet
2020-07-17 15:30:27 UTC
view on stackexchange narkive permalink

如先前的回答所述,至少在AVR版本的Arduino內核上, delay()是一個繁忙的等待,可保持CPU的運行。在他的回答中,Duncan C正確地指出:“ CMOS邏輯電路在切換狀態時比在空閒時消耗更多的功率”。然後,預計切換大量門或觸發器的指令比只切換少數門或指令的指令所消耗的功率更多。

出於好奇,我反彙編了對 delay()查看它執行哪種指令。我發現“熱路徑”是一個循環,每次迭代執行44條指令:

  • 其中23條指令進行算術或邏輯(加,減,比較,異或)
  • 13移動數據(寄存器加載,寄存器複製,I / O,讀取RAM)
  • 7更改程序流程(函數調用,返回,跳轉,條件分支,條件跳過)
  • 1會改變狀態寄存器中的位

我不知道這與“典型”代碼相比如何,但是執行算術和邏輯計算的指令的很大比例建議 delay() 應該比例如 nop 指令序列更加耗能。最後,唯一確定 delay()是否會改變特定程序的電源消耗的唯一方法就是對其進行測量。

作為附帶說明,一種簡單的方法節省AVR板上電源的一種方法是 #include <avr / sleep.h> ,然後在 loop() end>的結尾插入對 sleep_mode()的調用。代碼>。睡眠並不會持續很長時間,因為Arduinocore將Timer0設置為每1024 µs中斷CPU。



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...