| ESP32 教學 | MicroPython | 讓 ESP32 超省電!低功耗 DeepSleep Mode | 210 |

由於 ESP32 內建了 Wifi 無線通訊,在正常無線通訊運作下,耗電流也是不小的數值,以電池供電的環境下,就需要低功耗模式的支援,讓 MCU 在閒置或處理輕量工作時,可以更省電,同時提升電池續航力。ESP32 晶片本身設計了多種的省電模式選擇,今天這篇就來看一下在 micropython ESP32 平台上,要怎麼進入所謂的休眠 DeepSleep 模式。

1. ESP32 低功耗模式介紹

查詢 ESP32 的設計參考手冊,可以發現 ESP32 的電源模式有5種:Active、Modem Sleep、Light Sleep、Deep Sleep、Hibernation, 相關的設定流程如下:(參考資料:ESP32 Datasheet)

這5種功耗模式都有不一應用的場景,具體來說:

  • Active Mode: 就是一般操作模式,內部運作的時脈或模組都可以正常操作。
  • Modem Sleep Mode: 如字面上的定義,就是把 wifi 或 bluetooth 模組關掉或受限,CPU 保持正常運作。
  • Light Sleep Mode: CPU 開始暫停,記憶體與其他周邊進入受限制的狀態(clock-gate),但 RTC 和 ULP(協同處理器)保持 active,此模式可以將耗電流下降到 1mA 以下。
  • Deep Sleep Mode: CPU、Memory、其他周邊全部進入 PowerOff,僅剩 RTC、RTC 記憶體、RTC 周邊(ULP)保持 Active,RTC 的內部電壓降到0.7V。
  • Hibernate Mode:此狀態 RTC Timer 保持 Active,僅剩 RTC 或 限制的 IO 可以喚醒 CPU 運作。

回到我們今天想實作的 micropython ESP32平台,目前已經實踐的低功耗模式就是 Deep Sleep 模式,當我們在程式內執行後,搭配周邊電路的設計,是可以達到uA等級的低功耗。

2. ESP32 DeepSleep Mode 操作

>> 進入 Deep-Sleep Mode

怎麼讓 ESP32 進入 Deep-Sleep 模式? 相關的方法放在 machine 模組內, 所以只要 import machine,就可以進行下面的模式操作:

import machine
machine.deepsleep(5000)

machine.deepsleep(5000) 參數的單位是 ms,也就是 5000ms 等於 5 秒,這段程序的意思就是讓 ESP32 進入低功耗模式 5 秒,在之後就重新起動(Restart),這邊需注意一下,進入 Deep-Sleep 後的 Restart,會讓程序從第一行開始執行,如果需要有區別時,可以利用下面的程序來判斷:

f machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print("This is a deepsleep wake-up condition")

machine.reset_cause() 是一個回饋 reset 原因的方法,會有 5 種的回饋值,表示 PWRON_RESET、WDT_RESET 等相關因素,machine.DEEPSLEEP_RESET 就是表示此次開機為 DeepMode 喚醒重新起動 。

>> 喚醒 ESP32 的多種方式

剛剛我們的範例,是進入低功耗模式一定時間(5秒)後就回自行喚醒,這種方法就是 RTC(RealTimeClock) 喚醒, 因為在深度睡眠模式下,RTC Timer 仍保持運作,當 Timer 指定時間到達,即觸發 CPU Restart。

ESP32 喚醒除支援 RTC wakeup 外,還可以透過外部的 IO 腳位進行喚醒,這邊的腳位並不是任意 IO,而是標記為 RTC GPIO的腳位,怎麼確定那幾隻腳位是 RTC 的 GPIO 呢?最直覺的方法就是查閱 ESP32 的參考手冊:(下表擷取於 ESP32技術參考手冊 Page.56 表4.4)

表內就有 RTC GPIO 的編號,對應到一般我們在使用的 GPIO 編號,如果確認 OK 後就可以開始使用。

在來講一下外部IO喚醒方法,可以分為 ext0 跟 ext1,兩種喚醒最大的差別就在於 ext0 可以設定1支IO作為喚醒源,ext1 可以同時設定多支 IO 作為喚醒機制,下面為使用 ext0 外部觸發喚醒的範例:

import machine,esp32
from machine import Pin

ext_p32= Pin(32, Pin.IN,Pin.PULL_UP)
esp32.wake_on_ext0(pin = ext_p32, level = esp32.WAKEUP_ALL_LOW)

因為使用到 GPIO 控制的關係,所以除 esp32 外,再多匯入 Pin 類別,ext_p32 物件就是建立 GPIO32 的 Pin 物件,並指定為輸入腳位與預設內部會有 pull-high 電阻。

接下來設定 ext0 作為喚醒 CPU的來源,esp32.wake_on_ext0 內的 pin 參數指向 GPIO32 Pin 物件,level 是指觸發喚醒的準位,字面上定義來說,IO腳位 Low 或 High 都可以觸發,但因為我們剛剛已經設定 GPIO32 為 pull-high,預設腳位讀取值就是 High,所以這邊選用 esp32.WAKEUP_ALL_LOW ,一旦指定腳位是 LOW 立即喚醒CPU。

3. 休眠與喚醒測試

這次我們就使用 ESP32S 與 2 個外部按鈕來進行一個簡單的休眠與喚醒實驗。實驗很簡單,其中一顆用來進入休眠模式,另一顆則是用來喚醒 CPU。休眠按鈕一側接 GND,另一側接 GPIO13;喚醒用按鈕一側連接到 GND,一側連接 ESP32 的 GPIO32;同時利用 GPIO2 LED的亮暗來表示是否進入休眠模式。

>> 電路連接

備註:因 aithinker ESP32S 內建一個 LED 連接到 GPIO2,所以這邊就不額外接 LED。

>> 完整程式碼

import machine,esp32,time
from machine import Pin

led_p2=Pin(2,Pin.OUT) 
btn_p13=Pin(13,Pin.IN,Pin.PULL_UP)
ext_p32=Pin(32, Pin.IN,Pin.PULL_UP)
esp32.wake_on_ext0(pin = ext_p32, level = esp32.WAKEUP_ALL_LOW)
led_p2.value(1)
print('This is in the active mode now.')

while 1:
    if btn_p13.value() == 0:
        print('The cpu is going to enter the deep-sleep mode after 5s , look at LED !')
        time.sleep(5)       
        led_p2.value(0)
        machine.deepsleep()  
    else :
        pass

>> 程式解說

import machine,esp32,time
from machine import Pin

led_p2=Pin(2,Pin.OUT) 
btn_p13=Pin(13,Pin.IN,Pin.PULL_UP)
ext_p32=Pin(32, Pin.IN,Pin.PULL_UP)
esp32.wake_on_ext0(pin = ext_p32, level = esp32.WAKEUP_ALL_LOW)
led_p2.value(1)
print('This is in the active mode now.')

首先匯入需要的 module,包含 esp32、machine 和 time, 接著設定連接 LED 的 GPIO2 為 OUTPUT,連接外部按鈕的GPIO32 與 GPIO13 為 INPUT。esp32.wake_on_ext0(pin = ext_p32, level = esp32.WAKEUP_ALL_LOW) 此程序設定 GPIO32 為外部喚醒腳位,當該腳位 LOW時,觸發喚醒機制。 led_p2.value(1) 將 LED點亮,並顯示現在狀態為 active mode 正常模式。

while 1:
    if btn_p13.value() == 0:
        print('The cpu is going to enter the deep-sleep mode after 5s , look at LED !')
        time.sleep(5)       
        led_p2.value(0)
        machine.deepsleep()  
    else :
        pass

再來這邊就利用 while 迴圈來進行一個等待進入休眠模式,一旦 GPIO13 連接的按鈕被按下(Low),等待5秒後,LED熄滅,開始進入 ESP32 的 Deep Sleep Mode,machine.deepsleep() 內如果沒有填入數字的話,就是直接進入無限期的休眠,直到有任何的喚醒觸發引起系統 Restart。

>> 執行結果

一切就緒後,當程式開始執行時,LED點亮,按下休眠按鈕(GPIO13),直到 LED變暗,整個 ESP32S 模組便會進入所謂的深度休眠模式,這個範例如果各位有電表時,可以將電源線的部分再”串接”電流表,就可以明顯看到正常模式跟休眠模式的電流消耗的差異。

按下喚醒按鈕後,所以 CPU 重新 Restart,開始新的一次循環。

Tips:

  • 當系統從 deep-sleep 模式離開重新起動時,系統的執行動作會從 main.py 重新開始執行,所以如果要測試這個程式得將檔名存成 main.py 放入 ESP32 內。
  • 由於 CPU 在 deep-sleep 模式周邊都會關閉,包括 UART等,所以這個狀態下無法中斷程式(Ctrl+C)或上傳程式碼,需切換到 active-mode 才可,各位朋友在留意一下。

4. 小結

休眠模式在嵌入式平台的設計中很常見也很實用,因為很多使用環境都是採用電池供電的,最大宗就是手持式的裝置或遠端感測應用,系統如剛好遇到閒置時,透過這些休眠模式的操作,大幅的減少更換電池的機會,在實際產品上,更多會搭配周邊電路的設計以達到省電最佳化。

以我們創客常使用的應用來說,最常用的就是遠端感測服務,因為某些遠端感測的資訊更新並不需要非常頻繁(如我們常用的 DHT11 溫濕度),30秒或是更長時間的更新即可,此時適當的加入休眠模式操作(指定休眠時間)便是更好的機制,各位朋友可以再參考自己手邊的專案斟酌變化即可囉!

今天的內容就到這邊,如果有遇到什麼問題或想看那些教學內容,也歡迎在下面留言或寫信與我討論囉~

↓↓↓↓↓↓賣場連結↓↓↓↓↓↓

歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀 

吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw

Follow JIMI哥 Twitter : https://twitter.com/jimirobot  <–得到最新文章通知

發佈留言

Close Menu