一旦你的ESP專案開發測試完成,總會面臨一個電源的問題,我們會很直覺的意識到不可能你的ESP一直在運算或工作,其實大部份的時間CPU都是閒置的,等到一段時間我們才需要晶片工作,當晶片閒置或空閒時我們希望能簡一些電力的損毀不然你的外部電源能供應多久的時間。知道歸知道。問題是我們的硬體、軟體要做些什麼改變才能符合我們的需求。
我想設計的理想工作模式或流程應該是如此的
- Waken up
- 檢查及連線網路(假如没有連網)
- 作些工作 (從感測器讀資料,傳送資料)
- Sleep
n
microseconds或 ? 分鐘 - 重複上面步驟
Sleep 模式
事實上,你不可能一直永遠sleep,根據ESP8266 SDK文件,我們僅可以sleep 的時間為4,294,967,295 µs,大約 ~71 分鐘。
(1)NO-SLEEP
没有Sleep 設定,所有一切設備都是全力工作的,當然這是最没有效率且消耗最多電力的。
(2)MODEM-SLEEP
對ESP8266而言,當連線至AP點成功後,這是預定的設定模式,經過一段時間ESP8266將會diaable WiFi連線,連線時間長短是由你的route決定。
(3)LIGHT-SLEEP
Light-sleep 執行和Modem-sleep相同的功能,但是它會關掉system clock 和暫停CPU。
(4)DEEP-SLEEP
這是最理想的工作模式,從下面我們可以得知ESP8266不同模式和電流消耗情形。
ESP32有五種不同sleep模式,從每一個皆ON的active 模式至每一種皆OFF的 hibernation模式,現在我們只關注在Active 和deep-sleep模式就好。
進入Deep-Sleep 模式
對ESP8266而言,要使用Deep Sleep 要軟體,硬體相互配合 :第一個硬體方面是要GPIO16 脚連接至reset 接脚。第二個是軟體方面是使用timer去Wake up 晶片,ESP8266大約可長達一小時的sleep。個人偏好使用Micropython 所以下面為一個以Timer 喚醒晶片的方式來實作。
import machine
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000) # 以 μs 為單位 # put the device to sleep machine.deepsleep()
當昌片從deep sllep 被唤喚醒後,晶片會完全的被Reset,所以下面的程式碼可用來判斷晶片是被唤喚醒後的Reset 或是一般性的Reset。
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
else:
print('power on or hard reset')
從Deep-Sleep 至Wake up 模式
要使ESP32晶片從Deep-sleep至Wake up 有下列幾種方式?
Wakeup 來源
(1)Timer
(2)External wakeup (ext0)- RTC_IO
(3)External wakeup (ext1)- RTC_CNTL.
(4)The touch pads
(5)ULP coprocessor wakeup
資料來源:
http://www.instructables.com/id/ESP32-Deep-Sleep/
https://www.losant.com/blog/making-the-esp8266-low-powered-with-deep-sleep
https://esp-idf.readthedocs.io/en/v2.0/api/system/deep_sleep.html
http://www.iotsharing.com/2017/06/bring-esp32-to-low-power-sleep-save-battery.html