Jeśli nie możemy zastosować trybu deep sleep trzeba wykorzystać inne tryby dostępne w mikrokontrolerze zmniejszające pobór prądu.
Wszystko o tych trybach znajdziemy w dokumentacji firmowej tu>>> i tu>>>> choć dotarcie i zrozumienie wszystkich zawartych tam informacji nie będzie wcale oczywiste.
Skorzystajmy więc z doświadczenia innych osób analizujących ten temat .
W skrócie dostępne są 3 tryby usypiania ESP
O deep sleep już wiem wszystko - jest świetny i procesor ogranicza pobór prądu do ok 20 uA. Ale jak pisałem tryb jest nieprzydatny dla ESP-01S (choć nie do końca o czym w drugiej części wpisu).
Tryb Modem sleep i Light sleep występuje w dwu odmianach
- automatycznym
- wymuszonym
Tryb Light sleep
Pozostaje nam Light sleep. Inspiracją jest niniejszy wpis na https://community.blynk.cc)
To tryb mocno zbliżony do modem sleep ale oprócz modułu WiFI dodatkowo wstrzymywana jest jednostka centralna procesora CPU. Producent obiecuje iż w tym trybie średni pobór prądu to około 1 mA. To już coś!
Automatyczne wprowadzenie mikrokontrolera w tryb Light sleep
Mikrokontroler samoistnie przechodzi w tryb ligth sleep gdy użyjemy funkcji delay()!!Pod dwoma warunkami
- moduł WiFi pracuje jako stacja (tryb STA) - WiFi.mode(WIFI_STA);
- wywołany został rozkaz uruchamiający ten tryb wifi_set_sleep_type(LIGHT_SLEEP_T);
W większości przypadków przy normalnej konfiguracji Arduino IDE polecenie
wifi_set_sleep_type(LIGHT_SLEEP_T) generuje błąd kompilacji. Należy więc jako pierwszą instrukcję w programie umieścić
extern "C" {
#include "user_interface.h"
}
i powinno być OK
Po wykonaniu powyższych procedur mikrokontroler przechodzi w tryb Light sleep automatycznie jeśli w programie użyjemy instrukcji delay(czas); przy czym czas jest różny od zera. Jednak co 100 ms (lub wielokrotność zależną od parametru DTIM routera) procesor będzie samoistnie wybudzany dla sprawdzenia czy nie oczekuje na niego jakaś transmisja w routerze.
Przebieg prądu pobieranego przez procesor wygląda jakoś tak
Średnia wartość prądu obiecywana w tym trybie to kilka mA (przeciętnie 2 -3 mA) mocno uzależniona od sposobu i ilości transmitowanych przez WiFi danych. Poniżej przykładowy program z BLYNK i załączonym trybem light sleep funkcją delay(). Opóźnienie ustawine jest na 0,1 sek by zbyt mocno nie opóźniać działania BLYNKa. Wartość tę trzeba dobrać eksperymentalnie dostosowując ją do specyfiki swojego programu.
extern "C" {
#include "user_interface.h"
}
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
char auth[] = "YourAuthToken";
char ssid[] = "YourNetworkName"; char pass[] = YourPassword";
void setup()
{
Blynk.begin(auth, ssid, pass);
WiFi.mode(WIFI_STA);
wifi_set_sleep_type(LIGHT_SLEEP_T);
}
void loop()
{
Blynk.run();
delay(100); // Put the esp to sleep for 1s
}
Użycie funkcji delay() z reguły całkowicie dewastuje prawidłowe działania procedur w poolingu (takich jak BLYNK czy Timers.h) należy więc dokładnie przeanalizować co będzie się działo w programie gdy umieścimy w nim takie kukułcze jajo.
Wymuszone wprowadzenie mikrokontrolera w tryb Light sleep
Wybudzenie sygnałem zewnętrznym
#include <ESP8266WiFi.h>
char ssid[] = "0000";
char pass[] = "9999";
extern "C" {
#include "user_interface.h"
}
void fpm_wakup_cb_func()
{
wifi_fpm_close(); // disable force sleep function
wifi_set_opmode(STATION_MODE); // set station mode
wifi_station_connect(); // connect to AP
}
void loop(void) {
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE); // set WiFi mode to null mode.
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
wifi_fpm_open(); // enable force sleep
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO2);
wifi_enable_gpio_wakeup(2, GPIO_PIN_INTR_LOLEVEL);
wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func); // Set wakeup callback
wifi_fpm_do_sleep(0xFFFFFFF);
}
W funkcji wifi_fpm_do_sleep ustawiona jest maksymalna wartość 0xFFFFFFF . A to oznacza że procesor jest uśpiony na nieograniczony czas. Pobudką dla procesora jest pojawienie się impulsu H lub L o długości min 3 ms na określonym wejściu procesora (za wyjątkiem portu GPIO16). Impuls H to taki syganał
syganał L wygląda odwrotnie
Trzeba jeszcze określić który port ma służyć do wybudzenia procesora i jakim impulsem ma to robić
gpio_pin_wakeup_enable(GPIO_ID_PIN(nrPin),GPIO_PIN_INTR_LOLEVEL);
powyższa procedura wskazuje na budzenie sygnałem niskim na porcie nrPin a
gpio_pin_wakeup_enable(GPIO_ID_PIN(nrPin),GPIO_PIN_INTR_HILEVEL);
należy wpisać dla wybudzenia sygnałem wysokim.
W powyższym przykładzie wybudzenie następuje poprzez port GPIO2 stanem niskim. W sam raz dla ESP-01.
Możliwość wybudzenia procesora sygnałem na dowolnym pinie to ogromna przewaga LIGHT SLEEP nad DEEP SLEEP, Takim sygnałem może być np. naciśnięcie klawisza, sygnał z czujnika lub dowolny impuls wygenerowany w układzie zewnętrznym.
Jedyny minus takiego rozwiązania to konieczność rozbudowy elektroniki by taki sygnał dostarczyć do mikrokontrolera.
Wybudzenie wewnętrznym zegarem
Producent przewidział jeszcze jeden sposób wybudzenia mikrokontrolera ze stanu light sleep - wybudzenie wewnętrznym zegarem. Fragment programu odpowiedzialnego za tą funkcję wygląda tak
void fpm_wakup_cb_func()
{
wifi_fpm_close(); // disable force sleep function
wifi_set_opmode(STATION_MODE); // set station mode
wifi_station_connect(); // connect to AP
}
// ........ program .............
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE); // set WiFi mode to null mode.
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
wifi_fpm_open(); // enable force sleep
wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func); // Set wakeup callback
wifi_fpm_do_sleep(2000*1000);
//..................................
Na dwie sekundy powinien zostać zawieszony moduł WiFi i CPU. Powinien ..... ale to nie usypia modułu. Z wielu wpisów na ten temat wychodzi jedno - w tym fragmencie chińskie inżyniery coś sknocili i ta funkcja nie działa.
I kropka.
Inne sposoby ograniczenia poboru prądu przez ESP-01
Jak można ograniczyć pobór prądu mikrokontrolera jeśli on sam ma z tym problemy?
Po pierwsze możemy go wyłączyć - wtedy pobór jest najmniejszy z możliwych. Mimo pozornego absurdu takiego rozwiązania nie jest on pozbawiony sensu.
Sposób 1
Układ cyklicznie załączający/wyłączający procesor jest banalnie prosty. Wystarczy jakikolwiek tranzystor sterowany przebiegiem 0/1 o odpowiednio dobranych czasach by odcinać nim zasilanie procesora.
Układem generującym przebieg 0/1 może być znakomity 555. Ustawiając czasy np. zał/wył = 1 min/1 godz zyskujemy 60 krotne zmniejszenie poboru prądu.
R2 ustali czas stanu niskiego
R1 + R2 określi czas trwania stanu wysokiego
Oczywiście sam układ 555 będzie dodatkowym odbiornikiem ale jeśli zastosujemy jego wersję CMOS średni prąd pobierany przez taki układ będzie mniejszy niż 1 mA. Dlaczego trzeba załączyć ESP na 1 min? Niestety procedury logowania do sieci WiFi i do serwera BLYNK zabierają kilkanaście do kilkudziesięciu sekund + czas potrzebny do wykonania jakiegoś zadania przez mikrokontroler.
Sposób 2
Jeszcze łatwiej możemy wyłączyć procesor poprzez podanie stanu niskiego na wejście CH_PD dostępne w module ESP-01.
W takim przypadku prąd procesora spada do ok 200 uA (to głównie prąd płynący przez opornik polaryzacyjny pinu CH_PD) a wejście CH_PD może być bezpośrednio sterowane z wyjścia generatora 555.
Sposób 3
Odmianą powyższego może być połączenie trybu deep sleep z wybudzeniem modułu ESP-01 zewnętrznym sygnałem RESET z generatora 555. Ten sposób jest nawet lepszy bo optymalizuje czas wyłączenia dokładnie według potrzeb programu. Po zakończeniu wszystkich wymaganych działań procesor sam siebie usypia i czeka na kolejny zewnętrzny sygnał wybudzjący RST. No i nie ma dodatkowego przepływu prądu przez rezystor polaryzacyjny RST w stanie uśpienia
I to na razie tyle. A o przyszłość niech się martwi nasz ciąg dalszy.
Linki
https://blog.creations.de/?p=149
https://www.losant.com/blog/making-the-esp8266-low-powered-with-deep-sleep
https://randomnerdtutorials.com/esp8266-deep-sleep-with-arduino-ide/
136
ok
OdpowiedzUsuń