玩轉(zhuǎn) ESP32 + Arduino (十七) deepsleep深睡眠模式

一. 關(guān)于UPL協(xié)處理器的概念

ESP32 有強(qiáng)大的超低功耗協(xié)處理器 (ULP co-processor)

ULP 協(xié)處理器是一個功耗極低的協(xié)處理器設(shè)備,無論主 CPU 是處于正常運(yùn)行模式還是 Deep-sleep 模式纵揍,ULP 協(xié)處理器都可以獨(dú)立運(yùn)行携狭。超低功耗協(xié)處理器的補(bǔ)充使得 ESP32 能夠勝任一些對低功耗要求較高的應(yīng)用場合辱士。

ULP 協(xié)處理器的主要特性有:

采用 8 MHz 頻率和 8 KB 內(nèi)存
內(nèi)建 ADC 和 I2C 接口
支持正常模式和 Deep-sleep 模式
可喚醒主 CPU 或向主 CPU 發(fā)送中斷
能夠訪問主 CPU 的外圍設(shè)備、內(nèi)部傳感器及 RTC 寄存器

鑒于以上的特性耀里,ULP 協(xié)處理器能夠在消耗較低電流的情況下筒捺,完成 ADC 采樣,進(jìn)行 I2C Sensor 的讀寫势就,驅(qū)動 RTC GPIO 口動作泉瞻,可以在某些超低功耗場景中完全替代主 CPU脉漏。

重要的: ULP是ESP32做出優(yōu)秀低功耗產(chǎn)品的關(guān)鍵

但是致命的: ULP只能用匯編????????

參考文檔: https://blog.csdn.net/espressif/article/details/79131076

二. 理解了ULP之后, 讓我們看一下ESP32的工作模式

可以看到ESP32在深睡眠模式下可以啟動或停止ULP協(xié)處理器

三. ESP32 deepsleep模式喚醒方式及關(guān)鍵API

喚醒方式:

  • 定時器喚醒
  • 兩種引腳喚醒方式
  • 觸摸按鍵喚醒
  • ULP喚醒

1. 開始進(jìn)入深睡眠: esp_deep_sleep_start();

esp_deep_sleep_start();

2. 獲取esp32被喚醒的原因 esp_deep_sleep_get_wakeup_cause();

這是一個ESP-IDF的原生方法, 如果我們想用, 需要引入頭文件

#include <esp_sleep.h>

注意:#include <esp_deep_sleep.h>即將被棄用, 所以不要再用這個頭文件了

Serial.println(esp_deep_sleep_get_wakeup_cause());

返回: 被喚醒原因碼:

原因碼 對應(yīng)原因 說明
0 ESP_SLEEP_WAKEUP_UNDEFINED 沒有定義被喚醒的原因(第一次啟動時會報(bào))
2 ESP_SLEEP_WAKEUP_EXT0 被RTC_GPIO喚醒
3 ESP_SLEEP_WAKEUP_EXT1 被RTC_CNTL引腳集合的變化喚醒
4 ESP_SLEEP_WAKEUP_TIMER 被ESP的定時器喚醒
5 ESP_SLEEP_WAKEUP_TOUCHPAD 被觸摸喚醒
6 ESP_SLEEP_WAKEUP_ULP 被ULP喚醒
7 ESP_SLEEP_WAKEUP_GPIO 被GPIO喚醒(僅限輕睡眠模式light sleep)
8 ESP_SLEEP_WAKEUP_UART 被串口喚醒(僅限輕睡眠模式light sleep)

3. 設(shè)置具體的喚醒源請看下面的相關(guān)章節(jié)

四. RTC memory

ESP32有8KB的RTC存儲器
在RTC memory里的變量不會因?yàn)閐eepsleep被清除, 創(chuàng)建方法:

RTC_DATA_ATTR int bootCount = 0;

注意, RTC memory會被硬件reset清除

五. 進(jìn)入休眠后定時器喚醒

esp_sleep_enable_timer_wakeup(20000000);

參數(shù):

  • 定時時間,單位μ秒, 類型uint64_t, 所以定時時間要在584942年以內(nèi)??????

例子:

#include <Arduino.h>
#include <esp_sleep.h>

RTC_DATA_ATTR int bootCount = 0;

void setup()
{
  Serial.begin(115200);
  Serial.printf("ESP32 is restart now! It's the %d time\r\n", ++bootCount);
  delay(5000);
  esp_sleep_enable_timer_wakeup(20000000);
  Serial.println(esp_sleep_get_wakeup_cause());
}

void loop()
{
  Serial.println("ESP32 will sleep now!");
  delay(100);
  esp_deep_sleep_start();
}

六. 進(jìn)入休眠后被RTC_GPIO喚醒 (引腳喚醒方式一)

首先,并不是每個GPIO都是RTC_GPIO, 詳見下表

注意: 我們填寫的GPIO引腳號是真正的引腳號 不是其RTC_GPIO編號

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0);
#include <Arduino.h>
#include <esp_sleep.h>

RTC_DATA_ATTR int bootCount = 0;

void setup()
{
  Serial.begin(115200);
  Serial.printf("ESP32 is restart now! It's the %d time\r\n", ++bootCount);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0);
  Serial.printf("the wakeup reason is :%d\r\n", esp_sleep_get_wakeup_cause());
}

void loop()
{
  delay(3000);
  Serial.println("ESP32 will sleep now!");
  delay(100);
  esp_deep_sleep_start();
}

七. 進(jìn)入休眠后被RTC_CNTL喚醒 (引腳喚醒方式二)

思考一個問題, 如果我們有8個GPIO引腳想喚醒ESP32, 難道要用上一節(jié)的方法操作8遍嗎?

當(dāng)然不是, 我們可以直接操作引腳集合, (我們用一個mask片選想操作的引腳,然后這些引腳都具有了喚醒ESP32的能力)

我們可以設(shè)置這些引腳是 每個都能觸發(fā)(每個葫蘆娃都能自己去救爺爺), 還是一起共同發(fā)力才能觸發(fā)(集齊七龍珠??)

esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);

參數(shù):

  • mask :

如: 我們想讓 32 33 35 39觸發(fā), 這樣計(jì)算mask

注意: 我們不要使用 37 38

  • mode: 觸發(fā)方式 可選:
    • ESP_EXT1_WAKEUP_ALL_LOW : 全都置低時觸發(fā)喚醒
    • ESP_EXT1_WAKEUP_ANY_HIGH : 任意置高時觸發(fā)喚醒

八. 進(jìn)入休眠后被觸摸按鍵喚醒

值得注意的是,

  • 觸摸按鍵喚醒所需deepsleep電流要大于 按鍵和定時器
  • 必須寫觸摸回調(diào)函數(shù), 否則無用
#include <Arduino.h>
#include <esp_sleep.h>

RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int BTN_Pin_BITMASK = 0;


void callbackPin2()
{
  Serial.println("T2 weak ESP32 up");
}

void setup()
{
  Serial.begin(115200);
  Serial.printf("ESP32 is restart now! It's the %d time\r\n", ++bootCount);
  esp_sleep_enable_touchpad_wakeup();
  Serial.printf("the wakeup reason is :%d\r\n", esp_sleep_get_wakeup_cause());
  touchAttachInterrupt(2,callbackPin2,40);
}

void loop()
{
  delay(3000);
  Serial.println("ESP32 will sleep now!");
  delay(100);
  esp_deep_sleep_start();
}

九. 被ULP喚醒

這個要做一個專門的ULP專題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市袖牙,隨后出現(xiàn)的幾起案子侧巨,更是在濱河造成了極大的恐慌,老刑警劉巖鞭达,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件司忱,死亡現(xiàn)場離奇詭異,居然都是意外死亡畴蹭,警方通過查閱死者的電腦和手機(jī)坦仍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叨襟,“玉大人繁扎,你說我怎么就攤上這事『觯” “怎么了梳玫?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長墓怀。 經(jīng)常有香客問我汽纠,道長,這世上最難降的妖魔是什么傀履? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任虱朵,我火速辦了婚禮,結(jié)果婚禮上钓账,老公的妹妹穿的比我還像新娘碴犬。我一直安慰自己,他們只是感情好梆暮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布服协。 她就那樣靜靜地躺著,像睡著了一般啦粹。 火紅的嫁衣襯著肌膚如雪偿荷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天唠椭,我揣著相機(jī)與錄音跳纳,去河邊找鬼。 笑死贪嫂,一個胖子當(dāng)著我的面吹牛寺庄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼斗塘,長吁一口氣:“原來是場噩夢啊……” “哼赢织!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起馍盟,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤于置,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后朽合,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俱两,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年曹步,在試婚紗的時候發(fā)現(xiàn)自己被綠了宪彩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡讲婚,死狀恐怖尿孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筹麸,我是刑警寧澤活合,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站物赶,受9級特大地震影響白指,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酵紫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一告嘲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奖地,春花似錦橄唬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犬庇,卻和暖如春僧界,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背臭挽。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工捎泻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人埋哟。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赤赊。 傳聞我的和親對象是個殘疾皇子闯狱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345