我注意到大多數示例代碼段在循環中總是會有延遲,即使程序正常執行不需要它。
我只能假定添加了此代碼段,因為人們在不理解的情況下進行複制和粘貼發生了什麼,但讓我開始思考是否添加延遲也可以節省電源。
如果我有一個循環來檢查某些輸入的更改,是否可能添加 delay(10)
節省一些週期並因此省電?
我注意到大多數示例代碼段在循環中總是會有延遲,即使程序正常執行不需要它。
我只能假定添加了此代碼段,因為人們在不理解的情況下進行複制和粘貼發生了什麼,但讓我開始思考是否添加延遲也可以節省電源。
如果我有一個循環來檢查某些輸入的更改,是否可能添加 delay(10)
節省一些週期並因此省電?
延遲
函數並沒有做任何特別的事情。它基本上只是在while循環內倒數毫秒,然後用 micros()
計時。
void delay(unsigned long ms){uint32_t start = micros(); while(ms > 0){yield(); while(ms > 0 &&(micros()-start)> = 1000){ms--;開始+ = 1000; }}}
否,當您連接到外部傳感器時,通常會在void loop()中插入一小段延遲(最多100毫秒),以穩定讀數。但這與功耗無關。例如,以下是示例草圖“ AnalogInSerialOut”中的第49-52行:
// //在下一個循環之前等待2毫秒// //模數轉換器穩定/ /最後一次讀取後:delay(2);
是否可以添加delay(10)節省一些週期,從而節省功耗?
否, delay()
函數只是將代碼暫停指定的時間。
如果要節省電能,可以以節省能源的方式調整電路組件,或者如果要節省電能,則要消耗時間以等待時間。在Arduino上消耗能量時,您可以使用麵包板設置(說明此處和此處),也可以使用內部看門狗定時器以一定的時間間隔睡眠和喚醒。 此處介紹了有關看門狗計時器的更多教程。
乾杯!
以上答案是錯誤的,至少對於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); }}
我還沒有進一步研究為什麼延遲功能可以節省這麼多的功耗。
我懷疑答案取決於您使用的Arduino類型。
ESP8266是基於ARM的,我相信ARM芯片包括電源管理電路,子系統會自動進入低功耗狀態不使用它們時。基於ARM的Arduino在執行延遲時可能會比在其他事情上使用更少的功率。
我不認為AVR芯片具有任何電源管理功能,因此它們具有全部的矽芯片。始終點亮”。就是說,CMOS邏輯電路在切換狀態時確實比在空閒狀態下使用更多的功率,因此,即使是基於AVR的Arduino在使用delay()函數時也會比在運行使用算術單元的指令時使用更少的功率, UART和芯片的其他子系統。
通過將Arduino置於睡眠模式,您將獲得更好的節能效果。
如先前的回答所述,至少在AVR版本的Arduino內核上, delay()
是一個繁忙的等待,可保持CPU的運行。在他的回答中,Duncan C正確地指出:“ CMOS邏輯電路在切換狀態時比在空閒時消耗更多的功率”。然後,預計切換大量門或觸發器的指令比只切換少數門或指令的指令所消耗的功率更多。
出於好奇,我反彙編了對 delay()
查看它執行哪種指令。我發現“熱路徑”是一個循環,每次迭代執行44條指令:
我不知道這與“典型”代碼相比如何,但是執行算術和邏輯計算的指令的很大比例建議 delay()
應該比例如 nop
指令序列更加耗能。最後,唯一確定 delay()
是否會改變特定程序的電源消耗的唯一方法就是對其進行測量。
作為附帶說明,一種簡單的方法節省AVR板上電源的一種方法是 #include <avr / sleep.h>
,然後在 loop() end>的結尾插入對
sleep_mode()
的調用。代碼>。睡眠並不會持續很長時間,因為Arduinocore將Timer0設置為每1024 µs中斷CPU。