piątek, 5 lutego 2021

SERIAL.begin(9600) - jak oszczędzać pamięć

Arduino stało się już tak popularne, że nie ma co o nim się rozpisywać. Do czego służy, co można na nim zrobić dowiecie się z innych portali i poradników. Więc przechodzę do sedna. 
Często nowi posiadacze płytki którzy zaczynają swoją przygodę wcześniej czy później borykają się z problemem nie wystarczającej ilości wolnej pamięci.  Są to skutki bezmyślnego wklejania nie swoich kodów, które nie koniecznie są dobrze napisane. Zaczniemy od prawidłowej obsługi portu szeregowego. To dobre narzędzie, dzięki któremu można kontrolować na ekranie monitora wartości zmiennych. Ale ... ma swoje minusy. Pamięć pochłaniana przez dodanie do programu już samej obsługi Serial jest spora. Jest sposób by nie kasować później instrukcji związanych z nim, bo potrzeba kilka bajtów, po prostu sprytnie go trzeba wyłączyć.

// --- CODE START ------------------------------------------------------------------
#define SERIAL_PRINT false                     // definiujemy makro
                                                                                                                       
void setup()                                                 
{                                                                                                         
    #if SERIAL_PRINT 
    {                                                                // jeśli SERIAL_PRINT jest true                                
          Serial.begin(9600);                             // włącz obsługę Serial i dołacz do kodu
     }
     #endif
}

void loop()                                                   
{
    int x = 10;                                        
    #if SERIAL_PRINT
    {                                                                     // jeśli SERIAL_PRINT jest true
        Serial.print(F("Wartosc x wynosi = "));    // wyswietl na monitorze portu
        Serial.println(x);                                        // inaczej jest to pomijane i nie istnieje
    }
    #endif
}

// --- CODE END ------------------------------------------------------------------

Skompilowany powyższy kod na UNO z wartością: #define SERIAL_PRINT false powoduje, że komunikacja portu szeregowego jest wyłączona, do kodu wynikowego nie są dołączane żadne instrukcje obsługi SERIAL. Użyta pamięć to tylko 444 bajty pogramu i 9 bajtów pamięci dynamicznej.

Szkic używa 444 bajtów (1%) pamięci programu. Maksimum to 32256 bajtów.
Zmienne globalne używają 9 bajtów (0%) pamięci dynamicznej, pozostawiając 2039 bajtów dla zmiennych lokalnych. Maksimum to 2048 bajtów.

Teraz przestawny wartość na prawdziwą, #define SERIAL_PRINT true, w setup dołączana jest obsługa Serial, i zadziała wyświetlenie na ekranie napisu. Po kompilacji jednak, można zauważyć ile pochłonęło to pamięci, a pamiętajmy - tylko raz wyświetlamy coś na ekran, a jeśli takich monitów jest wiele, rozsianych gdzieś po naszym programie ? Użyta pamięć to 1584 bajtów pamięci programu i 188 bajtów pamięci dynamicznej.

Szkic używa 1584 bajtów (4%) pamięci programu. Maksimum to 32256 bajtów.
Zmienne globalne używają 188 bajtów (9%) pamięci dynamicznej, pozostawiając 1860 bajtów dla zmiennych lokalnych. Maksimum to 2048 bajtów.

Także widać, że sama obsługa SERIAL zabiera nam 9% pamięci dynamicznej. Nie wiem czy zauważyliście jeden ważny szczegół. Sposób wypisania komunikatu. Jest tam użyta funkcja F !!! Tu też sporo oszczędzamy, stosuje się ją tylko na tekstów w cudzysłowiu. Gdybyśmy pominęli ją, co robi prawie 99% programistów i zapisało to tak:

Serial.print("Wartosc x wynosi = "); 

zamiast tak : 

Serial.print(F("Wartosc x wynosi = "));

po kompilacji mamy kolejne wykorzystane bajty pamięci dynamicznej, które można oszczędzić. To aż 20 bajtów więcej. 

Szkic używa 1548 bajtów (4%) pamięci programu. Maksimum to 32256 bajtów.
Zmienne globalne używają 208 bajtów (10%) pamięci dynamicznej, pozostawiając 1840 bajtów dla zmiennych lokalnych. Maksimum to 2048 bajtów.

Myślę, że temat komunikacji szeregowej został Wam teraz dobrze przedstawiony - korzystajcie z makr, wyłączajcie zbędne rzeczy i można naprawdę dużo rzeczy w UNO i NANO wcisnąć jak się to robi z głową :-) 

Kto z Was będzie potem patrzeć w monitor jakie wartości są w zmiennych i co wyświetla SERIAL.PRINT ? nikt ... ale w kodzie źródłowym niech sobie będzie, do wsadu w układ nie jest dołączany więc trzeba to robić po prostu tak.








Brak komentarzy:

Prześlij komentarz

BME280 - Sensor temperatury, wilgotności i ciśnienia

  BME280 (ESP32/ESP2866) BME280 to prosty w użyciu czujnik temperatury, wilgotności oraz ciśnienia atmosferycznego. Zasilany jest napię...