niedziela, 1 grudnia 2019

ESP-01 ESP-01S jak zmniejszyć pobór prądu

ESP8266 do oszczędnych w poborze prądu nie należy. Co prawda specyfikacja mówi o średnim prądzie 80 mA  ale doświadczenie wie swoje. Zasilacz musi dać co najmniej 300 mA by chiński wynalazek dał się uruchomić i pracował w miarę stabilnie. I oczywiście nie zapominamy o dobrych kondensatorach blokujących - minimum 100uF.  A co zrobić gdy chcemy go zasilać z akumulatorka? Pozostaje nam uśpić pacjenta na możliwie długi czas. O głębokim śnie (deep sleep) już pisałem dosyć dawno temu. Ale sposób ten mimo iż znakomicie ogranicza pobór prądu jest nieprzydatny dla ulubionego ESP-01/S. Nie ma jak wybudzić pacjenta z narkozy - chińskie chłopaki nie pomyśleli o opcji połączenia GPIO16 z RST. Trzeba więc poszukać innych rozwiązań by nie trzeba było budować kolejnej elektrowni - zwłaszcza atomowej - dla naszej domowej automatyki. A co dopiero gdy zasilamy nasz moduł z baterii lub akumulatorka.

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
Modem sleep W tym trybie cały procesor działa normalnie za wyjątkiem bloku Wi-Fi. Blok Wi Fi jest w sposób automatyczny lub "ręcznie" wyłączany na określony czas. W trybie modem sleep mikrokontroler pobiera ok 15 mA. To sporo za  dużo jak na bateryjne zasilanie. Na razie zapominamy o tym trybie.

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ś!

Jaka jest różnica pomiędzy wstrzymaniem a wyłączaniem CPU?.  Wstrzymanie pozwala uruchomić CPU od miejsca (w programie), w którym zostało zatrzymane. Wyłączenie CPU (jak to ma miejsce w deep sleep) wymaga uruchomienia procesora od początku - de facto dokonywany jest restart systemu. Jaka to programowa różnica nie trzeba nawet mówić. Choć powiem np. uruchomienie po wstrzymaniu zachowuje wszelkie dane w pamięci RAM a więc w zmiennych w programie. Ale również porty zachowują swój stan sprzed wstrzymania. Jeśli więc przed uśpieniem port miał załączoną na sobie diodę to po wstrzymaniu procesora dioda będzie nadal świecić!

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);
UWAGA
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

 Możemy wprowadzić procesor w stan Light sleep ręcznie - jest to tak zwany Forced Light sleep.  Deklarowany przez producenta pobór prądu w tym stanie to ok 1 mA (u mnie ESP-01S pobiera 0,7mA). Dla wymuszenia tego stanu niezbędna sekwencja rozkazów jest już bardziej złożona

#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


136

Brak komentarzy:

Publikowanie komentarza