Redukcja zużycia energii elektrycznej w projektach IoT z użyciem płytki Micromis Base V1

Źródła zasilania urządzeń IoT bardzo często są najbardziej problematyczną częścią projektu. W przypadku zasilania bateryjnego lub akumulatorowego musimy określić wymagany czas pracy urządzenia na jednym pakiecie oraz zadbać o to aby był możliwie jak najdłuższy. W tym poradniku omówimy poszczególne metody oszczędzania energii elektrycznej dla projektów IoT, które bazują na platformie Micromis Base V1.

Podzespoły

Micromis Base V1
x1
Karta SIM w formacie nanoSIM
x1
Antena GSM ze złączem U.FL

Opis projektu

Podczas tego poradnika omówimy metody optymalizacji zużycia energii elektrycznej w projektach bazujących na platformie Micromis Base V1. Ze względu na możliwości komunikacji płytki przy pomocy WiFi oraz Bluetooth przez układ ESP32 oraz z siecią GSM przez modem Quectel M65 poradnik zostanie podzielony na część podzieloną na optymalizację zużycia energii przez układ ESP32 oraz zużycia energii przez modem GSM.

Do testów wykorzystamy oprogramowanie stworzone na potrzeby poradnika “Przesyłanie odczytów z czujników do Arkuszy Google przy pomocy płytki Micromis Base V1”.

Wykonanie poradnika wymaga posiadania płytki Micromis Base V1, anteny GSM ze złączem U.FL oraz aktywnej karty SIM.

Funkcje omówione w trakcie tego poradnika mogą zostać wykorzystane w kolejnych projektach IoT jako gotowe elementy kodu pozwalające na redukcję zużycia energii elektrycznej.

Zadania w projekcie

Krok 1 - Konfiguracja sprzętowej części projektu

Pierwszym krokiem do rozpoczęcia prac nad projektem jest podłączenie anteny GSM do złącza U.FL w płytce Micromis Base V1 oraz włożenie karty nanoSIM do dedykowanego slotu. Upewnij się, że karta SIM jest aktywna i ma wystarczające środki na połączenie z internetem.

Krok 2 - Konfigurowanie środowiska Arduino IDE

Do uruchomienia programu tworzonego w ramach tego poradnika niezbędne będzie środowisko Arduino IDE wraz z zainstalowanym zestawem zewnętrznych płytek ESP32. Zalecamy korzystanie z Arduino IDE nie starszego niż wersja 2.0.0. Aby program mógł być prawidłowo wgrany na płytkę Micromis Base V1 należy wybrać płytkę ESP32 Dev Module w „Narzędzia” > „Płytka” i wybrać port, do którego została podłączona płytka Micromis Base V1.

Krok 3 - Utworzenie środowiska omawianego w poradniku “Przesyłanie odczytów z czujników do Arkuszy Google przy pomocy płytki Micromis Base V1”

Do celów testowych niezbędnym elementem jest środowisko na którym będziemy pracować, w trakcie tego poradnika będziemy wykonywać modyfikacje istniejącego już oprogramowania.

Krok 4 - Analiza kodu

Gotowe warianty kodu znajdują się w sekcji “Pliki do pobrania”, w zależności od rodzaju optymalizacji poboru energii elektrycznej możemy wybrać konkretny wariant oprogramowania.

Szczegółowy opis poszczególnych funkcji oprogramowania i użytych poleceń znajduje się w sekcji “Scenariusze optymalizacji

Krok 5 - Test

Aby zaprogramować płytkę Micromis Base V1 i przetestować wybrany wariant optymalizacji wklej zawartość kodu, a następnie kliknij przycisk „wgraj”, żeby przetestować program!

Uwaga! Jeśli podczas wgrywania programu pojawi się błąd: 

“A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode”. 

Wystarczy przytrzymać przycisk “boot” do momentu, kiedy pokaże się wiadomość “Connecting… ” w oknie wyjściowym. To powinno rozwiązać problem.

Krok 6 - Efekty optymalizacji

Wykonanie optymalizacji opisanej w tym poradniku umożliwi zmniejszenie zużycia energii elektrycznej przez płytkę Micromis Base V1 w trybie bezczynności. Dzięki umiejętności ograniczania zużycia energii możemy pozwolić sobie na dłuższe działanie urządzeń IoT, które często pobierają dane w odległych miejscach.

 

Scenariusze optymalizacji

Charakterystyka projektów IoT zakłada, że urządzenia raportują o zebranych danych w pewnych interwałach czasowych, czasami są to krótkie interwały, które zakładają względnie dużą częstotliwość raportów, jednak zazwyczaj nie ma potrzeby wysyłania częstych raportów więc możemy sobie pozwolić na raportowanie raz na kilka godzin.

Jeśli przytoczymy przykład urządzenia opracowanego w ramach poradnika “Przesyłanie odczytów z czujników do Arkuszy Google przy pomocy płytki Micromis Base V1” to zdajemy sobie sprawę, że realny czas potrzebny na pobranie informacji z czujnika, a następnie przesłanie ich do Arkusza Google trwa zaledwie 15 sekund. Domyślnie po przesłaniu danych następuje minuta bezczynności urządzenia, które oczekuje na kolejne pobranie danych oraz ich przesłanie. Cykl urządzenia trwa więc 75 sekund z których 80% to bezczynność urządzenia.

Pamiętajmy, że urządzenie to domyślnie pracuje w bardzo krótkich cyklach. A co w przypadku założenia, że dane wysyłane są po godzinie bezczynności? Wtedy pobieranie danych z czujnika oraz przesyłanie ich do arkusza wynosi 0,04% całego cyklu, a pozostałe 99,6% czasu to bezczynność urządzenia. Ze względu na tak dużą różnicę pomiędzy czasem potrzebnym na pobieranie oraz wysyłanie danych, a czasem bezczynności warto skupić się na optymalizacji zużycia prądu elektrycznego w czasie, w którym urządzenie jest w trybie bezczynności.

Aktualne zużycie prądu w projekcie

Na samym początku musimy zająć się pomiarem prądu, który pobiera płytka Micromis Base V1 w trakcie pracy. Ze względu na fakt optymalizacji poboru energii w trakcie bezczynności nie będziemy skupiać się na elementach wykresu, które dotyczą momentu pobierania danych z czujników oraz wysyłania ich do arkusza.

Poniższy wykres prezentuje pobór prądu w ciągu minuty, istotny są dla nas dane przedstawione po 20 sekundzie działania urządzenia. Informują nas o tym, że urządzenie w trybie bezczyności pobiera prąd na poziomie 35 mA.

Aby zwizualizować pobór prądu w urządzeniu możemy porównać przeciętną pojemność ogniwa bateryjnego AA, która wynosi 2500 mAh. Oczywiście jedno ogniwo AA nie pozwoli na zasilenie płytki Micromis Base V1, dlatego musimy tymczasowo zapomnieć o napięciu. Gdyby napięcie baterii AA wynosiło 5V i pozwalałoby na zasilenie płytki Micromis Base V1 to w trybie bezczynności bez wprowadzenia jakiejkolwiek optymalizacji urządzenie mogłoby pracować przez 71 godzin. Zakładając, że urządzenie, które zaprojektowaliśmy ma cyklicznie przesyłać raporty czas 71 godzin jest niezwykle krótki.

Co możemy zrobić aby wydłużyć ten czas?

Optymalizacja pracy układu ESP32

Wykorzystany w płytce Micromis Base V1 układ ESP32 posiada liczne funkcje pozwalające na redukcję zużycia prądu w trakcie jego pracy. Mowa tutaj o trybach zasilania, dostępnych jest aż 5 trybów:

  • Tryb Active – włączone są wszystkie podzespoły układu ESP32, włącznie z WiFi, Bluetooth oraz układami radiowymi – w zależności od uruchomionych protokołów układ pobiera od 90 do nawet 250 mA
  • Tryb Modem Sleep – włączone są wszystkie podzespoły poza WiFi, Bluetooth i układami radiowymi – układ pobiera od 3 do 20 mA – w tym trybie obecnie pracuje układ- Tryb Light Sleep – włączony pozostaje tylko procesor, koprocesor ULP oraz układy RTC – w tej konfiguracji ESP32 pobiera od 0,4 do 1mA
  • Tryb Light Sleep – włączony pozostaje tylko procesor, koprocesor ULP oraz układy RTC – w tej konfiguracji ESP32 pobiera od 0,4 do 1mA
  • Tryb Deep Sleep – włączony pozostaje tylko koprocesor ULP oraz układy RTC, mamy dostęp do pamięci RTC – ESP32 pobiera tylko 10uA
  • Tryb Hibernation – pracuje tylko główny układ RTC, który odpowiedzialny jest za odmierzanie czasu, nie mamy dostępu do pamięci RTC – ESP32 pobiera w tym trybie zaledwie 2,5uA

Znając poszczególne tryby zasilania ESP32 możemy zastanowić się nad tym jaki tryb będzie najbardziej odpowiedni dla czasu bezczynności urządzenia w naszym projekcie.

Najbardziej oczywiste wydaje się wybranie trybu hibernacji, jednak warto pamiętać o tym, że korzystając z niego nie mamy dostępu do pamięci RTC w której możemy przechowywać informacje. Jakie dane możemy przechowywać w pamięci RTC? W przypadku projektu wykorzystującego modem GSM w pamięci warto zapisywać fakt wykonania konfiguracji modemu, którą należy wykonać tylko raz ze względu na zapis ustawień w pamięci wewnętrznej modemu.

Aby móc skorzystać z pamięci RTC i zapisać w niej informację o wykonanej konfiguracji wykorzystamy tryb Deep Sleep. Jak go użyć?

Do kodu z poradnika “Przesyłanie odczytów z czujników do Arkuszy Google przy pomocy płytki Micromis Base V1” zostanie dodanych kilka dodatkowych linijek. Na początku musimy dodać do oprogramowania deklaracje konwersji czasu z mikrosekund na sekundy oraz ustalić czas działania trybu Deep Sleep. Do ustalenia konwersji czasu oraz czasu działania trybu wykorzystujemy dwie linijki:

C++
#define CONVERT_US 1000000 //Conversion microseconds to seconds
#define DEEP_SLEEP_TIME  60 //Deep Sleep time in seconds

Wartość zmiennej CONVERT_US powinna pozostać w każdym przypadku taka sama, czasem trwania trybu Deep Sleep możemy zarządzać w zmiennej DEEP_SLEEP_TIME. Zmienna ta przechowuje informacje o czasie trwania trybu, wyrażonego w sekundach. Jeśli chcemy aby pomiędzy kolejnymi odczytami i wysyłaniem danych nastąpiła 10 minutowa przerwa podczas której zostanie aktywowany tryb Deep Sleep to zmienna powinna wynosić:

C++
#define DEEP_SLEEP_TIME  600 //Deep Sleep time in seconds

A jeśli chcemy pobierać i przesyłać dane w dwugodzinnych odstępach to powinna wynosić:

C++
#define DEEP_SLEEP_TIME  7200 //Deep Sleep time in seconds

Po ustaleniu czasu trwania trybu Deep Sleep możemy przejść do stworzenia zmiennej, która będzie przechowywać informacje o wykonanej konfiguracji modemu. Aby zmienna została zapisana w pamięci RTC budowa jej deklaracji musi wyglądać w następujący sposób:

C++
RTC_DATA_ATTR typ_zmiennej nazwa_zmiennej = wartość_zmiennej

Przykładowo, deklaracja zmiennej logicznej bool, która będzie przechowywać informacje o skonfigurowaniu modemu powinna wynosić:

C++
RTC_DATA_ATTR bool isModemConfiguration = false; //Variable to storage information about modem configuration

Oczywiście w pamięci RTC możemy zawrzeć również zmienną innego typu, dla zmiennej typu String deklaracja zmiennej będzie wynosić:

C++
RTC_DATA_ATTR String modemIMEI =112233445566778”;

Gdy wiemy już co czego służą przedstawione wyżej zmienne możemy przejść do modyfikacji kodu. Aby to zrobić wystarczy wkleić poniższe zmienne na początku naszego kodu:

C++
#define CONVERT_US 1000000 //Conversion microseconds to seconds
#define DEEP_SLEEP_TIME  60 //Deep Sleep time in seconds

RTC_DATA_ATTR bool isModemConfiguration = false; //Variable to storage information about modem configuration

Tak aby pierwsze linijki kodu wynosiły:

C++
//Include library of temperature sensor
#include <Temperature_LM75_Derived.h>
Generic_LM75 temperature; //Creating object for library

#define CONVERT_US 1000000 //Conversion microseconds to seconds
#define DEEP_SLEEP_TIME  60 //Deep Sleep time in seconds

RTC_DATA_ATTR bool isModemConfiguration = false; //Variable to storage information about modem configuration

//Defines the RX and TX pins for the cellular modem
#define RXD2 16
#define TXD2 17
Expand

A nie:

C++
//Include library of temperature sensor
#include <Temperature_LM75_Derived.h>
Generic_LM75 temperature; //Creating object for library

//Defines the RX and TX pins for the cellular modem
#define RXD2 16
#define TXD2 17

Po dodaniu nowych zmiennych musimy zmodyfikować funkcję setup i loop. Ze względu na to, że po wyjściu z trybu Deep Sleep ESP32 wykonuje reset, a nasze urządzenie wykonuje tylko jednorazowe odczytanie danych i przesłanie ich do Arkuszy Google nie powinniśmy korzystać z funkcji loop, a umieszczać wszystkie instrukcje w funkcji setup.

Na samym początku musimy sprawić aby konfiguracja modemu była wykonywana tylko raz. Aby to zrobić musimy dodać prostą instrukcję warunkową, która sprawdzi czy wartość zmiennej isModemConfiguration wynosi false. Jeśli wartość zmiennej będzie wskazywać na brak konfiguracji modemu to program musi ją wykonać i zmienić status zmiennej isModemConfiguration na true. Przy każdym kolejnym wybudzeniu z funkcji Deep Sleep konfiguracja modemu będzie pomijana. Aby program wykonywał tą instrukcję musimy do niego dodać poniższe linijki kodu:

C++
  if(!isModemConfiguration)
  {
    configurationModem(); //Configuration GSM modem
    isModemConfiguration = true; //The modem has been configured
  }

Gdy mamy pewność, że modem będzie konfigurowany tylko raz możemy przejść do dodania uruchomienia trybu Deep Sleep na końcu funkcji setup, aby to zrobić musimy dodać dwie linijki kodu:

C++
esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * CONVERT_US); //Set time to wake up
esp_deep_sleep_start(); //Start Deep Sleep

Funkcja esp_sleep_enable_timer_wakeup odpowiada za ustalenie czasu po którym układ ESP32 wyjdzie z trybu Deep Sleep i wróci do pracy w standardowym trybie. Do wyliczenia czasu funkcja wykorzystuje określone wcześniej zmienne DEEP_SLEEP_TIME oraz CONVERT_US. Oczywiście moglibyśmy do funkcji wprowadzić czas w mikrosekundach, jednak użycie zmiennych jest znacznie prostsze. Po ustaleniu czasu trwania trybu Deep Sleep należy wywołać jego uruchomienie przy pomocy funkcji esp_deep_sleep_start. Warto pamiętać o tym aby umieszczać tą funkcję na samym końcu instrukcji, jeśli w kolejnych linijkach dodamy jakiekolwiek instrukcję to nie zostaną one wykonane. 

Po dodaniu powyższych funkcji musimy przenieść wywołanie funkcji sendUpdate z funkcji loop do funkcji setup. Wywołanie sendUpdate musimy dodać pomiędzy wywołanie funkcji networkCheck, a rozpoczęcie pracy trybu Deep Sleep. Obecnie funkcje setup i loop powinny wynosić:

C++
void setup() 
{
  Serial.begin(115200); //Start main UART interface
  Serial.setTimeout(100); //Set timeout for main UART interface
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); //Configure and start Serial2 UART interface
  pinMode(MODEM_PWRKEY, OUTPUT); //Set MODEM_PWRKEY as output
  Wire.begin(); //Run resources for I2C temperature sensor
  Serial2.setTimeout(100); //Set timeout for Serial2 UART interface
  setupModem(); //Run GSM modem
  if(!isModemConfiguration)
  {
    configurationModem(); //Configuration GSM modem
    isModemConfiguration = true; //The modem has been configured
  }
  networkCheck(); //Check status of cellular connection
  sendUpdate(temperature.readTemperatureC(), getModemTime()); //Send data to Google Sheet endpoint
  Serial.print("ESP32 Deep Sleep for "); //Printing information in Serial Monitor
  Serial.print(DEEP_SLEEP_TIME); //Printing Deep Sleep time in Serial Monitor
  Serial.println(" seconds"); //Printing information in Serial Monitor
  esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * CONVERT_US); //Set time to wake up
  esp_deep_sleep_start(); //Start Deep Sleep
}

void loop() 
{
}
Expand

Po wprowadzeniu wszystkich zmian do kodu możemy wgrać go na płytkę Micromis Base V1 i sprawdzić jego działanie. Podczas pierwszego cyklu wykonywania programu modem po uruchomieniu powinien zostać skonfigurowany. Następnie urządzenie pobiera dane z czujnika i przesyła je do arkusza, a następnie wprowadza układ ESP32 w tryb Deep Sleep. Przy każdym kolejnym cyklu program powinien pomijać konfigurację modemu i po jego włączeniu przechodzić od razu do sprawdzenia połączenia z siecią.

Gdy mamy pewność, że program działa prawidłowo możemy przejść do sprawdzenia zużycia prądu w urządzeniu podczas przerwy pomiędzy raportami. Podobnie jak w przypadku poprzedniego wykresu obserwujemy dane po 20 sekundzie pomiaru. 

Obecnie pobór prądu w czasie bezczynności urządzenia wynosi 10 mA, czyli 3,5x mniej od urządzenia, które nie wykorzystuje trybu Deep Sleep. Analizując zużycie na przykładzie pojemności baterii AA czas pracy urządzenia zwiększa się z 71 na 250 godzin. Niestety nadal nie jest to satysfakcjonujący wynik ponieważ to niewiele więcej niż 10 dni pracy urządzenia w trybie bezczynności. Aby jeszcze bardziej wydłużyć czas pracy musimy zająć się optymalizacją zużycia prądu przez modem.

Optymalizacja pracy modemu Quectel M65

W trakcie działania trybu Deep Sleep w układzie ESP32 zostaje wyłączona większość podzespołów, eliminuje to w dużym stopniu zużycie prądu, musimy pamiętać jednak, że w trakcie działania tego trybu zostają wyłączone tylko podzespoły ESP32, a nie całego urządzenia. Łatwo zauważyć, że program nie posiada żadnej funkcji, która zmienia tryb pracy modemu. Co możemy zrobić aby obniżyć zużycie prądu przez modem w trakcie bezczynności urządzenia? Mamy do dyspozycji trzy możliwości:

  • Wyłączenie modemu
  • Uśpienie modemu
  • Wyłączenie funkcji sieciowych modemu

Każda z tych możliwości charakteryzuje się innymi skutkami oraz różnym działaniem modemu podczas kolejnego raportowania. Ze względu na niską skuteczność wyłączania funkcji sieciowych modułów GSM nie będziemy omawiać tej możliwości. Skupimy się jedynie na wyłączaniu oraz usypianiu modemu, dodanie funkcji wyłączania modemu jest niezwykle proste i w przypadku naszego projektu wymaga dodania jedynie jednej linijki kodu do funkcji setup, jednak jakie są różnice pomiędzy wyłączeniem modemu a jego uśpieniem?

Po wyłączeniu modemu, rozłącza on połączenie z siecią komórkową oraz aktywnymi wątkami GPRS i TCP/IP. Oznacza to, że po ponownym włączeniu modemu będziemy musieli zaczekać aż połączy się z siecią i od nowa aktywuje wątki, które wykorzystujemy do przesyłania danych.

W przypadku uśpienia modemu modem tymczasowo zawiesza aktywne wątki oraz połączenia, dzięki czemu szybko może je przywrócić. Dodatkowo modem może zostać wybudzony przez wiadomość SMS lub informację z sieci WEB co daje duże możliwości w zakresie kontrolowania jego pracy.

Aby porównać zużycie prądu przez całą płytkę w czasie bezczynności w obu scenariuszach musimy zmodyfikować oprogramowanie i zmierzyć pobór prądu w obu przypadkach.

Na samym początku dodamy do programu funkcję wyłączania modemu, aby to zrobić musimy dodać tylko jedną linijkę kodu, która wyłącza modem:

C++
Serial2.println("AT+QPOWD=1"); //Turn off modem

Polecenie to należy dodać do funkcji setup, pomiędzy wywołanie funkcji sendUpdate, a wywołaniem funkcji wprowadzającej ESP32 w tryb Deep Sleep. Funkcja setup z dodanym poleceniem powinna wynosić:

C++
void setup() 
{
  Serial.begin(115200); //Start main UART interface
  Serial.setTimeout(100); //Set timeout for main UART interface
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); //Configure and start Serial2 UART interface
  pinMode(MODEM_PWRKEY, OUTPUT); //Set MODEM_PWRKEY as output
  Wire.begin(); //Run resources for I2C temperature sensor
  Serial2.setTimeout(100); //Set timeout for Serial2 UART interface
  setupModem(); //Run GSM modem
  if(!isModemConfiguration)
  {
    configurationModem(); //Configuration GSM modem
    isModemConfiguration = true; //The modem has been configured
  }
  networkCheck(); //Check status of cellular connection
  sendUpdate(temperature.readTemperatureC(), getModemTime()); //Send data to Google Sheet endpoint
  Serial2.println("AT+QPOWD=1"); //Turn off modem
  Serial.print("ESP32 Deep Sleep for "); //Printing information in Serial Monitor
  Serial.print(DEEP_SLEEP_TIME); //Printing Deep Sleep time in Serial Monitor
  Serial.println(" seconds"); //Printing information in Serial Monitor
  esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * CONVERT_US); //Set time to wake up
  esp_deep_sleep_start(); //Start Deep Sleep
}
Expand

Po wgraniu kodu możemy go przetestować, w przeciwieństwie do wersji oprogramowania, która optymalizuje zużycie prądu wyłącznie przez wprowadzenie układu ESP32 w tryb Deep Sleep tutaj w każdym cyklu powinniśmy otrzymywać komunikat o włączeniu modemu przez pin PWR_KEY

Po pomiarach zużycia prądu możemy zauważyć, że urządzenie w stanie bezczynności przy wyłączonym modemie oraz ESP32 w trybie Deep Sleep pobiera średnio 3 mA, co w przeliczeniu na zużycie ogniwa bateryjnego o pojemności 2500 mAh daje nam wynik prawie 35 dni pracy. Jest to już zdecydowanie lepszy rezultat niż w przypadku 10 mA, które pozwalają na pracę przez 10 dni.

Obecnie modem na czas bezczynności zostaje całkowicie wyłączony jednak ze względu na utracenie połączeń, działania wątków oraz brak możliwości wybudzenia modemu przez zewnętrzne połączenie nie zawsze będzie to dobre rozwiązanie. W takiej sytuacji dużo lepiej sprawdzi się usypianie modemu.

Aby wdrożyć funkcję usypiania będziemy musieli użyć pin MAIN_DTR modemu, który pozwala na jego wybudzanie, możemy nim sterować przez 26 pin ESP32. Na samym początku musimy przejść do pierwszych linijek kodu i pod linijką definiującą pin ESP32 odpowiedzialny za sterowanie pinem PWR_KEY modemu, a następnie wkleić poniższą linijkę:

C++
const int MODEM_DTR = 26; //Define pin for modem DTR pin

Po dodaniu linijki kodu odpowiedzialnej za zdefiniowanie pinu musimy przejść do funkcji setup, jeśli znajduje się w niej polecenie odpowiedzialne za wyłączenie modemu to należy je usunąć. W miejsce polecenia wyłączającego modem należy dodać poniższą linijkę:

C++
Serial2.println("AT+QSCLK=1"); //Turn on sleep mode on modem

A pomiędzy linijki z poleceniami Serial2.setTimeout(100) oraz modemWakeup() dodać:

C++
pinMode(MODEM_DTR, OUTPUT); //Set MODEM_DTR as output
modemWakeup(); //Wakeup modem from sleep mode

Pierwsza z powyższych linijek kodu deklaruje pin zadeklarowany jako MODEM_DTR jako wyjściowy, a druga uruchamia funkcję modemWakeup, którą dodamy za chwilę. Obecnie funkcja setup powinna wynosić:

C++
void setup() 
{
  Serial.begin(115200); //Start main UART interface
  Serial.setTimeout(100); //Set timeout for main UART interface
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); //Configure and start Serial2 UART interface
  pinMode(MODEM_PWRKEY, OUTPUT); //Set MODEM_PWRKEY as output
  Wire.begin(); //Run resources for I2C temperature sensor
  Serial2.setTimeout(100); //Set timeout for Serial2 UART interface
  pinMode(MODEM_DTR, OUTPUT); //Set MODEM_DTR as output
  modemWakeup(); //Wakeup modem from sleep mode
  setupModem(); //Run GSM modem
  if(!isModemConfiguration)
  {
    configurationModem(); //Configuration GSM modem
    isModemConfiguration = true; //The modem has been configured
  }
  networkCheck(); //Check status of cellular connection
  sendUpdate(temperature.readTemperatureC(), getModemTime()); //Send data to Google Sheet endpoint
  Serial2.println("AT+QSCLK=1"); //Turn on sleep mode on modem
  Serial.print("ESP32 Deep Sleep for "); //Printing information in Serial Monitor
  Serial.print(DEEP_SLEEP_TIME); //Printing Deep Sleep time in Serial Monitor
  Serial.println(" seconds"); //Printing information in Serial Monitor
  esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * CONVERT_US); //Set time to wake up
  esp_deep_sleep_start(); //Start Deep Sleep
}
Expand

Ostatnim elementem do dodania jest krótka funkcja, która będzie odpowiadać za wybudzenie modemu przez podanie stanu wysokiego na pin MODEM_DTR przez 20 ms oraz wyłączenie trybu uśpienia. Możemy ją dodać w dowolne miejsce powyżej funkcji setup.

C++
//Function to wakeup modem from sleep mode
void modemWakeup()
{
  digitalWrite(MODEM_DTR, HIGH); //Turning on MAIN_DTR pin for modem wakeup
  delay(20); //20 ms pause
  digitalWrite(MODEM_DTR, LOW); //Turning off MAIN_DTR pin for modem wakeup
  delay(100); //100 ms pause
  Serial2.println("AT+QSCLK=0"); //Disable sleep mode
}

Teraz możemy ponownie grać program na płytkę Micromis Base V1 i ponownie sprawdzić pobór prądu. Pomiary pokazują, że pobór prądu w czasie bezczynności urządzenia wynosi 3,2 mA, czyli tylko o 0,2 mA więcej, przy obecnym poborze prądu pojemność ogniwa AA, które wcześniej używaliśmy do porównań pozwoli nam na utrzymanie urządzenia przez 32 dni w stanie bezczynności. 

32 dni to całkiem satysfakcjonujący czas! Czy można go jeszcze bardziej wydłużyć? Tak, mamy jeszcze jedną możliwość!

Rozłączenie diod LED sygnalizujących pracę urządzenia

Umieszczone na płytce Micromis Base V1 diody umożliwiają sprawdzenie czy płytka jest zasilana oraz czy modem jest włączony i przetwarza dane. Są to przydatne elementy w codziennej pracy jednak nie są one niezbędne w urządzeniu, którego jedynym zadaniem jest pobieranie danych a następnie przesyłanie ich do określonego punktu dostępu. Aby całkowicie całkowicie wyeliminować pobór prądu generowany przez diody LED wbudowane w płytkę Micromis Base V1 wystarczy wylutować rezystor oznaczony na płytce jako J1.

Po wylutowaniu rezystora oznaczonego jako J1 możemy ponownie wykonać pomiar poboru prądu, obecnie wynosi on 0,2 mA w stanie bezczynności urządzenia, obliczając czas pracy na przykładzie baterii AA o pojemności 2500 mAh uzyskujemy 520 dni pracy urządzenia w stanie bezczynności

Wynik ten pokazuje nam jak bardzo możemy dostosować pracę płytki Micromis Base V1 do naszych potrzeb. Czy tworzyliście już własne urządzenia IoT, które wymagały bardzo niskiego zużycia prądu? Jeśli tak to jak sobie z tym poradziliście?

O Autorze

Nikola Pająk

Absolwentka technologii informatycznych na uniwersytecie w Danii, pasjonuje się elektroniką, kognitywistyką i grą w szachy. Lubi stale poszerzać swoją wiedzę. Miłośniczka sportu, gotowania i spędzania czasu na świeżym powietrzu.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Label
Copyright © 2023 Device Prototype 
|
Polityka prywatności