2018年3月24日 星期六

【Ameba特異功能集(1-1)】省電模式教戰守則

作者:柯大
為了創造更輕便電的物聯網裝置,瑞昱阿米巴(Ameba)開發板加入了更多裝置端的省電模式,並提供Arduino開發環境不同的省電API,讓裝置可以輕易的以電池或太陽能板供電維持一段長時間的正常運作,以下來介紹實作的方式。

6種省電API功能

Realtek在2016/02/19釋出的Ameba IoT/Arduino Solution Version 1.0.5版本中,新增了對Ameba開發板的省電API功能,共提供了6組API:
void sleep(); //進入sleep
void active(); //關掉sleep(),不允許sleep
void deepsleep(uint32_t duration_ms); //進入最省電的模式深睡模式
void setPllReserved(bool reserve); //預設PLL clock關掉,防止其他週邊停止運作
void softReset(); //軟體重開機
bool safeLock(); //
要使用Ameba省電API功能,需於程式中加入以下library:
#include <PowerManagement.h>
API function 說明如下:

1. static void sleep();

呼叫這個function之後,就允許系統在閒暇的時候進入sleep(但不一定會馬上進入sleep),如果Ameba開著WiFi,WiFi依照802.11的省電模式定時起來並且醒著聽AP發出來的beacon,收完之後如果沒事就會繼續進入sleep。
如果WiFi資料量比較大的時候,WiFi會離開802.11的省電模式,此時系統也不會進入sleep,所以開著WiFi的耗電量會因為資料量與WiFi環境的乾淨程度有關。

2. static void active();

呼叫這個function等於是關掉sleep(),閒暇時不允許sleep。

3. static void deepsleep(uint32_t duration_ms);

這是最省電的模式,幾乎都關了,醒來之後會從頭開始執行,像是經過reset一樣,呼叫這個function之後會馬上進入deepsleep。
其中有個參數是duration_ms,可設定進入deepsleep之後多久之後醒來。

4. static void setPllReserved(bool reserve);

當Ameba進入sleep,如果PLL clock關掉,會讓一些週邊(Ex. UART, I2C, SPI…)無法收資料,目前預設是保留PLL不關掉,適合關掉的情況是:(1)沒有用到這些週邊,或是(2)用到這些週邊但不需要在Ameba進入sleep之後還收資料。關掉省掉的電大約是5.5mA,算是需要自己取捨的電量。

5. static void softReset();

呼叫之後馬上重開機,這是軟體行為,電路上並沒有重新上電。

6. static bool safeLock();

當Ameba進入deepsleep,會無法燒錄程式,為了避免使用者寫出程式是開啟Ameba就進入deepsleep的程式,所以使用D18這根PIN當做保護,當D18這根PIN被接到GND,就會防止Ameba進入deepsleep或sleep。
傳回值 :
true: D18 is connected to GND
false: D18 is not connected to GND
註:因為Ameba進入deepsleep之後就無法上傳程式,在deepsleep的API裡面我們將D18這根腳當作避免Ameba進入deepsleep的pin腳,只要將D18接GND,並且重開Ameba 即可重新燒錄新程式。
將D18接GND,並且重開Ameba 即可重新燒錄新程式。
將D18接GND,並且重開Ameba 即可重新燒錄新程式。

Ameba常用的省電模式

Ameba提供許多省電模式,最常用的是deepsleep與sleep。

1. Deepsleep mode

當Ameba進入deepsleep mode,會讓Ameba處於最省電的情況,它的耗電會小於20 uA (微安培),此時大部份元件都關掉了,但低解析度的timer仍在運作並且用來喚醒Ameba。這種模式適合定時運作的情境,像是每小時起來量測溫濕度、送出資料,再回到deepsleep。

2. Sleep mode

這個模式是Ameba可以維持WiFi連線的省電模式,它的耗電會因為WiFi資料量與無線環境的乾淨程度而有所不同,但是瞬間最低電流會在2.5 mA (毫安培),與WiFi起來運作之後的電流平均之後,仍然是相當省電的模式。這種應用適合需要遠端操控Ameba的情境,像是使用手機透過網路通知Ameba馬上量一次溫濕度,再回傳結果。

省電範例程式

範例一、讓Ameba處於WiFi連接的省電模式

Ameba的deepsleep無法讓WiFi處於連線狀態,如果想讓Ameba省電,並且保持WiFi連線,可以使用sleep API。
打開範例 “File” -> “Examples” -> “AmebaPowerSave” -> “SleepWithDHTUdpServ”
範例裡一樣需要設定連線AP的SSID和password。
這個範例裡,Ameba會先建立WiFi連線,進入sleep省電模式,Ameba會當作UDP server,每當接收到UDP封包內容為 ‘H’,就回傳濕度,接收到UDP封包為 ‘T’,就回傳溫度。
與deepsleep不同的地方是,當Ameba打開sleep模式,會自己找尋可以睡眠的時間,當裝置閒置時就會進入睡眠。整個睡眠與醒來的動作是自動的,不需要使用者干預。
當Ameba連線之後,我們參考之前測試TCP/UDP的工具Sokit設定Ameba的IP & port。我們每分鐘輪流問一次溫濕度,可以看到Ameba都有回應。
每分鐘輪流問一次溫濕度,可以看到Ameba都有回應。
每分鐘輪流問一次溫濕度,可以看到Ameba都有回應。
這個範例裡會偵測D18這根防止進入睡眠的pin腳,如果D18被接地,就不會讓Ameba進入sleep睡眠模式,於是我們可以測量兩種耗電:(實驗所使用的電錶為Keysight 34465A)
p7
註:實際情況裡,不會用到那麼久,它會因為升壓轉換造成能量損失,也會因為電池電壓隨時間而降低造成無法使用到全部的容量。
這裡的數據會因為網路狀況而有不同,讓Ameba保持連線的情況下會比讓Ameba進入deepsleep要耗電;但讓Ameba保持連線來提供使用者做遠端操控,這是deepsleep無法做到的,這端看使用者的應用而定。

範例二、將DHT資料上傳到LASS之後進入睡眠

使用Ameba通常都會使用到它的WiFi功能,實際的省電使用情況也會因為如何使用WiFi功能而有不同。這個範例裡會先量測DHT的溫濕度數據,打開WiFi並連上AP,取得NTP時間,連上LASS的MQTT server,將量測的溫濕度數據上傳,再進入deepsleep。每10分鐘重覆這樣的動作。
打開範例 “File” -> “Examples” -> “AmebaPowerSave” -> “DeepSleepWithDHTLass”
修改程式裡相關的設定,包括:
– DHT的型號:DHT11/DHT22/DHT21
– 連上AP的方式:ssid, password
– 目前的GPS位置:latitude & longitude
編譯並上傳之後,量測到的耗電會因為許多因素而影響,包括WiFi網路環境是否乾淨、網路連線是否順暢、Server是否馬上回應。但一般應該會在十多秒內完成。
範例測試的結果裡,我上傳所花的時間是13s,量得的Ameba module耗電平均為1.3mA。
這個數據比範例 “DeepSleepWithDHT” 要大上許多,因為Ameba在工作模式下的耗電通常大於29mA,甚至在WiFi連線時至少會大於68mA,與deepsleep的0.018 mA相比,我們要讓Ameba儘量待在deepsleep才會取得最大的省電效益。
為了比較未省電的情況,我們將程式碼修改如下,讓它平常保持網路連線,每10分鐘量一次,量完再上傳至LASS的MQTT Server:
void setup()
{
dht.begin();
initializeWiFi();
initializeMQTT();
}
void loop()
{
if (gatherHumidityAndTemperature() == DATA_CNT_FOR_UPLOAD) {
retrieveNtpTime();
if (!client.connected()) {
reconnectMQTT();
}

publishResults();
pDhtData-&gt;dataCount = 0;
}

// store data back to flash memory
FlashMemory.update();
delay(measureInterval * 1000);
}
這種方式量測到的平均耗電為67mA,和我們用2顆AA電池來比較耗電 (實驗所使用的電錶為Keysight 34465A)。
P8
可以看到沒省電的情況下只能用一天,但經過省電並且單獨供電給Ameba module可以使用2.8個月。
註:實際情況裡,不會用到那麼久,它會因為升壓轉換造成能量損失,也會因為電池電壓隨時間而降低造成無法使用到全部的容量。

沒有留言:

張貼留言