[Źródło: www.banggood.com]
Sposoby usypiania:
Do usypiania możliwa jest opcja wprowadzająca układ w stan głębokiego uśpienia. Aby ją zastosować należy ustawić np. jeden z dwóch przerwań od portów, timer, kontroler dotykowy na bądź koprocesor.
W tym trybie działa jedynie kontroler RTC, układy RTC w tym koprocesor ULP oraz dostęp do pamięci RTC szybkiej i wolnej. Sposoby wybudzania oraz usypiania mogą zostać ze sobą powiązane. np. można wybudzać za pomocą portu GPIO oraz timera.
Należy pamiętać o poprawnej konfiguracji zasilania. Oznacza to że opcja którą chce się używać w celu wybudzenia układu.
W celu konfiguracji należy zapoznać się z następującymi funkcjami:
esp_deep_sleep_pd_config - pozwala na ustawienie poszczególnych elementów które są zasilane.
- esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain, esp_deep_sleep_pd_option_t option);
W przypadku nie wywołania tej funkcji ustawiony jest parametr ESP_PD_OPTION_AUTO.
Funkcja zwraca ESP_OK w przypadku poprawnej konfiguracji, bądź ESP_ERR_INVALID_ARG w przypadku gdy argument jest nieodpowiedni.
Jako parametry podaje się w pierwszym miejscu domenę do konfiguracji. Do wyboru są:
- ESP_PD_DOMAIN_RTC_PERIPH - uruchomione są piny gpio RTC, czujniki oraz koprocesor ULP.
- ESP_PD_DOMAIN_RTC_SLOW_MEM - uruchomienia jest wolna pamięć RTC. Zawiera ona globalne i statyczne zmienne, które są wykorzystywane przez kod z pamięci RTC.
- ESP_PD_DOMAIN_RTC_FAST_MEM - uruchomiony dostęp do szybkiej pamięci RTC. Jest ona zarezerwowana dla kodu wykonywanego po obudzeniu procesora z głębokiego uśpienia.
- ESP_PD_DOMAIN_MAX - liczba domen.
Drugim elementem są opcje wyłączenia zasilania. W tym przypadku do wyboru są trzy elementy:
- ESP_PD_OPTION_OFF - wyłącz podaną domenę w czasie głębokiego uśpienia.
- ESP_PD_OPTION_ON - utrzymuj zasilanie na podanej domenie.
- ESP_PD_OPTION_AUTO - automatyczne ustawienie. Otrzymuje zasilania na domenach wymaganych do wybudzenia. W innym przypadku je wyłącza.
esp_deep_sleep_enable_timer_wakeup - uruchomienie timera do wybudzania układu z uśpienia.
- esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us);
Jako argument podawany jest czas mikrosekundach, Natomiast jego dokładność zależy od zegara RTC SLOW_CLOCK. Do wybudzenia nie trzeba zasilać pamięci RTC podczas uśpienia. Wartości zwracane są takie sam jak w przypadku esp_deep_sleep_pd_config.
esp_deep_sleep_enable_ext0_wakeup - uruchamianie wybudzenia poprzez podany podany pin.
- esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
Funkcja zwraca takie same argumenty jak funkcje opisane powyżej.
Jako argumenty podaje się numery pinów. Do wyboru są tylko te piny które posiadają funkcjonalność RTC (0, 2, 4, 12 - 15, 25 - 27, 32 - 39). Drugi argument podaje się stan jakim ma być obudzony układ. 0 dla stanu niskiego, 1 dla stanu wysokiego.
esp_deep_sleep_start - uruchamianie uśpienia.
- void esp_deep_sleep_start();
Przed jej wywołaniem należy skonfigurować sposoby wybudzania. Bez konfiguracji wybudzenie nie będzie możliwe. Funkcja nie zwraca żadnych wartości.
esp_deep_sleep_get_ext0_wakeup_status - pozwala na sprawdzenie czy wybudzenie zostało wywołane z pinów przypisanych do ext0.
esp_deep_sleep_get_ext0_wakeup_status - to samo co dla funkcji powyżej tylko z innego przerwania.
Implementacja w programie:
Poniżej funkcje znajdujące się w przygotowanej bibliotece. Funkcja pozwalająca na uruchomienie wybranego pinu:
- static uint8_t configGpioForEnableInterrupt(gpio_num_t gpio_num, uint8_t enablePullUp, uint8_tenablePullDown)
- {
- esp_err_t status;
- if(enablePullUp == enablePullDown) {
- return 1; /* Return Error */
- }
- if(gpio_num > 2) {
- return 1; /* Return Error */
- }
- if(enablePullUp == 1) { gpio_pullup_en(gpio_num); }
- else { gpio_pullup_dis(gpio_num); }
- if(enablePullDown == 1) { gpio_pulldown_en(gpio_num); }
- else { gpio_pulldown_dis(gpio_num); }
- if((gpio_num == 0) && enablePullUp == 1) { esp_deep_sleep_enable_ext0_wakeup(gpio_num, 0); }
- else if(gpio_num == 0 && enablePullDown == 1) { esp_deep_sleep_enable_ext0_wakeup(gpio_num, 1); }
- else if(gpio_num == 1 && enablePullUp == 1) { esp_deep_sleep_enable_ext1_wakeup(gpio_num, 0); }
- else if(gpio_num == 1 && enablePullDown == 1) { esp_deep_sleep_enable_ext1_wakeup(gpio_num, 1); }
- return 0;
- }
Ustawienie domeny zasilania:
- static uint8_t configPowerDomain()
- {
- esp_err_t status;
- status = esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_AUTO);
- if(status == ESP_OK) { return 0; }
- return 1;
- }
Uruchomienie timera w trybie uśpienia:
- static uint8_t enableTimerForSleepMode(uint32_t time)
- {
- esp_err_t status;
- esp_deep_sleep_enable_timer_wakeup(time * DEEP_SLEEP_DURATION);
- if(status == ESP_OK) { return 0; }
- return 1;
- }
Przykładowa konfiguracja do uruchomienia timera oraz jednego pinu do wybudzania z uśpienia:
- void SleepFunction(void)
- {
- configGpioForEnableInterrupt(IO_TRIGGER, 1, 0);
- enableTimerForSleepMode(3000000LL);
- esp_deep_sleep_start();
- }
Można je konfigurować osobno jak i połączone razem. Można je wywoływać osobno jak i razem. W przykładzie umieszczonym powyżej wybudzenie może nastąpić po przez sygnał niski z pinu lub po przekroczeniu czasu w timerze.